Loading csp-lmc-common/csp_lmc_common/CspSubarray.py +188 −117 Original line number Original line Diff line number Diff line Loading @@ -26,7 +26,7 @@ import json # tango imports # tango imports import tango import tango from tango import DebugIt from tango import DebugIt, EnsureOmniThread from tango.server import run from tango.server import run from tango.server import Device from tango.server import Device from tango.server import attribute, command from tango.server import attribute, command Loading @@ -44,6 +44,7 @@ from .utils.cspcommons import CmdExecState from .utils.decorators import transaction_id from .utils.decorators import transaction_id from . import release from . import release from .csp_manage_json import JsonConfiguration from .csp_manage_json import JsonConfiguration from .csp_subarray_state_model import CspSubarrayStateModel # PROTECTED REGION END # // CspSubarray.additionnal_import # PROTECTED REGION END # // CspSubarray.additionnal_import __all__ = ["CspSubarray", "main"] __all__ = ["CspSubarray", "main"] Loading Loading @@ -115,6 +116,69 @@ class CspSubarray(SKASubarray): """ """ class ForceObsStateTransitionCommand(ActionCommand): def __init__(self, target, state_model, logger=None): """ Constructor for ForceObsStateTransition. It's not a TANGO command. This command in invoked at CSP.LMC Subarray re-initialization. :param target: the object that this command acts upon; for example, the SKASubarray device for which this class implements the command :type target: object :param state_model: the state model that this command uses to check that it is allowed to run, and that it drives with actions. :type state_model: :py:class:`SKASubarrayStateModel` :param logger: the logger to be used by this Command. If not provided, then a default module logger will be used. :type logger: a logger that implements the standard library logger interface """ super().__init__( target, state_model, "force", start_action=False, logger=logger ) self.action = None def __call__(self, argin=None): """ Override the __call__ method to set the action to execute when the succeeded method is called. """ self.action = argin super().__call__(argin) def check_allowed(self): """ check_allowed is invoked before the do() in the command __call__ method. The basic behavior is to check for a transition named 'force_succeeded'. At re-initialization there are several 'succeeded' transitions, depending on the expected observing state of the CSP Subarray, so it's necessary to modify the succeeded method name with the one stored in the action attribute. """ self.logger.info("check for transition trigger {}".format(self.action)) self._succeeded_hook = self.action return super().check_allowed() def do(self, argin): self.action = argin return (ResultCode.OK, f"Executed {argin}") def succeeded(self): """ Action to take on successful completion of device server re-initialization. """ self.logger.info("Execute succeeded with arg {}".format(self.action)) if not self.action: self.logger.info("Action not specified!!") self.state_model.perform_action(self.action) def failed(self): self.state_model.perform_action("fatal_error") class InitCommand(SKASubarray.InitCommand): class InitCommand(SKASubarray.InitCommand): """ """ A class for the SKASubarray's init_device() "command". A class for the SKASubarray's init_device() "command". Loading @@ -131,6 +195,8 @@ class CspSubarray(SKASubarray): (result_code, message) = super().do() (result_code, message) = super().do() device = self.target device = self.target self.logger.info("CspSubarray INIT COMMAND STARTED!!") self.logger.info("CspSubarray obs_state: {}".format(device._obs_state)) device._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) device._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) device._version_id = release.version device._version_id = release.version # connect to CSP.LMC TANGO DB # connect to CSP.LMC TANGO DB Loading Loading @@ -308,34 +374,27 @@ class CspSubarray(SKASubarray): #device._reserved_search_beam_num = 0 #device._reserved_search_beam_num = 0 device._assigned_timing_beams= [] device._assigned_timing_beams= [] device._assigned_vlbi_beams = [] device._assigned_vlbi_beams = [] device.init_thread = threading.Thread(target=self.initialize_thread,name="Thread-Initialization ObsState Alignment", # Try connection with the CBF sub-array args=()) device.connect_to_subarray_subcomponent(device.CbfSubarray) device.init_thread.start() # Try connection with the PSS sub-array device.connect_to_subarray_subcomponent(device.PssSubarray) # to use the push model in command_inout_asynch (the one with the callback parameter), # to use the push model in command_inout_asynch (the one with the callback parameter), # change the global TANGO model to PUSH_CALLBACK. # change the global TANGO model to PUSH_CALLBACK. apiutil = tango.ApiUtil.instance() apiutil = tango.ApiUtil.instance() apiutil.set_asynch_cb_sub_model(tango.cb_sub_model.PUSH_CALLBACK) apiutil.set_asynch_cb_sub_model(tango.cb_sub_model.PUSH_CALLBACK) self.logger.info(message) return (ResultCode.STARTED, "CSP Subarray Init STARTED") alignment_thr = threading.Thread(target=self.obs_state_alignment, name="Thread-Initialization ObsState Alignment", args=()) alignment_thr.start() return (result_code, message) def obs_state_alignment(self): def initialize_thread(self): try: with EnsureOmniThread(): self.logger.info("Init thread started") device = self.target device = self.target # create a list with all the obs_states of sub-elements args = (device, device.state_model, self.logger) # !!! delete the logger !!! self.force_cmd_obj = device.ForceObsStateTransitionCommand(*args) self.logger.info(f'obs state of CBF: {device._sc_subarray_obs_state[self.CbfSubarray].name}') device.on_cmd_obj = device.OnCommand(*args) #list of obs_states of sub-elements obs_states_list = [str(device._sc_subarray_obs_state[fqdn]) for fqdn in device._sc_subarray_fqdn] obs_states_list = [device._sc_subarray_obs_state[fqdn].name for fqdn in device._sc_subarray_fqdn] # obs_state of cbf_subarray # obs_state of cbf_subarray #cbf_obs_state = device._sc_subarray_obs_state[self.CbfSubarray].name #cbf_obs_state = device._sc_subarray_obs_state[self.CbfSubarray].name # allowed coupled states for different sub-elements # allowed coupled states for different sub-elements Loading @@ -350,9 +409,24 @@ class CspSubarray(SKASubarray): transitional_states = allowed_coupled.keys() transitional_states = allowed_coupled.keys() timeout = 10 # seconds timeout = 10 # seconds # Try connection with the CBF sub-array device.connect_to_subarray_subcomponent(device.CbfSubarray) # Try connection with the PSS sub-array device.connect_to_subarray_subcomponent(device.PssSubarray) # to put the device in OFF/EMPTY self.succeeded() if device._sc_subarray_state[device.CbfSubarray] is not DevState.ON: self.logger.info('devo leggerlo se sono alla prima inizializzazione') return # to put the device in ON/EMPTY self.logger.info('Non devo leggerlo se sono alla prima inizializzazione') device.on_cmd_obj.succeeded() # CASE B: CBF is ON # CASE B: CBF is ON if device._sc_subarray_state[self.CbfSubarray] == DevState.ON: self.logger.info('CSP is already ON. Aligning to Sub-elements...') # start a loop in case of transitional states (CASE 2) # start a loop in case of transitional states (CASE 2) timeout = 10 starting_time = time.time() starting_time = time.time() exit_loop = False exit_loop = False while time.time() - starting_time < timeout or exit_loop: while time.time() - starting_time < timeout or exit_loop: Loading @@ -362,11 +436,11 @@ class CspSubarray(SKASubarray): if not transitional_present: if not transitional_present: # CASE 1.1: All obsStates are EQUAL # CASE 1.1: All obsStates are EQUAL if len(set(obs_states_list)) == 1: if len(set(obs_states_list)) == 1: self.state_model._update_obs_state(obs_states_list[0]) self.set_csp_obs_state(obs_states_list[0]) exit_loop = True exit_loop = True # CASE 1.1: obsStates are DIFFERENT # CASE 1.1: obsStates are DIFFERENT else: else: self.state_model._update_obs_state('FAULT') self.set_csp_obs_state('FAULT') exit_loop = True exit_loop = True # CASE 2: Transitional states ARE present # CASE 2: Transitional states ARE present else: else: Loading @@ -374,17 +448,30 @@ class CspSubarray(SKASubarray): for sub_elt_obs_state in obs_states_list: for sub_elt_obs_state in obs_states_list: # CASE 2.1: Other obs_states are NOT ALLOWED # CASE 2.1: Other obs_states are NOT ALLOWED if sub_elt_obs_state is not (state or allowed_coupled[state]): if sub_elt_obs_state is not (state or allowed_coupled[state]): self.state_model._update_obs_state('FAULT') self.set_csp_obs_state('FAULT') exit_loop = True exit_loop = True break break # CASE 2.2: Other obs_states are ALLOWED # CASE 2.2: Other obs_states are ALLOWED else: else: self.state_model._update_obs_state(state) self.set_csp_obs_state(state) # CASE A: CBF is OFF except Exception as msg: else: self.logger.info(f'error in thread: {msg}') self.state_model._update_op_state('OFF') def set_csp_obs_state(self, state): self.state_model._update_obs_state('EMPTY') self.force_cmd_obj(f"force_to_{state.lower()}") # if device._sc_subarray_obs_state[device.CbfSubarray] == ObsState.IDLE: # force_cmd_obj("force_to_idle") # self.logger.info(self.state_model.obs_state) # self.logger.info(self._obs_state) # if device._sc_subarray_obs_state[device.CbfSubarray] == ObsState.ABORTED: # force_cmd_obj("force_to_aborted") # self.logger.info(self.state_model.obs_state) # self.logger.info(self._obs_state) # if device._sc_subarray_obs_state[device.CbfSubarray] == ObsState.READY: # self.logger.info("force_to_ready") # force_cmd_obj("force_to_ready") # self.logger.info(self.state_model.obs_state) # self.logger.info(self._obs_state) class OnCommand(SKASubarray.OnCommand): class OnCommand(SKASubarray.OnCommand): def do(self): def do(self): Loading Loading @@ -759,26 +846,26 @@ class CspSubarray(SKASubarray): self.logger.info("CspSubarray timeout flag:{}".format(target_device._timeout_expired)) self.logger.info("CspSubarray timeout flag:{}".format(target_device._timeout_expired)) if target_device._abort_obs_event.is_set(): if target_device._abort_obs_event.is_set(): if target_device._timeout_expired or target_device._failure_raised: if target_device._timeout_expired or target_device._failure_raised: return target_device._abort_cmd_obj.failed() return self.failed() self.logger.info("Abort configure ends with success!!") self.logger.info("Abort configure ends with success!!") if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): return target_device._abort_cmd_obj.succeeded() return self.succeeded() return target_device._abort_cmd_obj.abort_monitoring(device_list) return target_device.abort_cmd_obj.abort_monitoring(device_list) if target_device._timeout_expired or target_device._failure_raised: if target_device._timeout_expired or target_device._failure_raised: # if failure/timeout found check if the CBF subarray is configured. In # if failure/timeout found check if the CBF subarray is configured. In # this case the CSP.LMC Subarray obsState is set to READY. # this case the CSP.LMC Subarray obsState is set to READY. if target_device._sc_subarray_obs_state[target_device.CbfSubarray] == ObsState.READY: if target_device._sc_subarray_obs_state[target_device.CbfSubarray] == ObsState.READY: return target_device._configure_cmd_obj.succeeded() return self.succeeded() self.logger.info("Configure ends with failure") self.logger.info("Configure ends with failure") return target_device._configure_cmd_obj.failed() return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.READY for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.READY for fqdn in device_list): target_device._valid_scan_configuration = input_arg[1] target_device._valid_scan_configuration = input_arg[1] target_device._cmd_duration_measured[cmd_name] = time.time() - command_start_time target_device._cmd_duration_measured[cmd_name] = time.time() - command_start_time target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("Configure ends with success!!") self.logger.info("Configure ends with success!!") return target_device._configure_cmd_obj.succeeded() return self.succeeded() def validate_scan_configuration(self, argin): def validate_scan_configuration(self, argin): """ """ Loading Loading @@ -913,9 +1000,9 @@ class CspSubarray(SKASubarray): return return if target_device._abort_obs_event.is_set(): if target_device._abort_obs_event.is_set(): if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._abort_cmd_obj.failed() return target_device.abort_cmd_obj.failed() self.logger.info("Abort of scan command ends with success!") self.logger.info("Abort of scan command ends with success!") return target_device._abort_cmd_obj.succeeded() return target_device.abort_cmd_obj.succeeded() class EndScanCommand(SKASubarray.EndScanCommand): class EndScanCommand(SKASubarray.EndScanCommand): Loading Loading @@ -967,7 +1054,7 @@ class CspSubarray(SKASubarray): if target_device._sc_subarray_obs_state[device] == ObsState.IDLE: if target_device._sc_subarray_obs_state[device] == ObsState.IDLE: continue continue if target_device._sc_subarray_obs_state[device] == ObsState.READY: if target_device._sc_subarray_obs_state[device] == ObsState.READY: (result_code, msg) = target_device._gotoidle_cmd_obj.do() (result_code, msg) = target_device.gotoidle_cmd_obj.do() return (result_code, msg) return (result_code, msg) for device in devices_to_reset: for device in devices_to_reset: try: try: Loading Loading @@ -1024,13 +1111,13 @@ class CspSubarray(SKASubarray): # end of the while loop # end of the while loop # check for timeout/failure conditions on each sub-component # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._obsreset_cmd_obj.failed() return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("ObsReset ends with success") self.logger.info("ObsReset ends with success") return target_device._obsreset_cmd_obj.succeeded() return self.succeeded() class AbortCommand(SKASubarray.AbortCommand): class AbortCommand(SKASubarray.AbortCommand): Loading Loading @@ -1105,13 +1192,13 @@ class CspSubarray(SKASubarray): # end of the while loop # end of the while loop # check for timeout/failure conditions on each sub-component # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._abort_cmd_obj.failed() return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("Abort ends with success") self.logger.info("Abort ends with success") return target_device._abort_cmd_obj.succeeded() return self.succeeded() class RestartCommand(SKASubarray.RestartCommand): class RestartCommand(SKASubarray.RestartCommand): Loading Loading @@ -1188,13 +1275,13 @@ class CspSubarray(SKASubarray): # end of the while loop # end of the while loop # check for timeout/failure conditions on each sub-component # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._restart_cmd_obj.failed() return target_device.restart_cmd_obj.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("Restart ends with success") self.logger.info("Restart ends with success") return target_device._restart_cmd_obj.succeeded() return target_device.restart_cmd_obj.succeeded() ''' ''' class GoToIdleCommand(ActionCommand): class GoToIdleCommand(ActionCommand): Loading Loading @@ -1364,14 +1451,14 @@ class CspSubarray(SKASubarray): self.logger.info("1") self.logger.info("1") target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._gotoidle_cmd_obj.failed() return target_device.gotoidle_cmd_obj.failed() self.logger.info("2") self.logger.info("2") if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name # reset the CSP Subarray command execution flag # reset the CSP Subarray command execution flag target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE return target_device._gotoidle_cmd_obj.succeeded() return target_device.gotoidle_cmd_obj.succeeded() def check_allowed(self): def check_allowed(self): """ """ Loading Loading @@ -1506,7 +1593,8 @@ class CspSubarray(SKASubarray): # update CSP sub-array SCM # update CSP sub-array SCM #07-2020: with the new base classes, transitions are handled via actions. #07-2020: with the new base classes, transitions are handled via actions. #if evt.attr_value.name.lower() in ["state", "healthstate", "adminmode", "obsstate"]: #if evt.attr_value.name.lower() in ["state", "healthstate", "adminmode", "obsstate"]: # self.update_subarray_state() if evt.attr_value.name.lower() in ["obsstate"]: self.update_subarray_state() if evt.attr_value.name.lower() == "healthstate": if evt.attr_value.name.lower() == "healthstate": self._update_subarray_health_state() self._update_subarray_health_state() except tango.DevFailed as df: except tango.DevFailed as df: Loading Loading @@ -1655,28 +1743,7 @@ class CspSubarray(SKASubarray): :return: None :return: None """ """ self._update_subarray_health_state() self.logger.info("update_subarray_state") if self._command_thread: a = [self._command_thread[cmd_name].is_alive() for cmd_name in self._command_thread.keys()] self.logger.info("list of running threds:{}".format(a)) if any(self._command_thread[cmd_name].is_alive() for cmd_name in self._command_thread.keys()): self.logger.info("A command is already running...the obsState is not updated") return False # CSP state reflects the status of CBF. Only if CBF is present # CSP can work. The state of PSS and PST sub-elements only contributes # to determine the CSP health state. if self._sc_subarray_state[self.CbfSubarray] == DevState.OFF: if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: self._off_cmd_obj.succeeded() if self._sc_subarray_state[self.CbfSubarray] == DevState.ON: if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: self._on_cmd_obj.succeeded() if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.READY: self._configure_cmd_obj.succeeded() #self.set_state(self._sc_subarray_state[self.CbfSubarray]) #self.logger.info("Csp subarray state: {} obsState: {}".format(self.get_state(), self.state_model._obs_state)) return True def _update_subarray_health_state(self): def _update_subarray_health_state(self): """ """ Loading Loading @@ -1903,30 +1970,34 @@ class CspSubarray(SKASubarray): # ---------------- # ---------------- # Class private methods # Class private methods # ---------------- # ---------------- ''' def _init_state_model(self): def _init_state_model(self): """ """ Sets up the state model for the device Sets up the state model for the device """ """ self.state_model = CspSubarrayStateModel( self.state_model = CspSubarrayStateModel( dev_state_callback=self._update_state, logger=self.logger, op_state_callback=self._update_state, admin_mode_callback=self._update_admin_mode, obs_state_callback=self._update_obs_state, ) ) ''' def init_command_objects(self): def init_command_objects(self): """ """ Sets up the command objects Sets up the command objects. The init_command_method is called after InitCommand in the SKABaseDevice class. This means that the command object handler has to be defined into the InitCommandClass. """ """ super().init_command_objects() super().init_command_objects() args = (self, self.state_model, self.logger) args = (self, self.state_model, self.logger) self._configure_cmd_obj = self.ConfigureCommand(*args) #self.configure_cmd_obj = self.ConfigureCommand(*args) self._off_cmd_obj = self.OffCommand(*args) self.scan_cmd_obj = self.ScanCommand(*args) self._on_cmd_obj = self.OnCommand(*args) self.gotoidle_cmd_obj = self.GoToIdleCommand(*args) self._scan_cmd_obj = self.ScanCommand(*args) self.abort_cmd_obj = self.AbortCommand(*args) self._gotoidle_cmd_obj = self.GoToIdleCommand(*args) self.restart_cmd_obj = self.RestartCommand(*args) self._obsreset_cmd_obj = self.ObsResetCommand(*args) self._abort_cmd_obj = self.AbortCommand(*args) self._restart_cmd_obj = self.RestartCommand(*args) self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) Loading csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py +14 −0 Original line number Original line Diff line number Diff line Loading @@ -450,6 +450,20 @@ class MidCspSubarrayBase(CspSubarray): self.logger.debug("len assigned_receptors:{}".format(assigned_receptors)) self.logger.debug("len assigned_receptors:{}".format(assigned_receptors)) return len(assigned_receptors) return len(assigned_receptors) def init_command_objects(self): """ Sets up the command objects """ super().init_command_objects() args = (self, self.state_model, self.logger) self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) self.register_command_object("ReleaseResources", self.ReleaseResourcesCommand(*args)) self.register_command_object("ReleaseAllResources", self.ReleaseAllResourcesCommand(*args)) def update_subarray_state(self): def update_subarray_state(self): """ """ Class protected method. Class protected method. Loading Loading
csp-lmc-common/csp_lmc_common/CspSubarray.py +188 −117 Original line number Original line Diff line number Diff line Loading @@ -26,7 +26,7 @@ import json # tango imports # tango imports import tango import tango from tango import DebugIt from tango import DebugIt, EnsureOmniThread from tango.server import run from tango.server import run from tango.server import Device from tango.server import Device from tango.server import attribute, command from tango.server import attribute, command Loading @@ -44,6 +44,7 @@ from .utils.cspcommons import CmdExecState from .utils.decorators import transaction_id from .utils.decorators import transaction_id from . import release from . import release from .csp_manage_json import JsonConfiguration from .csp_manage_json import JsonConfiguration from .csp_subarray_state_model import CspSubarrayStateModel # PROTECTED REGION END # // CspSubarray.additionnal_import # PROTECTED REGION END # // CspSubarray.additionnal_import __all__ = ["CspSubarray", "main"] __all__ = ["CspSubarray", "main"] Loading Loading @@ -115,6 +116,69 @@ class CspSubarray(SKASubarray): """ """ class ForceObsStateTransitionCommand(ActionCommand): def __init__(self, target, state_model, logger=None): """ Constructor for ForceObsStateTransition. It's not a TANGO command. This command in invoked at CSP.LMC Subarray re-initialization. :param target: the object that this command acts upon; for example, the SKASubarray device for which this class implements the command :type target: object :param state_model: the state model that this command uses to check that it is allowed to run, and that it drives with actions. :type state_model: :py:class:`SKASubarrayStateModel` :param logger: the logger to be used by this Command. If not provided, then a default module logger will be used. :type logger: a logger that implements the standard library logger interface """ super().__init__( target, state_model, "force", start_action=False, logger=logger ) self.action = None def __call__(self, argin=None): """ Override the __call__ method to set the action to execute when the succeeded method is called. """ self.action = argin super().__call__(argin) def check_allowed(self): """ check_allowed is invoked before the do() in the command __call__ method. The basic behavior is to check for a transition named 'force_succeeded'. At re-initialization there are several 'succeeded' transitions, depending on the expected observing state of the CSP Subarray, so it's necessary to modify the succeeded method name with the one stored in the action attribute. """ self.logger.info("check for transition trigger {}".format(self.action)) self._succeeded_hook = self.action return super().check_allowed() def do(self, argin): self.action = argin return (ResultCode.OK, f"Executed {argin}") def succeeded(self): """ Action to take on successful completion of device server re-initialization. """ self.logger.info("Execute succeeded with arg {}".format(self.action)) if not self.action: self.logger.info("Action not specified!!") self.state_model.perform_action(self.action) def failed(self): self.state_model.perform_action("fatal_error") class InitCommand(SKASubarray.InitCommand): class InitCommand(SKASubarray.InitCommand): """ """ A class for the SKASubarray's init_device() "command". A class for the SKASubarray's init_device() "command". Loading @@ -131,6 +195,8 @@ class CspSubarray(SKASubarray): (result_code, message) = super().do() (result_code, message) = super().do() device = self.target device = self.target self.logger.info("CspSubarray INIT COMMAND STARTED!!") self.logger.info("CspSubarray obs_state: {}".format(device._obs_state)) device._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) device._build_state = '{}, {}, {}'.format(release.name, release.version, release.description) device._version_id = release.version device._version_id = release.version # connect to CSP.LMC TANGO DB # connect to CSP.LMC TANGO DB Loading Loading @@ -308,34 +374,27 @@ class CspSubarray(SKASubarray): #device._reserved_search_beam_num = 0 #device._reserved_search_beam_num = 0 device._assigned_timing_beams= [] device._assigned_timing_beams= [] device._assigned_vlbi_beams = [] device._assigned_vlbi_beams = [] device.init_thread = threading.Thread(target=self.initialize_thread,name="Thread-Initialization ObsState Alignment", # Try connection with the CBF sub-array args=()) device.connect_to_subarray_subcomponent(device.CbfSubarray) device.init_thread.start() # Try connection with the PSS sub-array device.connect_to_subarray_subcomponent(device.PssSubarray) # to use the push model in command_inout_asynch (the one with the callback parameter), # to use the push model in command_inout_asynch (the one with the callback parameter), # change the global TANGO model to PUSH_CALLBACK. # change the global TANGO model to PUSH_CALLBACK. apiutil = tango.ApiUtil.instance() apiutil = tango.ApiUtil.instance() apiutil.set_asynch_cb_sub_model(tango.cb_sub_model.PUSH_CALLBACK) apiutil.set_asynch_cb_sub_model(tango.cb_sub_model.PUSH_CALLBACK) self.logger.info(message) return (ResultCode.STARTED, "CSP Subarray Init STARTED") alignment_thr = threading.Thread(target=self.obs_state_alignment, name="Thread-Initialization ObsState Alignment", args=()) alignment_thr.start() return (result_code, message) def obs_state_alignment(self): def initialize_thread(self): try: with EnsureOmniThread(): self.logger.info("Init thread started") device = self.target device = self.target # create a list with all the obs_states of sub-elements args = (device, device.state_model, self.logger) # !!! delete the logger !!! self.force_cmd_obj = device.ForceObsStateTransitionCommand(*args) self.logger.info(f'obs state of CBF: {device._sc_subarray_obs_state[self.CbfSubarray].name}') device.on_cmd_obj = device.OnCommand(*args) #list of obs_states of sub-elements obs_states_list = [str(device._sc_subarray_obs_state[fqdn]) for fqdn in device._sc_subarray_fqdn] obs_states_list = [device._sc_subarray_obs_state[fqdn].name for fqdn in device._sc_subarray_fqdn] # obs_state of cbf_subarray # obs_state of cbf_subarray #cbf_obs_state = device._sc_subarray_obs_state[self.CbfSubarray].name #cbf_obs_state = device._sc_subarray_obs_state[self.CbfSubarray].name # allowed coupled states for different sub-elements # allowed coupled states for different sub-elements Loading @@ -350,9 +409,24 @@ class CspSubarray(SKASubarray): transitional_states = allowed_coupled.keys() transitional_states = allowed_coupled.keys() timeout = 10 # seconds timeout = 10 # seconds # Try connection with the CBF sub-array device.connect_to_subarray_subcomponent(device.CbfSubarray) # Try connection with the PSS sub-array device.connect_to_subarray_subcomponent(device.PssSubarray) # to put the device in OFF/EMPTY self.succeeded() if device._sc_subarray_state[device.CbfSubarray] is not DevState.ON: self.logger.info('devo leggerlo se sono alla prima inizializzazione') return # to put the device in ON/EMPTY self.logger.info('Non devo leggerlo se sono alla prima inizializzazione') device.on_cmd_obj.succeeded() # CASE B: CBF is ON # CASE B: CBF is ON if device._sc_subarray_state[self.CbfSubarray] == DevState.ON: self.logger.info('CSP is already ON. Aligning to Sub-elements...') # start a loop in case of transitional states (CASE 2) # start a loop in case of transitional states (CASE 2) timeout = 10 starting_time = time.time() starting_time = time.time() exit_loop = False exit_loop = False while time.time() - starting_time < timeout or exit_loop: while time.time() - starting_time < timeout or exit_loop: Loading @@ -362,11 +436,11 @@ class CspSubarray(SKASubarray): if not transitional_present: if not transitional_present: # CASE 1.1: All obsStates are EQUAL # CASE 1.1: All obsStates are EQUAL if len(set(obs_states_list)) == 1: if len(set(obs_states_list)) == 1: self.state_model._update_obs_state(obs_states_list[0]) self.set_csp_obs_state(obs_states_list[0]) exit_loop = True exit_loop = True # CASE 1.1: obsStates are DIFFERENT # CASE 1.1: obsStates are DIFFERENT else: else: self.state_model._update_obs_state('FAULT') self.set_csp_obs_state('FAULT') exit_loop = True exit_loop = True # CASE 2: Transitional states ARE present # CASE 2: Transitional states ARE present else: else: Loading @@ -374,17 +448,30 @@ class CspSubarray(SKASubarray): for sub_elt_obs_state in obs_states_list: for sub_elt_obs_state in obs_states_list: # CASE 2.1: Other obs_states are NOT ALLOWED # CASE 2.1: Other obs_states are NOT ALLOWED if sub_elt_obs_state is not (state or allowed_coupled[state]): if sub_elt_obs_state is not (state or allowed_coupled[state]): self.state_model._update_obs_state('FAULT') self.set_csp_obs_state('FAULT') exit_loop = True exit_loop = True break break # CASE 2.2: Other obs_states are ALLOWED # CASE 2.2: Other obs_states are ALLOWED else: else: self.state_model._update_obs_state(state) self.set_csp_obs_state(state) # CASE A: CBF is OFF except Exception as msg: else: self.logger.info(f'error in thread: {msg}') self.state_model._update_op_state('OFF') def set_csp_obs_state(self, state): self.state_model._update_obs_state('EMPTY') self.force_cmd_obj(f"force_to_{state.lower()}") # if device._sc_subarray_obs_state[device.CbfSubarray] == ObsState.IDLE: # force_cmd_obj("force_to_idle") # self.logger.info(self.state_model.obs_state) # self.logger.info(self._obs_state) # if device._sc_subarray_obs_state[device.CbfSubarray] == ObsState.ABORTED: # force_cmd_obj("force_to_aborted") # self.logger.info(self.state_model.obs_state) # self.logger.info(self._obs_state) # if device._sc_subarray_obs_state[device.CbfSubarray] == ObsState.READY: # self.logger.info("force_to_ready") # force_cmd_obj("force_to_ready") # self.logger.info(self.state_model.obs_state) # self.logger.info(self._obs_state) class OnCommand(SKASubarray.OnCommand): class OnCommand(SKASubarray.OnCommand): def do(self): def do(self): Loading Loading @@ -759,26 +846,26 @@ class CspSubarray(SKASubarray): self.logger.info("CspSubarray timeout flag:{}".format(target_device._timeout_expired)) self.logger.info("CspSubarray timeout flag:{}".format(target_device._timeout_expired)) if target_device._abort_obs_event.is_set(): if target_device._abort_obs_event.is_set(): if target_device._timeout_expired or target_device._failure_raised: if target_device._timeout_expired or target_device._failure_raised: return target_device._abort_cmd_obj.failed() return self.failed() self.logger.info("Abort configure ends with success!!") self.logger.info("Abort configure ends with success!!") if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): return target_device._abort_cmd_obj.succeeded() return self.succeeded() return target_device._abort_cmd_obj.abort_monitoring(device_list) return target_device.abort_cmd_obj.abort_monitoring(device_list) if target_device._timeout_expired or target_device._failure_raised: if target_device._timeout_expired or target_device._failure_raised: # if failure/timeout found check if the CBF subarray is configured. In # if failure/timeout found check if the CBF subarray is configured. In # this case the CSP.LMC Subarray obsState is set to READY. # this case the CSP.LMC Subarray obsState is set to READY. if target_device._sc_subarray_obs_state[target_device.CbfSubarray] == ObsState.READY: if target_device._sc_subarray_obs_state[target_device.CbfSubarray] == ObsState.READY: return target_device._configure_cmd_obj.succeeded() return self.succeeded() self.logger.info("Configure ends with failure") self.logger.info("Configure ends with failure") return target_device._configure_cmd_obj.failed() return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.READY for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.READY for fqdn in device_list): target_device._valid_scan_configuration = input_arg[1] target_device._valid_scan_configuration = input_arg[1] target_device._cmd_duration_measured[cmd_name] = time.time() - command_start_time target_device._cmd_duration_measured[cmd_name] = time.time() - command_start_time target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("Configure ends with success!!") self.logger.info("Configure ends with success!!") return target_device._configure_cmd_obj.succeeded() return self.succeeded() def validate_scan_configuration(self, argin): def validate_scan_configuration(self, argin): """ """ Loading Loading @@ -913,9 +1000,9 @@ class CspSubarray(SKASubarray): return return if target_device._abort_obs_event.is_set(): if target_device._abort_obs_event.is_set(): if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._abort_cmd_obj.failed() return target_device.abort_cmd_obj.failed() self.logger.info("Abort of scan command ends with success!") self.logger.info("Abort of scan command ends with success!") return target_device._abort_cmd_obj.succeeded() return target_device.abort_cmd_obj.succeeded() class EndScanCommand(SKASubarray.EndScanCommand): class EndScanCommand(SKASubarray.EndScanCommand): Loading Loading @@ -967,7 +1054,7 @@ class CspSubarray(SKASubarray): if target_device._sc_subarray_obs_state[device] == ObsState.IDLE: if target_device._sc_subarray_obs_state[device] == ObsState.IDLE: continue continue if target_device._sc_subarray_obs_state[device] == ObsState.READY: if target_device._sc_subarray_obs_state[device] == ObsState.READY: (result_code, msg) = target_device._gotoidle_cmd_obj.do() (result_code, msg) = target_device.gotoidle_cmd_obj.do() return (result_code, msg) return (result_code, msg) for device in devices_to_reset: for device in devices_to_reset: try: try: Loading Loading @@ -1024,13 +1111,13 @@ class CspSubarray(SKASubarray): # end of the while loop # end of the while loop # check for timeout/failure conditions on each sub-component # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._obsreset_cmd_obj.failed() return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("ObsReset ends with success") self.logger.info("ObsReset ends with success") return target_device._obsreset_cmd_obj.succeeded() return self.succeeded() class AbortCommand(SKASubarray.AbortCommand): class AbortCommand(SKASubarray.AbortCommand): Loading Loading @@ -1105,13 +1192,13 @@ class CspSubarray(SKASubarray): # end of the while loop # end of the while loop # check for timeout/failure conditions on each sub-component # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._abort_cmd_obj.failed() return self.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.ABORTED for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("Abort ends with success") self.logger.info("Abort ends with success") return target_device._abort_cmd_obj.succeeded() return self.succeeded() class RestartCommand(SKASubarray.RestartCommand): class RestartCommand(SKASubarray.RestartCommand): Loading Loading @@ -1188,13 +1275,13 @@ class CspSubarray(SKASubarray): # end of the while loop # end of the while loop # check for timeout/failure conditions on each sub-component # check for timeout/failure conditions on each sub-component if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._restart_cmd_obj.failed() return target_device.restart_cmd_obj.failed() if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY for fqdn in device_list): target_device._cmd_progress[cmd_name] = 100 target_device._cmd_progress[cmd_name] = 100 target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name self.logger.info("Restart ends with success") self.logger.info("Restart ends with success") return target_device._restart_cmd_obj.succeeded() return target_device.restart_cmd_obj.succeeded() ''' ''' class GoToIdleCommand(ActionCommand): class GoToIdleCommand(ActionCommand): Loading Loading @@ -1364,14 +1451,14 @@ class CspSubarray(SKASubarray): self.logger.info("1") self.logger.info("1") target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE if target_device._failure_raised or target_device._timeout_expired: if target_device._failure_raised or target_device._timeout_expired: return target_device._gotoidle_cmd_obj.failed() return target_device.gotoidle_cmd_obj.failed() self.logger.info("2") self.logger.info("2") if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): target_device._last_executed_command = cmd_name target_device._last_executed_command = cmd_name # reset the CSP Subarray command execution flag # reset the CSP Subarray command execution flag target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE return target_device._gotoidle_cmd_obj.succeeded() return target_device.gotoidle_cmd_obj.succeeded() def check_allowed(self): def check_allowed(self): """ """ Loading Loading @@ -1506,7 +1593,8 @@ class CspSubarray(SKASubarray): # update CSP sub-array SCM # update CSP sub-array SCM #07-2020: with the new base classes, transitions are handled via actions. #07-2020: with the new base classes, transitions are handled via actions. #if evt.attr_value.name.lower() in ["state", "healthstate", "adminmode", "obsstate"]: #if evt.attr_value.name.lower() in ["state", "healthstate", "adminmode", "obsstate"]: # self.update_subarray_state() if evt.attr_value.name.lower() in ["obsstate"]: self.update_subarray_state() if evt.attr_value.name.lower() == "healthstate": if evt.attr_value.name.lower() == "healthstate": self._update_subarray_health_state() self._update_subarray_health_state() except tango.DevFailed as df: except tango.DevFailed as df: Loading Loading @@ -1655,28 +1743,7 @@ class CspSubarray(SKASubarray): :return: None :return: None """ """ self._update_subarray_health_state() self.logger.info("update_subarray_state") if self._command_thread: a = [self._command_thread[cmd_name].is_alive() for cmd_name in self._command_thread.keys()] self.logger.info("list of running threds:{}".format(a)) if any(self._command_thread[cmd_name].is_alive() for cmd_name in self._command_thread.keys()): self.logger.info("A command is already running...the obsState is not updated") return False # CSP state reflects the status of CBF. Only if CBF is present # CSP can work. The state of PSS and PST sub-elements only contributes # to determine the CSP health state. if self._sc_subarray_state[self.CbfSubarray] == DevState.OFF: if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: self._off_cmd_obj.succeeded() if self._sc_subarray_state[self.CbfSubarray] == DevState.ON: if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: self._on_cmd_obj.succeeded() if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.READY: self._configure_cmd_obj.succeeded() #self.set_state(self._sc_subarray_state[self.CbfSubarray]) #self.logger.info("Csp subarray state: {} obsState: {}".format(self.get_state(), self.state_model._obs_state)) return True def _update_subarray_health_state(self): def _update_subarray_health_state(self): """ """ Loading Loading @@ -1903,30 +1970,34 @@ class CspSubarray(SKASubarray): # ---------------- # ---------------- # Class private methods # Class private methods # ---------------- # ---------------- ''' def _init_state_model(self): def _init_state_model(self): """ """ Sets up the state model for the device Sets up the state model for the device """ """ self.state_model = CspSubarrayStateModel( self.state_model = CspSubarrayStateModel( dev_state_callback=self._update_state, logger=self.logger, op_state_callback=self._update_state, admin_mode_callback=self._update_admin_mode, obs_state_callback=self._update_obs_state, ) ) ''' def init_command_objects(self): def init_command_objects(self): """ """ Sets up the command objects Sets up the command objects. The init_command_method is called after InitCommand in the SKABaseDevice class. This means that the command object handler has to be defined into the InitCommandClass. """ """ super().init_command_objects() super().init_command_objects() args = (self, self.state_model, self.logger) args = (self, self.state_model, self.logger) self._configure_cmd_obj = self.ConfigureCommand(*args) #self.configure_cmd_obj = self.ConfigureCommand(*args) self._off_cmd_obj = self.OffCommand(*args) self.scan_cmd_obj = self.ScanCommand(*args) self._on_cmd_obj = self.OnCommand(*args) self.gotoidle_cmd_obj = self.GoToIdleCommand(*args) self._scan_cmd_obj = self.ScanCommand(*args) self.abort_cmd_obj = self.AbortCommand(*args) self._gotoidle_cmd_obj = self.GoToIdleCommand(*args) self.restart_cmd_obj = self.RestartCommand(*args) self._obsreset_cmd_obj = self.ObsResetCommand(*args) self._abort_cmd_obj = self.AbortCommand(*args) self._restart_cmd_obj = self.RestartCommand(*args) self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) Loading
csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py +14 −0 Original line number Original line Diff line number Diff line Loading @@ -450,6 +450,20 @@ class MidCspSubarrayBase(CspSubarray): self.logger.debug("len assigned_receptors:{}".format(assigned_receptors)) self.logger.debug("len assigned_receptors:{}".format(assigned_receptors)) return len(assigned_receptors) return len(assigned_receptors) def init_command_objects(self): """ Sets up the command objects """ super().init_command_objects() args = (self, self.state_model, self.logger) self._assignresources_cmd_obj = self.AssignResourcesCommand(*args) self._releaseresources_cmd_obj = self.ReleaseResourcesCommand(*args) self.register_command_object("AssignResources", self.AssignResourcesCommand(*args)) self.register_command_object("ReleaseResources", self.ReleaseResourcesCommand(*args)) self.register_command_object("ReleaseAllResources", self.ReleaseAllResourcesCommand(*args)) def update_subarray_state(self): def update_subarray_state(self): """ """ Class protected method. Class protected method. Loading