Loading csp-lmc-common/csp_lmc_common/CspSubarray.py +179 −166 Original line number Diff line number Diff line Loading @@ -37,17 +37,18 @@ from tango import AttrWriteType, DeviceProxy # PROTECTED REGION ID(CspSubarray.additionnal_import) ENABLED START # from ska.base import SKASubarray, SKASubarrayStateModel #from ska.base import utils from ska.base.commands import ActionCommand, ResultCode from ska.base.commands import ResponseCommand, ResultCode from ska.base.faults import CapabilityValidationError from ska.base.control_model import HealthState, AdminMode, ObsState, ObsMode from .utils.decorators import AdminModeCheck, ObsStateCheck, SubarrayRejectCmd from .utils.cspcommons import CmdExecState from .utils.utils import tango_raise from . import release # PROTECTED REGION END # // CspSubarray.additionnal_import __all__ = ["CspSubarray", "main"] ''' class CspSubarrayStateModel(SKASubarrayStateModel): _subarray_transitions = { ('READY', 'goto_idle_succeeded'): ( Loading @@ -74,7 +75,7 @@ class CspSubarrayStateModel(SKASubarrayStateModel): ) self.logger.info("Update CspSubarrayStateModel") self.update_transitions(self._subarray_transitions) ''' class CspSubarray(SKASubarray): """ CSP subarray functionality is modeled via a TANGCSP.LMC Common Class for the CSPSubarray TANGO Device. Loading Loading @@ -331,7 +332,9 @@ class CspSubarray(SKASubarray): class OnCommand(SKASubarray.OnCommand): def do(self): super().do() device = self.target self.logger.info("Call to OnCommand") for fqdn in device._sc_subarray_fqdn: try: (result_code, message) = device._sc_subarray_proxies[fqdn].On() Loading @@ -355,6 +358,22 @@ class CspSubarray(SKASubarray): class AbortCommand(SKASubarray.AbortCommand): def do(self): device = self.target device_list = device._sc_subarray_assigned_fqdn if not any(device._sc_subarray_assigned_fqdn): # beed to add a check also on PSTBeams belonging to subarray device_list = device._sc_subarray_fqdn for fqdn in device_list: try: proxy = device._sc_subarray_proxies[fqdn] proxy.command_inout_asynch("Abort", self._cmd_ended_cb) except KeyError as key_err: self.logger.warning("No key {} found".format(key_err)) device._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED except tango.DevFailed as tango_err: device._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED self.logger.warning(tango_err.args[0].desc) device._abort_command_event.set() message = "Abort command completed OK" self.logger.info(message) return (ResultCode.OK, message) Loading @@ -362,9 +381,124 @@ class CspSubarray(SKASubarray): class ConfigureCommand(SKASubarray.ConfigureCommand): def do(self): message = "Abort command completed OK" # checks on State, adminMode and obsState values are performed inside the # python decorators # the dictionary with the scan configuration target_device = self.target try: # if the stored configuration attribute is not empty, check # for the received configuration content if target_device._valid_scan_configuration: try: stored_configuration = json.dumps(self._valid_scan_configuration, sort_keys=True) received_configuration = json.dumps(argin, sort_keys=True) # if the received configuration is equal to the last valid configuration and the # state of the subarray is READY than subarray is not re-configured. if (stored_configuration == received_configuration) and (target_device._obs_state == ObsState.READY): self.logger.info("Subarray is going to use the same configuration") return except Exception as e: self.logger.warning(str(e)) # go ahead and parse the received configuration self.validate_scan_configuration(argin) except tango.DevFailed as tango_err: # validation failure msg = "Failure during validation of configuration:{}".format(tango_err.args[0].desc) self.logger.error(msg) tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) # Forward the Configure command to the sub-elements # components (subarrays, pst beams) for device in self._sc_subarray_assigned_fqdn: # reset the command progress counter for each # sub-array component target_device._sc_subarray_cmd_progress[device]['configurescan'] = 0 target_device._failure_message['configurescan'] = '' # NOTE: what happens if a sub-element subarray/PSt beam TANGO # device is not running? The next calls to proxy should fail # with a tango.DevFailed exception. if not self._is_sc_subarray_running(device): msg = "Device {} not running".format(device) if device == target_device.CbfSubarray: # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) target_device._failure_message['configurescan'] += msg target_device._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED #skip to next device continue proxy = target_device._sc_subarray_proxies[device] # subscribe sub-elements attributes to track command execution and # timeout on subarray sub-components attributes = ['configureScanCmdProgress', 'timeoutExpiredFlag'] for attr in attributes: try: if target_device._sc_subarray_event_id[attr.lower()] == 0: event_id = proxy.subscribe_event(attr, tango.EventType.CHANGE_EVENT, self._attributes_change_evt_cb, stateless=False) target_device._sc_subarray_event_id[device][attr] = event_id except tango.DevFailed as df: self.logger.info(df.args[0].desc) # NOTE: CBF/PSS sub-array checks for the validity of its # configuration. Failure in configuration throws an exception that is # caught via the _cmd_ended_cb callback try: # read the timeout configured for the operation on the device target_device._sc_subarray_duration_expected[device]['configurescan'] = proxy.configureDelayExpected except AttributeError as attr_err: self.logger.info("No attribute {} on device {}".format(str(attr_err), device)) try: proxy.command_inout_asynch("ConfigureScan", target_device._sc_subarray_scan_configuration[device], self._cmd_ended_cb) self.logger.info("Exec state command flag is {}".format(target_device._sc_subarray_cmd_exec_state[device]['configurescan'])) # Note: check if callaback executed... if target_device._sc_subarray_cmd_exec_state[device]['configurescan'] != CmdExecState.FAILED: target_device._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.RUNNING except tango.DevFailed as tango_err: if device == target_device.CbfSubarray: msg = "Failure in configuring CBF: {}".format(tango_err.args[0].desc) # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) target_device._failure_message['configurescan'] += tango_err.args[0].desc target_device._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED # register the starting time for the command target_device._sc_subarray_cmd_starting_time[device] = time.time() self.logger.debug("configure starting time: {}".format(target_device._sc_subarray_cmd_starting_time[device])) # end for loop on devices # TODO: evaluate the global timeout as the max of the single sub-element # timeouts # configure the timeout for the operation if self._config_delay_expected > 0: target_device._cmd_duration_expected['configurescan'] = self._config_delay_expected self.logger.debug("_config_delay_expected :{}".format(self._config_delay_expected)) # invoke the constructor for the command thread thread_args = [target_device._sc_subarray_assigned_fqdn, argin] self._command_thread['configurescan'] = threading.Thread(target=self.__configure_scan, name="Thread-Configure", args=(thread_args,)) self._abort_command_event.clear() self._cmd_execution_state['configurescan'] = CmdExecState.RUNNING self._cmd_duration_measured['configurescan'] = 0 self._command_thread['configurescan'].start() message = "Configure command started" self.logger.info(message) return (ResultCode.OK, message) return (ResultCode.STARTED, message) class ScanCommand(SKASubarray.ScanCommand): Loading @@ -380,30 +514,10 @@ class CspSubarray(SKASubarray): self.logger.info(message) return (ResultCode.OK, message) ''' class GoToIdleCommand(ActionCommand): class GoToIdleCommand(ResponseCommand): """ A class for the CSPSubarray's GoToIdle() command. """ def __init__(self, target, state_model, logger=None): """ Constructor for GoToIdle :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: SKABaseClassStateModel or a subclass of same :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, "goto_idle", start_action = True, logger=logger) def do(self): """ Stateless hook for GoToIdle() command functionality. Loading Loading @@ -457,6 +571,29 @@ class CspSubarray(SKASubarray): self.logger.info(message) return (ResultCode.STARTED, message) def check_allowed(self): """ Whether this command is allowed to be run in current device state :return: True if this command is allowed to be run in current device state :rtype: boolean :raises: DevFailed if this command is not allowed to be run in current device state """ if not self.state_model.dev_state in [ DevState.FAULT, DevState.UNKNOWN, DevState.DISABLE, ]: tango_raise( "GoToIdle() is not allowed in current state" ) if not self.state_model.admin_mode in [AdminMode.READY]: tango_raise( "GoToIdle() is not allowed in current " ) return True # PROTECTED REGION ID(CspSubarray.class_variable) ENABLED START # # PROTECTED REGION END # // CspSubarray.class_variable Loading Loading @@ -1188,25 +1325,24 @@ class CspSubarray(SKASubarray): self._last_executed_command = cmd_name # reset the CSP Subarray command execution flag self._cmd_execution_state[cmd_name] = CmdExecState.IDLE ''' def _init_state_model(self): """ Sets up the state model for the device """ self.state_model = SKASubarrayStateModel( self.state_model = CspStateModel( dev_state_callback=self._update_state, ) ''' def _init_command_objects(self): def init_command_objects(self): """ Sets up the command objects """ super()._init_command_objects() device_args = (self, self.state_model, self.logger) resource_args = (self.resource_manager, self.state_model, self.logger) super().init_command_objects() self._goto_idle_command = self.GoToIdleCommand(*device_args) args = (self, self.state_model, self.logger) self.register_command_object("GoToIdle", self.GoToIdleCommand(*args)) # ---------------- Loading Loading @@ -2249,119 +2385,6 @@ class CspSubarray(SKASubarray): """ # PROTECTED REGION ID(CspSubarray.Configure) ENABLED START # # checks on State, adminMode and obsState values are performed inside the # python decorators # the dictionary with the scan configuration try: # if the stored configuration attribute is not empty, check # for the received configuration content if self._valid_scan_configuration: try: stored_configuration = json.dumps(self._valid_scan_configuration, sort_keys=True) received_configuration = json.dumps(argin, sort_keys=True) # if the received configuration is equal to the last valid configuration and the # state of the subarray is READY than subarray is not re-configured. if (stored_configuration == received_configuration) and (self._obs_state == ObsState.READY): self.logger.info("Subarray is going to use the same configuration") return except Exception as e: self.logger.warning(str(e)) # go ahead and parse the received configuration self.validate_scan_configuration(argin) except tango.DevFailed as tango_err: # validation failure msg = "Failure during validation of configuration:{}".format(tango_err.args[0].desc) self.logger.error(msg) tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) # Forward the Configure command to the sub-elements # components (subarrays, pst beams) for device in self._sc_subarray_assigned_fqdn: # reset the command progress counter for each # sub-array component self._sc_subarray_cmd_progress[device]['configurescan'] = 0 self._failure_message['configurescan'] = '' # NOTE: what happens if a sub-element subarray/PSt beam TANGO # device is not running? The next calls to proxy should fail # with a tango.DevFailed exception. if not self._is_sc_subarray_running(device): msg = "Device {} not running".format(device) if device == self.CbfSubarray: # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) self._failure_message['configurescan'] += msg self._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED #skip to next device continue proxy = self._sc_subarray_proxies[device] # subscribe sub-elements attributes to track command execution and # timeout on subarray sub-components attributes = ['configureScanCmdProgress', 'timeoutExpiredFlag'] for attr in attributes: try: if self._sc_subarray_event_id[attr.lower()] == 0: event_id = proxy.subscribe_event(attr, tango.EventType.CHANGE_EVENT, self._attributes_change_evt_cb, stateless=False) self._sc_subarray_event_id[device][attr] = event_id except tango.DevFailed as df: self.logger.info(df.args[0].desc) # NOTE: CBF/PSS sub-array checks for the validity of its # configuration. Failure in configuration throws an exception that is # caught via the _cmd_ended_cb callback try: # read the timeout configured for the operation on the device self._sc_subarray_duration_expected[device]['configurescan'] = proxy.configureDelayExpected except AttributeError as attr_err: self.logger.info("No attribute {} on device {}".format(str(attr_err), device)) try: proxy.command_inout_asynch("ConfigureScan", self._sc_subarray_scan_configuration[device], self._cmd_ended_cb) self.logger.info("Exec state command flag is {}".format(self._sc_subarray_cmd_exec_state[device]['configurescan'])) # Note: check if callaback executed... if self._sc_subarray_cmd_exec_state[device]['configurescan'] != CmdExecState.FAILED: self._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.RUNNING except tango.DevFailed as tango_err: if device == self.CbfSubarray: msg = "Failure in configuring CBF: {}".format(tango_err.args[0].desc) # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) self._failure_message['configurescan'] += tango_err.args[0].desc self._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED # register the starting time for the command self._sc_subarray_cmd_starting_time[device] = time.time() self.logger.debug("configure starting time: {}".format(self._sc_subarray_cmd_starting_time[device])) # end for loop on devices # TODO: evaluate the global timeout as the max of the single sub-element # timeouts # configure the timeout for the operation if self._config_delay_expected > 0: self._cmd_duration_expected['configurescan'] = self._config_delay_expected self.logger.debug("_config_delay_expected :{}".format(self._config_delay_expected)) # invoke the constructor for the command thread thread_args = [self._sc_subarray_assigned_fqdn, argin] self._command_thread['configurescan'] = threading.Thread(target=self.__configure_scan, name="Thread-Configure", args=(thread_args,)) self._abort_command_event.clear() self._cmd_execution_state['configurescan'] = CmdExecState.RUNNING self._cmd_duration_measured['configurescan'] = 0 self._command_thread['configurescan'].start() # PROTECTED REGION END # // CspSubarray.Configure @AdminModeCheck('AddNumOfSearchBeams') Loading Loading @@ -2566,7 +2589,8 @@ class CspSubarray(SKASubarray): # PROTECTED REGION END # // CspSubarray.EndScan def is_GoToIdle_allowed(self): return self._goto_idle_command.check_allowed() handler = self.get_command_object("GoToIdle") return handler.check_allowed() @command( dtype_out='DevVarLongStringArray', Loading @@ -2580,8 +2604,9 @@ class CspSubarray(SKASubarray): :return: None """ (return_code, message) = self._goto_idle_command() return [[return_code], [message]] handler = self.get_command_object("GoToIdle") (result_code, message) = handler(argin) return [[result_code], [message]] # PROTECTED REGION END # // CspSubarray.GoToIdle @command( Loading @@ -2596,22 +2621,10 @@ class CspSubarray(SKASubarray): :return:'DevVarLongStringArray' """ device_list = self._sc_subarray_assigned_fqdn if not any(self._sc_subarray_assigned_fqdn): # beed to add a check also on PSTBeams belonging to subarray device_list = self._sc_subarray_fqdn for fqdn in device_list: try: proxy = self._sc_subarray_proxies[fqdn] proxy.command_inout_asynch("Abort", self._cmd_ended_cb) except KeyError as key_err: self.logger.warning("No key {} found".format(key_err)) self._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED except tango.DevFailed as tango_err: self._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED self.logger.warning(tango_err.args[0].desc) self._abort_command_event.set() return [[0], [""]] handler = self.get_command_object("GoToIdle") (result_code, message) = handler(argin) return [[result_code], [message]] # PROTECTED REGION END # // CspSubarray.Abort # ---------- Loading Loading
csp-lmc-common/csp_lmc_common/CspSubarray.py +179 −166 Original line number Diff line number Diff line Loading @@ -37,17 +37,18 @@ from tango import AttrWriteType, DeviceProxy # PROTECTED REGION ID(CspSubarray.additionnal_import) ENABLED START # from ska.base import SKASubarray, SKASubarrayStateModel #from ska.base import utils from ska.base.commands import ActionCommand, ResultCode from ska.base.commands import ResponseCommand, ResultCode from ska.base.faults import CapabilityValidationError from ska.base.control_model import HealthState, AdminMode, ObsState, ObsMode from .utils.decorators import AdminModeCheck, ObsStateCheck, SubarrayRejectCmd from .utils.cspcommons import CmdExecState from .utils.utils import tango_raise from . import release # PROTECTED REGION END # // CspSubarray.additionnal_import __all__ = ["CspSubarray", "main"] ''' class CspSubarrayStateModel(SKASubarrayStateModel): _subarray_transitions = { ('READY', 'goto_idle_succeeded'): ( Loading @@ -74,7 +75,7 @@ class CspSubarrayStateModel(SKASubarrayStateModel): ) self.logger.info("Update CspSubarrayStateModel") self.update_transitions(self._subarray_transitions) ''' class CspSubarray(SKASubarray): """ CSP subarray functionality is modeled via a TANGCSP.LMC Common Class for the CSPSubarray TANGO Device. Loading Loading @@ -331,7 +332,9 @@ class CspSubarray(SKASubarray): class OnCommand(SKASubarray.OnCommand): def do(self): super().do() device = self.target self.logger.info("Call to OnCommand") for fqdn in device._sc_subarray_fqdn: try: (result_code, message) = device._sc_subarray_proxies[fqdn].On() Loading @@ -355,6 +358,22 @@ class CspSubarray(SKASubarray): class AbortCommand(SKASubarray.AbortCommand): def do(self): device = self.target device_list = device._sc_subarray_assigned_fqdn if not any(device._sc_subarray_assigned_fqdn): # beed to add a check also on PSTBeams belonging to subarray device_list = device._sc_subarray_fqdn for fqdn in device_list: try: proxy = device._sc_subarray_proxies[fqdn] proxy.command_inout_asynch("Abort", self._cmd_ended_cb) except KeyError as key_err: self.logger.warning("No key {} found".format(key_err)) device._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED except tango.DevFailed as tango_err: device._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED self.logger.warning(tango_err.args[0].desc) device._abort_command_event.set() message = "Abort command completed OK" self.logger.info(message) return (ResultCode.OK, message) Loading @@ -362,9 +381,124 @@ class CspSubarray(SKASubarray): class ConfigureCommand(SKASubarray.ConfigureCommand): def do(self): message = "Abort command completed OK" # checks on State, adminMode and obsState values are performed inside the # python decorators # the dictionary with the scan configuration target_device = self.target try: # if the stored configuration attribute is not empty, check # for the received configuration content if target_device._valid_scan_configuration: try: stored_configuration = json.dumps(self._valid_scan_configuration, sort_keys=True) received_configuration = json.dumps(argin, sort_keys=True) # if the received configuration is equal to the last valid configuration and the # state of the subarray is READY than subarray is not re-configured. if (stored_configuration == received_configuration) and (target_device._obs_state == ObsState.READY): self.logger.info("Subarray is going to use the same configuration") return except Exception as e: self.logger.warning(str(e)) # go ahead and parse the received configuration self.validate_scan_configuration(argin) except tango.DevFailed as tango_err: # validation failure msg = "Failure during validation of configuration:{}".format(tango_err.args[0].desc) self.logger.error(msg) tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) # Forward the Configure command to the sub-elements # components (subarrays, pst beams) for device in self._sc_subarray_assigned_fqdn: # reset the command progress counter for each # sub-array component target_device._sc_subarray_cmd_progress[device]['configurescan'] = 0 target_device._failure_message['configurescan'] = '' # NOTE: what happens if a sub-element subarray/PSt beam TANGO # device is not running? The next calls to proxy should fail # with a tango.DevFailed exception. if not self._is_sc_subarray_running(device): msg = "Device {} not running".format(device) if device == target_device.CbfSubarray: # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) target_device._failure_message['configurescan'] += msg target_device._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED #skip to next device continue proxy = target_device._sc_subarray_proxies[device] # subscribe sub-elements attributes to track command execution and # timeout on subarray sub-components attributes = ['configureScanCmdProgress', 'timeoutExpiredFlag'] for attr in attributes: try: if target_device._sc_subarray_event_id[attr.lower()] == 0: event_id = proxy.subscribe_event(attr, tango.EventType.CHANGE_EVENT, self._attributes_change_evt_cb, stateless=False) target_device._sc_subarray_event_id[device][attr] = event_id except tango.DevFailed as df: self.logger.info(df.args[0].desc) # NOTE: CBF/PSS sub-array checks for the validity of its # configuration. Failure in configuration throws an exception that is # caught via the _cmd_ended_cb callback try: # read the timeout configured for the operation on the device target_device._sc_subarray_duration_expected[device]['configurescan'] = proxy.configureDelayExpected except AttributeError as attr_err: self.logger.info("No attribute {} on device {}".format(str(attr_err), device)) try: proxy.command_inout_asynch("ConfigureScan", target_device._sc_subarray_scan_configuration[device], self._cmd_ended_cb) self.logger.info("Exec state command flag is {}".format(target_device._sc_subarray_cmd_exec_state[device]['configurescan'])) # Note: check if callaback executed... if target_device._sc_subarray_cmd_exec_state[device]['configurescan'] != CmdExecState.FAILED: target_device._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.RUNNING except tango.DevFailed as tango_err: if device == target_device.CbfSubarray: msg = "Failure in configuring CBF: {}".format(tango_err.args[0].desc) # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) target_device._failure_message['configurescan'] += tango_err.args[0].desc target_device._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED # register the starting time for the command target_device._sc_subarray_cmd_starting_time[device] = time.time() self.logger.debug("configure starting time: {}".format(target_device._sc_subarray_cmd_starting_time[device])) # end for loop on devices # TODO: evaluate the global timeout as the max of the single sub-element # timeouts # configure the timeout for the operation if self._config_delay_expected > 0: target_device._cmd_duration_expected['configurescan'] = self._config_delay_expected self.logger.debug("_config_delay_expected :{}".format(self._config_delay_expected)) # invoke the constructor for the command thread thread_args = [target_device._sc_subarray_assigned_fqdn, argin] self._command_thread['configurescan'] = threading.Thread(target=self.__configure_scan, name="Thread-Configure", args=(thread_args,)) self._abort_command_event.clear() self._cmd_execution_state['configurescan'] = CmdExecState.RUNNING self._cmd_duration_measured['configurescan'] = 0 self._command_thread['configurescan'].start() message = "Configure command started" self.logger.info(message) return (ResultCode.OK, message) return (ResultCode.STARTED, message) class ScanCommand(SKASubarray.ScanCommand): Loading @@ -380,30 +514,10 @@ class CspSubarray(SKASubarray): self.logger.info(message) return (ResultCode.OK, message) ''' class GoToIdleCommand(ActionCommand): class GoToIdleCommand(ResponseCommand): """ A class for the CSPSubarray's GoToIdle() command. """ def __init__(self, target, state_model, logger=None): """ Constructor for GoToIdle :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: SKABaseClassStateModel or a subclass of same :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, "goto_idle", start_action = True, logger=logger) def do(self): """ Stateless hook for GoToIdle() command functionality. Loading Loading @@ -457,6 +571,29 @@ class CspSubarray(SKASubarray): self.logger.info(message) return (ResultCode.STARTED, message) def check_allowed(self): """ Whether this command is allowed to be run in current device state :return: True if this command is allowed to be run in current device state :rtype: boolean :raises: DevFailed if this command is not allowed to be run in current device state """ if not self.state_model.dev_state in [ DevState.FAULT, DevState.UNKNOWN, DevState.DISABLE, ]: tango_raise( "GoToIdle() is not allowed in current state" ) if not self.state_model.admin_mode in [AdminMode.READY]: tango_raise( "GoToIdle() is not allowed in current " ) return True # PROTECTED REGION ID(CspSubarray.class_variable) ENABLED START # # PROTECTED REGION END # // CspSubarray.class_variable Loading Loading @@ -1188,25 +1325,24 @@ class CspSubarray(SKASubarray): self._last_executed_command = cmd_name # reset the CSP Subarray command execution flag self._cmd_execution_state[cmd_name] = CmdExecState.IDLE ''' def _init_state_model(self): """ Sets up the state model for the device """ self.state_model = SKASubarrayStateModel( self.state_model = CspStateModel( dev_state_callback=self._update_state, ) ''' def _init_command_objects(self): def init_command_objects(self): """ Sets up the command objects """ super()._init_command_objects() device_args = (self, self.state_model, self.logger) resource_args = (self.resource_manager, self.state_model, self.logger) super().init_command_objects() self._goto_idle_command = self.GoToIdleCommand(*device_args) args = (self, self.state_model, self.logger) self.register_command_object("GoToIdle", self.GoToIdleCommand(*args)) # ---------------- Loading Loading @@ -2249,119 +2385,6 @@ class CspSubarray(SKASubarray): """ # PROTECTED REGION ID(CspSubarray.Configure) ENABLED START # # checks on State, adminMode and obsState values are performed inside the # python decorators # the dictionary with the scan configuration try: # if the stored configuration attribute is not empty, check # for the received configuration content if self._valid_scan_configuration: try: stored_configuration = json.dumps(self._valid_scan_configuration, sort_keys=True) received_configuration = json.dumps(argin, sort_keys=True) # if the received configuration is equal to the last valid configuration and the # state of the subarray is READY than subarray is not re-configured. if (stored_configuration == received_configuration) and (self._obs_state == ObsState.READY): self.logger.info("Subarray is going to use the same configuration") return except Exception as e: self.logger.warning(str(e)) # go ahead and parse the received configuration self.validate_scan_configuration(argin) except tango.DevFailed as tango_err: # validation failure msg = "Failure during validation of configuration:{}".format(tango_err.args[0].desc) self.logger.error(msg) tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) # Forward the Configure command to the sub-elements # components (subarrays, pst beams) for device in self._sc_subarray_assigned_fqdn: # reset the command progress counter for each # sub-array component self._sc_subarray_cmd_progress[device]['configurescan'] = 0 self._failure_message['configurescan'] = '' # NOTE: what happens if a sub-element subarray/PSt beam TANGO # device is not running? The next calls to proxy should fail # with a tango.DevFailed exception. if not self._is_sc_subarray_running(device): msg = "Device {} not running".format(device) if device == self.CbfSubarray: # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) self._failure_message['configurescan'] += msg self._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED #skip to next device continue proxy = self._sc_subarray_proxies[device] # subscribe sub-elements attributes to track command execution and # timeout on subarray sub-components attributes = ['configureScanCmdProgress', 'timeoutExpiredFlag'] for attr in attributes: try: if self._sc_subarray_event_id[attr.lower()] == 0: event_id = proxy.subscribe_event(attr, tango.EventType.CHANGE_EVENT, self._attributes_change_evt_cb, stateless=False) self._sc_subarray_event_id[device][attr] = event_id except tango.DevFailed as df: self.logger.info(df.args[0].desc) # NOTE: CBF/PSS sub-array checks for the validity of its # configuration. Failure in configuration throws an exception that is # caught via the _cmd_ended_cb callback try: # read the timeout configured for the operation on the device self._sc_subarray_duration_expected[device]['configurescan'] = proxy.configureDelayExpected except AttributeError as attr_err: self.logger.info("No attribute {} on device {}".format(str(attr_err), device)) try: proxy.command_inout_asynch("ConfigureScan", self._sc_subarray_scan_configuration[device], self._cmd_ended_cb) self.logger.info("Exec state command flag is {}".format(self._sc_subarray_cmd_exec_state[device]['configurescan'])) # Note: check if callaback executed... if self._sc_subarray_cmd_exec_state[device]['configurescan'] != CmdExecState.FAILED: self._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.RUNNING except tango.DevFailed as tango_err: if device == self.CbfSubarray: msg = "Failure in configuring CBF: {}".format(tango_err.args[0].desc) # throw the exception, configuration can't proceed tango.Except.throw_exception("Command failed", msg, "Configure", tango.ErrSeverity.ERR) self._failure_message['configurescan'] += tango_err.args[0].desc self._sc_subarray_cmd_exec_state[device]['configurescan'] = CmdExecState.FAILED # register the starting time for the command self._sc_subarray_cmd_starting_time[device] = time.time() self.logger.debug("configure starting time: {}".format(self._sc_subarray_cmd_starting_time[device])) # end for loop on devices # TODO: evaluate the global timeout as the max of the single sub-element # timeouts # configure the timeout for the operation if self._config_delay_expected > 0: self._cmd_duration_expected['configurescan'] = self._config_delay_expected self.logger.debug("_config_delay_expected :{}".format(self._config_delay_expected)) # invoke the constructor for the command thread thread_args = [self._sc_subarray_assigned_fqdn, argin] self._command_thread['configurescan'] = threading.Thread(target=self.__configure_scan, name="Thread-Configure", args=(thread_args,)) self._abort_command_event.clear() self._cmd_execution_state['configurescan'] = CmdExecState.RUNNING self._cmd_duration_measured['configurescan'] = 0 self._command_thread['configurescan'].start() # PROTECTED REGION END # // CspSubarray.Configure @AdminModeCheck('AddNumOfSearchBeams') Loading Loading @@ -2566,7 +2589,8 @@ class CspSubarray(SKASubarray): # PROTECTED REGION END # // CspSubarray.EndScan def is_GoToIdle_allowed(self): return self._goto_idle_command.check_allowed() handler = self.get_command_object("GoToIdle") return handler.check_allowed() @command( dtype_out='DevVarLongStringArray', Loading @@ -2580,8 +2604,9 @@ class CspSubarray(SKASubarray): :return: None """ (return_code, message) = self._goto_idle_command() return [[return_code], [message]] handler = self.get_command_object("GoToIdle") (result_code, message) = handler(argin) return [[result_code], [message]] # PROTECTED REGION END # // CspSubarray.GoToIdle @command( Loading @@ -2596,22 +2621,10 @@ class CspSubarray(SKASubarray): :return:'DevVarLongStringArray' """ device_list = self._sc_subarray_assigned_fqdn if not any(self._sc_subarray_assigned_fqdn): # beed to add a check also on PSTBeams belonging to subarray device_list = self._sc_subarray_fqdn for fqdn in device_list: try: proxy = self._sc_subarray_proxies[fqdn] proxy.command_inout_asynch("Abort", self._cmd_ended_cb) except KeyError as key_err: self.logger.warning("No key {} found".format(key_err)) self._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED except tango.DevFailed as tango_err: self._sc_subarray_cmd_exec_state[fqdn]['abort'] = CmdExecState.FAILED self.logger.warning(tango_err.args[0].desc) self._abort_command_event.set() return [[0], [""]] handler = self.get_command_object("GoToIdle") (result_code, message) = handler(argin) return [[result_code], [message]] # PROTECTED REGION END # // CspSubarray.Abort # ---------- Loading