Commit 48420d6b authored by Elisabetta Giani's avatar Elisabetta Giani
Browse files

AT5-373: Added CspSubElementSubarray TANGO device.

Included: POGO file, tests and Docker configuration files.
Removed overloading of the adminMode attribute for SubElement
Master and Subarray.
Use of pytest-fork.
Updated release version.
Added HISTORY file to records release changes.
parent 456e1832
Loading
Loading
Loading
Loading
Loading

HISTORY

0 → 100644
+13 −0
Original line number Diff line number Diff line
0.1.0

- first release of the csp-lmc-subelement software
- CspElementMaster and tests
- decorator function to hadle is_XXX_allowed method for the Master

0.1.1

- added CspSubElementSubarray TANGO device
- removed adminMode overloading: each instance of a sub-element writes its own
  method for the adminMode write method.
- decorator function to hadle is_XXX_allowed method for the Subarray 
- tests for Subarray
+1 −0
Original line number Diff line number Diff line
@@ -3,4 +3,5 @@ __all__ = (
)

from .subelement_master import CspSubElementMaster
from .subelement_subarray import CspSubElementSubarray
+83 −1
Original line number Diff line number Diff line
import functools
import tango
from ska.base.control_model import ObsState

tasks = {}

@@ -51,6 +52,55 @@ def is_off_allowed(device_instance):
        return True
    return False

@task
def is_configurescan_allowed(device_instance):
    """
    Allowed method for ConfigureScan method.
    Command *ConfigureScan* is allowed when the device *State* is ON.

    :return: True if the method is allowed, otherwise False.
    """
    if device_instance.get_state() == tango.DevState.ON:
        return True
    return False

@task
def is_scan_allowed(device_instance):
    """
    Allowed method for Scan method.
    Command *Scan* is allowed when the device *State* is ON.

    :return: True if the method is allowed, otherwise False.
    """
    if device_instance.get_state() == tango.DevState.ON:
        return True
    return False


@task
def is_gotoidle_allowed(device_instance):
    """
    Allowed method for GoToIdle method.
    Command *GoToIdle* is allowed when the device *State* is ON.

    :return: True if the method is allowed, otherwise False.
    """
    if device_instance.get_state() == [tango.DevState.ON, tango.DevState.OFF]:
        return True
    return False

@task
def is_endscan_allowed(device_instance):
    """
    Allowed method for EndScan method.
    Command *EndScan* is allowed when the device *State* is ON.

    :return: True if the method is allowed, otherwise False.
    """
    if device_instance.get_state() == [tango.DevState.ON]:
        return True
    return False

def is_command_allowed(device_instance, cmd_name):
    """
    Call the allowed method for the command name specified
@@ -62,7 +112,7 @@ def is_command_allowed(device_instance, cmd_name):
    """
    tasks[cmd_name](device_instance)

class IsCommandAllowed(object):
class IsMasterCommandAllowed(object):
    """
    Class designed to be a decorator for the Master power methods.
    The *decorator function* performs a check on the input argument
@@ -95,6 +145,7 @@ class IsCommandAllowed(object):
            # Note: device list is a reference to args[1]: changing
            # device_list content, args[1] changes accordingly!
            num_of_devices = len(input_arg)
            dev_instance.logger.info("num_of_devices:{}".format(num_of_devices))
            if num_of_devices == 0:
                # check the device State: if it not the proper value the command is
                # not executed
@@ -106,3 +157,34 @@ class IsCommandAllowed(object):
                                             tango.ErrSeverity.ERR)
            return f(*args, **kwargs)
        return input_args_check

class IsSubarrayCommandAllowed(object):
    """
    Class designed to be a decorator for the Master power methods.
    The *decorator function* performs a check on the input argument
    to control if the command is issued on the whole sub-element.
    If this is the case, it checks the State of the sub-element Master
    device and rejects the command accordingly to the State
    machine setting.

    :raise: tango.DevFailed exception if the command can't be executed 
    """
    def __call__(self, f):
        @functools.wraps(f)
        def input_args_check(*args, **kwargs):
            # the Master device instance
            dev_instance = args[0]
            # the command name
            cmd_to_exec = f.__name__
            dev_instance.logger.info("Isallo Sono qui!!")
            # check the device State: if it not the proper value the command is
            # not executed
            if not is_command_allowed(dev_instance, cmd_to_exec.lower()):
                msg = "Command {} can't be executed when the device is {}".format(cmd_to_exec,
                                                                                   dev_instance.get_state())
                tango.Except.throw_exception("Command failure",msg,
                                         "IsCommandAllowed decorator",
                                         tango.ErrSeverity.ERR)
            return f(*args, **kwargs)
        return input_args_check
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
"""Release information for Python Package"""

name = """csp-lmc-subelement"""
version = "0.1.0"
version = "0.1.1"
version_info = version.split(".")
description = """SKA CSP Sub-element LMC"""
author = "INAF-OAA"
+25 −47
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ 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 .decorators import IsMasterCommandAllowed
from . import release
# PROTECTED REGION END #    //  CspSubElementMaster.additionnal_import

@@ -104,15 +104,6 @@ class CspSubElementMaster(SKAMaster):
        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",
@@ -248,66 +239,67 @@ class CspSubElementMaster(SKAMaster):
        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
        # command for the whole CSP sub-element. Setting this attribute prevent the execution
        # of the same command while it is already running.
        # implemented as a default dictionary:
        # Implemented as a Python 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'..)
        # Implemented as a Python dictionary:
        # keys: command name in lower case ('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',..)
        # Implemented as Python default dictionary
        # keys: command name in lower case ('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',..)
        # Implemented as Python default dictionary
        # keys: command name in lower case ('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'..)
        # Implemented as a Python default dictionary
        # keys: command name in lower case ('on', 'off',..)
        # 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'..)
        # Implemented as a Python default dictionary
        # keys: command name in lower case ('on', 'off',..)
        # 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'..)
        # Implemented as a Python default dictionary
        # keys: command name in lower case ('on', 'off',..)
        # 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',...)
        # Implemented as a Python default dictionary
        # keys: command name in lower case ('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
        # sub-element components FQDNs.
        # Implemented as a Python list
        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',...)
        # Implemented as a Python default dictionary
        # keys: command name in lower case ('on', 'off',..)
        # values: the number of components
        self._num_dev_completed_task = defaultdict(lambda:0)
        
@@ -376,20 +368,6 @@ class CspSubElementMaster(SKAMaster):
        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."""
@@ -507,7 +485,7 @@ class CspSubElementMaster(SKAMaster):
               "CSP SubElement component to switch ON.",
    )
    @DebugIt()
    @IsCommandAllowed()
    @IsMasterCommandAllowed()
    @AdminModeCheck('On')
    def On(self, argin):
        # PROTECTED REGION ID(CspSubElementMaster.On) ENABLED START #
@@ -538,7 +516,7 @@ class CspSubElementMaster(SKAMaster):
               "CSP SubElement component to switch OFF.",
    )
    @DebugIt()
    @IsCommandAllowed()
    @IsMasterCommandAllowed()
    @AdminModeCheck('Off')
    def Off(self, argin):
        # PROTECTED REGION ID(CspSubElementMaster.Off) ENABLED START #
@@ -569,7 +547,7 @@ class CspSubElementMaster(SKAMaster):
               "CSP SubElement icomponent to put in STANDBY mode.",
    )
    @DebugIt()
    @IsCommandAllowed()
    @IsMasterCommandAllowed()
    @AdminModeCheck('Standby')
    def Standby(self, argin):
        # PROTECTED REGION ID(CspSubElementMaster.Standby) ENABLED START #
Loading