Commit 09f68698 authored by Gianluca Marotta's avatar Gianluca Marotta
Browse files

Merge branch 'CT-207' into 'master'

CT-207 CSP.LMC subarray Off command

See merge request ska-telescope/csp-lmc!14
parents b96f7c2d 3746607a
Loading
Loading
Loading
Loading
Loading
+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.
+35 −22
Original line number Diff line number Diff line
@@ -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):
        """
@@ -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()
@@ -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()
@@ -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()
+74 −23
Original line number Diff line number Diff line
@@ -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
@@ -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 
+1 −1
Original line number Diff line number Diff line
@@ -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"
+1 −1
Original line number Diff line number Diff line
@@ -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