diff --git a/HISTORY b/HISTORY new file mode 100644 index 0000000000000000000000000000000000000000..0e0deff14a7a5a43d90a66450538ff5173d5fe01 --- /dev/null +++ b/HISTORY @@ -0,0 +1,13 @@ +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 diff --git a/cspse/lmc/__init__.py b/cspse/lmc/__init__.py index 1daa8afc6388e8fe8e23169bc724c10f4eb12e52..6b7a031347734994ed985aa669dd5b7fdec16d45 100644 --- a/cspse/lmc/__init__.py +++ b/cspse/lmc/__init__.py @@ -3,4 +3,5 @@ __all__ = ( ) from .subelement_master import CspSubElementMaster +from .subelement_subarray import CspSubElementSubarray diff --git a/cspse/lmc/decorators.py b/cspse/lmc/decorators.py index 44364402606d31825fef0e46c586ca35bc1f8aff..22366bb888f203a70d00cbc5d4a5e062e9a19c67 100644 --- a/cspse/lmc/decorators.py +++ b/cspse/lmc/decorators.py @@ -1,5 +1,6 @@ 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 + diff --git a/cspse/lmc/release.py b/cspse/lmc/release.py index 9e0117bcf595da924d8cb116dfba55c54daaf7bf..cd6558f1ff3db36262ab4c852965aefee054076e 100755 --- a/cspse/lmc/release.py +++ b/cspse/lmc/release.py @@ -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" diff --git a/cspse/lmc/subelement_master.py b/cspse/lmc/subelement_master.py index fc4454c196d50b3a8593d658092ee79606fa592c..353ff7f18a54a0793d4a67d66668c67e581b4301 100644 --- a/cspse/lmc/subelement_master.py +++ b/cspse/lmc/subelement_master.py @@ -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 # diff --git a/cspse/lmc/subelement_subarray.py b/cspse/lmc/subelement_subarray.py new file mode 100644 index 0000000000000000000000000000000000000000..a0aa95b466b51eab0e09a4404e81823a3cdebafb --- /dev/null +++ b/cspse/lmc/subelement_subarray.py @@ -0,0 +1,476 @@ +# -*- coding: utf-8 -*- +# +# This file is part of the CspSubElementSubarray project +# +# INAF - SKA Telescope +# +# Distributed under the terms of the GPL license. +# See LICENSE.txt for more info. + +""" CSP SubElement Subarray + +CSP SubElementbsubarray functionality is modeled via a TANGO Device Class +""" + +# 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(CspSubElementSubarray.additionnal_import) ENABLED START # +from ska.base import SKASubarray +from ska.base.control_model import HealthState, AdminMode, ObsState, ObsMode +from csp_lmc_common.utils.cspcommons import CmdExecState +from csp_lmc_common.utils.decorators import AdminModeCheck, ObsStateCheck, SubarrayRejectCmd +from .decorators import IsSubarrayCommandAllowed +from . import release +# PROTECTED REGION END # // CspSubElementSubarray.additionnal_import + +__all__ = ["CspSubElementSubarray", "main"] + + +class CspSubElementSubarray(SKASubarray): + """ + CSP SubElementbsubarray functionality is modeled via a TANGO Device Class + + **Properties:** + + - Device Property + Master + - The TANGO address of the CSP SubElement Master. + - Type:'DevString' + """ + # PROTECTED REGION ID(CspSubElementSubarray.class_variable) ENABLED START # + # PROTECTED REGION END # // CspSubElementSubarray.class_variable + + # ----------------- + # Device Properties + # ----------------- + + Master = device_property( + dtype='DevString', + ) + + # ---------- + # Attributes + # ---------- + + scanID = attribute( + dtype='DevULong64', + access=AttrWriteType.READ_WRITE, + doc="The scan identification number sent as argument of the Scan command.", + ) + + validScanConfiguration = attribute( + dtype='DevString', + label="Valid Scan Configuration", + doc="Store the last valid scan configuration.", + ) + + goToIdleDurationExpected = attribute( + dtype='DevUShort', + access=AttrWriteType.READ_WRITE, + label="GoToIdle command duration expected", + doc="The duration expected (in sec) for the EndSB command.", + ) + + goToIdleDurationMeasured = attribute( + dtype='DevDouble', + label="GoToIdle command duration measured", + doc="The duration measured (in sec) for the EndSB command.", + ) + + numOfDevCompletedTask = attribute( + dtype=(('DevString',),), + max_dim_x=10, max_dim_y=2, + label="Number of devices that completed the task", + doc="Number of devices that completed the task", + ) + + goToIdleCmdProgress = attribute( + dtype='DevUShort', + label="GoToIdle command progress percentage", + polling_period=1500, + abs_change=5, + doc="The progress percentage for the EndSB command.", + ) + + endScanCmdProgress = attribute( + dtype='DevUShort', + label="EndScan command progress percentage", + polling_period=1500, + abs_change=5, + doc="The progress percentage for the EndScan command.", + ) + + scanCmdProgress = attribute( + dtype='DevUShort', + label="Scan percentage progress", + polling_period=1500, + abs_change=5, + doc="The progress percentage for the Scan command.", + ) + + timeoutExpiredFlag = attribute( + dtype='DevBoolean', + label="Subarray command execution timeout flag", + polling_period=1000, + doc="The timeout flag for a Subarray command.", + ) + + failureRaisedFlag = attribute( + dtype='DevBoolean', + label="Subarray failure flag", + polling_period=1000, + doc="The failure flag for a Subarray command.", + ) + + failureMessage = attribute( + dtype=(('DevString',),), + max_dim_x=10, max_dim_y=2, + label="The failure message", + doc="The failure message", + ) + + configureScanCmdProgress = attribute( + dtype='DevUShort', + label="ConfigureScan command execution progress", + doc="The progress percentage for the ConfigureScan command.", + ) + + configureScanDurationMeasured = attribute( + dtype='DevDouble', + label="ConfigureScan execution time", + doc="The measured execution time for the ConfigureScan command", + ) + + listOfDevCompletedTask = attribute( + dtype=(('DevString',),), + max_dim_x=10, max_dim_y=2, + label="List of devices that completed the task", + doc="List of devices that completed the task", + ) + + # --------------- + # General methods + # --------------- + + def init_device(self): + """Initialises the attributes and properties of the CspSubElementSubarray.""" + SKASubarray.init_device(self) + self.set_state(tango.DevState.INIT) + # PROTECTED REGION ID(CspSubElementSubarray.init_device) ENABLED START # + + # _scanID: the scan identification number send as argument of the Scan + # command + # Implemented as unsigned long64. + self._scanID = 0 + + # _cmd_execution_state: implement the execution state of a long-running + # command for the whole CSP Sub-element subarray. Setting this attribute + # prevents the execution of the same command while it is already running. + # 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 Python dictionary: + # keys: command name in lower case('gotoidle', 'configurescan'..) + # values: the percentage + self._cmd_progress = defaultdict(lambda: 0) + + # _cmd_duration_expected: store the duration (in sec.) configured for + # a long-running command + # Implemented as Python default dictionary + # keys: command name in lower case('gotoidle', 'configurescan'..) + # values: the duration (in sec) + self._cmd_duration_expected = defaultdict(lambda: 30) + + # _config_delay_expected: inherited attribute from SKAObsDevice class + self._config_delay_expected = 30 + + # _cmd_duration_measured: report the measured duration (in sec.) for + # a long-running command + # Implemented as Python default dictionary + # keys: command name in lower case('gotoidle', 'configurescan'..) + # values: the duration (in sec) + self._cmd_duration_measured = defaultdict(lambda: 0) + + # _timeout_expired: report the timeout flag + # True/False + self._timeout_expired = False + + # _failure_raised: report the failure flag + # True/False + self._failure_raised = False + + # _failure_message: report the failure message + # Implemented as Python default dictionary + # keys: command name in lower case('gotoidle', 'configurescan'..) + # values: the message + self._failure_message = defaultdict(lambda: '') + + # _list_dev_completed_task: for each long-running command report the list of subordinate + # components that completed the task + # Implemented as Python default dictionary + # keys: command name in lower case('gotoidle', 'configurescan'..) + # values: the list of components + self._list_dev_completed_task = defaultdict(lambda: []) + + # _num_dev_completed_task: for each long-running command report the number + # of subordinate components that completed the task + # Implemented as Python default dictionary + # keys: command name in lower case('gotoidle', 'configurescan'..) + # values: the number of components completed the task (stored as string). + self._num_dev_completed_task = defaultdict(lambda:'0') + + + # _valid_scan_coniguration: store the last valid scan configuration (json format) + # Impemented as a string. + self._valid_scan_configuration = '' + # PROTECTED REGION END # // CspSubElementSubarray.init_device + + def always_executed_hook(self): + """Method always executed before any TANGO command is executed.""" + # PROTECTED REGION ID(CspSubElementSubarray.always_executed_hook) ENABLED START # + # PROTECTED REGION END # // CspSubElementSubarray.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(CspSubElementSubarray.delete_device) ENABLED START # + # PROTECTED REGION END # // CspSubElementSubarray.delete_device + # ------------------ + # Attributes methods + # ------------------ + + def read_scanID(self): + # PROTECTED REGION ID(CspSubElementSubarray.scanID_read) ENABLED START # + """Return the scanID attribute.""" + return self._scanID + # PROTECTED REGION END # // CspSubElementSubarray.scanID_read + + def write_scanID(self, value): + # PROTECTED REGION ID(CspSubElementSubarray.scanID_write) ENABLED START # + """Set the scanID attribute.""" + self._scanID = value + # PROTECTED REGION END # // CspSubElementSubarray.scanID_write + + def read_validScanConfiguration(self): + # PROTECTED REGION ID(CspSubElementSubarray.validScanConfiguration_read) ENABLED START # + """Return the validScanConfiguration attribute.""" + return self._valid_scan_configuration + # PROTECTED REGION END # // CspSubElementSubarray.validScanConfiguration_read + + def read_goToIdleDurationExpected(self): + # PROTECTED REGION ID(CspSubElementSubarray.goToIdleDurationExpected_read) ENABLED START # + """Return the goToIdleDurationExpected attribute.""" + return self._cmd_duration_expected['gotoidle'] + # PROTECTED REGION END # // CspSubElementSubarray.goToIdleDurationExpected_read + + def write_goToIdleDurationExpected(self, value): + # PROTECTED REGION ID(CspSubElementSubarray.goToIdleDurationExpected_write) ENABLED START # + """Set the goToIdleDurationExpected attribute.""" + self._cmd_duration_expected['gotoidle'] = value + # PROTECTED REGION END # // CspSubElementSubarray.goToIdleDurationExpected_write + + def read_goToIdleDurationMeasured(self): + # PROTECTED REGION ID(CspSubElementSubarray.goToIdleDurationMeasured_read) ENABLED START # + """Return the goToIdleDurationMeasured attribute.""" + return self._cmd_duration_measured['gotoidle'] + # PROTECTED REGION END # // CspSubElementSubarray.goToIdleDurationMeasured_read + + def read_numOfDevCompletedTask(self): + # PROTECTED REGION ID(CspSubElementSubarray.numOfDevCompletedTask_read) ENABLED START # + """Return the numOfDevCompletedTask attribute. + The attribute value is returned as a nested listed (TANGO image attribute): + - x index: addresses the command name + - y index: addresses the number (string) of completed task + + Es: + [['gotoidle','3'],['configurescan': '10']] + """ + image_attr = [[cmd_name, dev_num] for cmd_name, dev_num in self._num_dev_completed_task.items()] + return image_attr + # PROTECTED REGION END # // CspSubElementSubarray.numOfDevCompletedTask_read + + def read_goToIdleCmdProgress(self): + # PROTECTED REGION ID(CspSubElementSubarray.goToIdleCmdProgress_read) ENABLED START # + """Return the goToIdleCmdProgress attribute.""" + return self._cmd_progress['gotoidle'] + # PROTECTED REGION END # // CspSubElementSubarray.goToIdleCmdProgress_read + + def read_endScanCmdProgress(self): + # PROTECTED REGION ID(CspSubElementSubarray.endScanCmdProgress_read) ENABLED START # + """Return the endScanCmdProgress attribute.""" + return self._cmd_progress['endscan'] + # PROTECTED REGION END # // CspSubElementSubarray.endScanCmdProgress_read + + def read_scanCmdProgress(self): + # PROTECTED REGION ID(CspSubElementSubarray.scanCmdProgress_read) ENABLED START # + """Return the scanCmdProgress attribute.""" + return self._cmd_progress['scan'] + # PROTECTED REGION END # // CspSubElementSubarray.scanCmdProgress_read + + def read_timeoutExpiredFlag(self): + # PROTECTED REGION ID(CspSubElementSubarray.timeoutExpiredFlag_read) ENABLED START # + """Return the timeoutExpiredFlag attribute.""" + return self._timeout_expired + # PROTECTED REGION END # // CspSubElementSubarray.timeoutExpiredFlag_read + + def read_failureRaisedFlag(self): + # PROTECTED REGION ID(CspSubElementSubarray.failureRaisedFlag_read) ENABLED START # + """Return the failureRaisedFlag attribute.""" + return self._failure_raised + # PROTECTED REGION END # // CspSubElementSubarray.failureRaisedFlag_read + + def read_failureMessage(self): + # PROTECTED REGION ID(CspSubElementSubarray.failureMessage_read) ENABLED START # + """Return the failureMessage attribute. + For each failed commad, it reports the associated failure message. + Es: + self._failure_message = {'gotoidle': 'Device XXX can't execute the command when in SCANNING'} + image_attr = [['gotoidle', 'Device XXX can't execute the command when in SCANNING']] + """ + image_attr = [[cmd_name, message] for cmd_name, message in self._failure_message.items()] + return image_attr + # PROTECTED REGION END # // CspSubElementSubarray.failureMessage_read + + def read_configureScanCmdProgress(self): + # PROTECTED REGION ID(CspSubElementSubarray.configureScanProgress_read) ENABLED START # + """Return the configureScanProgress attribute.""" + return self._cmd_progress['configurescan'] + # PROTECTED REGION END # // CspSubElementSubarray.configureScanProgress_read + + def read_configureScanDurationMeasured(self): + # PROTECTED REGION ID(CspSubElementSubarray.configureScanDurationMeasured_read) ENABLED START # + """Return the configureScanDurationMeasured attribute.""" + return self._cmd_duration_measured['configurescan'] + # PROTECTED REGION END # // CspSubElementSubarray.configureScanDurationMeasured_read + + def read_listOfDevCompletedTask(self): + # PROTECTED REGION ID(CspSubElementSubarray.listOfDevCompletedTask_read) ENABLED START # + """Return the listOfDevCompletedTask attribute.""" + # build the content of the TANGO attribute listOfDevCompletedTask + # (type Image of DevString) as a nested list. + # x element: the command name + # y element: the number of devices (stored as a string) that completed the task + # + # Es: + # self._list_dev_completed_task = {'gotoidle': '3', 'configurescan': '10'} + # image_attr = [['gotoidle','3'], ['configurescan':'10']] + image_attr = [[cmd_name, dev_list] for cmd_name, dev_list in self._list_dev_completed_task.items()] + return image_attr + # PROTECTED REGION END # // CspSubElementSubarray.listOfDevCompletedTask_read + + # -------- + # Commands + # -------- + + @command( + ) + @DebugIt() + def Abort(self): + # PROTECTED REGION ID(CspSubElementSubarray.Abort) ENABLED START # + """ + Change obsState to ABORTED. + + :return:None + """ + pass + # PROTECTED REGION END # // CspSubElementSubarray.Abort + + @command( + ) + @DebugIt() + @IsSubarrayCommandAllowed() + @ObsStateCheck('endscan') + def EndScan(self): + # PROTECTED REGION ID(CspSubElementSubarray.EndScan) ENABLED START # + """ + Change obsState to IDLE. + + :return:None + """ + pass + # PROTECTED REGION END # // CspSubElementSubarray.EndScan + + @command( + dtype_in='DevVarStringArray', + ) + @DebugIt() + @IsSubarrayCommandAllowed() + @ObsStateCheck('scan') + def Scan(self, argin): + # PROTECTED REGION ID(CspSubElementSubarray.Scan) ENABLED START # + """ + Starts the scan. + + :param argin: 'DevVarStringArray' + + :return:None + """ + pass + # PROTECTED REGION END # // CspSubElementSubarray.Scan + + @command( + dtype_in='DevString', + doc_in="A Json-encoded string with the scan configuration.", + ) + @DebugIt() + @IsSubarrayCommandAllowed() + @ObsStateCheck('configscan') + def ConfigureScan(self, argin): + # PROTECTED REGION ID(CspSubElementSubarray.ConfigureScan) ENABLED START # + """ + Configure a complete scan for the subarray. + + :param argin: 'DevString' + A Json-encoded string with the scan configuration. + + :return:None + """ + pass + # PROTECTED REGION END # // CspSubElementSubarray.ConfigureScan + + @command( + ) + @DebugIt() + @IsSubarrayCommandAllowed() + @ObsStateCheck('gotoidle') + @SubarrayRejectCmd('Configure', 'Scan') + def GoToIdle(self): + # PROTECTED REGION ID(CspSubElementSubarray.GoToIdle) ENABLED START # + """ + Set the Subarray obsState to IDLE. + + :return:None + """ + pass + # PROTECTED REGION END # // CspSubElementSubarray.GoToIdle + +# ---------- +# Run server +# ---------- + + +def main(args=None, **kwargs): + """Main function of the CspSubElementSubarray module.""" + # PROTECTED REGION ID(CspSubElementSubarray.main) ENABLED START # + return run((CspSubElementSubarray,), args=args, **kwargs) + # PROTECTED REGION END # // CspSubElementSubarray.main + + +if __name__ == '__main__': + main() diff --git a/docker/.release b/docker/.release index 87dca79f7d33c662b775fc4365b82a6e9e2af259..6bfe32e7521cbbfcb690018ec549201357417232 100644 --- a/docker/.release +++ b/docker/.release @@ -9,7 +9,7 @@ """Release information for Python Package""" name = """csplmc-subelement""" -version = "0.1.0" +version = "0.1.1" version_info = version.split(".") description = """SKA CSP.LMC Subelement Classes""" author = "E.G" @@ -18,5 +18,5 @@ license = """BSD-3-Clause""" url = """www.tango-controls.org""" copyright = """""" -release=0.1.0 -tag=csp-lmc-subelement-0.1.0 +release=0.1.1 +tag=csp-lmc-subelement-0.1.1 diff --git a/docker/config/csplmc_dsconfig.json b/docker/config/csplmc_dsconfig.json index 29d976ddfa1244ce65eae47a50dbf041444c2aef..c52b58b12dd39ff9162e72cde0295895512a6f29 100644 --- a/docker/config/csplmc_dsconfig.json +++ b/docker/config/csplmc_dsconfig.json @@ -125,7 +125,7 @@ "properties": { "SubID": [ "1" - ] + ] } } } @@ -159,7 +159,7 @@ "properties": { "SubID": [ "2" - ] + ] } } } diff --git a/docker/se-lmc.yml b/docker/se-lmc.yml index af6db57a2492da01ab2e6d467551c0db3822d105..9b5ed2eb3a49289637c6683b14c3526a0ce7cc45 100644 --- a/docker/se-lmc.yml +++ b/docker/se-lmc.yml @@ -39,7 +39,7 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- retry --max=5 -- tango_admin --ping-device subelement/sub_elt/master &&\ - /venv/bin/python -m cspse.lmc.SubElementSubarray subarray1" + CspSubElementSubarray subarray1" sesubarray02: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/csp-lmc-subelement:latest network_mode: ${NETWORK_MODE} @@ -52,7 +52,7 @@ services: command: > sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- retry --max=5 -- tango_admin --ping-device subelement/sub_elt/master &&\ - /venv/bin/python -m cspse.lmc.SubElementSubarray subarray2" + CspSubElementSubarray subarray2" semaster: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/csp-lmc-subelement:latest diff --git a/pogo/CspSubElementMaster.xmi b/pogo/CspSubElementMaster.xmi index 0abe206bc1527317ac3396b899b2ee31bb20d166..146a1f8b7fe0d30c2859357e722a77ddae166896 100644 --- a/pogo/CspSubElementMaster.xmi +++ b/pogo/CspSubElementMaster.xmi @@ -235,11 +235,12 @@ <status abstract="false" inherited="true" concrete="true"/> <properties description="The health state reported for this device. It interprets the current device condition 
and condition of all managed devices to set this. Most possibly an aggregate attribute." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> - <attributes name="adminMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> + <attributes name="adminMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true" isDynamic="false"> <dataType xsi:type="pogoDsl:EnumType"/> <changeEvent fire="false" libCheckCriteria="false"/> <archiveEvent fire="false" libCheckCriteria="false"/> - <status abstract="false" inherited="true" concrete="true" concreteHere="true"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> <properties description="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." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> </attributes> <attributes name="controlMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true"> diff --git a/pogo/CspSubElementSubarray.xmi b/pogo/CspSubElementSubarray.xmi new file mode 100644 index 0000000000000000000000000000000000000000..fd0d2814fa5a71b0d50e03bc4bc6167c7f87cffa --- /dev/null +++ b/pogo/CspSubElementSubarray.xmi @@ -0,0 +1,455 @@ +<?xml version="1.0" encoding="ASCII"?> +<pogoDsl:PogoSystem xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pogoDsl="http://www.esrf.fr/tango/pogo/PogoDsl"> + <classes name="CspSubElementSubarray" pogoRevision="9.6"> + <description description="CSP SubElementbsubarray functionality is modeled via a TANGO Device Class " title="CSP SubElement Subarray" sourcePath="/home/softir/src/ska-git/csp-lmc-subelement/pogo" language="PythonHL" filestogenerate="XMI file,Code files,Protected Regions" license="GPL" copyright="INAF - SKA Telescope" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false"> + <inheritances classname="Device_Impl" sourcePath=""/> + <inheritances classname="SKAObsDevice" sourcePath="../../lmc-base-classes/pogo"/> + <inheritances classname="SKASubarray" sourcePath="/home/softir/src/ska-git/lmc-base-classes/pogo"/> + <identification contact="at inaf.it - elisabetta.giani" author="elisabetta.giani" emailDomain="inaf.it" classFamily="SkaCsp" siteSpecific="" platform="All Platforms" bus="Not Applicable" manufacturer="INAF" reference=""/> + </description> + <deviceProperties name="CapabilityTypes" description="List of Capability types e.g. capCorr, capPss,
capPstBf, capVlbi, this will be used to dynamically
define groups for subarray."> + <type xsi:type="pogoDsl:StringVectorType"/> + <status abstract="false" inherited="true" concrete="true"/> + </deviceProperties> + <deviceProperties name="GroupDefinitions" description="Each string in the list is a JSON serialised dict defining the ``group_name``,
``devices`` and ``subgroups`` in the group. A TANGO Group object is created
for each item in the list, according to the hierarchy defined. This provides
easy access to the managed devices in bulk, or individually.

The general format of the list is as follows, with optional ``devices`` and
``subgroups`` keys:
 [ {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ...]},
 {``group_name``: ``<name>``,
 ``devices``: [``<dev name>``, ``<dev name>``, ...],
 ``subgroups`` : [{<nested group>},
 {<nested group>}, ...]},
 ...
 ]

For example, a hierarchy of racks, servers and switches:
 [ {``group_name``: ``servers``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/server/3``, ``elt/server/4``]},
 {``group_name``: ``switches``,
 ``devices``: [``elt/switch/A``, ``elt/switch/B``]},
 {``group_name``: ``pdus``,
 ``devices``: [``elt/pdu/rackA``, ``elt/pdu/rackB``]},
 {``group_name``: ``racks``,
 ``subgroups``: [
 {``group_name``: ``rackA``,
 ``devices``: [``elt/server/1``, ``elt/server/2``,
 ``elt/switch/A``, ``elt/pdu/rackA``]},
 {``group_name``: ``rackB``,
 ``devices``: [``elt/server/3``, ``elt/server/4``,
 ``elt/switch/B``, ``elt/pdu/rackB``],
 ``subgroups``: []}
 ]} ]"> + <type xsi:type="pogoDsl:StringVectorType"/> + <status abstract="false" inherited="true" concrete="true"/> + </deviceProperties> + <deviceProperties name="SkaLevel" description="Indication of importance of the device in the SKA hierarchy 
to support drill-down navigation: 1..6, with 1 highest.
Default is 4, making provision for 
EltMaster, EltAlarms, EltTelState = 1
SubEltMaster = 2
Subarray, Capability = 2/3
Others = 4 (or 5 or 6)"> + <type xsi:type="pogoDsl:ShortType"/> + <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> + </deviceProperties> + <deviceProperties name="SubID" description="Unique identifier of the subarray device."> + <type xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="true" concrete="true"/> + </deviceProperties> + <deviceProperties name="LoggingLevelDefault" description="Default logging level at device startup.
(0=OFF, 1=FATAL, 2=ERROR, 3=WARNING, 4=INFO, 5=DEBUG)"> + <type xsi:type="pogoDsl:UShortType"/> + <status abstract="false" inherited="true" concrete="true"/> + <DefaultPropValue>4</DefaultPropValue> + </deviceProperties> + <deviceProperties name="LoggingTargetsDefault" description="Default logging targets at device startup.
Each item has the format: target_type::target_name.
To log to stdout, use 'console::cout'.
To log to syslog, use 'syslog::<address>',
 where <address> is a file path,
 for example 'syslog::/var/run/rsyslog/dev/log'.
To log to a file, use 'file::<path>',
 where <path> is a file path,
 for example 'file::/tmp/my_dev.log'."> + <type xsi:type="pogoDsl:StringVectorType"/> + <status abstract="false" inherited="true" concrete="true"/> + </deviceProperties> + <deviceProperties name="Master" description="The TANGO address of the CSP SubElement Master."> + <type xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </deviceProperties> + <commands name="Abort" description="Change obsState to ABORTED." execMethod="abort" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true" concreteHere="true"/> + </commands> + <commands name="ConfigureCapability" description="Configures number of instances for each capability. If the capability exists, 
it increments the configured instances by the number of instances requested, 
otherwise an exception will be raised.
Note: The two lists arguments must be of equal length or an exception will be raised." execMethod="configure_capability" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="[Number of instances to add][Capability types]"> + <type xsi:type="pogoDsl:LongStringArrayType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="DeconfigureAllCapabilities" description="Deconfigure all instances of the given Capability type. If the capability type does not exist an exception will be raised, 
otherwise it sets the configured instances for that capability type to zero." execMethod="deconfigure_all_capabilities" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="Capability type"> + <type xsi:type="pogoDsl:StringType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="DeconfigureCapability" description="Deconfigures a given number of instances for each capability. If the capability exists, 
it decrements the configured instances by the number of instances requested,
otherwise an exceptioin will be raised.
Note: The two lists arguments must be of equal length or an exception will be raised" execMethod="deconfigure_capability" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="[Number of instances to remove][Capability types]"> + <type xsi:type="pogoDsl:LongStringArrayType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="GetVersionInfo" description="Array of version strings of all entities modelled by this device. 
(One level down only)
Each string in the array lists the version info for one entity
managed by this device. 
The first entry is version info for this TANGO Device itself.
The entities may be TANGO devices, or hardware LRUs or 
anything else this devices manages/models.
The intention with this command is that it can provide more 
detailed information than can be captured in the versionId 
and buildState attributes, if necessary.
In the minimal case the GetVersionInfo will contain only the 
versionId and buildState attributes of the next lower level
entities." execMethod="get_version_info" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description="[ name: EltTelState"> + <type xsi:type="pogoDsl:StringArrayType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="Status" description="This command gets the device status (stored in its device_status data member) and returns it to the caller." execMethod="dev_status" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="none"> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description="Device status"> + <type xsi:type="pogoDsl:ConstStringType"/> + </argout> + <status abstract="true" inherited="true" concrete="true"/> + </commands> + <commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="none"> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description="Device state"> + <type xsi:type="pogoDsl:StateType"/> + </argout> + <status abstract="true" inherited="true" concrete="true"/> + </commands> + <commands name="AssignResources" description="" execMethod="assign_resources" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="List of Resources to add to subarray."> + <type xsi:type="pogoDsl:StringArrayType"/> + </argin> + <argout description="A list of Resources added to the subarray."> + <type xsi:type="pogoDsl:StringArrayType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="EndScan" description="Change obsState to IDLE." execMethod="end_scan" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true" concreteHere="true"/> + </commands> + <commands name="ObsState" description="Set the observation state" execMethod="obs_state" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description="Observation state"> + <type xsi:type="pogoDsl:ConstStringType"/> + </argout> + <status abstract="true" inherited="true" concrete="true"/> + </commands> + <commands name="Pause" description="Pause scan." execMethod="pause" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="ReleaseAllResources" description="Remove all resources to tear down to an empty subarray." execMethod="release_all_resources" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description="List of resources removed from the subarray."> + <type xsi:type="pogoDsl:StringArrayType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="ReleaseResources" description="Delta removal of assigned resources." execMethod="release_resources" displayLevel="OPERATOR" polledPeriod="0"> + <argin description="List of resources to remove from the subarray."> + <type xsi:type="pogoDsl:StringArrayType"/> + </argin> + <argout description="List of resources removed from the subarray."> + <type xsi:type="pogoDsl:StringArrayType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="Reset" description="Reset device to its default state" execMethod="reset" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="Resume" description="Resume scan." execMethod="resume" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true"/> + </commands> + <commands name="Scan" description="Starts the scan." execMethod="scan" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:StringArrayType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true" concreteHere="true"/> + </commands> + <commands name="ConfigureScan" description="Configure a complete scan for the subarray." execMethod="configure_scan" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> + <argin description="A Json-encoded string with the scan configuration."> + <type xsi:type="pogoDsl:StringType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </commands> + <commands name="EndSB" description="Set the subarray obsState to IDLE." execMethod="end_sb" displayLevel="OPERATOR" polledPeriod="0"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> + </commands> + <commands name="GoToIdle" description="Set the Subarray obsState to IDLE." execMethod="go_to_idle" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false"> + <argin description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argin> + <argout description=""> + <type xsi:type="pogoDsl:VoidType"/> + </argout> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + </commands> + <attributes name="activationTime" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:DoubleType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Time of activation in seconds since Unix epoch." label="" unit="s" standardUnit="s" displayUnit="s" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="adminMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> + <properties description="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." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="buildState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="60000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="configurationDelayExpected" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:UShortType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true" concreteHere="false"/> + <properties description="Configuration delay expected in seconds" label="" unit="seconds" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="configurationProgress" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:UShortType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Percentage configuration progress" label="" unit="%" standardUnit="" displayUnit="" format="" maxValue="100" minValue="0" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="controlMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="The control mode of the device. REMOTE, LOCAL
TANGO Device accepts only from a ‘local’ client and ignores commands and queries received from TM
or any other ‘remote’ clients. The Local clients has to release LOCAL control before REMOTE clients
can take control again." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="healthState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="The health state reported for this device. It interprets the current device condition 
and condition of all managed devices to set this. Most possibly an aggregate attribute." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="obsMode" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Observing Mode" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="obsState" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Observing State" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="simulationMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Reports the simulation mode of the device. Some devices may implement both modes,
while others will have simulators that set simulationMode to True while the real
devices always set simulationMode to False." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="testMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" memorized="true" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="The test mode of the device. 
Either no test mode (empty string) or an indication of the test mode." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="versionId" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="60000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:StringType"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Build state of this device" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="scanID" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:ULongType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The scan identification number sent as argument of the Scan command." label="Scan ID number" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="validScanConfiguration" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="Store the last valid scan configuration." label="Valid Scan Configuration" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="goToIdleDurationExpected" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:UShortType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The duration expected (in sec) for the GoToIdle command." label="GoToIdle command duration expected" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="goToIdleDurationMeasured" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:DoubleType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The duration measured (in sec) for the GoToIdle command." label="GoToIdle command duration measured" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="goToIdleCmdProgress" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1500" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:UShortType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The progress percentage for the GoToIdle command." label="GoToIdle command progress percentage" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <eventCriteria relChange="" absChange="5" period=""/> + </attributes> + <attributes name="endScanCmdProgress" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1500" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:UShortType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The progress percentage for the EndScan command." label="EndScan command progress percentage" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <eventCriteria relChange="" absChange="5" period=""/> + </attributes> + <attributes name="scanCmdProgress" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1500" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:UShortType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="he progress percentage for the Scan command." label="Scan percentage progress" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + <eventCriteria relChange="" absChange="5" period=""/> + </attributes> + <attributes name="timeoutExpiredFlag" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:BooleanType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The timeout flag for a Subarray command." label="Subarray command execution timeout flag" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="failureRaisedFlag" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:BooleanType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The failure flag for a Subarray command." label="Subarray failure flag" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="loggingLevel" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:EnumType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging level for this device - initialises to LoggingLevelDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="configureScanCmdProgress" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:UShortType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The progress percentage for the ConfigureScan command." label="ConfigureScan command execution progress" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="configureScanDurationMeasured" attType="Scalar" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="" maxY="" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:DoubleType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="The measured execution time for the ConfigureScan command" label="ConfigureScan execution time" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="assignedResources" attType="Spectrum" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="100" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="The list of resources assigned to the subarray." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="configuredCapabilities" attType="Spectrum" rwType="READ" displayLevel="OPERATOR" polledPeriod="1000" maxX="10" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="A list of capability types with no. of instances in use on this subarray; e.g.
Correlators:512, PssBeams:4, PstBeams:4, VlbiBeams:0." label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="loggingTargets" attType="Spectrum" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="0" maxX="3" maxY="" allocReadMember="true"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <status abstract="false" inherited="true" concrete="true"/> + <properties description="Current logging targets for this device - 
initialises to LoggingTargetsDefault on startup" label="" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="listOfDevCompletedTask" attType="Image" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="2" maxY="10" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="List of devices that completed the task" label="List of devices that completed the task" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="numOfDevCompletedTask" attType="Image" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="2" maxY="10" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="Number of devices that completed the task" label="Number of devices that completed the task" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <attributes name="failureMessage" attType="Image" rwType="READ" displayLevel="OPERATOR" polledPeriod="0" maxX="10" maxY="2" allocReadMember="true" isDynamic="false"> + <dataType xsi:type="pogoDsl:StringType"/> + <changeEvent fire="false" libCheckCriteria="false"/> + <archiveEvent fire="false" libCheckCriteria="false"/> + <dataReadyEvent fire="false" libCheckCriteria="true"/> + <status abstract="false" inherited="false" concrete="true" concreteHere="true"/> + <properties description="For each failed command returns the associated message." label="The failure message" unit="" standardUnit="" displayUnit="" format="" maxValue="" minValue="" maxAlarm="" minAlarm="" maxWarning="" minWarning="" deltaTime="" deltaValue=""/> + </attributes> + <states name="ON" description="This state could have been called OK or OPERATIONAL. It means that the device is in its operational state. (E.g. the power supply is giving its nominal current, th motor is ON and ready to move, the instrument is operating). This state is modified by the Attribute alarm checking of the DeviceImpl:dev_state method. i.e. if the State is ON and one attribute has its quality factor to ATTR_WARNING or ATTR_ALARM, then the State is modified to ALARM."> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <states name="OFF" description="The device is in normal condition but is not active. E.g. the power supply main circuit breaker is open; the RF transmitter has no power etc..."> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <states name="FAULT" description="The device has a major failure that prevents it to work. For instance, A power supply has stopped due to over temperature A motor cannot move because it has fault conditions. Usually we cannot get out from this state without an intervention on the hardware or a reset command."> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <states name="INIT" description="This state is reserved to the starting phase of the device server. It means that the software is not fully operational and that the user must wait"> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <states name="ALARM" description="ALARM - The device is operating but
at least one of the attributes is out of range. It can be linked to alarm conditions set by attribute properties or a specific case. (E.g. temperature alarm on a stepper motor, end switch pressed on a stepper motor, up water level in a tank, etc....). In alarm, usually the device does its job, but the operator has to perform an action to avoid a bigger problem that may switch the state to FAULT."> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <states name="UNKNOWN" description="The device cannot retrieve its state. It is the case when there is a communication problem to the hardware (network cut, broken cable etc...) It could also represent an incoherent situation"> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <states name="STANDBY" description="Equates to LOW-POWER mode. This is the initial transition from INIT if the device supports a low-power mode. The device is not fully active but is ready to operate."> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <states name="DISABLE" description="The device cannot be switched ON for an external reason. E.g. the power supply has its door open, the safety conditions are not satisfactory to allow the device to operate."> + <status abstract="false" inherited="true" concrete="true"/> + </states> + <preferences docHome="./doc_html" makefileHome="/usr/local/share/pogo/preferences"/> + <overlodedPollPeriodObject name="adminMode" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="configurationDelayExpected" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="configurationProgress" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="controlMode" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="healthState" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="obsMode" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="obsState" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="simulationMode" type="attribute" pollPeriod="0"/> + <overlodedPollPeriodObject name="testMode" type="attribute" pollPeriod="0"/> + </classes> +</pogoDsl:PogoSystem> diff --git a/setup.cfg b/setup.cfg index 3fd66934bf6ec15ede95c42bab17fdfce248311e..0cd5b4412acbba54eaf500c3094fec1f5798f2f7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,7 +11,8 @@ source = cspse [tool:pytest] testpaths = tests -addopts = --verbose +addopts = --forked + --verbose --cov=cspse --json-report --json-report-file=htmlcov/report.json diff --git a/setup.py b/setup.py index 25947e60b6af751f95f34c693e69441b56e50bae..31803482ec40cf93805b75aef50c420039c9a10f 100644 --- a/setup.py +++ b/setup.py @@ -53,17 +53,16 @@ setup( ], tests_require=[ 'pytest', - 'pytest-cov', + 'coverage', 'pytest-json-report', + 'pytest-forked', 'pycodestyle', 'mock' ], entry_points={ "console_scripts": [ "CspSubElementMaster=cspse.lmc.subelement_master:main", + "CspSubElementSubarray=cspse.lmc.subelement_subarray:main", ] - }, - extras_require={ - 'dev': ['prospector[with_pyroma]', 'yapf', 'isort'], } ) diff --git a/tests/conftest.py b/tests/conftest.py index 69c7a6dbf67e4c7c6752195d1f5eca61a2f79728..a921b30ed07aa8339d6d2fa71914160edb9eed2b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,7 +18,7 @@ def tango_context(request): """ test_properties = { 'CspSubElementMaster': { - 'SkaLevel': '4', + 'SkaLevel': '2', 'LoggingTargetsDefault': '', 'GroupDefinitions': '', 'NrSubarrays': '16', @@ -27,10 +27,9 @@ def tango_context(request): }, 'CspSubElementSubarray': { - 'CapabilityTypes': ['VCC','FSP'], 'LoggingTargetsDefault': '', 'GroupDefinitions': '', - 'SkaLevel': '4', + 'SkaLevel': '2', 'SubID': '1', }, } @@ -61,5 +60,4 @@ def initialize_device(tango_context): tango_context: tango.test_context.DeviceTestContext Context to run a device without a database. """ - print("Sono qui") yield tango_context.device.Init() diff --git a/tests/test_se_master.py b/tests/test_se_master.py index a598ec38a983f0c8591894c47c96549c8f7b0cd6..f24cffd019832615a8d1de33967bd4ed4094f988 100644 --- a/tests/test_se_master.py +++ b/tests/test_se_master.py @@ -107,60 +107,47 @@ class TestCspSubElementMaster(object): assert tango_context.device.healthState == HealthState.OK # PROTECTED REGION END # // CspSubElementMaster.test_healthState - # PROTECTED REGION ID(CspSubElementMaster.test_adminMode_decorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_adminMode_decorators def test_adminMode(self, tango_context): """Test for adminMode""" - # PROTECTED REGION ID(CspSubElementMaster.test_adminMode) ENABLED START # + # PROTECTED REGION ID(CspSubElementMaster.test_set_adminMode_to_offline) ENABLED START # assert tango_context.device.adminMode == AdminMode.ONLINE - # PROTECTED REGION END # // CspSubElementMaster.test_adminMode + # PROTECTED REGION END # // CspSubElementMaster.test_set_adminMode_to_offline - # PROTECTED REGION ID(CspSubElementMaster.test_write_adminMode_decorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_adminMode_decorators - def test_write_adminMode(self, tango_context): - """Test for adminMode""" - # PROTECTED REGION ID(CspSubElementMaster.test_adminMode) ENABLED START # - tango_context.device.adminMode = AdminMode.OFFLINE - time.sleep(2) - assert tango_context.device.adminMode == AdminMode.OFFLINE - assert tango_context.device.State() == DevState.DISABLE - # PROTECTED REGION END # // CspSubElementMaster.test_adminMode - - # PROTECTED REGION ID(CspSubElementMaster.test_On_invalid_adminModedecorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_On_invalid_adminMode decorators def test_On_invalid_adminMode(self, tango_context): """Test On command with offline adminmode""" # PROTECTED REGION ID(CspSubElementMaster.test_On_invalid_adminMode) ENABLED START # + tango_context.device.adminMode = AdminMode.OFFLINE + assert tango_context.device.adminMode == AdminMode.OFFLINE with pytest.raises(DevFailed) as df: argin = [""] tango_context.device.On(argin) assert "On command can't" in str(df.value.args[0].desc) # PROTECTED REGION END # // CspSubElementMaster.test_On_invalid_adminMode - # PROTECTED REGION ID(CspSubElementMaster.test_Off_invalid_adminModedecorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_Off_invalid_adminMode decorators def test_Off_invalid_adminMode(self, tango_context): """Test Off command with offline adminmode""" # PROTECTED REGION ID(CspSubElementMaster.test_Off_invalid_adminMode) ENABLED START # + # set the adminMode to OFFLINE to test the behavior of the AdminModeCheck decorator + tango_context.device.adminMode = AdminMode.OFFLINE + assert tango_context.device.adminMode == AdminMode.OFFLINE with pytest.raises(DevFailed) as df: argin = [""] tango_context.device.Off(argin) assert "Off command can't" in str(df.value.args[0].desc) # PROTECTED REGION END # // CspSubElementMaster.test_Off_invalid_adminMode - # PROTECTED REGION ID(CspSubElementMaster.test_Standby_invalid_adminModedecorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_Standby_invalid_adminMode decorators def test_Standby_invalid_adminMode(self, tango_context): """Test Standby command with offline adminmode""" # PROTECTED REGION ID(CspSubElementMaster.test_Standby_invalid_adminMode) ENABLED START # + # set the adminMode to OFFLINE to test the behavior of the AdminModeCheck decorator + tango_context.device.adminMode = AdminMode.OFFLINE + assert tango_context.device.adminMode == AdminMode.OFFLINE with pytest.raises(DevFailed) as df: argin = [""] tango_context.device.Standby(argin) assert "Standby command can't" in str(df.value.args[0].desc) # PROTECTED REGION END # // CspSubElementMaster.test_Standby_invalid_adminMode - # PROTECTED REGION ID(CspSubElementMaster.test_On_invalid_Statedecorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_On_invalid_State decorators def test_On_invalid_State(self, tango_context): """Test On command with offline adminmode""" # PROTECTED REGION ID(CspSubElementMaster.test_On_invalid_State) ENABLED START # @@ -177,8 +164,6 @@ class TestCspSubElementMaster(object): assert "Command On can't" in str(df.value.args[0].desc) # PROTECTED REGION END # // CspSubElementMaster.test_On_invalid_State - # PROTECTED REGION ID(CspSubElementMaster.test_Off_invalid_Statedecorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_Off_invalid_State decorators def test_Off_invalid_State(self, tango_context): """Test Off command with offline adminmode""" # PROTECTED REGION ID(CspSubElementMaster.test_Off_invalid_State) ENABLED START # @@ -189,8 +174,6 @@ class TestCspSubElementMaster(object): assert "Command Off can't" in str(df.value.args[0].desc) # PROTECTED REGION END # // CspSubElementMaster.test_Off_invalid_State - # PROTECTED REGION ID(CspSubElementMaster.test_Standby_invalid_Statedecorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_Standby_invalid_State decorators def test_Standby_invalid_State(self, tango_context): """Test Standby command with offline adminmode""" # PROTECTED REGION ID(CspSubElementMaster.test_Standby_invalid_State) ENABLED START # @@ -201,24 +184,18 @@ class TestCspSubElementMaster(object): assert "Command Standby can't" in str(df.value.args[0].desc) # PROTECTED REGION END # // CspSubElementMaster.test_Standby_invalid_State - # PROTECTED REGION ID(CspSubElementMaster.test_controlMode_decorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_controlMode_decorators def test_controlMode(self, tango_context): """Test for controlMode""" # PROTECTED REGION ID(CspSubElementMaster.test_controlMode) ENABLED START # assert tango_context.device.controlMode == ControlMode.REMOTE # PROTECTED REGION END # // CspSubElementMaster.test_controlMode - # PROTECTED REGION ID(CspSubElementMaster.test_maxCapabilities_decorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_maxCapabilities_decorators def test_maxCapabilities(self, tango_context): """Test for maxCapabilities""" # PROTECTED REGION ID(CspSubElementMaster.test_maxCapabilities) ENABLED START # assert tango_context.device.maxCapabilities == ('FSP:27', 'VCC:197') # PROTECTED REGION END # // CspSubElementMaster.test_maxCapabilities - # PROTECTED REGION ID(CspSubElementMaster.test_availableCapabilities_decorators) ENABLED START # - # PROTECTED REGION END # // CspSubElementMaster.test_availableCapabilities_decorators def test_availableCapabilities(self, tango_context): """Test for availableCapabilities""" # PROTECTED REGION ID(CspSubElementMaster.test_availableCapabilities) ENABLED START # @@ -239,7 +216,9 @@ class TestCspSubElementMaster(object): def test_timeout_expired(self, tango_context): """Test xxxTimeoutExpired flags attribute""" - assert not tango_context.device.onCmdTimeoutExpired + timeout = tango_context.device.onCmdTimeoutExpired + #assert not tango_context.device.onCmdTimeoutExpired + assert timeout == 0 assert not tango_context.device.offCmdTimeoutExpired assert not tango_context.device.standbyCmdTimeoutExpired diff --git a/tests/test_se_subarray.py b/tests/test_se_subarray.py new file mode 100644 index 0000000000000000000000000000000000000000..786d2d7f5b3dc00d32a163ca35845a5072653b71 --- /dev/null +++ b/tests/test_se_subarray.py @@ -0,0 +1,197 @@ +# +# -*- coding: utf-8 -*- +# +# This file is part of the CspSubElementSubarray project +# +"""Contain the tests for the Master.""" + +# Standard imports +import sys +import os +import time + +# Imports +import re +import pytest +from tango import DevState +from tango import DevFailed + +# PROTECTED REGION ID(CspSubElementSubarray.test_additional_imports) ENABLED START # +from ska.base.control_model import AdminMode, ControlMode, HealthState, SimulationMode, TestMode +# PROTECTED REGION END # // CspSubElementSubarray.test_additional_imports +# Device test case +# PROTECTED REGION ID(CspSubElementSubarray.test_CspSubElementSubarray_decorators) ENABLED START # +@pytest.mark.usefixtures("tango_context") +# PROTECTED REGION END # // CspSubElementSubarray.test_CspSubElementSubarray_decorators +class TestCspSubElementSubarray(object): + """Test case for packet generation.""" + + properties = { + 'SkaLevel': '2', + 'LoggingTargetsDefault': '', + 'GroupDefinitions': '', + } + + @classmethod + def mocking(cls): + """Mock external libraries.""" + # Example : Mock numpy + # cls.numpy = CspSubElementSubarray.numpy = MagicMock() + # PROTECTED REGION ID(CspSubElementSubarray.test_mocking) ENABLED START # + # PROTECTED REGION END # // CspSubElementSubarray.test_mocking + + def test_properties(self, tango_context): + # Test the properties + # PROTECTED REGION ID(CspSubElementSubarray.test_properties) ENABLED START # + # PROTECTED REGION END # // CspSubElementSubarray.test_properties + pass + + def test_State(self, tango_context): + """Test for State""" + # PROTECTED REGION ID(CspSubElementSubarray.test_State) ENABLED START # + assert tango_context.device.State() == DevState.INIT + # PROTECTED REGION END # // CspSubElementSubarray.test_State + + def test_Status(self, tango_context): + """Test for Status""" + # PROTECTED REGION ID(CspSubElementSubarray.test_Status) ENABLED START # + assert tango_context.device.Status() == "The device is in INIT state." + # PROTECTED REGION END # // CspSubElementSubarray.test_Status + + def test_GetVersionInfo(self, tango_context): + """Test for GetVersionInfo""" + # PROTECTED REGION ID(CspSubElementSubarray.test_GetVersionInfo) ENABLED START # + versionPattern = re.compile( + r'CspSubElementSubarray, lmcbaseclasses, [0-9].[0-9].[0-9], ' + r'A set of generic base devices for SKA Telescope.') + versionInfo = tango_context.device.GetVersionInfo() + assert (re.match(versionPattern, versionInfo[0])) != None + # PROTECTED REGION END # // CspSubElementSubarray.test_GetVersionInfo + + def test_buildState(self, tango_context): + """Test for buildState""" + # PROTECTED REGION ID(CspSubElementSubarray.test_buildState) ENABLED START # + buildPattern = re.compile( + r'lmcbaseclasses, [0-9].[0-9].[0-9], ' + r'A set of generic base devices for SKA Telescope') + assert (re.match(buildPattern, tango_context.device.buildState)) != None + # PROTECTED REGION END # // CspSubElementSubarray.test_buildState + + def test_versionId(self, tango_context): + """Test for versionId""" + # PROTECTED REGION ID(CspSubElementSubarray.test_versionId) ENABLED START # + versionIdPattern = re.compile(r'[0-9].[0-9].[0-9]') + assert (re.match(versionIdPattern, tango_context.device.versionId)) != None + # PROTECTED REGION END # // CspSubElementSubarray.test_versionId + + def test_healthState(self, tango_context): + """Test for healthState""" + # PROTECTED REGION ID(CspSubElementSubarray.test_healthState) ENABLED START # + assert tango_context.device.healthState == HealthState.OK + # PROTECTED REGION END # // CspSubElementSubarray.test_healthState + + def test_adminMode(self, tango_context): + """Test for adminMode""" + # PROTECTED REGION ID(CspSubElementSubarray.test_adminMode) ENABLED START # + tango_context.device.adminMode == AdminMode.ONLINE + # PROTECTED REGION END # // CspSubElementSubarray.test_adminMode + + def test_controlMode(self, tango_context): + """Test for controlMode""" + # PROTECTED REGION ID(CspSubElementSubarray.test_controlMode) ENABLED START # + assert tango_context.device.controlMode == ControlMode.REMOTE + # PROTECTED REGION END # // CspSubElementSubarray.test_controlMode + + def test_configureScan_invalid_adminMode(self, tango_context): + tango_context.device.adminMode = AdminMode.OFFLINE + assert tango_context.device.adminMode == AdminMode.OFFLINE + with pytest.raises(DevFailed) as df: + argin = '' + tango_context.device.ConfigureScan(argin) + assert "Command ConfigureScan can't" in str(df.value.args[0].desc) + + def test_configureScan_invalid_state(self, tango_context): + assert tango_context.device.adminMode == AdminMode.ONLINE + with pytest.raises(DevFailed) as df: + argin = '' + tango_context.device.ConfigureScan(argin) + assert "Command ConfigureScan can't" in str(df.value.args[0].desc) + + def test_goToIdle_invalid_adminMode(self, tango_context): + tango_context.device.adminMode = AdminMode.OFFLINE + assert tango_context.device.adminMode == AdminMode.OFFLINE + with pytest.raises(DevFailed) as df: + argin = '' + tango_context.device.GoToIdle() + assert "Command GoToIdle can't" in str(df.value.args[0].desc) + + def test_goToIdle_invalid_state(self, tango_context): + assert tango_context.device.adminMode == AdminMode.ONLINE + with pytest.raises(DevFailed) as df: + argin = '' + tango_context.device.GoToIdle() + assert "Command GoToIdle can't" in str(df.value.args[0].desc) + + def test_scan_invalid_adminMode(self, tango_context): + tango_context.device.adminMode = AdminMode.OFFLINE + assert tango_context.device.adminMode == AdminMode.OFFLINE + with pytest.raises(DevFailed) as df: + argin = '1' + tango_context.device.Scan(argin) + assert "Command Scan can't" in str(df.value.args[0].desc) + + def test_scan_invalid_state(self, tango_context): + assert tango_context.device.adminMode == AdminMode.ONLINE + with pytest.raises(DevFailed) as df: + argin = '1' + tango_context.device.Scan(argin) + assert "Command Scan can't" in str(df.value.args[0].desc) + + def test_endscan_invalid_adminMode(self, tango_context): + tango_context.device.adminMode = AdminMode.OFFLINE + assert tango_context.device.adminMode == AdminMode.OFFLINE + with pytest.raises(DevFailed) as df: + tango_context.device.EndScan() + assert "Command EndScan can't" in str(df.value.args[0].desc) + + def test_endscan_invalid_state(self, tango_context): + assert tango_context.device.adminMode == AdminMode.ONLINE + with pytest.raises(DevFailed) as df: + tango_context.device.EndScan() + assert "Command EndScan can't" in str(df.value.args[0].desc) + + def test_num_of_dev_completed_task(self, tango_context): + # PROTECTED REGION ID(CspSubElementSubarray.test_num_of_dev_completed_task) ENABLED START # + """Test numOfCompletedTask attribute""" + # PROTECTED REGION END # // CspSubElementSubarray.test_num_of_dev_completed_task + assert tango_context.device.numOfDevCompletedTask == None + + def test_list_of_completed_task(self, tango_context): + # PROTECTED REGION ID(CspSubElementSubarray.test_list_of_completed_task) ENABLED START # + """Test listOfCompletedTask attribute""" + assert tango_context.device.listOfDevCompletedTask == None + # PROTECTED REGION END # // CspSubElementSubarray.test_list_of_completed_task + + def test_command_progress(self, tango_context): + """Test xxxCommandProgress attributes""" + assert tango_context.device.goToIdleCmdProgress == 0 + assert tango_context.device.configurationProgress == 0 + + def test_command_duration_measured(self, tango_context): + """Test xxxCmdDurationMeasured attributes""" + assert tango_context.device.goToIdleDurationMeasured == 0 + assert tango_context.device.configureScanDurationMeasured == 0 + + def test_command_duration_expected(self, tango_context): + """Test xxxCmdDurationExpected attributes""" + assert tango_context.device.goToIdleDurationExpected == 30 + assert tango_context.device.configurationDelayExpected == 30 + + def test_set_command_duration_expected(self, tango_context): + """Test xxxCmdDurationExpected attributes""" + tango_context.device.goToIdleDurationExpected = 20 + # wait to let the polling thread update the attrs value + time.sleep(3) + assert tango_context.device.goToIdleDurationExpected == 20 + +