diff --git a/csp-lmc-common/HISTORY b/csp-lmc-common/HISTORY index 202552793afb1c5930b443c8d4aaf20d74d23482..90b87493eb0a52e731cb65a6f4f9a87a25c17330 100644 --- a/csp-lmc-common/HISTORY +++ b/csp-lmc-common/HISTORY @@ -1,3 +1,7 @@ +0.6.2 +- Finalized support for Configure command. +- Added GoToIdle command subclassing the ActionCommand class. + 0.6.1 - adding support for Configure command diff --git a/csp-lmc-common/csp_lmc_common/CspSubarray.py b/csp-lmc-common/csp_lmc_common/CspSubarray.py index 14c8bb28982cf41b72892c149c2e456be5a73594..a41ee64d2c79f2e5132ad7830b3572eb782c2a2b 100644 --- a/csp-lmc-common/csp_lmc_common/CspSubarray.py +++ b/csp-lmc-common/csp_lmc_common/CspSubarray.py @@ -37,7 +37,7 @@ 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 ResponseCommand, ResultCode +from ska.base.commands import ActionCommand, ResultCode from ska.base.faults import CapabilityValidationError from ska.base.control_model import HealthState, AdminMode, ObsState, ObsMode from .utils.decorators import AdminModeCheck, ObsStateCheck, SubarrayRejectCmd @@ -46,20 +46,16 @@ from . import release # PROTECTED REGION END # // CspSubarray.additionnal_import __all__ = ["CspSubarray", "main"] - class CspSubarrayStateModel(SKASubarrayStateModel): _subarray_transitions = { ('READY', 'goto_idle_succeeded'): ( "IDLE", - lambda self: self._set_dev_state(DevState.ON) - ), - ('READY', 'goto_idle_started'): ( - "READY", - lambda self: self._set_dev_state(DevState.ON) + lambda self: self._set_obs_state(ObsState.IDLE) ), + ('READY', 'goto_idle_started'): ("READY",None), ('READY', 'goto_idle_failed'): ( "OBSFAULT", - lambda self: self._set_dev_state(DevState.FAULT) + lambda self: self._set_obs_state(ObsState.FAULT) ), } @@ -148,6 +144,9 @@ class CspSubarray(SKASubarray): device._config_delay_expected = 10 device._scan_id = 0 device._configuration_id = '' + # flag to signal if we have a recofniguraiton + device._reconfiguring = False + # connect to TANGO DB # use defaultdict to initialize the sub-element State,healthState @@ -427,6 +426,7 @@ class CspSubarray(SKASubarray): except AttributeError as attr_err: self.logger.info("No attribute {} on device {}".format(str(attr_err), device)) try: + self.logger.info("Issue the command") proxy.command_inout_asynch("ConfigureScan", target_device._sc_subarray_scan_configuration[device], target_device._cmd_ended_cb) @@ -437,6 +437,7 @@ class CspSubarray(SKASubarray): except tango.DevFailed as tango_err: if device == target_device.CbfSubarray: msg = "Failure in configuring CBF: {}".format(tango_err.args[0].desc) + self.logger.error(msg) # throw the exception, configuration can't proceed return (ResultCode.FAILED, msg) @@ -462,6 +463,7 @@ class CspSubarray(SKASubarray): target_device._abort_command_event.clear() target_device._cmd_execution_state['configurescan'] = CmdExecState.RUNNING target_device._cmd_duration_measured['configurescan'] = 0 + self.logger.info("Thread started!") target_device._command_thread['configurescan'].start() message = "Configure command started" self.logger.info(message) @@ -484,6 +486,7 @@ class CspSubarray(SKASubarray): :return: None """ target_device = self.target + self.logger.info("__configure scan started!!") cmd_name = 'configurescan' dev_successful_state = ObsState.READY # tango_cmd_name: is the TANGO command name with the capital letter @@ -499,7 +502,9 @@ class CspSubarray(SKASubarray): device_done = defaultdict(lambda:False) # inside the end-less lop check the obsState of each sub-component device_list = input_arg[0] + self.logger.info("device_list:{}".format(device_list)) while True: + self.logger.info("inside the loop!!!") command_progress = 0 for device in device_list: self.logger.info("Command {} obs_state: {}".format(cmd_name, @@ -509,8 +514,8 @@ class CspSubarray(SKASubarray): # if the sub-component execution flag is no more RUNNING, the command has # ended with or without success. Go to check next device state. if target_device._sc_subarray_obs_state[device] == dev_successful_state: - self.logger.info("Reconfiguring is:{}".format(self._reconfiguring)) - if not self._reconfiguring: + self.logger.info("Reconfiguring is:{}".format(target_device._reconfiguring)) + if not target_device._reconfiguring: self.logger.info("Command {} ended with success on device {}.".format(cmd_name, device)) # update the list and number of device that completed the task @@ -554,11 +559,11 @@ class CspSubarray(SKASubarray): target_device._cmd_progress[cmd_name] = command_progress if any(target_device._sc_subarray_obs_state[device] == ObsState.CONFIGURING for device in device_list): target_device._reconfiguring = False - self.logger.info("Reconfiguring is:{}".format(self._reconfiguring)) - self.logger.info("Current CspSubarray ObsState:{}".format(self._obs_state)) + self.logger.info("Reconfiguring is:{}".format(target_device._reconfiguring)) if all(value == True for value in device_done.values()): self.logger.info("All devices have been handled!") break + self.logger.info("6") # check for global timeout expiration # may be this check is not necessary if target_device._cmd_duration_expected[cmd_name] < (time.time() - command_start_time): @@ -577,8 +582,8 @@ class CspSubarray(SKASubarray): # reset sub-component execution flag target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE - self.logger.info("CspSubarray failure flag:{}".format(self._failure_raised)) - self.logger.info("CspSubarray timeout flag:{}".format(self._timeout_expired)) + self.logger.info("CspSubarray failure flag:{}".format(target_device._failure_raised)) + self.logger.info("CspSubarray timeout flag:{}".format(target_device._timeout_expired)) if target_device._timeout_expired or target_device._failure_raised: # if failure/timeout found check if the CBF subarray is configured. In # this case the CSP.LMC Subarray obsState is set to READY. @@ -745,6 +750,29 @@ class CspSubarray(SKASubarray): target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE target_device._last_executed_command = cmd_name target_device.scan_cmd_obj.succeeded() + + class EndScanCommand(SKASubarray.ScanCommand): + + def do(self): + target_device = self.target + device_list = target_device._sc_subarray_assigned_fqdn + if not any(target_device._sc_subarray_assigned_fqdn): + # need to add a check also on PSTBeams belonging to subarray + device_list = target_device._sc_subarray_fqdn + for device in device_list: + try: + proxy = target_device._sc_subarray_proxies[device] + proxy.command_inout_asynch("EndScan", target_device._cmd_ended_cb) + except KeyError as key_err: + self.logger.warning("No key {} found".format(key_err)) + except tango.DevFailed as tango_err: + self.logger.warning(tango_err.args[0].desc) + # TODO: address this case! + # signal the failure raising the failure flag? + # set the threading endScan event + target_device._end_scan_event.set() + return (ResultCode.OK, "EndScan command executed OK") + ''' class AbortCommand(SKASubarray.AbortCommand): @@ -770,25 +798,15 @@ class CspSubarray(SKASubarray): return (ResultCode.OK, message) - class ScanCommand(SKASubarray.ScanCommand): - - def do(self): - message = "Scan command completed OK" - self.logger.info(message) - return (ResultCode.OK, message) - - class EndScanCommand(SKASubarray.ScanCommand): - - def do(self): - message = "Abort command completed OK" - self.logger.info(message) - return (ResultCode.OK, message) ''' - #class GoToIdleCommand(ResponseCommand): - class GoToIdleCommand(SKASubarray.EndCommand): + class GoToIdleCommand(ActionCommand): """ A class for the CSPSubarray's GoToIdle() command. """ + def __init__(self, target, state_model, logger=None): + super().__init__( + target, state_model, "goto_idle", start_action=True, logger=logger + ) def do(self): """ Stateless hook for GoToIdle() command functionality. @@ -812,14 +830,19 @@ class CspSubarray(SKASubarray): proxy = target_device._sc_subarray_proxies[device] # register the starting time for the command target_device._sc_subarray_cmd_starting_time[device] = time.time() + proxy.command_inout_asynch("GoToIdle", target_device._cmd_ended_cb) # read the timeout attribute configured for this command # if not implemented an AttributeError exception is thrown # and the default value is used target_device._sc_subarray_cmd_duration_expected[device]['gotoidle'] = proxy.gotoIdleCmdDurationExpected except KeyError as key_err: - self.logger.warning("GoToIdle execution:no key {} found".format(str(key_err))) + msg = "GoToIdle execution:no key {} found".format(str(key_err)) + self.logger.warning(msg) + return (ResultCode.FAILED, msg) except tango.DevFailed as tango_err: - self.logger.warning("GotToIdle execution: {}".format(tango_err.args[0].desc)) + msg = "GotToIdle execution: {}".format(tango_err.args[0].desc) + self.logger.warning(msg) + return (ResultCode.FAILED, msg) except AttributeError as attr_err: self.logger.info("Attribute {} not exported by device {}".format(str(attr_err), device)) @@ -841,114 +864,115 @@ class CspSubarray(SKASubarray): self.logger.info(message) return (ResultCode.STARTED, message) - def _gotoidle(self, device_list, **args_dict): - """ - Thread target function invoked from GoToIdle method. - It monitors the obsState value of each sub-array sub-component - looking for timeout or failure conditions. - - :param device_list: the FQDNs of the sub-array sub-components - - :return: None - """ - target_device = self.target - cmd_name = 'gotoidle' - dev_successful_state = ObsState.IDLE - # tango_cmd_name: is the TANGO command name with the capital letter - # In the dictionary keys, is generally used the command name in lower letters - target_device._num_dev_completed_task[cmd_name] = 0 - target_device._list_dev_completed_task[cmd_name] = [] - target_device._cmd_progress[cmd_name] = 0 - target_device._cmd_duration_measured[cmd_name] = 0 - # sub-component command execution measured time - sc_cmd_duration_measured = defaultdict(lambda:defaultdict(lambda:0)) - # loop on the devices and issue asynchrnously the Configure command - command_progress = target_device._cmd_progress[cmd_name] - # flag to signal when configuration ends on a sub-array sub-component - device_done = defaultdict(lambda:False) - # inside the end-less lop check the obsState of each sub-component - while True: - for device in device_list: - elapsed_time = time.time() - target_device._sc_subarray_cmd_starting_time[device] - sc_cmd_duration_measured[device][cmd_name] = elapsed_time - self.logger.debug("Command {} obs_state: {}".format(cmd_name, - target_device._sc_subarray_obs_state[device])) - if device_done[device] == True: - continue - # if the sub-component execution flag is no more RUNNING, the command has - # ended with or without success. Go to check next device state. - if target_device._sc_subarray_obs_state[device] == dev_successful_state: - self.logger.info("Command {} ended with success on device {}.".format(cmd_name, - device)) - # update the list and number of device that completed the task - target_device._num_dev_completed_task[cmd_name] += 1 - target_device._list_dev_completed_task[cmd_name].append(device) - # reset the value of the attribute reporting the execution state of - # the command - target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE - target_device._sc_subarray_cmd_progress[device][cmd_name] = 100 - # calculate the execution time for the command as the max value of all the execution times - if sc_cmd_duration_measured[device][cmd_name] >= target_device._cmd_duration_measured[cmd_name]: - target_device._cmd_duration_measured[cmd_name] = sc_cmd_duration_measured[device][cmd_name] - # command success: step to next device - device_done[device] = True - # check for timeout event. A timeout event can be detected in two ways: - # 1- the sub-element implements the 'onTimeoutExpired' attribute configured - # for change event - # 2- the CspMaster periodically checks the time elapsed from the start - # of the command: if the value is greater than the sub-element expected time - # for command execution, the sub-element command execution state is set - # to TIMEOUT - # Note: the second check, can be useful if the timeout event is not received - # (for example for a temporary connection timeout) - #elapsed_time = time.time() - self._sc_subarray_cmd_starting_time[device] - #sc_cmd_duration_measured[device][cmd_name] = elapsed_time - if (elapsed_time > target_device._sc_subarray_cmd_duration_expected[device][cmd_name] or - target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.TIMEOUT): - msg = ("Timeout executing {} command on device {}".format(cmd_name, device)) - self.logger.warning(msg) - target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.TIMEOUT - device_done[device] = True - self.logger.info("elapsed_time:{} device {}".format(elapsed_time, device)) - # check if sub-element command ended throwing an exception: in this case the - # 'cmd_ended_cb' callback is invoked. - if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.FAILED: - # execution ended for this sub-element, skip to the next one - device_done[device] = True - # update the progress counter inside the loop taking into account the number of devices - # executing the command - target_device._cmd_progress[cmd_name] = command_progress+ target_device._sc_subarray_cmd_progress[device][cmd_name]/len(device_list) - self.logger.debug("Command {} on device {} obsState {}:".format(cmd_name,device, - target_device._sc_subarray_cmd_exec_state[device][cmd_name])) - if all(value == True for value in device_done.values()): - self.logger.info("All devices have been handled!") - break - self.logger.info("Sleeping...") - time.sleep(0.2) - # end of the while loop - # check for timeout/failure conditions on each sub-component + def _gotoidle(self, device_list, **args_dict): + """ + Thread target function invoked from GoToIdle method. + It monitors the obsState value of each sub-array sub-component + looking for timeout or failure conditions. + + :param device_list: the FQDNs of the sub-array sub-components + + :return: None + """ + target_device = self.target + cmd_name = 'gotoidle' + dev_successful_state = ObsState.IDLE + # tango_cmd_name: is the TANGO command name with the capital letter + # In the dictionary keys, is generally used the command name in lower letters + target_device._num_dev_completed_task[cmd_name] = 0 + target_device._list_dev_completed_task[cmd_name] = [] + target_device._cmd_progress[cmd_name] = 0 + target_device._cmd_duration_measured[cmd_name] = 0 + # sub-component command execution measured time + sc_cmd_duration_measured = defaultdict(lambda:defaultdict(lambda:0)) + # loop on the devices and issue asynchrnously the Configure command + command_progress = target_device._cmd_progress[cmd_name] + # flag to signal when configuration ends on a sub-array sub-component + device_done = defaultdict(lambda:False) + # inside the end-less lop check the obsState of each sub-component + while True: for device in device_list: - self.logger.info("Device {} running state is : {}".format(device, - target_device._sc_subarray_cmd_exec_state[device][cmd_name])) - if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.TIMEOUT: - target_device._timeout_expired = True + elapsed_time = time.time() - target_device._sc_subarray_cmd_starting_time[device] + sc_cmd_duration_measured[device][cmd_name] = elapsed_time + self.logger.debug("Command {} obs_state: {}".format(cmd_name, + target_device._sc_subarray_obs_state[device])) + if device_done[device] == True: + continue + # if the sub-component execution flag is no more RUNNING, the command has + # ended with or without success. Go to check next device state. + if target_device._sc_subarray_obs_state[device] == dev_successful_state: + self.logger.info("Command {} ended with success on device {}.".format(cmd_name, + device)) + # update the list and number of device that completed the task + target_device._num_dev_completed_task[cmd_name] += 1 + target_device._list_dev_completed_task[cmd_name].append(device) + # reset the value of the attribute reporting the execution state of + # the command + target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE + target_device._sc_subarray_cmd_progress[device][cmd_name] = 100 + # calculate the execution time for the command as the max value of all the execution times + if sc_cmd_duration_measured[device][cmd_name] >= target_device._cmd_duration_measured[cmd_name]: + target_device._cmd_duration_measured[cmd_name] = sc_cmd_duration_measured[device][cmd_name] + # command success: step to next device + device_done[device] = True + # check for timeout event. A timeout event can be detected in two ways: + # 1- the sub-element implements the 'onTimeoutExpired' attribute configured + # for change event + # 2- the CspMaster periodically checks the time elapsed from the start + # of the command: if the value is greater than the sub-element expected time + # for command execution, the sub-element command execution state is set + # to TIMEOUT + # Note: the second check, can be useful if the timeout event is not received + # (for example for a temporary connection timeout) + #elapsed_time = time.time() - self._sc_subarray_cmd_starting_time[device] + #sc_cmd_duration_measured[device][cmd_name] = elapsed_time + if (elapsed_time > target_device._sc_subarray_cmd_duration_expected[device][cmd_name] or + target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.TIMEOUT): + msg = ("Timeout executing {} command on device {}".format(cmd_name, device)) + self.logger.warning(msg) + target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.TIMEOUT + device_done[device] = True + self.logger.info("elapsed_time:{} device {}".format(elapsed_time, device)) + # check if sub-element command ended throwing an exception: in this case the + # 'cmd_ended_cb' callback is invoked. if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.FAILED: - target_device._failure_raised = True - # reset sub-component execution flag - # update the progress counter at the end of the loop - target_device._cmd_progress[cmd_name] = command_progress + target_device._sc_subarray_cmd_progress[device][cmd_name]/len(device_list) + # execution ended for this sub-element, skip to the next one + device_done[device] = True + # update the progress counter inside the loop taking into account the number of devices + # executing the command + target_device._cmd_progress[cmd_name] = command_progress+ target_device._sc_subarray_cmd_progress[device][cmd_name]/len(device_list) + self.logger.debug("Command {} on device {} obsState {}:".format(cmd_name,device, + target_device._sc_subarray_cmd_exec_state[device][cmd_name])) + if all(value == True for value in device_done.values()): + self.logger.info("All devices have been handled!") + break + self.logger.info("Sleeping...") + time.sleep(0.1) + # end of the while loop + # check for timeout/failure conditions on each sub-component + for device in device_list: + self.logger.info("Device {} running state is : {}".format(device, + target_device._sc_subarray_cmd_exec_state[device][cmd_name])) + if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.TIMEOUT: + target_device._timeout_expired = True + if target_device._sc_subarray_cmd_exec_state[device][cmd_name] == CmdExecState.FAILED: + target_device._failure_raised = True + # reset sub-component execution flag + # update the progress counter at the end of the loop + target_device._cmd_progress[cmd_name] = command_progress + target_device._sc_subarray_cmd_progress[device][cmd_name]/len(device_list) - target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE - if target_device._failure_raised or target_device._timeout_expired: - return target_device.gotoidle_cmd_obj.failed() - - if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): - target_device._last_executed_command = cmd_name - # reset the CSP Subarray command execution flag - target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE - target_device.gotoidle_cmd_obj.succeeded() + self.logger.info("1") + target_device._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE + if target_device._failure_raised or target_device._timeout_expired: + return target_device.gotoidle_cmd_obj.failed() + + self.logger.info("2") + if all(target_device._sc_subarray_obs_state[fqdn] == dev_successful_state for fqdn in device_list): + target_device._last_executed_command = cmd_name + # reset the CSP Subarray command execution flag + target_device._cmd_execution_state[cmd_name] = CmdExecState.IDLE + return target_device.gotoidle_cmd_obj.succeeded() - ''' def check_allowed(self): """ Whether this command is allowed to be run in current device @@ -960,22 +984,19 @@ class CspSubarray(SKASubarray): :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, - ]: - msg = "GoToIdle not allowed in State {}".format(self.state_model.dev_state) - tango.Except.throw_exception("API_CommandFailed", - msg, - "GoToIdle", - tango.ErrSeverity.ERR) - if not self.state_model.obs_state in [ObsState.READY]: - msg = "GoToIdle not allowed in obsState {}".format(self.state_model.obs_state) - tango.Except.throw_exception("API_CommandFailed", - msg, - "GoToIdle", - tango.ErrSeverity.ERR) - return True - ''' + if self.state_model.dev_state == DevState.ON: + return True + msg = "GoToIdle not allowed in State {}".format(self.state_model.dev_state) + tango.Except.throw_exception("API_CommandFailed", + msg, + "GoToIdle", + tango.ErrSeverity.ERR) + #if not self.state_model.obs_state in [ObsState.READY]: + # msg = "GoToIdle not allowed in obsState {}".format(self.state_model.obs_state) + # tango.Except.throw_exception("API_CommandFailed", + # msg, + # "GoToIdle", + # tango.ErrSeverity.ERR) # PROTECTED REGION ID(CspSubarray.class_variable) ENABLED START # # PROTECTED REGION END # // CspSubarray.class_variable @@ -1006,14 +1027,16 @@ class CspSubarray(SKASubarray): try: if dev_name in self._sc_subarray_fqdn: if evt.attr_value.name.lower() == "state": + self.logger.info("device: {} state value {}".format(dev_name,evt.attr_value.value)) self._sc_subarray_state[dev_name] = evt.attr_value.value elif evt.attr_value.name.lower() == "healthstate": + self.logger.info("device: {} healthstate value {}".format(dev_name,evt.attr_value.value)) self._sc_subarray_health_state[dev_name] = evt.attr_value.value elif evt.attr_value.name.lower() == "adminmode": - self.logger.debug("device: {} adminMode value {}".format(dev_name,evt.attr_value.value)) + self.logger.info("device: {} adminMode value {}".format(dev_name,evt.attr_value.value)) self._sc_subarray_admin_mode[dev_name] = evt.attr_value.value elif evt.attr_value.name.lower() == "obsstate": - self.logger.debug("device: {} obsState value {}".format(dev_name,evt.attr_value.value )) + self.logger.info("device: {} obsState value {}".format(dev_name,evt.attr_value.value )) self._sc_subarray_obs_state[dev_name] = evt.attr_value.value elif evt.attr_value.name.lower() == "obsmode": self.logger.debug("device: {} obsMode value {}".format(dev_name, evt.attr_value.value )) @@ -1044,6 +1067,7 @@ class CspSubarray(SKASubarray): # API_EventTimeout: if sub-element device not reachable it transitions # to UNKNOWN state. if item.reason == "API_EventTimeout": + self.logger.info("API_EventTimeout") # only if the device is ONLINE/MAINTENANCE, its State is set to # UNKNOWN when there is a timeout on connection, otherwise its # State should be reported always as DISABLE @@ -1172,14 +1196,13 @@ class CspSubarray(SKASubarray): """ self.logger.info("CspSubarray") self._update_subarray_health_state() - self.logger.info("threading.enumerate(): {}".format(threading.enumerate())) 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 running don't update state!") - return + 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. @@ -1193,6 +1216,7 @@ class CspSubarray(SKASubarray): if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.READY: self.configure_cmd_obj.succeeded() self.logger.info("Csp subarray state: {} obsState: {}".format(self.get_state(), self.state_model.obs_state)) + return True def _update_subarray_health_state(self): """ @@ -1409,7 +1433,6 @@ class CspSubarray(SKASubarray): # ---------------- - def _init_state_model(self): """ Sets up the state model for the device @@ -2391,12 +2414,29 @@ class CspSubarray(SKASubarray): :return: None """ + self.logger.info("Call to GoToIdle method") handler = self.get_command_object("GoToIdle") (result_code, message) = handler() return [[result_code], [message]] # PROTECTED REGION END # // CspSubarray.GoToIdle ''' + @command( + dtype_out='DevVarLongStringArray', + ) + @DebugIt() + def EndScan(self): + # PROTECTED REGION ID(CspSubarray.EndScan) ENABLED START # + """ + *Class method* + End the execution of a running scan. After successful execution, the CspSubarray \ + *ObsState* is IDLE. + + :raises: *tango.DevFailed* if the subarray *obsState* is not SCANNING or if an exception + is caught during the command execution. + """ + # PROTECTED REGION END # // CspSubarray.EndScan + @command( dtype_in='DevUShort', doc_in="The number of SearchBeams Capabilities to assign to the subarray.", @@ -2555,44 +2595,6 @@ class CspSubarray(SKASubarray): """ self._cmd_execution_state['removetimingbeams'] = CmdExecState.RUNNING # PROTECTED REGION END # // CspSubarray.RemoveTimingBeams - - @AdminModeCheck('EndScan') - def is_EndScan_allowed(self): - return self._is_subarray_configuring_allowed() - - @command( - dtype_out='DevVarLongStringArray', - ) - @DebugIt() - #@ObsStateCheck('endscan') - def EndScan(self): - # PROTECTED REGION ID(CspSubarray.EndScan) ENABLED START # - """ - *Class method* - End the execution of a running scan. After successful execution, the CspSubarray \ - *ObsState* is IDLE. - - :raises: *tango.DevFailed* if the subarray *obsState* is not SCANNING or if an exception - is caught during the command execution. - """ - device_list = self._sc_subarray_assigned_fqdn - if not any(self._sc_subarray_assigned_fqdn): - # need to add a check also on PSTBeams belonging to subarray - device_list = self._sc_subarray_fqdn - for device in device_list: - try: - proxy = self._sc_subarray_proxies[device] - proxy.command_inout_asynch("EndScan", self._cmd_ended_cb) - except KeyError as key_err: - self.logger.warning("No key {} found".format(key_err)) - except tango.DevFailed as tango_err: - self.logger.warning(tango_err.args[0].desc) - # TODO: address this case! - # signal the failure raising the failure flag? - # set the threading endScan event - self._end_scan_event.set() - return [[0], [""]] - # PROTECTED REGION END # // CspSubarray.EndScan @command( dtype_out='DevVarLongStringArray', diff --git a/csp-lmc-common/csp_lmc_common/release.py b/csp-lmc-common/csp_lmc_common/release.py index fc5e00496b903d0f20667afabf107f9786d210d9..f96470ef7b0ae84fd87bba3c65a218bf55366df3 100755 --- a/csp-lmc-common/csp_lmc_common/release.py +++ b/csp-lmc-common/csp_lmc_common/release.py @@ -10,7 +10,7 @@ """Release information for Python Package""" name = """csp-lmc-common""" -version = "0.6.1" +version = "0.6.2" version_info = version.split(".") description = """SKA CSP.LMC Common Software""" author = "INAF-OAA" diff --git a/csp-lmc-common/docker/.release b/csp-lmc-common/docker/.release index cbc89b55e60cb520f93aaad1b9a8bc0fef97ba66..0ceb498ff0500c1aa0de6ad70964b7148a01a5e9 100644 --- a/csp-lmc-common/docker/.release +++ b/csp-lmc-common/docker/.release @@ -9,7 +9,7 @@ """Release information for Python Package""" name = """csplmc-common""" -version = "0.6.1" +version = "0.6.2" version_info = version.split(".") description = """SKA CSP.LMC Common Classe""" author = "E.G" @@ -18,5 +18,5 @@ license = """BSD-3-Clause""" url = """www.tango-controls.org""" copyright = """""" -release=0.6.1 -tag=csp-lmc-common-0.6.1 +release=0.6.2 +tag=csp-lmc-common-0.6.2 diff --git a/csp-lmc-mid/HISTORY b/csp-lmc-mid/HISTORY index 8e1f0b7c217207fa6add648a7d3495fbd52db97d..2a2f17f5cd057ebfc2bbb47064fc0d2235e50e43 100644 --- a/csp-lmc-mid/HISTORY +++ b/csp-lmc-mid/HISTORY @@ -1,3 +1,6 @@ +0.6.2 +- use csp-lmc-common version 0.6.2 + 0.6.1 - use csp-lmc-common version 0.6.1 diff --git a/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py b/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py index a8651e20ea6aad429b0a0c87ce3464a93888876f..3342002ae20485d7326231bca4cb3af4ba655314 100644 --- a/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py +++ b/csp-lmc-mid/csp_lmc_mid/MidCspSubarrayBase.py @@ -95,7 +95,7 @@ class MidCspSubarrayBase(CspSubarray): # NOTE: To remove when CBF Subarray implements the correct state def do(self): self.logger.info("dev_State:{}".format(self.state_model.dev_state)) - #super().do() + super().do() return (ResultCode.OK, "On command completed OK") class AddReceptorsCommand(SKASubarray.AssignResourcesCommand): @@ -305,7 +305,7 @@ class MidCspSubarrayBase(CspSubarray): def do(self,argin): self.logger.info("Call Mid CspSubarray Configure") try: - super().do(argin) + return super().do(argin) except tango.DevFailed as tango_err: log_msg = ("Configure Command failure. Reason: {} " "Desc: {}".format(tango_err.args[0].reason, @@ -403,14 +403,15 @@ class MidCspSubarrayBase(CspSubarray): :return: None """ self.logger.info("MidCspSubarray") - CspSubarray.update_subarray_state(self) - if self.get_state() == DevState.ON: - if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.IDLE: - self._addreceptors_cmd_obj.succeeded() - if self.get_state() == DevState.ON: - if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: - self._removereceptors_cmd_obj.succeeded() - self.logger.info("MidCsp subarray state: {} obsState: {}".format(self.get_state(), self.state_model.obs_state)) + if CspSubarray.update_subarray_state(self): + if self.get_state() == DevState.ON: + if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.IDLE: + self._addreceptors_cmd_obj.succeeded() + if self.get_state() == DevState.ON: + if self._sc_subarray_obs_state[self.CbfSubarray] == ObsState.EMPTY: + self._removereceptors_cmd_obj.succeeded() + self.logger.info("MidCsp subarray state: {} obsState: {}".format(self.get_state(), self.state_model.obs_state)) + return True def _get_cbfsubarray_assigned_receptors(self): """ @@ -495,7 +496,7 @@ class MidCspSubarrayBase(CspSubarray): self._cmd_execution_state[cmd_name] = CmdExecState.IDLE self.logger.info("AddReceptors end!") #self.AddReceptorsCommand.succeeded() - self._addreceptors_cmd_obj.succeeded() + return self._addreceptors_cmd_obj.succeeded() # PROTECTED REGION END # // MidCspSubarrayBase.private_methods @@ -573,8 +574,8 @@ class MidCspSubarrayBase(CspSubarray): # reset the command exeuction state self._sc_subarray_cmd_exec_state[device][cmd_name] = CmdExecState.IDLE self._cmd_execution_state[cmd_name] = CmdExecState.IDLE - self._removereceptors_cmd_obj.succeeded() self.logger.info("CspSubarray monitor_remove end") + return self._removereceptors_cmd_obj.succeeded() diff --git a/csp-lmc-mid/csp_lmc_mid/release.py b/csp-lmc-mid/csp_lmc_mid/release.py index 4f19cac78f822567d18afe1de437d259564a4926..2b288999d63e744468eaaed179accac48245053f 100755 --- a/csp-lmc-mid/csp_lmc_mid/release.py +++ b/csp-lmc-mid/csp_lmc_mid/release.py @@ -10,7 +10,7 @@ """Release information for Python Package""" name = """mid-csp-lmc""" -version = "0.6.1" +version = "0.6.2" version_info = version.split(".") description = """SKA MID CSP.LMC""" author = "INAF-OAA" diff --git a/csp-lmc-mid/docker/.release b/csp-lmc-mid/docker/.release index 03ea66f1ddf893f9e7c1862f9c04a663f92edadc..c71e1d27c9555c38f54e1f5cf8f885d04e4873bd 100644 --- a/csp-lmc-mid/docker/.release +++ b/csp-lmc-mid/docker/.release @@ -9,7 +9,7 @@ """Release information for Python Package""" name = """MID CSP.LMC""" -version = "0.6.1" +version = "0.6.2" version_info = version.split(".") description = """SKA MID CSP.LMC Classes""" author = "E.G" @@ -18,5 +18,5 @@ license = """BSD-3-Clause""" url = """www.tango-controls.org""" copyright = """""" -release=0.6.1 -tag=mid-csp-lmc-0.6.1 +release=0.6.2 +tag=mid-csp-lmc-0.6.2 diff --git a/csp-lmc-mid/tests/MidCspSubarray_test.py b/csp-lmc-mid/tests/MidCspSubarray_test.py index 4756b77d882ff362fa6e1ae5f7977d332deaf0fb..87fa087ca558a655f94035cb6b58b7eb71f51da6 100755 --- a/csp-lmc-mid/tests/MidCspSubarray_test.py +++ b/csp-lmc-mid/tests/MidCspSubarray_test.py @@ -61,9 +61,8 @@ class TestCspSubarray(TestBase): """ Set the subarray state to ON-EMPTY """ - subarray_state = self.midcsp_subarray01.State() - LOGGER.info("setup_subarray state:{}".format(subarray_state)) - if subarray_state == DevState.DISABLE: + master_state = self.midcsp_master.State() + if master_state == DevState.STANDBY: self.midcsp_master.On("") prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.OFF, f"CSP Master not ON") Poller(4, 0.2).check(prober_subarray_state) @@ -82,22 +81,29 @@ class TestCspSubarray(TestBase): self.midcsp_subarray01.ObsReset() prober_obs_state = Probe(self.midcsp_subarray01, "obsState", ObsState.IDLE, f"CSP Subarray not IDLE") Poller(4, 0.2).check(prober_obs_state) + obs_state = self.midcsp_subarray01.obsState if obs_state == ObsState.EMPTY: return - else: + if obs_state == ObsState.READY: + self._goto_idle() + obs_state = self.midcsp_subarray01.obsState + if obs_state == ObsState.IDLE: self._release_all_receptors() def _setup_subarray_off(self): subarray_state = self.midcsp_subarray01.State() LOGGER.info("setup_subarray_off state:{}".format(subarray_state)) - if subarray_state == DevState.DISABLE: - self.midcsp_master.On("") - prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.OFF, f"CSP Master not ON") - Poller(4, 0.2).check(prober_subarray_state) + #if subarray_state == DevState.DISABLE: + # self.midcsp_master.On("") + # prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.OFF, f"CSP Master not ON") + # Poller(4, 0.2).check(prober_subarray_state) if subarray_state == DevState.OFF: return if subarray_state == DevState.ON: obs_state = self.midcsp_subarray01.obsState + if obs_state == ObsState.READY: + self._goto_idle() + obs_state = self.midcsp_subarray01.obsState if obs_state == ObsState.IDLE: self._release_all_receptors() subarray_state = self.midcsp_subarray01.State() @@ -139,9 +145,13 @@ class TestCspSubarray(TestBase): Remove all the receptors from the subarray. The final subarray state is ON-EMPTY """ + LOGGER.info("release_all_receptors") obs_state = self.midcsp_subarray01.obsState assert obs_state == ObsState.IDLE - self.midcsp_subarray01.RemoveAllReceptors() + try: + self.midcsp_subarray01.RemoveAllReceptors() + except Exception as e: + LOGGER.info(str(e)) # wait for the transition to EMPTY prober_obs_state = Probe(self.midcsp_subarray01, "obsState", ObsState.EMPTY, f"CSP Subarray is not EMPTY") Poller(4, 0.2).check(prober_obs_state) @@ -150,15 +160,26 @@ class TestCspSubarray(TestBase): time.sleep(0.5) receptor_list = self.midcsp_master.unassignedReceptorIDs LOGGER.info(f"release_all_receptors:Unassigned receptors:{receptor_list}") - if self.midcsp_subarray01.State() == DevState.OFF: - self.midcsp_subarray01.On() + #if self.midcsp_subarray01.State() == DevState.OFF: + # self.midcsp_subarray01.On() + + def _goto_idle(self): + """ + """ + LOGGER.info("Call to GoToIdle") + obs_state = self.midcsp_subarray01.obsState + assert obs_state == ObsState.READY + self.midcsp_subarray01.GoToIdle() + # wait for the transition to IDLE + prober_obs_state = Probe(self.midcsp_subarray01, "obsState", ObsState.IDLE, f"CSP Subarray is not IDLE") + Poller(4, 0.2).check(prober_obs_state) + LOGGER.info("End GoToIdle") - def test_state_AFTER_initialization(self): + def test_AFTER_initialization(self): """ Test for State after CSP startup. The CspSubarray State at start is OFF. """ - state = self.midcsp_subarray01.Init() state = self.midcsp_subarray01.State() LOGGER.info("subarray state:{}".format(state)) prober_subarray_state = Probe(self.midcsp_subarray01, "State", DevState.OFF, f"CSP Subarray not OFF") @@ -360,7 +381,6 @@ class TestCspSubarray(TestBase): assert_that(obs_state).described_as("CSP Subarray obsState has wrong value ({obs_state}").is_equal_to(ObsState.FAULT) #assert obs_state == ObsState.FAULT, f"CSP Subarray obsState is not EMPTY" - ''' def test_send_configure_to_cbf_and_json_stored(self): """ Configure the CSP Subarray with a JSon string including @@ -374,19 +394,20 @@ class TestCspSubarray(TestBase): LOGGER.info("CSP Subarray State before exercise :{}-{}".format(state, ObsState(obs_state).name)) # exercise the device LOGGER.info(f"Configuring CSP subarray01") - self.midcsp_subarray01.Configure(f.read().replace("\n", "")) + (result_code, msg) = self.midcsp_subarray01.Configure(f.read().replace("\n", "")) f.close() # check prober_subarray_obstate = Probe(self.midcsp_subarray01, 'obsState', ObsState.READY, f"Wrong CSP Subarray obsState {self.midcsp_subarray01.obsState}") Poller(5, 0.2).check(prober_subarray_obstate) - stored_json = self.midcsp_subarray01.validScanConfiguration - assert stored_json == configuration_string - json_dict = json.loads(configuration_string) - configID = json_dict["id"] - stored_id = self.midcsp_subarray01.configurationID - assert stored_id == configID + obs_state = self.midcsp_subarray01.obsState + LOGGER.info("obs_state:{}".format(obs_state)) + #json_dict = json.loads(configuration_string) + #configID = json_dict["id"] + #stored_id = self.midcsp_subarray01.configurationID + #assert stored_id == configID + ''' def test_configureScan(self, midcsp_subarray01, midcsp_master): """ Test that the Configure() command is issued when the Subarray