Skip to content
Snippets Groups Projects
Select Git revision
  • d0f83e77a788864ecff0b38f66a5b521b9c21dd7
  • master default protected
  • publish_python_package
  • AT5-374
  • AT5-373
  • AT5-370
  • ST-174
  • ST-85
  • ST94_Update_Pipfile
  • ST72_integrate_versioning_in_ci
  • test-code-climate
  • ST3_containerise_Python_device
  • ST59_Python_TANGO_device_to_be_demonstrated_as_part_of_PI_demo
13 results

subelement_master.py

Blame
  • subelement_master.py 24.71 KiB
    # -*- coding: utf-8 -*-
    #
    # This file is part of the CspSubElementMaster project
    #
    # INAF-SKA Telescope
    #
    # Distributed under the terms of the GPL license.
    # See LICENSE.txt for more info.
    
    """ CSP.LMC Sub-element Master
    
    A base class for the Master of a SKA Sub-element.
    """
    
    # PyTango imports
    import tango
    from tango import DebugIt
    from tango.server import run
    from tango.server import Device
    from tango.server import attribute, command
    from tango.server import device_property
    from tango import AttrQuality, DispLevel, DevState
    from tango import AttrWriteType, PipeWriteType
    from collections import defaultdict
    # Additional import
    # PROTECTED REGION ID(CspSubElementMaster.additionnal_import) ENABLED START #
    from ska.base import SKAMaster
    from ska.base.control_model import HealthState, AdminMode, LoggingLevel
    from csp_lmc_common.utils.cspcommons import CmdExecState
    from csp_lmc_common.utils.decorators import AdminModeCheck
    from .decorators import IsCommandAllowed
    from . import release
    # PROTECTED REGION END #    //  CspSubElementMaster.additionnal_import
    
    __all__ = ["CspSubElementMaster", "main"]
    
    
    class CspSubElementMaster(SKAMaster):
        """
        A base class for the Master of a SKA Sub-element.
    
        **Properties:**
    
        - Device Property
            Racks
                - The list with the FQDNs of the sub-element racks devices.
                - Type:'DevVarStringArray'
        """
        # PROTECTED REGION ID(CspSubElementMaster.class_variable) ENABLED START #
        # PROTECTED REGION END #    //  CspSubElementMaster.class_variable
    
        # -----------------
        # Device Properties
        # -----------------
    
        Racks = device_property(
            dtype='DevVarStringArray',
        )
    
        # ----------
        # Attributes
        # ----------
    
        numOfDevCompletedTask = attribute(
            dtype='DevUShort',
            label="Number of devices that completed the task",
            doc="Number of devices that completed the task",
        )
    
        onCmdFailure = attribute(
            dtype='DevBoolean',
            label="CBF command failure flag",
            #polling_period=1000,
            doc="Failure flag set when the On command fails with error(s).",
        )
    
        onFailureMessage = attribute(
            dtype='DevString',
            label="On execution failure message",
            doc="Failure message when the On command fails with error(s).",
        )
    
        offCmdFailure = attribute(
            dtype='DevBoolean',
            label="Off execution failure flag",
            doc="Failure flag set when the Off command fails with error(s).",
        )
    
        offFailureMessage = attribute(
            dtype='DevString',
            label="Off execution failure message",
            doc="Failure message when the Off command fails with error(s).",
        )
    
        standbyCmdFailure = attribute(
            dtype='DevBoolean',
            label="Standby execution failure message",
            doc="Failure flag set when the Standby command fails with error(s).",
        )
    
        standbyFailureMessage = attribute(
            dtype='DevString',
            label="Standby execution failure message",
            doc="Failure message when the Standby command fails with error(s).",
        )
    
        adminMode = attribute(
            dtype=AdminMode,
            access=AttrWriteType.READ_WRITE,
            memorized=True,
            doc=("The admin mode reported for this device. It may interpret the current"
                 " device condition and condition of all managed devices to set this."
                 " Most possibly an aggregate attribute."),
        )
    
        onCommandProgress = attribute(
            dtype='DevUShort',
            label="Progress percentage for the On command",
            abs_change=10,
            max_value=100,
            min_value=0,
            doc=("Percentage progress implemented for commands that  result in state/mode"
                " transitions for a large number of components and/or are executed in "
                "stages (e.g power up, power down)"),
        )
    
        offCommandProgress = attribute(
            dtype='DevUShort',
            label="Progress percentage for the Off command",
            abs_change=10,
            max_value=100,
            min_value=0,
            doc=("Percentage progress implemented for commands that result in state/mode transitions"
                " for a large number of components and/or are executed in stages"
                " (e.g power up, power down)"),
        )
    
        standbyCommandProgress = attribute(
            dtype='DevUShort',
            label="Progress percentage for the Standby command",
            abs_change=10,
            max_value=100,
            min_value=0,
            doc=("Percentage progress implemented for commands that result in state/mode"
                " transitions for a large number of components and/or are executed in"
                " stages (e.g power up, power down)"),
        )
    
        onCmdDurationExpected = attribute(
            dtype='DevUShort',
            access=AttrWriteType.READ_WRITE,
            label="Expected duration (sec) of the On command execution",
            abs_change=0,
            max_value=100,
            min_value=0,
            memorized=True,
            doc="Set/Report the duration expected for the On command execution",
        )
    
        offCmdDurationExpected = attribute(
            dtype='DevUShort',
            access=AttrWriteType.READ_WRITE,
            label="Expected duration (sec) of the Off command",
            abs_change=0,
            max_value=100,
            min_value=0,
            memorized=True,
            doc="Set/Report the duration expected for the Off command execution",
        )
    
        standbyCmdDurationExpected = attribute(
            dtype='DevUShort',
            access=AttrWriteType.READ_WRITE,
            label="Expected duration (sec) of the Standby command",
            abs_change=0,
            max_value=100,
            min_value=0,
            memorized=True,
            doc="Set/Report the duration expected for the Standby command",
        )
    
        onCmdDurationMeasured = attribute(
            dtype='DevUShort',
            label="Measured duration (sec) of the On command execution",
            abs_change=0,
            max_value=100,
            min_value=0,
            doc="Report the measured duration of the On command execution",
        )
    
        offCmdDurationMeasured = attribute(
            dtype='DevUShort',
            label="Measured duration (sec) of the Off command",
            abs_change=0,
            max_value=100,
            min_value=0,
            doc="Report the measured duration of the Off command execution",
        )
    
        standbyCmdDurationMeasured = attribute(
            dtype='DevUShort',
            label="Measured duration (sec) of the Standby command",
            abs_change=0,
            max_value=100,
            min_value=0,
            doc="Report the measured duration of the Standby command",
        )
    
        onCmdTimeoutExpired = attribute(
            dtype='DevBoolean',
            label="On execution timeout flag",
            doc="Signal the occurence of a timeout during the execution of the on command.",
        )
    
        offCmdTimeoutExpired = attribute(
            dtype='DevBoolean',
            label="Off execution timeout flag",
            doc="Signal the occurence of a timeout during the execution of the Off command.",
        )
    
        standbyCmdTimeoutExpired = attribute(
            dtype='DevBoolean',
            label="Standby execution timeout flag.",
            doc="Signal the occurence of a timeout during the execution of the Standby command.",
        )
    
        listOfDevCompletedTask = attribute(
            dtype=('DevString',),
            max_dim_x=100,
            label="List of devices that completed the task",
            doc="List of devices that completed the task",
        )
    
        listOfComponents = attribute(
            dtype=('DevString',),
            max_dim_x=100,
            label="List of sub-element components",
            doc="The list o the FQDNs of the sub-element components.",
        )
    
        # ---------------
        # General methods
        # ---------------
    
        def init_device(self):
            """Initialises the attributes and properties of the CspSubElementMaster."""
            SKAMaster.init_device(self)
            self.set_state(tango.DevState.INIT)
            # PROTECTED REGION ID(CspSubElementMaster.init_device) ENABLED START #
            # _cmd_execution_state: implement the execution state of a long-running
            # command for the whole CSP.  Setting this attribute prevent the execution
            # of the same command while it is already running.
            # implemented as a default dictionary:
            # keys: command name
            # values:command state
            self._cmd_execution_state = defaultdict(lambda: CmdExecState.IDLE)
            # _cmd_progress: report the execution progress of a long-running command
            # implemented as a dictionary:
            # keys: command name ('on', 'off'..)
            # values: the percentage
            self._cmd_progress = defaultdict(lambda: 0)
            
            # _cmd_duration_expected: store the duration (in sec.) configured for
            # a long-running command 
            # Implemented asdefault dictionary
            # keys: command name ('on', 'off',..)
            # values: the duration (in sec)
            self._cmd_duration_expected = defaultdict(lambda: 30)
    
            # _cmd_duration_measured: report the measured duration (in sec.) for
            # a long-running command 
            # Implemented as default dictionary
            # keys: command name ('on', 'off',..)
            # values: the duration (in sec)
            self._cmd_duration_measured = defaultdict(lambda: 0)
            
            # _timeout_expired: report the timeout flag 
            # Implemented as a dictionary
            # keys: command name ('on', 'off', 'standby'..)
            # values: True/False
            self._timeout_expired = defaultdict(lambda: False)
    
            # _failure_raised: report the failure flag 
            # Implemented as a dictionary
            # keys: command name ('on', 'off', 'standby'..)
            # values: True/False
            self._failure_raised = defaultdict(lambda: False)
    
            # _failure_message: report the failure message
            # Implemented as a dictionary
            # keys: command name ('on', 'off', 'standby'..)
            # values: the message
            self._failure_message = defaultdict(lambda: '')
    
            # _list_dev_completed_task: for each long-running command report the list
            # of subordinate sub-element components that completed the task
            # Implemented as a dictionary
            # keys: the command name ('on', 'off',...)
            # values: the list of components
            self._list_dev_completed_task = defaultdict(lambda: [])
            
           # _list_of_components: report the list of subordinate
            # sub-element components.
            # Implemented as a list of FQDNs
            self._list_of_components = []
            
            # _num_dev_completed_task: for each long-running command report the number
            #  of subordinate components that completed the task
            # Implemented as a dictionary
            # keys: the command name ('on', 'off',...)
            # values: the number of components
            self._num_dev_completed_task = defaultdict(lambda:0)
            
            # the last executed command 
            self._last_executed_command = "none"
    
            # PROTECTED REGION END #    //  CspSubElementMaster.init_device
    
        def always_executed_hook(self):
            """Method always executed before any TANGO command is executed."""
            # PROTECTED REGION ID(CspSubElementMaster.always_executed_hook) ENABLED START #
            # PROTECTED REGION END #    //  CspSubElementMaster.always_executed_hook
    
        def delete_device(self):
            """Hook to delete resources allocated in init_device.
    
            This method allows for any memory or other resources allocated in the
            init_device method to be released.  This method is called by the device
            destructor and by the device Init command.
            """
            # PROTECTED REGION ID(CspSubElementMaster.delete_device) ENABLED START #
            # PROTECTED REGION END #    //  CspSubElementMaster.delete_device
        # ------------------
        # Attributes methods
        # ------------------
    
        def read_numOfDevCompletedTask(self):
            # PROTECTED REGION ID(CspSubElementMaster.numOfDevCompletedTask_read) ENABLED START #
            """Return the numOfDevCompletedTask attribute."""
            return self._num_dev_completed_task[self._last_executed_command]
            # PROTECTED REGION END #    //  CspSubElementMaster.numOfDevCompletedTask_read
    
        def read_onCmdFailure(self):
            # PROTECTED REGION ID(CspSubElementMaster.onCmdFailure_read) ENABLED START #
            """Return the onCmdFailure attribute."""
            return self._failure_raised['on']
            # PROTECTED REGION END #    //  CspSubElementMaster.onCmdFailure_read
    
        def read_onFailureMessage(self):
            # PROTECTED REGION ID(CspSubElementMaster.onFailureMessage_read) ENABLED START #
            """Return the onFailureMessage attribute."""
            return self._failure_message['on']
            # PROTECTED REGION END #    //  CspSubElementMaster.onFailureMessage_read
    
        def read_offCmdFailure(self):
            # PROTECTED REGION ID(CspSubElementMaster.offCmdFailure_read) ENABLED START #
            """Return the offCmdFailure attribute."""
            return self._failure_raised['off']
            # PROTECTED REGION END #    //  CspSubElementMaster.offCmdFailure_read
    
        def read_offFailureMessage(self):
            # PROTECTED REGION ID(CspSubElementMaster.offFailureMessage_read) ENABLED START #
            """Return the offFailureMessage attribute."""
            return self._failure_message['off']
            # PROTECTED REGION END #    //  CspSubElementMaster.offFailureMessage_read
    
        def read_standbyCmdFailure(self):
            # PROTECTED REGION ID(CspSubElementMaster.standbyCmdFailure_read) ENABLED START #
            """Return the standbyCmdFailure attribute."""
            return self._failure_raised['standby']
            # PROTECTED REGION END #    //  CspSubElementMaster.standbyCmdFailure_read
    
        def read_standbyFailureMessage(self):
            # PROTECTED REGION ID(CspSubElementMaster.standbyFailureMessage_read) ENABLED START #
            """Return the standbyFailureMessage attribute."""
            return self._failure_message['standby']
            # PROTECTED REGION END #    //  CspSubElementMaster.standbyFailureMessage_read
    
        def read_adminMode(self):
            # PROTECTED REGION ID(CspSubElementMaster.adminMode_read) ENABLED START #
            """Return the adminMode attribute."""
            return self._admin_mode
            # PROTECTED REGION END #    //  CspSubElementMaster.adminMode_read
    
        def write_adminMode(self, value):
            # PROTECTED REGION ID(CspSubElementMaster.adminMode_write) ENABLED START #
            """Set the adminMode attribute."""
            self._admin_mode = value
            if self._admin_mode not in [AdminMode.ONLINE, AdminMode.MAINTENANCE]:
                self.set_state(tango.DevState.DISABLE)
            # PROTECTED REGION END #    //  CspSubElementMaster.adminMode_write
    
        def read_onCommandProgress(self):
            # PROTECTED REGION ID(CspSubElementMaster.onCommandProgress_read) ENABLED START #
            """Return the onCommandProgress attribute."""
            return self._cmd_progress['on']
            # PROTECTED REGION END #    //  CspSubElementMaster.onCommandProgress_read
    
        def read_offCommandProgress(self):
            # PROTECTED REGION ID(CspSubElementMaster.offCommandProgress_read) ENABLED START #
            """Return the offCommandProgress attribute."""
            return self._cmd_progress['off']
            # PROTECTED REGION END #    //  CspSubElementMaster.offCommandProgress_read
    
        def read_standbyCommandProgress(self):
            # PROTECTED REGION ID(CspSubElementMaster.standbyCommandProgress_read) ENABLED START #
            """Return the standbyCommandProgress attribute."""
            return self._cmd_progress['standby']
            # PROTECTED REGION END #    //  CspSubElementMaster.standbyCommandProgress_read
    
        def read_onCmdDurationExpected(self):
            # PROTECTED REGION ID(CspSubElementMaster.onCmdDurationExpected_read) ENABLED START #
            """Return the onCmdDurationExpected attribute."""
            return self._cmd_duration_expected['on']
            # PROTECTED REGION END #    //  CspSubElementMaster.onCmdDurationExpected_read
    
        def write_onCmdDurationExpected(self, value):
            # PROTECTED REGION ID(CspSubElementMaster.onCmdDurationExpected_write) ENABLED START #
            """Set the onCmdDurationExpected attribute."""
            self._cmd_duration_expected['on'] = value
            # PROTECTED REGION END #    //  CspSubElementMaster.onCmdDurationExpected_write
    
        def read_offCmdDurationExpected(self):
            # PROTECTED REGION ID(CspSubElementMaster.offCmdDurationExpected_read) ENABLED START #
            """Return the offCmdDurationExpected attribute."""
            return self._cmd_duration_expected['off']
            # PROTECTED REGION END #    //  CspSubElementMaster.offCmdDurationExpected_read
    
        def write_offCmdDurationExpected(self, value):
            # PROTECTED REGION ID(CspSubElementMaster.offCmdDurationExpected_write) ENABLED START #
            """Set the offCmdDurationExpected attribute."""
            self._cmd_duration_expected['off'] = value
            # PROTECTED REGION END #    //  CspSubElementMaster.offCmdDurationExpected_write
    
        def read_standbyCmdDurationExpected(self):
            # PROTECTED REGION ID(CspSubElementMaster.standbyCmdDurationExpected_read) ENABLED START #
            """Return the standbyCmdDurationExpected attribute."""
            return self._cmd_duration_expected['standby']
            # PROTECTED REGION END #    //  CspSubElementMaster.standbyCmdDurationExpected_read
    
        def write_standbyCmdDurationExpected(self, value):
            # PROTECTED REGION ID(CspSubElementMaster.standbyCmdDurationExpected_write) ENABLED START #
            """Set the standbyCmdDurationExpected attribute."""
            self._cmd_duration_expected['standby'] = value
            # PROTECTED REGION END #    //  CspSubElementMaster.standbyCmdDurationExpected_write
    
        def read_onCmdDurationMeasured(self):
            # PROTECTED REGION ID(CspSubElementMaster.onCmdDurationMeasured_read) ENABLED START #
            """Return the onCmdDurationMeasured attribute."""
            return self._cmd_duration_measured['on']
            # PROTECTED REGION END #    //  CspSubElementMaster.onCmdDurationMeasured_read
    
        def read_offCmdDurationMeasured(self):
            # PROTECTED REGION ID(CspSubElementMaster.offCmdDurationMeasured_read) ENABLED START #
            """Return the offCmdDurationMeasured attribute."""
            return self._cmd_duration_measured['off']
            # PROTECTED REGION END #    //  CspSubElementMaster.offCmdDurationMeasured_read
    
        def read_standbyCmdDurationMeasured(self):
            # PROTECTED REGION ID(CspSubElementMaster.standbyCmdDurationMeasured_read) ENABLED START #
            """Return the standbyCmdDurationMeasured attribute."""
            return self._cmd_duration_measured['standby']
            # PROTECTED REGION END #    //  CspSubElementMaster.standbyCmdDurationMeasured_read
    
        def read_onCmdTimeoutExpired(self):
            # PROTECTED REGION ID(CspSubElementMaster.onCmdTimeoutExpired_read) ENABLED START #
            """Return the onCmdTimeoutExpired attribute."""
            return self._timeout_expired['on']
            # PROTECTED REGION END #    //  CspSubElementMaster.onCmdTimeoutExpired_read
    
        def read_offCmdTimeoutExpired(self):
            # PROTECTED REGION ID(CspSubElementMaster.offCmdTimeoutExpired_read) ENABLED START #
            """Return the offCmdTimeoutExpired attribute."""
            return self._timeout_expired['off']
    
            # PROTECTED REGION END #    //  CspSubElementMaster.offCmdTimeoutExpired_read
    
        def read_standbyCmdTimeoutExpired(self):
            # PROTECTED REGION ID(CspSubElementMaster.standbyCmdTimeoutExpired_read) ENABLED START #
            """Return the standbyCmdTimeoutExpired attribute."""
            return self._timeout_expired['standby']
            # PROTECTED REGION END #    //  CspSubElementMaster.standbyCmdTimeoutExpired_read
    
        def read_listOfDevCompletedTask(self):
            # PROTECTED REGION ID(CspSubElementMaster.listOfDevCompletedTask_read) ENABLED START #
            """Return the listOfDevCompletedTask attribute."""
            return self._list_dev_completed_task[self._last_executed_command]
            # PROTECTED REGION END #    //  CspSubElementMaster.listOfDevCompletedTask_read
    
        def read_listOfComponents(self):
            # PROTECTED REGION ID(CspSubElementMaster.listOfComponents_read) ENABLED START #
            """Return the listOfComponents attribute."""
            return self._list_of_components
            # PROTECTED REGION END #    //  CspSubElementMaster.listOfComponents_read
    
        # --------
        # Commands
        # --------
    
        @command(
            dtype_in='DevVarStringArray',
            doc_in="The list of sub-element components FQDNs to switch-on or an empty list to switch-on the whole "
                   "CSP Sub-element."
                   "                    "
                   "If the array length is 0, the command applies to the whole CSP Sub-Element. If the "
                   "array length is > 1, each array element specifies the FQDN of the"
                   "CSP SubElement component to switch ON.",
        )
        @DebugIt()
        @IsCommandAllowed()
        @AdminModeCheck('On')
        def On(self, argin):
            # PROTECTED REGION ID(CspSubElementMaster.On) ENABLED START #
            """
                Switch-on the CSP sub-element components specified by the input argument. If no argument is
                specified, the command is issued on all the CSP sub-element components.
                The command is executed if the *AdminMode* is ONLINE or *MAINTENANCE*.
                If the AdminMode is *OFFLINE*, *NOT-FITTED* or *RESERVED*, the method throws an 
                exception.
                The CSP sub-element components can be organized as tango-groups or controlled
                by some tango device drivers which actas as 'cache'. We call these devices 
                'racks', even if they can contro a different phisical arrangement.
    
            :param argin: The list of sub-element components FQDNs: if the array length is 0 (empty input \
                    list), the command applies to the whole CSP Sub-Element. If the array length is > 1, \
                    each array element specifies the FQDN of the CSP SubElement component to switch ON.
            :type: 'DevVarStringArray'
            :return: None
            """
            pass
            # PROTECTED REGION END #    //  CspSubElementMaster.On
        
        @command(
            dtype_in='DevVarStringArray',
            doc_in="If the array length is 0, the command applies to the whole"
                   "CSP Sub-element."
                   "If the array length is > 1, each array element specifies the FQDN of the"
                   "CSP SubElement component to switch OFF.",
        )
        @DebugIt()
        @IsCommandAllowed()
        @AdminModeCheck('Off')
        def Off(self, argin):
            # PROTECTED REGION ID(CspSubElementMaster.Off) ENABLED START #
            """
                Switch-off the CSP sub-element components specified by the input argument. 
                If no argument is specified, the command is issued to all the CSP 
                sub-element components.
                The CSP sub-element components can be organized as tango-groups or controlled
                by some tango device drivers which actas as 'cache'. We call these devices 
                'racks', even if they can contro a different phisical arrangement.
    
    
            :param argin: The list of sub-element components FQDNs: if the array length is 0 (no list \
                    specified), the command applies to the whole CSP sub-element. If the array length \
                    is > 1, each array element specifies the FQDN of a CSP SubElement component to switch \
                    off.
            :type: 'DevVarStringArray'
            :return: None
            """
            pass
            # PROTECTED REGION END #    //  CspSubElementMaster.Off
    
        @command(
            dtype_in='DevVarStringArray',
            doc_in="If the array length is 0, the command applies to the whole"
                   "CSP sub-element."
                   "If the array length is > 1, each array element specifies the FQDN of the"
                   "CSP SubElement icomponent to put in STANDBY mode.",
        )
        @DebugIt()
        @IsCommandAllowed()
        @AdminModeCheck('Standby')
        def Standby(self, argin):
            # PROTECTED REGION ID(CspSubElementMaster.Standby) ENABLED START #
            """
                Transit the CSP Sub-element or one or more CSP SubElement components from ON/OFF to 
                STANDBY.
    
            :param argin: The list of sub-element components FQDNs: if the array length is 0 (no list \
                    specified), the command applies to the whole CSP sub-element. If the array length \
                    is > 1, each array element specifies the FQDN of a CSP SubElement component to put \
                    in STANDBY mode.
            :type: 'DevVarStringArray'
            :return: None
            """
            pass
            # PROTECTED REGION END #    //  CspSubElementMaster.Standby
    
        @command(
        )
        @DebugIt()
        def Upgrade(self):
            # PROTECTED REGION ID(CspSubElementMaster.Upgrade) ENABLED START #
            """
            :return: None
            """
            pass
            # PROTECTED REGION END #    //  CspSubElementMaster.Upgrade
    
    # ----------
    # Run server
    # ----------
    
    def main(args=None, **kwargs):
        """Main function of the CspSubElementMaster module."""
        # PROTECTED REGION ID(CspSubElementMaster.main) ENABLED START #
        return run((CspSubElementMaster,), args=args, **kwargs)
        # PROTECTED REGION END #    //  CspSubElementMaster.main
    
    
    if __name__ == '__main__':
        main()