Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
Pipeline #11381 passed
HISTORY 0 → 100644
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
...@@ -3,4 +3,5 @@ __all__ = ( ...@@ -3,4 +3,5 @@ __all__ = (
) )
from .subelement_master import CspSubElementMaster from .subelement_master import CspSubElementMaster
from .subelement_subarray import CspSubElementSubarray
import functools import functools
import tango import tango
from ska.base.control_model import ObsState
tasks = {} tasks = {}
...@@ -51,6 +52,55 @@ def is_off_allowed(device_instance): ...@@ -51,6 +52,55 @@ def is_off_allowed(device_instance):
return True return True
return False 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): def is_command_allowed(device_instance, cmd_name):
""" """
Call the allowed method for the command name specified Call the allowed method for the command name specified
...@@ -62,7 +112,7 @@ def is_command_allowed(device_instance, cmd_name): ...@@ -62,7 +112,7 @@ def is_command_allowed(device_instance, cmd_name):
""" """
tasks[cmd_name](device_instance) tasks[cmd_name](device_instance)
class IsCommandAllowed(object): class IsMasterCommandAllowed(object):
""" """
Class designed to be a decorator for the Master power methods. Class designed to be a decorator for the Master power methods.
The *decorator function* performs a check on the input argument The *decorator function* performs a check on the input argument
...@@ -95,6 +145,7 @@ class IsCommandAllowed(object): ...@@ -95,6 +145,7 @@ class IsCommandAllowed(object):
# Note: device list is a reference to args[1]: changing # Note: device list is a reference to args[1]: changing
# device_list content, args[1] changes accordingly! # device_list content, args[1] changes accordingly!
num_of_devices = len(input_arg) num_of_devices = len(input_arg)
dev_instance.logger.info("num_of_devices:{}".format(num_of_devices))
if num_of_devices == 0: if num_of_devices == 0:
# check the device State: if it not the proper value the command is # check the device State: if it not the proper value the command is
# not executed # not executed
...@@ -106,3 +157,34 @@ class IsCommandAllowed(object): ...@@ -106,3 +157,34 @@ class IsCommandAllowed(object):
tango.ErrSeverity.ERR) tango.ErrSeverity.ERR)
return f(*args, **kwargs) return f(*args, **kwargs)
return input_args_check 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
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
"""Release information for Python Package""" """Release information for Python Package"""
name = """csp-lmc-subelement""" name = """csp-lmc-subelement"""
version = "0.1.0" version = "0.1.1"
version_info = version.split(".") version_info = version.split(".")
description = """SKA CSP Sub-element LMC""" description = """SKA CSP Sub-element LMC"""
author = "INAF-OAA" author = "INAF-OAA"
......
...@@ -28,7 +28,7 @@ from ska.base import SKAMaster ...@@ -28,7 +28,7 @@ from ska.base import SKAMaster
from ska.base.control_model import HealthState, AdminMode, LoggingLevel from ska.base.control_model import HealthState, AdminMode, LoggingLevel
from csp_lmc_common.utils.cspcommons import CmdExecState from csp_lmc_common.utils.cspcommons import CmdExecState
from csp_lmc_common.utils.decorators import AdminModeCheck from csp_lmc_common.utils.decorators import AdminModeCheck
from .decorators import IsCommandAllowed from .decorators import IsMasterCommandAllowed
from . import release from . import release
# PROTECTED REGION END # // CspSubElementMaster.additionnal_import # PROTECTED REGION END # // CspSubElementMaster.additionnal_import
...@@ -104,15 +104,6 @@ class CspSubElementMaster(SKAMaster): ...@@ -104,15 +104,6 @@ class CspSubElementMaster(SKAMaster):
doc="Failure message when the Standby command fails with error(s).", 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( onCommandProgress = attribute(
dtype='DevUShort', dtype='DevUShort',
label="Progress percentage for the On command", label="Progress percentage for the On command",
...@@ -248,66 +239,67 @@ class CspSubElementMaster(SKAMaster): ...@@ -248,66 +239,67 @@ class CspSubElementMaster(SKAMaster):
self.set_state(tango.DevState.INIT) self.set_state(tango.DevState.INIT)
# PROTECTED REGION ID(CspSubElementMaster.init_device) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.init_device) ENABLED START #
# _cmd_execution_state: implement the execution state of a long-running # _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. # of the same command while it is already running.
# implemented as a default dictionary: # Implemented as a Python default dictionary:
# keys: command name # keys: command name
# values:command state # values:command state
self._cmd_execution_state = defaultdict(lambda: CmdExecState.IDLE) self._cmd_execution_state = defaultdict(lambda: CmdExecState.IDLE)
# _cmd_progress: report the execution progress of a long-running command # _cmd_progress: report the execution progress of a long-running command
# implemented as a dictionary: # Implemented as a Python dictionary:
# keys: command name ('on', 'off'..) # keys: command name in lower case ('on', 'off'..)
# values: the percentage # values: the percentage
self._cmd_progress = defaultdict(lambda: 0) self._cmd_progress = defaultdict(lambda: 0)
# _cmd_duration_expected: store the duration (in sec.) configured for # _cmd_duration_expected: store the duration (in sec.) configured for
# a long-running command # a long-running command
# Implemented asdefault dictionary # Implemented as Python default dictionary
# keys: command name ('on', 'off',..) # keys: command name in lower case ('on', 'off',..)
# values: the duration (in sec) # values: the duration (in sec)
self._cmd_duration_expected = defaultdict(lambda: 30) self._cmd_duration_expected = defaultdict(lambda: 30)
# _cmd_duration_measured: report the measured duration (in sec.) for # _cmd_duration_measured: report the measured duration (in sec.) for
# a long-running command # a long-running command
# Implemented as default dictionary # Implemented as Python default dictionary
# keys: command name ('on', 'off',..) # keys: command name in lower case ('on', 'off',..)
# values: the duration (in sec) # values: the duration (in sec)
self._cmd_duration_measured = defaultdict(lambda: 0) self._cmd_duration_measured = defaultdict(lambda: 0)
# _timeout_expired: report the timeout flag # _timeout_expired: report the timeout flag
# Implemented as a dictionary # Implemented as a Python default dictionary
# keys: command name ('on', 'off', 'standby'..) # keys: command name in lower case ('on', 'off',..)
# values: True/False # values: True/False
self._timeout_expired = defaultdict(lambda: False) self._timeout_expired = defaultdict(lambda: False)
# _failure_raised: report the failure flag # _failure_raised: report the failure flag
# Implemented as a dictionary # Implemented as a Python default dictionary
# keys: command name ('on', 'off', 'standby'..) # keys: command name in lower case ('on', 'off',..)
# values: True/False # values: True/False
self._failure_raised = defaultdict(lambda: False) self._failure_raised = defaultdict(lambda: False)
# _failure_message: report the failure message # _failure_message: report the failure message
# Implemented as a dictionary # Implemented as a Python default dictionary
# keys: command name ('on', 'off', 'standby'..) # keys: command name in lower case ('on', 'off',..)
# values: the message # values: the message
self._failure_message = defaultdict(lambda: '') self._failure_message = defaultdict(lambda: '')
# _list_dev_completed_task: for each long-running command report the list # _list_dev_completed_task: for each long-running command report the list
# of subordinate sub-element components that completed the task # of subordinate sub-element components that completed the task
# Implemented as a dictionary # Implemented as a Python default dictionary
# keys: the command name ('on', 'off',...) # keys: command name in lower case ('on', 'off',..)
# values: the list of components # values: the list of components
self._list_dev_completed_task = defaultdict(lambda: []) self._list_dev_completed_task = defaultdict(lambda: [])
# _list_of_components: report the list of subordinate # _list_of_components: report the list of subordinate
# sub-element components. # sub-element components FQDNs.
# Implemented as a list of FQDNs # Implemented as a Python list
self._list_of_components = [] self._list_of_components = []
# _num_dev_completed_task: for each long-running command report the number # _num_dev_completed_task: for each long-running command report the number
# of subordinate components that completed the task # of subordinate components that completed the task
# Implemented as a dictionary # Implemented as a Python default dictionary
# keys: the command name ('on', 'off',...) # keys: command name in lower case ('on', 'off',..)
# values: the number of components # values: the number of components
self._num_dev_completed_task = defaultdict(lambda:0) self._num_dev_completed_task = defaultdict(lambda:0)
...@@ -376,20 +368,6 @@ class CspSubElementMaster(SKAMaster): ...@@ -376,20 +368,6 @@ class CspSubElementMaster(SKAMaster):
return self._failure_message['standby'] return self._failure_message['standby']
# PROTECTED REGION END # // CspSubElementMaster.standbyFailureMessage_read # 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): def read_onCommandProgress(self):
# PROTECTED REGION ID(CspSubElementMaster.onCommandProgress_read) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.onCommandProgress_read) ENABLED START #
"""Return the onCommandProgress attribute.""" """Return the onCommandProgress attribute."""
...@@ -507,7 +485,7 @@ class CspSubElementMaster(SKAMaster): ...@@ -507,7 +485,7 @@ class CspSubElementMaster(SKAMaster):
"CSP SubElement component to switch ON.", "CSP SubElement component to switch ON.",
) )
@DebugIt() @DebugIt()
@IsCommandAllowed() @IsMasterCommandAllowed()
@AdminModeCheck('On') @AdminModeCheck('On')
def On(self, argin): def On(self, argin):
# PROTECTED REGION ID(CspSubElementMaster.On) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.On) ENABLED START #
...@@ -538,7 +516,7 @@ class CspSubElementMaster(SKAMaster): ...@@ -538,7 +516,7 @@ class CspSubElementMaster(SKAMaster):
"CSP SubElement component to switch OFF.", "CSP SubElement component to switch OFF.",
) )
@DebugIt() @DebugIt()
@IsCommandAllowed() @IsMasterCommandAllowed()
@AdminModeCheck('Off') @AdminModeCheck('Off')
def Off(self, argin): def Off(self, argin):
# PROTECTED REGION ID(CspSubElementMaster.Off) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.Off) ENABLED START #
...@@ -569,7 +547,7 @@ class CspSubElementMaster(SKAMaster): ...@@ -569,7 +547,7 @@ class CspSubElementMaster(SKAMaster):
"CSP SubElement icomponent to put in STANDBY mode.", "CSP SubElement icomponent to put in STANDBY mode.",
) )
@DebugIt() @DebugIt()
@IsCommandAllowed() @IsMasterCommandAllowed()
@AdminModeCheck('Standby') @AdminModeCheck('Standby')
def Standby(self, argin): def Standby(self, argin):
# PROTECTED REGION ID(CspSubElementMaster.Standby) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.Standby) ENABLED START #
......
# -*- 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()
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
"""Release information for Python Package""" """Release information for Python Package"""
name = """csplmc-subelement""" name = """csplmc-subelement"""
version = "0.1.0" version = "0.1.1"
version_info = version.split(".") version_info = version.split(".")
description = """SKA CSP.LMC Subelement Classes""" description = """SKA CSP.LMC Subelement Classes"""
author = "E.G" author = "E.G"
...@@ -18,5 +18,5 @@ license = """BSD-3-Clause""" ...@@ -18,5 +18,5 @@ license = """BSD-3-Clause"""
url = """www.tango-controls.org""" url = """www.tango-controls.org"""
copyright = """""" copyright = """"""
release=0.1.0 release=0.1.1
tag=csp-lmc-subelement-0.1.0 tag=csp-lmc-subelement-0.1.1
...@@ -39,7 +39,7 @@ services: ...@@ -39,7 +39,7 @@ services:
command: > command: >
sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict --
retry --max=5 -- tango_admin --ping-device subelement/sub_elt/master &&\ retry --max=5 -- tango_admin --ping-device subelement/sub_elt/master &&\
/venv/bin/python -m cspse.lmc.SubElementSubarray subarray1" CspSubElementSubarray subarray1"
sesubarray02: sesubarray02:
image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/csp-lmc-subelement:latest image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/csp-lmc-subelement:latest
network_mode: ${NETWORK_MODE} network_mode: ${NETWORK_MODE}
...@@ -52,7 +52,7 @@ services: ...@@ -52,7 +52,7 @@ services:
command: > command: >
sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- sh -c "wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict --
retry --max=5 -- tango_admin --ping-device subelement/sub_elt/master &&\ retry --max=5 -- tango_admin --ping-device subelement/sub_elt/master &&\
/venv/bin/python -m cspse.lmc.SubElementSubarray subarray2" CspSubElementSubarray subarray2"
semaster: semaster:
image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/csp-lmc-subelement:latest image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}/csp-lmc-subelement:latest
......
...@@ -235,11 +235,12 @@ ...@@ -235,11 +235,12 @@
<status abstract="false" inherited="true" concrete="true"/> <status abstract="false" inherited="true" concrete="true"/>
<properties description="The health state reported for this device. It interprets the current device condition &#xA;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=""/> <properties description="The health state reported for this device. It interprets the current device condition &#xA;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>
<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"/> <dataType xsi:type="pogoDsl:EnumType"/>
<changeEvent fire="false" libCheckCriteria="false"/> <changeEvent fire="false" libCheckCriteria="false"/>
<archiveEvent 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 &#xA;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=""/> <properties description="The admin mode reported for this device. It may interpret the current device condition &#xA;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>
<attributes name="controlMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true"> <attributes name="controlMode" attType="Scalar" rwType="READ_WRITE" displayLevel="OPERATOR" polledPeriod="1000" maxX="" maxY="" memorized="true" allocReadMember="true">
......
<?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,&#xA;capPstBf, capVlbi, this will be used to dynamically&#xA;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``,&#xA;``devices`` and ``subgroups`` in the group. A TANGO Group object is created&#xA;for each item in the list, according to the hierarchy defined. This provides&#xA;easy access to the managed devices in bulk, or individually.&#xA;&#xA;The general format of the list is as follows, with optional ``devices`` and&#xA;``subgroups`` keys:&#xA; [ {``group_name``: ``&lt;name>``,&#xA; ``devices``: [``&lt;dev name>``, ...]},&#xA; {``group_name``: ``&lt;name>``,&#xA; ``devices``: [``&lt;dev name>``, ``&lt;dev name>``, ...],&#xA; ``subgroups`` : [{&lt;nested group>},&#xA; {&lt;nested group>}, ...]},&#xA; ...&#xA; ]&#xA;&#xA;For example, a hierarchy of racks, servers and switches:&#xA; [ {``group_name``: ``servers``,&#xA; ``devices``: [``elt/server/1``, ``elt/server/2``,&#xA; ``elt/server/3``, ``elt/server/4``]},&#xA; {``group_name``: ``switches``,&#xA; ``devices``: [``elt/switch/A``, ``elt/switch/B``]},&#xA; {``group_name``: ``pdus``,&#xA; ``devices``: [``elt/pdu/rackA``, ``elt/pdu/rackB``]},&#xA; {``group_name``: ``racks``,&#xA; ``subgroups``: [&#xA; {``group_name``: ``rackA``,&#xA; ``devices``: [``elt/server/1``, ``elt/server/2``,&#xA; ``elt/switch/A``, ``elt/pdu/rackA``]},&#xA; {``group_name``: ``rackB``,&#xA; ``devices``: [``elt/server/3``, ``elt/server/4``,&#xA; ``elt/switch/B``, ``elt/pdu/rackB``],&#xA; ``subgroups``: []}&#xA; ]} ]">
<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 &#xA;to support drill-down navigation: 1..6, with 1 highest.&#xA;Default is 4, making provision for &#xA;EltMaster, EltAlarms, EltTelState = 1&#xA;SubEltMaster = 2&#xA;Subarray, Capability = 2/3&#xA;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.&#xA;(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.&#xA;Each item has the format: target_type::target_name.&#xA;To log to stdout, use 'console::cout'.&#xA;To log to syslog, use 'syslog::&lt;address>',&#xA; where &lt;address> is a file path,&#xA; for example 'syslog::/var/run/rsyslog/dev/log'.&#xA;To log to a file, use 'file::&lt;path>',&#xA; where &lt;path> is a file path,&#xA; 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, &#xA;it increments the configured instances by the number of instances requested, &#xA;otherwise an exception will be raised.&#xA;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, &#xA;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, &#xA;it decrements the configured instances by the number of instances requested,&#xA;otherwise an exceptioin will be raised.&#xA;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. &#xA;(One level down only)&#xA;Each string in the array lists the version info for one entity&#xA;managed by this device. &#xA;The first entry is version info for this TANGO Device itself.&#xA;The entities may be TANGO devices, or hardware LRUs or &#xA;anything else this devices manages/models.&#xA;The intention with this command is that it can provide more &#xA;detailed information than can be captured in the versionId &#xA;and buildState attributes, if necessary.&#xA;In the minimal case the GetVersionInfo will contain only the &#xA;versionId and buildState attributes of the next lower level&#xA;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 &#xA;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&#xA;TANGO Device accepts only from a &#x2018;local&#x2019; client and ignores commands and queries received from TM&#xA;or any other &#x2018;remote&#x2019; clients. The Local clients has to release LOCAL control before REMOTE clients&#xA;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 &#xA;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,&#xA;while others will have simulators that set simulationMode to True while the real&#xA;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. &#xA;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.&#xA;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 - &#xA;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&#xA;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>
...@@ -11,7 +11,8 @@ source = cspse ...@@ -11,7 +11,8 @@ source = cspse
[tool:pytest] [tool:pytest]
testpaths = tests testpaths = tests
addopts = --verbose addopts = --forked
--verbose
--cov=cspse --cov=cspse
--json-report --json-report
--json-report-file=htmlcov/report.json --json-report-file=htmlcov/report.json
......
...@@ -53,17 +53,16 @@ setup( ...@@ -53,17 +53,16 @@ setup(
], ],
tests_require=[ tests_require=[
'pytest', 'pytest',
'pytest-cov', 'coverage',
'pytest-json-report', 'pytest-json-report',
'pytest-forked',
'pycodestyle', 'pycodestyle',
'mock' 'mock'
], ],
entry_points={ entry_points={
"console_scripts": [ "console_scripts": [
"CspSubElementMaster=cspse.lmc.subelement_master:main", "CspSubElementMaster=cspse.lmc.subelement_master:main",
"CspSubElementSubarray=cspse.lmc.subelement_subarray:main",
] ]
},
extras_require={
'dev': ['prospector[with_pyroma]', 'yapf', 'isort'],
} }
) )
...@@ -18,7 +18,7 @@ def tango_context(request): ...@@ -18,7 +18,7 @@ def tango_context(request):
""" """
test_properties = { test_properties = {
'CspSubElementMaster': { 'CspSubElementMaster': {
'SkaLevel': '4', 'SkaLevel': '2',
'LoggingTargetsDefault': '', 'LoggingTargetsDefault': '',
'GroupDefinitions': '', 'GroupDefinitions': '',
'NrSubarrays': '16', 'NrSubarrays': '16',
...@@ -27,10 +27,9 @@ def tango_context(request): ...@@ -27,10 +27,9 @@ def tango_context(request):
}, },
'CspSubElementSubarray': { 'CspSubElementSubarray': {
'CapabilityTypes': ['VCC','FSP'],
'LoggingTargetsDefault': '', 'LoggingTargetsDefault': '',
'GroupDefinitions': '', 'GroupDefinitions': '',
'SkaLevel': '4', 'SkaLevel': '2',
'SubID': '1', 'SubID': '1',
}, },
} }
...@@ -61,5 +60,4 @@ def initialize_device(tango_context): ...@@ -61,5 +60,4 @@ def initialize_device(tango_context):
tango_context: tango.test_context.DeviceTestContext tango_context: tango.test_context.DeviceTestContext
Context to run a device without a database. Context to run a device without a database.
""" """
print("Sono qui")
yield tango_context.device.Init() yield tango_context.device.Init()
...@@ -107,60 +107,47 @@ class TestCspSubElementMaster(object): ...@@ -107,60 +107,47 @@ class TestCspSubElementMaster(object):
assert tango_context.device.healthState == HealthState.OK assert tango_context.device.healthState == HealthState.OK
# PROTECTED REGION END # // CspSubElementMaster.test_healthState # 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): def test_adminMode(self, tango_context):
"""Test for adminMode""" """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 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): def test_On_invalid_adminMode(self, tango_context):
"""Test On command with offline adminmode""" """Test On command with offline adminmode"""
# PROTECTED REGION ID(CspSubElementMaster.test_On_invalid_adminMode) ENABLED START # # 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: with pytest.raises(DevFailed) as df:
argin = [""] argin = [""]
tango_context.device.On(argin) tango_context.device.On(argin)
assert "On command can't" in str(df.value.args[0].desc) assert "On command can't" in str(df.value.args[0].desc)
# PROTECTED REGION END # // CspSubElementMaster.test_On_invalid_adminMode # 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): def test_Off_invalid_adminMode(self, tango_context):
"""Test Off command with offline adminmode""" """Test Off command with offline adminmode"""
# PROTECTED REGION ID(CspSubElementMaster.test_Off_invalid_adminMode) ENABLED START # # 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: with pytest.raises(DevFailed) as df:
argin = [""] argin = [""]
tango_context.device.Off(argin) tango_context.device.Off(argin)
assert "Off command can't" in str(df.value.args[0].desc) assert "Off command can't" in str(df.value.args[0].desc)
# PROTECTED REGION END # // CspSubElementMaster.test_Off_invalid_adminMode # 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): def test_Standby_invalid_adminMode(self, tango_context):
"""Test Standby command with offline adminmode""" """Test Standby command with offline adminmode"""
# PROTECTED REGION ID(CspSubElementMaster.test_Standby_invalid_adminMode) ENABLED START # # 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: with pytest.raises(DevFailed) as df:
argin = [""] argin = [""]
tango_context.device.Standby(argin) tango_context.device.Standby(argin)
assert "Standby command can't" in str(df.value.args[0].desc) assert "Standby command can't" in str(df.value.args[0].desc)
# PROTECTED REGION END # // CspSubElementMaster.test_Standby_invalid_adminMode # 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): def test_On_invalid_State(self, tango_context):
"""Test On command with offline adminmode""" """Test On command with offline adminmode"""
# PROTECTED REGION ID(CspSubElementMaster.test_On_invalid_State) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.test_On_invalid_State) ENABLED START #
...@@ -177,8 +164,6 @@ class TestCspSubElementMaster(object): ...@@ -177,8 +164,6 @@ class TestCspSubElementMaster(object):
assert "Command On can't" in str(df.value.args[0].desc) assert "Command On can't" in str(df.value.args[0].desc)
# PROTECTED REGION END # // CspSubElementMaster.test_On_invalid_State # 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): def test_Off_invalid_State(self, tango_context):
"""Test Off command with offline adminmode""" """Test Off command with offline adminmode"""
# PROTECTED REGION ID(CspSubElementMaster.test_Off_invalid_State) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.test_Off_invalid_State) ENABLED START #
...@@ -189,8 +174,6 @@ class TestCspSubElementMaster(object): ...@@ -189,8 +174,6 @@ class TestCspSubElementMaster(object):
assert "Command Off can't" in str(df.value.args[0].desc) assert "Command Off can't" in str(df.value.args[0].desc)
# PROTECTED REGION END # // CspSubElementMaster.test_Off_invalid_State # 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): def test_Standby_invalid_State(self, tango_context):
"""Test Standby command with offline adminmode""" """Test Standby command with offline adminmode"""
# PROTECTED REGION ID(CspSubElementMaster.test_Standby_invalid_State) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.test_Standby_invalid_State) ENABLED START #
...@@ -201,24 +184,18 @@ class TestCspSubElementMaster(object): ...@@ -201,24 +184,18 @@ class TestCspSubElementMaster(object):
assert "Command Standby can't" in str(df.value.args[0].desc) assert "Command Standby can't" in str(df.value.args[0].desc)
# PROTECTED REGION END # // CspSubElementMaster.test_Standby_invalid_State # 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): def test_controlMode(self, tango_context):
"""Test for controlMode""" """Test for controlMode"""
# PROTECTED REGION ID(CspSubElementMaster.test_controlMode) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.test_controlMode) ENABLED START #
assert tango_context.device.controlMode == ControlMode.REMOTE assert tango_context.device.controlMode == ControlMode.REMOTE
# PROTECTED REGION END # // CspSubElementMaster.test_controlMode # 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): def test_maxCapabilities(self, tango_context):
"""Test for maxCapabilities""" """Test for maxCapabilities"""
# PROTECTED REGION ID(CspSubElementMaster.test_maxCapabilities) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.test_maxCapabilities) ENABLED START #
assert tango_context.device.maxCapabilities == ('FSP:27', 'VCC:197') assert tango_context.device.maxCapabilities == ('FSP:27', 'VCC:197')
# PROTECTED REGION END # // CspSubElementMaster.test_maxCapabilities # 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): def test_availableCapabilities(self, tango_context):
"""Test for availableCapabilities""" """Test for availableCapabilities"""
# PROTECTED REGION ID(CspSubElementMaster.test_availableCapabilities) ENABLED START # # PROTECTED REGION ID(CspSubElementMaster.test_availableCapabilities) ENABLED START #
...@@ -239,7 +216,9 @@ class TestCspSubElementMaster(object): ...@@ -239,7 +216,9 @@ class TestCspSubElementMaster(object):
def test_timeout_expired(self, tango_context): def test_timeout_expired(self, tango_context):
"""Test xxxTimeoutExpired flags attribute""" """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.offCmdTimeoutExpired
assert not tango_context.device.standbyCmdTimeoutExpired assert not tango_context.device.standbyCmdTimeoutExpired
......
#
# -*- 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment