Commit c7411ecf authored by Elisabetta Giani's avatar Elisabetta Giani
Browse files

AT5-257: removed some bugs from decorators. More comments.

parent 9ee8f3df
Loading
Loading
Loading
Loading
+63 −57
Original line number Diff line number Diff line
@@ -97,12 +97,18 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
    # PROTECTED REGION END #    //  CspMaster.class_variable
    # PROTECTED REGION ID(CspMaster.class_protected_methods) ENABLED START #
    
    
    # !! NOTE !!: 
    # In methods and attributes of the class:
    # 'se' prefix stands for 'sub-element
    # 'cb' suffix stands for 'callback'
    
    #----------------
    # Event Callback functions
    # ---------------
    def _se_scm_change_event_cb(self, evt):
        """
        Class protected callback function.
        Class callback function.
        Retrieve the values of the sub-element SCM attributes subscribed
        for change event at device initialization.

@@ -163,9 +169,9 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
    
    def _attributes_change_evt_cb(self, evt):
        """
        Class protected callback function.
        Retrieve the value of the sub-element xxxCommandProgress attribute
        subscribed for change event when a long-running command is issued
        Class callback function.
        Retrieve the value of the sub-element xxxCommandProgress and xxxcmdTimeoutExpired
        attributes subscribed for change event when a long-running command is issued
        on the sub-element device.

        :param evt: The event data
@@ -242,7 +248,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                    msg = "Error!!Command {} ended on device {}.\n".format(evt.cmd_name,
                                                                           evt.device.dev_name())
                    msg += " Desc: {}".format(evt.errors[0].desc)
                    #self.dev_logging(msg, tango.LogLevel.LOG_ERROR)
                    self.dev_logging(msg, tango.LogLevel.LOG_ERROR)
                    print(msg)
                    self._se_cmd_execution_state[evt.device.dev_name()][evt.cmd_name.lower()] = CmdExecState.IDLE
                    # obsState and obsMode values take on the CbfSubarray's values via
@@ -259,32 +265,31 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
            self.dev_logging(msg, tango.LogLevel.LOG_ERROR)
            
    # ---------------
    # Class protected methods
    # Class methods
    # ---------------
    
    def _update_csp_state(self):
        """
        Class protected method.
        Retrieve the State attribute values of the CSP sub-elements and aggregate
        them to build up the CSP global state.
        Class method.
        Retrieve the *State* attribute value of the CBF sub-element and build up
        the CSP global state: only if CBF sub-element is present CSP can work.
        The *State* of of PSS and PST sub-elements (if ONLINE/MAINTENANCE) only
        contributes to determine the CSP *healthState*

        :param: None

        :return: None
        """
        self._update_csp_health_state()
        # CSP state reflects the status of CBF. Only if CBF is present
        # CSP can work. The state of PSS and PST sub-elements only contributes
        # to determine the CSP health state.
        self.set_state(self._se_state[self.CspCbf])
        if self._admin_mode in [AdminMode.OFFLINE, AdminMode.NOTFITTED, AdminMode.RESERVED]:
            self.set_state[tango.DevState.DISABLE]

    def _update_csp_health_state(self):
        """
        Class protected method.
        Retrieve the healthState attribute of the CSP sub-elements and
        aggregate them to build up the CSP health state
        Class method.
        Retrieve the *healthState* and *adminMode* attributes of the CSP
        sub-elements and aggregate them to build up the CSP *healthState*.
        
        :param: None

@@ -310,7 +315,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                self._healthstate = HealthState.OK
            elif self._se_health_state[self.CspCbf] in [HealthState.FAILED,
                                                      HealthState.UNKNOWN,
                                                      HealthState.DEGREADED]:
                                                      HealthState.DEGRADED]:
                self._healthstate = self._se_health_state[self.CbfSubarray]
        else:
            # if CBF is not ONLINE/MAINTENANCE ....
@@ -319,16 +324,12 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
    
    def _connect_to_subelements (self):
        """
        Class private method.
        Establish a *stateless* connection with each CSP sub-element.
        Retrieve from the CSP TANGO DB  the memorized adminMode value for each 
        sub-element.
        Exceptions are logged.
        Class method.
        Establish a *stateless* connection with each CSP sub-element and
        subscribe for the sub-element SCM attributes.
        
        :return: None
        """
        
        
        for fqdn in self._se_fqdn:
            try:
                # DeviceProxy to sub-elements
@@ -345,7 +346,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                # store the sub-element proxies
                self._se_proxies[fqdn] = device_proxy
                # subscription of SCM attributes (State, healthState and adminMode).
                # Note: subscription is performed also for devices not ONLINE or MAINTENANCE.
                # Note: subscription is performed also for devices not ONLINE/MAINTENANCE.
                # In this way the CspMaster is able to detect a change in the admin value.
                
                # if the sub-element device is running,the adminMode is updated here
@@ -368,8 +369,6 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                                                     self._se_scm_change_event_cb,
                                                     stateless=True)
                self._se_event_id[fqdn]['healthState'] = ev_id
                
                
            except KeyError as key_err:
                log_msg = ("No key {} found".format(str(key_err)))
                self.dev_logging(log_msg, tango.LogLevel.LOG_WARN)
@@ -381,7 +380,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
       
    def _is_se_device_running (self, subelement_name):
        """
        *Class protected method.*
        *Class method.*

        Check if a sub-element is exported in the TANGO DB (i.e its TANGO 
        device server is running).
