From 3f4f3798c85d0f5aa35f3e06b23c3416f7d6f553 Mon Sep 17 00:00:00 2001 From: Elisabetta Giani <elisabetta.giani@inaf.it> Date: Tue, 5 May 2020 11:20:51 -0400 Subject: [PATCH] AT5-374: Updated SubElement Subarray documentation. --- cspse/lmc/decorators.py | 19 +- cspse/lmc/subelement_subarray.py | 302 +++++++++++++++++++++++++------ docs/src/README.md | 1 + docs/src/index.rst | 23 ++- docs/src/package/guide.rst | 4 - 5 files changed, 270 insertions(+), 79 deletions(-) create mode 120000 docs/src/README.md diff --git a/cspse/lmc/decorators.py b/cspse/lmc/decorators.py index 22366bb..c9e440e 100644 --- a/cspse/lmc/decorators.py +++ b/cspse/lmc/decorators.py @@ -147,7 +147,7 @@ class IsMasterCommandAllowed(object): num_of_devices = len(input_arg) dev_instance.logger.info("num_of_devices:{}".format(num_of_devices)) if num_of_devices == 0: - # check the device State: if it not the proper value the command is + # check the device State: if 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, @@ -160,30 +160,27 @@ class IsMasterCommandAllowed(object): 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. - + Class designed to be a decorator for the Subarray methods. + The *decorator function* performs a check on the State of + the sub-element Subarray 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 + # the Subarray 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", + "IsSubarrayCommandAllowed decorator", tango.ErrSeverity.ERR) return f(*args, **kwargs) return input_args_check diff --git a/cspse/lmc/subelement_subarray.py b/cspse/lmc/subelement_subarray.py index a0aa95b..f04b541 100644 --- a/cspse/lmc/subelement_subarray.py +++ b/cspse/lmc/subelement_subarray.py @@ -88,7 +88,7 @@ class CspSubElementSubarray(SKASubarray): numOfDevCompletedTask = attribute( dtype=(('DevString',),), - max_dim_x=10, max_dim_y=2, + max_dim_x=2, max_dim_y=10, label="Number of devices that completed the task", doc="Number of devices that completed the task", ) @@ -133,7 +133,7 @@ class CspSubElementSubarray(SKASubarray): failureMessage = attribute( dtype=(('DevString',),), - max_dim_x=10, max_dim_y=2, + max_dim_x=2, max_dim_y=10, label="The failure message", doc="The failure message", ) @@ -152,7 +152,7 @@ class CspSubElementSubarray(SKASubarray): listOfDevCompletedTask = attribute( dtype=(('DevString',),), - max_dim_x=10, max_dim_y=2, + max_dim_x=2, max_dim_y=10, label="List of devices that completed the task", doc="List of devices that completed the task", ) @@ -162,7 +162,7 @@ class CspSubElementSubarray(SKASubarray): # --------------- def init_device(self): - """Initialises the attributes and properties of the CspSubElementSubarray.""" + """Initialise 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 # @@ -231,7 +231,6 @@ class CspSubElementSubarray(SKASubarray): # 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 = '' @@ -269,37 +268,82 @@ class CspSubElementSubarray(SKASubarray): def read_validScanConfiguration(self): # PROTECTED REGION ID(CspSubElementSubarray.validScanConfiguration_read) ENABLED START # - """Return the validScanConfiguration attribute.""" + """ + Return the validScanConfiguration attribute. + + *validScanConfiguration* attribute stores the last scan configuration + programmed for the sub-element. + """ 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 the goToIdleDurationExpected attribute. + + *goToIdleDurationExpected* attribute reports the time expected (in sec) for the + execution of the *GoToIdle* command. + + The value for this attribute can be configured via the associate *write* method. + """ 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.""" + """ + Set the goToIdleDurationExpected attribute. + + Configure the time expected (in sec) for the execution of the *GoToIdle* command. + """ + 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 the goToIdleDurationMeasured attribute. + + *goToIdleDurationMeasured* attribute reports the effective execution time for the + *GoToIdle* command. + """ + 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']] + """ + Return the numOfDevCompletedTask attribute. + + The TANGO attribute *numOfDevCompletedTask* is an Image type attribute of strings. + It is represented as a matrix of *(N_rows, N_cols)* where: + + - N_rows = image max_dim_y + - N_cols = image max_dim_x + + Examples: + + *server side* + + self._num_dev_completed_task = {'gotoidle':'3', 'configurescan':'10', ...} + image_attr = [[gotoidle','3'], ['configurescan','10']...] + + *client side* + + >>> num_of_dev_completed_task = proxy.numOfDevCompletedTask + >>> num_of_dev_completed_task + ((gotoidle','3'), ('configurescan','10')...) + >>> num_of_dev_completed_task[0][0] + 'gotoidle' + >>> num_of_dev_completed_task[0][1] + '3' + + num_of_dev_completed_task is a Python nested tuple + + - row_index addresses the command name + - col_index addresses the number (string) of completed tasks """ image_attr = [[cmd_name, dev_num] for cmd_name, dev_num in self._num_dev_completed_task.items()] return image_attr @@ -307,69 +351,178 @@ class CspSubElementSubarray(SKASubarray): def read_goToIdleCmdProgress(self): # PROTECTED REGION ID(CspSubElementSubarray.goToIdleCmdProgress_read) ENABLED START # - """Return the goToIdleCmdProgress attribute.""" + """ + Return the goToIdleCmdProgress attribute. + + *goToIdleCmdProgress* attribute stores the execution percentage of the + *GoToIdle* command. + + The CSP Subarray device can subscribe to this attribute to monitor and report + the command execution progress. + + The attribute assumes values in the range [0, 100]. + """ + 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 the endScanCmdProgress attribute. + + *endScanCmdProgres* attribute stores the execution percentage of the + *EndScan* command. + + The CSP Subarray device can subscribe to this attribute to monitor and report + the command execution progress. + + The attribute assumes values in the range [0, 100]. + """ + 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 the scanCmdProgress attribute. + + *scanCmdProgress* attribute stores the execution percentage of the + *Scan* command. + + The CSP Subarray device can subscribe to this attribute to monitor and report + the command execution progress. + + The attribute assumes values in the range [0, 100]. + """ + 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 the timeoutExpiredFlag attribute. + + *timeoutExpiredFlag* attribute is of type DevBoolean. + + Its value is True when a timeout condition occurs during the execution of + a command. + + The Csp Subarray device can subscribe to this attribute to monitor a timeout + condition. + """ + 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 the failureRaisedFlag attribute. + + *failureRaisedFlag* attribute is of type DevBoolean. + + Its value is True when a failure condition occurs during the execution of + a command. + + The Sub-element AlarmHandler, as well the Csp Subarray can subscribe to this attribute + to monitor failures during command execution. + """ + 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']] """ + Return the failureMessage attribute. + + *failureMessage* attribute reports the failure message associated to each failed commad. + + Example: + *server side* + + 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'],...] + + *client side* + + >>> failure_message = proxy.failureMessage + >>> failureMessage + (('gotoidle', 'Device XXX can't execute the command when in SCANNING'),...)) + >>> failureMessage[0][0] + 'gotoidle' + >>> failureMessage[0][1] + 'Device XXX can't execute the command when in SCANNING' + + - row_index addresses the command name + - col_index addresses the number (string) of completed tasks + """ + 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 the configureScanProgress attribute. + + *configureScanProgress* attribute stores the execution percentage of the + *ConfigureScan* command. + + The CSP Subarray device can subscribe to this attribute to monitor and report + the command execution progress. + + The attribute assumes values in the range [0, 100]. + """ + 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 the configureScanDurationMeasured attribute. + + *configureScanDurationMeasured* attribute reports the effective execution time for the + *ConfigureScan* command. + """ + 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']] + """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 list of devices that completed the task + + Example: + *server side* + + self._list_dev_completed_task = {'gotoidle': 'device, device2, device3', 'configurescan': 'device1, device2'} + image_attr = [['gotoidle',''], ['device, device2, deviceconfigurescan':''device1, device2']]*client side* + + *client side* + + >>> list_dev_completed_task = proxy.listOfDevCompletedTask + >>> list_dev_completed_task + (('gotoidle', 'Device XXX can't execute the command when in SCANNING'),...)) + >>> list_dev_completed_task[0][0] + 'gotoidle' + >>> list_dev_completed_task[0][1] + 'device, device2, device3'' + + - row_index addresses the command name + - col_index addresses the list of devices that completed tasks + """ + 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 @@ -384,9 +537,10 @@ class CspSubElementSubarray(SKASubarray): def Abort(self): # PROTECTED REGION ID(CspSubElementSubarray.Abort) ENABLED START # """ - Change obsState to ABORTED. + Stop abruptly the execution of a command. + After execution, the subarray obsState moves to ABORTED. - :return:None + :return: None """ pass # PROTECTED REGION END # // CspSubElementSubarray.Abort @@ -399,9 +553,19 @@ class CspSubElementSubarray(SKASubarray): def EndScan(self): # PROTECTED REGION ID(CspSubElementSubarray.EndScan) ENABLED START # """ - Change obsState to IDLE. - - :return:None + Stop the execution of the current scan. + + The command is processed when the subarray is in ON State and its obsState value + is SCANNING. + On success, the device obsState moves to READY. + The *EndScan* class method behavior is modified by two Python decorators: + *IsSubarrayCommandAllowed* and *ObsStateCheck*. + These decorators respectively verify if the subarray is the required State and observing + state. + + :return: None + :raises: tango.DevFailed exception when the subarray is not in the proper State or + obsState value. """ pass # PROTECTED REGION END # // CspSubElementSubarray.EndScan @@ -415,11 +579,22 @@ class CspSubElementSubarray(SKASubarray): def Scan(self, argin): # PROTECTED REGION ID(CspSubElementSubarray.Scan) ENABLED START # """ - Starts the scan. - - :param argin: 'DevVarStringArray' + Start the execution of the scan. + The command can be issued only when the subarray State is ON and its obsState + is READY. + On success, the subarray obsState moves to SCANNING. + The *Scan* class method behavior is modified by two Python decorators: + *IsSubarrayCommandAllowed* and *ObsStateCheck*. + These decorators respectively verify if the subarray is the required State and observing + state. + + :param argin: the scan id (integer number) + :type: DevVarStringArray + + :return: None + :raises: tango.DevFailed exception when the subarray is not in the proper State or + obsState value. - :return:None """ pass # PROTECTED REGION END # // CspSubElementSubarray.Scan @@ -435,11 +610,21 @@ class CspSubElementSubarray(SKASubarray): # 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 + The command is processed when the subarray is in ON State and its obsState value + is IDLE or READY (re-configuration). + The subarray obsState moves to CONFIGURING during the configuration process and then to + READY when the command ends with success. + The *ConfigureScan* class method behavior is modified by two Python decorators: + *IsSubarrayCommandAllowed* and *ObsStateCheck*. + These decorators respectively verify if the subarray is the required State and observing + state. + + :param argin: a Json-encoded string with the scan configuration + :type: DevString + + :return: None + :raises: tango.DevFailed exception when the subarray is not in the proper State or + observing state value. """ pass # PROTECTED REGION END # // CspSubElementSubarray.ConfigureScan @@ -449,13 +634,21 @@ class CspSubElementSubarray(SKASubarray): @DebugIt() @IsSubarrayCommandAllowed() @ObsStateCheck('gotoidle') - @SubarrayRejectCmd('Configure', 'Scan') + @SubarrayRejectCmd('ConfigureScan', 'Scan') def GoToIdle(self): # PROTECTED REGION ID(CspSubElementSubarray.GoToIdle) ENABLED START # """ Set the Subarray obsState to IDLE. - - :return:None + The *GoToIdle* class method behavior is modified by three Python decorators: + *IsSubarrayCommandAllowed* and *ObsStateCheck* decorators respectively verify + if the subarray is the required State and observing state. + *SubarrayRejectCmd* decorator checks if there is another command is already running. + In this the case, the current command is rejected throwing an exception. + + :return: None + :raises: tango.DevFailed exception when the subarray: + - is not in the proper State or observing state value + - is running the *ConfigureScan* or *Scan* command """ pass # PROTECTED REGION END # // CspSubElementSubarray.GoToIdle @@ -464,7 +657,6 @@ class CspSubElementSubarray(SKASubarray): # Run server # ---------- - def main(args=None, **kwargs): """Main function of the CspSubElementSubarray module.""" # PROTECTED REGION ID(CspSubElementSubarray.main) ENABLED START # diff --git a/docs/src/README.md b/docs/src/README.md new file mode 120000 index 0000000..fe84005 --- /dev/null +++ b/docs/src/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/docs/src/index.rst b/docs/src/index.rst index 4b79b17..23812df 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -13,10 +13,15 @@ :caption: Home :hidden: -SKA CSP-LMC-SUBELEMENT Abstract Class -===================================== +SKA CSP.LMC SubElement Base Classes +======================================= + +This project provides a limited set of base classes to be extended by each CSP.LMC +SubElement class. -This project contains the `CSP.LMC.SUBELEMENT` abstract classes prototype. +The scope of the CSP.LMC SubElement Base classes is to provide to a CSP.LMC Element +a common set of TANGO methods and attributes to access its SubElements in an uniform +way. .. README ============================================================= @@ -24,9 +29,9 @@ This project contains the `CSP.LMC.SUBELEMENT` abstract classes prototype. .. toctree:: :maxdepth: 2 - :caption: Introduction + :caption: Introduction - ../../README + README .. COMMUNITY SECTION ================================================== @@ -34,18 +39,18 @@ This project contains the `CSP.LMC.SUBELEMENT` abstract classes prototype. .. toctree:: :maxdepth: 2 - :caption: Csp.LMC SubElement TANGO Classes + :caption: CSP.LMC SubElement TANGO Classes :hidden: package/guide -Detailed Abstract Class Documentation +Detailed Class Documentation ===================================== We report here the detailed descriptions of the component that form part of the project. -This project includes few classes: the `CspSubElementMaster`, the `CspSubElementSubarray` and -the `Rack` device drivers. +This project includes few TANGO Device Classes: the `CspSubElementMaster`, the `CspSubElementSubarray`. + - :doc:`package/guide` diff --git a/docs/src/package/guide.rst b/docs/src/package/guide.rst index 6513f5f..8eabc31 100644 --- a/docs/src/package/guide.rst +++ b/docs/src/package/guide.rst @@ -1,10 +1,6 @@ .. doctest-skip-all .. _package-guide: -.. todo:: - - write documentation for private and protected attributes and methods of - the CSP.LMC Subelement classes. - ************************ Public API documentation ************************ -- GitLab