Loading csp-lmc-common/HISTORY +4 −0 Original line number Diff line number Diff line 0.7.1 - Off command in Subarray drives each sub-element component to the final OFF/EMPTY state. - CspMaster On/Standby commands are executed synchronously 0.7.0 - Align CSP.LMC to be compliant with the SKA Base Classes API: add of Assign/ReleaseResources commands. Loading csp-lmc-common/csp_lmc_common/CspMaster.py +35 −22 Original line number Diff line number Diff line Loading @@ -592,42 +592,48 @@ class CspMaster(SKAMaster): # reset the CSP command execution flag with self._cmd_exec_state_lock: self._cmd_execution_state[cmd_name] = CmdExecState.IDLE self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) self._enable_subarrays(tango_cmd_name) def _enable_subarrays(self, tango_cmd_name): enable = False subarray_cmd = tango_cmd_name if tango_cmd_name == 'On': enable = True if tango_cmd_name == 'Standby': subarray_cmd = 'Off' """ Helper method to execute the On[Off] command on the CSP subarrays. :param tangp_cmd_name: The command to execute :type tamgo_cmd_name: string :return: None """ subarray_action = tango_cmd_name.lower() if subarray_action not in ['on', 'off']: self.logger.warning(f"Invalid command {subarray_action} to issue on CSP subarray") return master_state = self.get_state() if (enable, master_state) not in [(True, tango.DevState.ON), (False, tango.DevState.STANDBY)]: if (subarray_action, master_state) not in [('on', tango.DevState.ON), ('off', tango.DevState.STANDBY)]: self.logger.warning("CSPMaster is not in the proper state ({})".format(self.get_state())) return try: subarray_group = tango.Group("CSPSubarray") for subarray in self.CspSubarrays: subarray_group.add(subarray) self.logger.info("Issue command {} on subarray group".format(subarray_cmd)) answers = subarray_group.command_inout(subarray_cmd) self.logger.info("Going to switch-{} the subarrays".format(subarray_action)) answers = subarray_group.command_inout(subarray_action) for reply in answers: if reply.has_failed(): self.logger.info("stack: {}".format(len(reply.get_err_stack()))) for err in reply.get_err_stack(): self.logger.info("err {} reason {}".format(err.desc, err.reason) ) self.logger.warning("Subarray {} failed executing command {}".format(reply.dev_name(), subarray_cmd)) subarray_action)) else: (result_code, msg) = reply.get_data() if result_code == ResultCode.FAILED: self.logger.error(msg[0]) self.logger.error(f"Subarray {reply.dev_name()}: {msg[0]}") elif result_code == ResultCode.OK: self.logger.info(msg[0]) self.logger.info(f"Subarray {reply.dev_name()}: {msg[0]}") except tango.DevFailed as df: log_msg = (f"Failure in command {subarray_action} " "for device {str(fqdn)}: {str(df.args[0].reason)}") self.logger.error(log_msg) except Exception: self.logger.error("TANGO Group command failed") self.logger.error("command {} failed on subarray".format(subarray_action)) def _se_write_adminMode(self, value, device_fqdn): """ Loading Loading @@ -1885,8 +1891,11 @@ class CspMaster(SKAMaster): self._cmd_execution_state['on'] = CmdExecState.RUNNING self._command_thread['on'].start() self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items())) # sleep for a while to let the thread start #time.sleep(0.1) # To temporarily solve SKB-26 -> join the thread to synchronize the command self._command_thread['on'].join() self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) self._enable_subarrays('On') except Exception: # reset the sub-element command exec state self._se_cmd_execution_state.clear() Loading Loading @@ -1970,8 +1979,9 @@ class CspMaster(SKAMaster): self._cmd_execution_state['off'] = CmdExecState.RUNNING # start the thread self._command_thread['off'].start() # sleep for a while to let the thread start #time.sleep(0.1) self._command_thread['off'].join() self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) except Exception: # reset the sub-element command exec state self._se_cmd_execution_state.clear() Loading Loading @@ -2054,8 +2064,11 @@ class CspMaster(SKAMaster): # start the thread self._command_thread['standby'].start() self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items())) # sleep for a while to let the thread start #time.sleep(0.1) # To temprarily solve the SKB-26 -> join the thread to synchronize the command self._command_thread['standby'].join() self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) self._enable_subarrays('Off') except Exception: # reset the sub-element command exec state self._se_cmd_execution_state.clear() Loading csp-lmc-common/csp_lmc_common/CspSubarray.py +74 −23 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ from tango import AttrWriteType, DeviceProxy from ska.base import SKASubarray, SKASubarrayStateModel #from ska.base import utils from ska.base.commands import ActionCommand, ResultCode from ska.base.faults import CapabilityValidationError from ska.base.faults import CapabilityValidationError, CommandError from ska.base.control_model import HealthState, AdminMode, ObsState, ObsMode from .utils.cspcommons import CmdExecState from .utils.decorators import transaction_id Loading Loading @@ -351,39 +351,90 @@ class CspSubarray(SKASubarray): def do(self): self.logger.info("Call Off Command") device = self.target subelement_thr = {} self.thread_succeeded = {} off_failed = False # First loop that start the sub-element threads to get the ObsState.EMPTY for fqdn in device._sc_subarray_fqdn: try: # check if the sub-element subarray is already in the # requested state if device._sc_subarray_state[fqdn] == tango.DevState.OFF: continue (result_code, message) = device._sc_subarray_proxies[fqdn].Off() if result_code == ResultCode.FAILED: self.logger.error("Off command failed on device {}".format(fqdn)) if fqdn != device.CbfSubarray: device._health_state = HealthState.DEGRADED continue if device._sc_subarray_obs_state[fqdn] != ObsState.EMPTY: subelement_thr[fqdn] = threading.Thread(target=self.off_sequence, name="Thread-OffSequence", args=(fqdn,)) subelement_thr[fqdn].start() else: return (ResultCode.FAILED, message) self.logger.info(f'ObsState of device {fqdn} is not EMPTY. ObsState:{device._sc_subarray_obs_state[fqdn]}') # Second loop check if the thread is succeeded and send the Off command to sub-element for fqdn in subelement_thr.keys(): subelement_thr[fqdn].join() if any(self.thread_succeeded[fqdn] == True for fqdn in subelement_thr.keys()): for fqdn in subelement_thr.keys(): try: (result_code, message) = device._sc_subarray_proxies[fqdn].Off() except tango.DevFailed as tango_err: message = str(tango_err.args[0].desc) return (ResultCode.FAILED, message) result_code = ResultCode.FAILED if result_code == ResultCode.FAILED: self.logger.error("Off command failed on device {}".format(fqdn)) self.logger.info(message) off_failed = True if off_failed: return ResultCode.FAILED, 'Off command Failed' message = "Off command completed OK" self.logger.info(message) return (ResultCode.OK, message) return ResultCode.OK, message class AssignResourcesCommand(SKASubarray.AssignResourcesCommand): def off_sequence(self, fqdn): #Off command send the device in the state:OFF, ObsState:EMPTY self.logger.info('off sequence started!') self.logger.info(f'FQDN: {fqdn}') device = self.target starting_time = time.time() timeout = device._sc_subarray_cmd_duration_expected[fqdn]['off'] while (time.time() - starting_time) < timeout and (device._sc_subarray_obs_state[fqdn] != ObsState.EMPTY): # Try to send Abort Command. # Device goes to ABORTED in case ObsState is: IDLE, READY, CONFIGURING, SCANNING, RESETTING try: self.logger.info('Try to execute Abort command') self.logger.info(f'ObState: {device._sc_subarray_obs_state[fqdn]}') device._sc_subarray_proxies[fqdn].Abort() while (time.time() - starting_time) < timeout and (device._sc_subarray_obs_state[fqdn] != ObsState.ABORTED): if device._sc_subarray_obs_state[fqdn] == ObsState.FAULT: break time.sleep(0.1) except Exception as msg: self.logger.info(msg) # Try to send Restart Command. # Device goes to EMPTY if ObsState is: FAULT, ABORTED # ObsState could be aborted from above try section try: self.logger.info('Try to execute Restart command') device._sc_subarray_proxies[fqdn].Restart() except Exception as msg: self.logger.info(msg) time.sleep(0.1) # if ObsState is: RESOURCING, ABORTING start again to wait end of the transition if device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY: self.thread_succeeded[fqdn] = True else: self.thread_succeeded[fqdn] = False class AssignResourcesCommand(SKASubarray.AssignResourcesCommand): @transaction_id def do(self, argin): #TODO: Edit the logger self.logger.info('Assign resource command ... ') return (ResultCode.OK, "Assign Resources command completed OK") class ConfigureCommand(SKASubarray.ConfigureCommand): @transaction_id def do(self, argin): # checks on State, adminMode and obsState values are performed inside the Loading csp-lmc-common/csp_lmc_common/release.py +1 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ """Release information for Python Package""" name = """csp-lmc-common""" version = "0.7.0" version = "0.7.1" version_info = version.split(".") description = """SKA CSP.LMC Common Software""" author = "INAF-OAA" Loading csp-lmc-mid/.release +1 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ """Release information for Python Package""" name = """MID CSP.LMC""" version = "0.7.0" version = "0.7.1" version_info = version.split(".") description = """SKA MID CSP.LMC Classes""" author = "E.G" Loading Loading
csp-lmc-common/HISTORY +4 −0 Original line number Diff line number Diff line 0.7.1 - Off command in Subarray drives each sub-element component to the final OFF/EMPTY state. - CspMaster On/Standby commands are executed synchronously 0.7.0 - Align CSP.LMC to be compliant with the SKA Base Classes API: add of Assign/ReleaseResources commands. Loading
csp-lmc-common/csp_lmc_common/CspMaster.py +35 −22 Original line number Diff line number Diff line Loading @@ -592,42 +592,48 @@ class CspMaster(SKAMaster): # reset the CSP command execution flag with self._cmd_exec_state_lock: self._cmd_execution_state[cmd_name] = CmdExecState.IDLE self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) self._enable_subarrays(tango_cmd_name) def _enable_subarrays(self, tango_cmd_name): enable = False subarray_cmd = tango_cmd_name if tango_cmd_name == 'On': enable = True if tango_cmd_name == 'Standby': subarray_cmd = 'Off' """ Helper method to execute the On[Off] command on the CSP subarrays. :param tangp_cmd_name: The command to execute :type tamgo_cmd_name: string :return: None """ subarray_action = tango_cmd_name.lower() if subarray_action not in ['on', 'off']: self.logger.warning(f"Invalid command {subarray_action} to issue on CSP subarray") return master_state = self.get_state() if (enable, master_state) not in [(True, tango.DevState.ON), (False, tango.DevState.STANDBY)]: if (subarray_action, master_state) not in [('on', tango.DevState.ON), ('off', tango.DevState.STANDBY)]: self.logger.warning("CSPMaster is not in the proper state ({})".format(self.get_state())) return try: subarray_group = tango.Group("CSPSubarray") for subarray in self.CspSubarrays: subarray_group.add(subarray) self.logger.info("Issue command {} on subarray group".format(subarray_cmd)) answers = subarray_group.command_inout(subarray_cmd) self.logger.info("Going to switch-{} the subarrays".format(subarray_action)) answers = subarray_group.command_inout(subarray_action) for reply in answers: if reply.has_failed(): self.logger.info("stack: {}".format(len(reply.get_err_stack()))) for err in reply.get_err_stack(): self.logger.info("err {} reason {}".format(err.desc, err.reason) ) self.logger.warning("Subarray {} failed executing command {}".format(reply.dev_name(), subarray_cmd)) subarray_action)) else: (result_code, msg) = reply.get_data() if result_code == ResultCode.FAILED: self.logger.error(msg[0]) self.logger.error(f"Subarray {reply.dev_name()}: {msg[0]}") elif result_code == ResultCode.OK: self.logger.info(msg[0]) self.logger.info(f"Subarray {reply.dev_name()}: {msg[0]}") except tango.DevFailed as df: log_msg = (f"Failure in command {subarray_action} " "for device {str(fqdn)}: {str(df.args[0].reason)}") self.logger.error(log_msg) except Exception: self.logger.error("TANGO Group command failed") self.logger.error("command {} failed on subarray".format(subarray_action)) def _se_write_adminMode(self, value, device_fqdn): """ Loading Loading @@ -1885,8 +1891,11 @@ class CspMaster(SKAMaster): self._cmd_execution_state['on'] = CmdExecState.RUNNING self._command_thread['on'].start() self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items())) # sleep for a while to let the thread start #time.sleep(0.1) # To temporarily solve SKB-26 -> join the thread to synchronize the command self._command_thread['on'].join() self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) self._enable_subarrays('On') except Exception: # reset the sub-element command exec state self._se_cmd_execution_state.clear() Loading Loading @@ -1970,8 +1979,9 @@ class CspMaster(SKAMaster): self._cmd_execution_state['off'] = CmdExecState.RUNNING # start the thread self._command_thread['off'].start() # sleep for a while to let the thread start #time.sleep(0.1) self._command_thread['off'].join() self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) except Exception: # reset the sub-element command exec state self._se_cmd_execution_state.clear() Loading Loading @@ -2054,8 +2064,11 @@ class CspMaster(SKAMaster): # start the thread self._command_thread['standby'].start() self.logger.debug("self._cmd_execution_state: {}".format(self._cmd_execution_state.items())) # sleep for a while to let the thread start #time.sleep(0.1) # To temprarily solve the SKB-26 -> join the thread to synchronize the command self._command_thread['standby'].join() self._update_csp_state() self.logger.info("CSP State:{}".format(self.get_state())) self._enable_subarrays('Off') except Exception: # reset the sub-element command exec state self._se_cmd_execution_state.clear() Loading
csp-lmc-common/csp_lmc_common/CspSubarray.py +74 −23 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ from tango import AttrWriteType, DeviceProxy from ska.base import SKASubarray, SKASubarrayStateModel #from ska.base import utils from ska.base.commands import ActionCommand, ResultCode from ska.base.faults import CapabilityValidationError from ska.base.faults import CapabilityValidationError, CommandError from ska.base.control_model import HealthState, AdminMode, ObsState, ObsMode from .utils.cspcommons import CmdExecState from .utils.decorators import transaction_id Loading Loading @@ -351,39 +351,90 @@ class CspSubarray(SKASubarray): def do(self): self.logger.info("Call Off Command") device = self.target subelement_thr = {} self.thread_succeeded = {} off_failed = False # First loop that start the sub-element threads to get the ObsState.EMPTY for fqdn in device._sc_subarray_fqdn: try: # check if the sub-element subarray is already in the # requested state if device._sc_subarray_state[fqdn] == tango.DevState.OFF: continue (result_code, message) = device._sc_subarray_proxies[fqdn].Off() if result_code == ResultCode.FAILED: self.logger.error("Off command failed on device {}".format(fqdn)) if fqdn != device.CbfSubarray: device._health_state = HealthState.DEGRADED continue if device._sc_subarray_obs_state[fqdn] != ObsState.EMPTY: subelement_thr[fqdn] = threading.Thread(target=self.off_sequence, name="Thread-OffSequence", args=(fqdn,)) subelement_thr[fqdn].start() else: return (ResultCode.FAILED, message) self.logger.info(f'ObsState of device {fqdn} is not EMPTY. ObsState:{device._sc_subarray_obs_state[fqdn]}') # Second loop check if the thread is succeeded and send the Off command to sub-element for fqdn in subelement_thr.keys(): subelement_thr[fqdn].join() if any(self.thread_succeeded[fqdn] == True for fqdn in subelement_thr.keys()): for fqdn in subelement_thr.keys(): try: (result_code, message) = device._sc_subarray_proxies[fqdn].Off() except tango.DevFailed as tango_err: message = str(tango_err.args[0].desc) return (ResultCode.FAILED, message) result_code = ResultCode.FAILED if result_code == ResultCode.FAILED: self.logger.error("Off command failed on device {}".format(fqdn)) self.logger.info(message) off_failed = True if off_failed: return ResultCode.FAILED, 'Off command Failed' message = "Off command completed OK" self.logger.info(message) return (ResultCode.OK, message) return ResultCode.OK, message class AssignResourcesCommand(SKASubarray.AssignResourcesCommand): def off_sequence(self, fqdn): #Off command send the device in the state:OFF, ObsState:EMPTY self.logger.info('off sequence started!') self.logger.info(f'FQDN: {fqdn}') device = self.target starting_time = time.time() timeout = device._sc_subarray_cmd_duration_expected[fqdn]['off'] while (time.time() - starting_time) < timeout and (device._sc_subarray_obs_state[fqdn] != ObsState.EMPTY): # Try to send Abort Command. # Device goes to ABORTED in case ObsState is: IDLE, READY, CONFIGURING, SCANNING, RESETTING try: self.logger.info('Try to execute Abort command') self.logger.info(f'ObState: {device._sc_subarray_obs_state[fqdn]}') device._sc_subarray_proxies[fqdn].Abort() while (time.time() - starting_time) < timeout and (device._sc_subarray_obs_state[fqdn] != ObsState.ABORTED): if device._sc_subarray_obs_state[fqdn] == ObsState.FAULT: break time.sleep(0.1) except Exception as msg: self.logger.info(msg) # Try to send Restart Command. # Device goes to EMPTY if ObsState is: FAULT, ABORTED # ObsState could be aborted from above try section try: self.logger.info('Try to execute Restart command') device._sc_subarray_proxies[fqdn].Restart() except Exception as msg: self.logger.info(msg) time.sleep(0.1) # if ObsState is: RESOURCING, ABORTING start again to wait end of the transition if device._sc_subarray_obs_state[fqdn] == ObsState.EMPTY: self.thread_succeeded[fqdn] = True else: self.thread_succeeded[fqdn] = False class AssignResourcesCommand(SKASubarray.AssignResourcesCommand): @transaction_id def do(self, argin): #TODO: Edit the logger self.logger.info('Assign resource command ... ') return (ResultCode.OK, "Assign Resources command completed OK") class ConfigureCommand(SKASubarray.ConfigureCommand): @transaction_id def do(self, argin): # checks on State, adminMode and obsState values are performed inside the Loading
csp-lmc-common/csp_lmc_common/release.py +1 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ """Release information for Python Package""" name = """csp-lmc-common""" version = "0.7.0" version = "0.7.1" version_info = version.split(".") description = """SKA CSP.LMC Common Software""" author = "INAF-OAA" Loading
csp-lmc-mid/.release +1 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ """Release information for Python Package""" name = """MID CSP.LMC""" version = "0.7.0" version = "0.7.1" version_info = version.split(".") description = """SKA MID CSP.LMC Classes""" author = "E.G" Loading