@@ -417,21 +416,20 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
         
    def _issue_power_command(self, device_list, **args_dict):
        """
        Target function called when the command threads start.
        The On, Standby and Off methods issue the command on the sub-element devices
        in a separate thread. 
        Information about the command to execute and the list of devices are passed as
        argument when the target function is called'
        Target function called when the power command threads start.
        The *On*, *Standby* and *Off* methods issue the command on the sub-element
        devices in a separate thread.
        The target function accepts as input arguments the command to execute and
        the list of devices to command.
        
        :param  device_list: tuple with the FQDN of the sub-element devices
                args_dict: dictionary with information about the command to execute.
                           The dictionary keys are:
                            - cmd_name : the TANGO command name to execute
                            - attr_name: the corresponding command progress attribute to subscribe
                            - dev_state: the expected finale state for the device transition
                            - dev_state: the expected end state for the device transition
        """
        #TODO: order the list alphabetically so that the CBF is always the first element to start
        
        # the TANGO command to execute
        tango_cmd_name = 0
        # the command progress attribute to check subscription         
@@ -462,7 +460,6 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
        self._cmd_progress[cmd_name] = 0
        # sub-element command execution measured time
        se_cmd_duration_measured = defaultdict(lambda:defaultdict(lambda:0))
        # timer is started outside the for loop: it has to start only once.
        # loop on the devices and power-on them sequentially
        for device in device_list:
            # set the sub-element command execution flag
@@ -472,14 +469,16 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                device_proxy = self._se_proxies[device] 
                print("Issue asynch command {} on device {}:".format(cmd_name, device))
               
                # Note: if the command ends on the sub-element, the _cmd_ended_cb callback
                # is called.This callback sets the sub-element execution state to IDLE if
                # an exception is caught during the execution on the sub-element. In both
                # cases the command_state = IDLE is right.
                # Note: If the command is already running on the sub-element, this device has
                # to return without throwing any exception. In this case the current method enters
                # the while loop and the execution of the sub-element command is tracked in the
                # right way.
                # Note: when the command ends on the sub-element, the _cmd_ended_cb callback
                # is called. This callback sets the sub-element execution state to FAULT if
                # an exception is caught during the execution on the sub-element.
                #
                # !!Note!!: 
                # If the command is issued while the same command is already running on a
                # sub-element, the sub-element should return without throwing any exception
                # (see "SKA System Control Guidelines").
                # In this case the current method enters the while loop and the execution of the
                # sub-element command is tracked in the right way.
                device_proxy.command_inout_asynch(tango_cmd_name, self._cmd_ended_cb)
                # register the starting time for the command
                self._se_cmd_starting_time[device] = time.time() 
@@ -513,7 +512,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                    # check for other sub-element device State values
                    if self._se_state[device] in [tango.DevState.FAULT, tango.DevState.ALARM]:
                        self._se_cmd_execution_state[device][cmd_name] = CmdExecState.IDLE
                        msg = ("Device {} is {}}".format(device, self.get_status()))
                        msg = ("Device {} is {}".format(device, self.get_status()))
                        print(msg)
                        self.dev_logging(msg, tango.LogLevel.LOG_WARN) 
                        num_of_failed_device += 1
@@ -546,8 +545,12 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                        # if the CBF command timeout expires, the CSP power-on is stopped
                        # TODO: verify if this behavior conflicts with ICD
                        print("elapsed_time:{} device {}".format(elapsed_time, device))
                        if device.find("cbf") > -1:
                        if device == self.CspCbf:
                            self.dev_logging("CBF Timeout during power-on!!! Exit", tango.LogLevel.LOG_ERROR)
                            self._se_timeout_expired[device][cmd_name] = True
                            self._se_cmd_execution_state[device][cmd_name] = CmdExecState.IDLE
                            self._timeout_expired[cmd_name] = True
                            self._cmd_execution_state[cmd_name] = CmdExecState.IDLE
                            return
                        # timeout on the sub-element, skip to the next device
                        break
@@ -562,11 +565,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                    print("All devices have been handled!")
                    # end of the command: the command has been issued on all the sub-element devices
                    # reset the execution flag for the CSP
                    self._cmd_execution_state[cmd_name] = CmdExecState.IDLE
                    self._last_executed_command = cmd_name
                    # if one or more sub-elements go in timeout, se the CSP timeout flag to True
                    if num_of_failed_device > 0:
                        self._timeout_expired[cmd_name] = True
                    break   
            except KeyError as key_err:
                msg = "No key {} found".format(str(key_err))
                self.dev_logging(msg, tango.LogLevel.LOG_WARN)
@@ -574,6 +573,14 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                # It should not happen! Verify
                msg = "Failure reason: {} Desc: {}".format(str(df.args[0].reason), str(df.args[0].desc))
                self.dev_logging(msg, tango.LogLevel.LOG_ERROR)
        # out of the for loop
        self._cmd_execution_state[cmd_name] = CmdExecState.IDLE
        self._last_executed_command = cmd_name
        # if one or more sub-elements go in timeout, se the CSP timeout flag to True
        for device in device_list:
            if self._se_timeout_expired[device][cmd_name] == True:
                self._timeout_expired[cmd_name] = True
                self._se_timeout_expired[device][cmd_name] = False
                
# PROTECTED REGION END #    //  CspMaster.class_protected_methods
    # -----------------
@@ -1092,7 +1099,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
            self._admin_mode = memorized_attr_dict['adminMode']
            self._storage_logging_level = memorized_attr_dict['storageLoggingLevel']
        except KeyError as key_err:
            self.dev_logging("Key {} not found".format(key_err), tango.LogLevel.INFO)
            self.dev_logging("Key {} not found".format(key_err), tango.LogLevel.LOG_INFO)
        
        # initialize list with CSP sub-element FQDNs
        self._se_fqdn = []
@@ -1811,8 +1818,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
        # The target thread function is common to all the invoked commands. Specifc information
        # are passed as arguments of the function
        # args: the list of sub-element FQDNS
        # args_dict: dictionary with the specifif command information
        print("ON {} STANDBY {}".format( tango.DevState.ON,  tango.DevState.STANDBY))
        # args_dict: dictionary with the specific command information
        args_dict = {'cmd_name':'On', 'attr_name': 'onCommandProgress', 'dev_state': tango.DevState.ON}
        self._command_thread['on'] = threading.Thread(target=self._issue_power_command, name="Thread-On",
                                               args=(device_list,),
+62 −58

File changed.

Preview size limit exceeded, changes collapsed.