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

AT5-257: memorized attributes read at device initialization.

Removed some small bugs.
parent 51576695
Loading
Loading
Loading
Loading
+83 −41
Original line number Diff line number Diff line
@@ -182,11 +182,11 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                        # removing the last 15 chars
                        cmd_name = evt.attr_value.name[:-15]
                        self._se_cmd_progress[dev_name][cmd_name] = evt.attr_value.value
                elif evt.attr_value.name.lower() == "onCmdTimeoutExpired":
                elif evt.attr_value.name.lower() == "oncmdtimeoutexpired":
                    self._se_timeout_expired[dev_name]['on'] = True
                elif evt.attr_value.name.lower() == "offCmdTimeoutExpired":
                elif evt.attr_value.name.lower() == "offcmdtimeoutexpired":
                    self._se_timeout_expired[dev_name]['off'] = True
                elif evt.attr_value.name.lower() == "standbyCmdTimeoutExpired":
                elif evt.attr_value.name.lower() == "standbycmdtimeoutexpired":
                    self._se_timeout_expired[dev_name]['standby'] = True
                else:
                    log_msg = ("Unexpected change event for"
@@ -292,23 +292,29 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
        """

        # The whole CSP HealthState is OK only if:
        # - all sub-elements with adminMode OFF-LINE or MAINTENACE are ON AND
        # - all sub-elements with adminMode ON-LINE or MAINTENACE are ON AND
        # - each sub-element HealthState is OK
        
        admin_on = 0
        health_ok = 0
        admin_fqdn = [fqdn for fqdn, admin_value in self._se_admin_mode.items()
                      if admin_value in [AdminMode.ONLINE, AdminMode.MAINTENANCE]]
        health_fqdn = [fqdn for fqdn, health_value in self._se_health_state.items()
                       if health_value == HealthState.OK]
        state_fqdn =  [fqdn for fqdn, state_value in self._se_state.items()
                       if state_value in [tango.DevState.ON, tango.DevState.STANDBY]]
        admin_fqdn.sort()
        health_fqdn.sort()
        state_fqdn.sort()
        # default value to DEGRADED
        self._health_state = HealthState.DEGRADED
        for fqdn in self._se_fqdn:
            if self._se_admin_mode[fqdn] not in [AdminMode.OFFLINE, AdminMode.MAINTENANCE]:
                if fqdn == self.CspCbf:
                    self._health_state = self._se_health_state[self.CspCbf] 
                    return
                continue
            admin_on += 1
            if self._se_health_state[fqdn] == HealthState.OK:
                health_ok += 1
        if admin_on == health_ok:
        if self.CspCbf not in admin_fqdn:
            if admin_fqdn == health_fqdn == state_fqdn:
                self._healthstate = HealthState.OK
            elif self._se_health_state[self.CspCbf] in [HealthState.FAILED,
                                                      HealthState.UNKNOWN,
                                                      HealthState.DEGREADED]:
                self._healthstate = self._se_health_state[self.CbfSubarray]
        else:
            # if CBF is not ONLINE/MAINTENANCE ....
            self._healthstate = self._se_health_state[self.CspCbf]
        return
    
    def _connect_to_subelements (self):
@@ -321,11 +327,11 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):

        :return: None
        """
        # connect to TANGO DB
        csp_tango_db = tango.Database() 
        
        
        for fqdn in self._se_fqdn:
            try:
                # DeviceProxy to sub-elements
                log_msg = "Trying connection to" + str(fqdn) + " device"
                print(log_msg)
                self.dev_logging(log_msg, int(tango.LogLevel.LOG_INFO))
@@ -341,6 +347,16 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                # subscription of SCM attributes (State, healthState and adminMode).
                # Note: subscription is performed also for devices not ONLINE or 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
                # adminMode has to be subscribed first so that healthState and State are
                # updated accordingly with its value!
                ev_id = device_proxy.subscribe_event("adminMode",
                                                     EventType.CHANGE_EVENT,
                                                     self._se_scm_change_event_cb,
                                                     stateless=True)
                self._se_event_id[fqdn]['adminMode'] = ev_id
                
                ev_id = device_proxy.subscribe_event("State",
                                                     EventType.CHANGE_EVENT,
                                                     self._se_scm_change_event_cb,
@@ -353,18 +369,7 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                                                     stateless=True)
                self._se_event_id[fqdn]['healthState'] = ev_id
                
                ev_id = device_proxy.subscribe_event("adminMode",
                                                     EventType.CHANGE_EVENT,
                                                     self._se_scm_change_event_cb,
                                                     stateless=True)
                self._se_event_id[fqdn]['adminMode'] = ev_id
                # read the sub-element adminMode (memorized) attribute from
                # the TANGO DB. 
                # Note: a memorized attribute has defined the attribute property '__value'
                attribute_properties = csp_tango_db.get_device_attribute_property(fqdn, {'adminMode': ['__value']})
                print("fqdn: {} attribute_properties: {}".format(fqdn, attribute_properties))
                admin_mode_memorized = attribute_properties['adminMode']['__value']
                self._se_admin_mode[fqdn] = int(admin_mode_memorized[0])
                
            except KeyError as key_err:
                log_msg = ("No key {} found".format(str(key_err)))
                self.dev_logging(log_msg, tango.LogLevel.LOG_WARN)
@@ -1050,9 +1055,21 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
        # PROTECTED REGION ID(CspMaster.init_device) ENABLED START #
        self._build_state = '{}, {}, {}'.format(release.name, release.version, release.description)
        self._version_id = release.version
        # connect to TANGO DB
        csp_tango_db = tango.Database()
        # read the CSP memorized attributes from the TANGO DB. 
        # Note: a memorized attribute has defined the attribute
        # property '__value'
        attribute_properties = csp_tango_db.get_device_attribute_property(self.get_name(),
                                                                          {'adminMode': ['__value'],
                                                                           'storageLoggingLevel': ['__value'],
                                                                           'elementLoggingLevel': ['__value'],
                                                                           'centralLoggingLevel': ['__value'],})
        
        # set storage and element logging level
        self._storage_logging_level = int(tango.LogLevel.LOG_INFO)
        self._element_logging_level = int(tango.LogLevel.LOG_INFO)
        self._central_logging_level = int(tango.LogLevel.LOG_WARN)
        # set init values for the CSP Element and Sub-element SCM states
        self.set_state(tango.DevState.INIT)
        self._health_state = HealthState.OK
@@ -1066,6 +1083,17 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
        self._se_health_state  = defaultdict(lambda: HealthState.UNKNOWN)
        self._se_admin_mode    = defaultdict(lambda: AdminMode.NOTFITTED)
        
        # build a dictionary with the (attr_name, value) of the memorized attributes
        # use memorized atrtibute if present, otherwise the default one
        memorized_attr_dict = {attr_name : int(value[0]) for attr_name, db_key in attribute_properties.items() 
                                                         for key, value in db_key.items() 
                                                         if key == '__value'}
        try:
            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)
        
        # initialize list with CSP sub-element FQDNs
        self._se_fqdn = []
        # NOTE:
@@ -1079,6 +1107,21 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
        self._se_fqdn.append(self.CspPss)
        self._se_fqdn.append(self.CspPst)
        
        # read the sub-elements adminMode (memorized) attributes from
        # the TANGO DB. 
        # Note: a memorized attribute has defined the attribute property '__value'
        for fqdn in  self._se_fqdn:
            attribute_properties = csp_tango_db.get_device_attribute_property(fqdn,
                                                                              {'adminMode': ['__value']})
            print("fqdn: {} attribute_properties: {}".format(fqdn, attribute_properties))
            try:
                admin_mode_memorized = attribute_properties['adminMode']['__value']
                self._se_admin_mode[fqdn] = int(admin_mode_memorized[0])
            except KeyError as key_err:
                msg = ("No key {} found for sub-element {}"
                        " adminMode attribute".format(key_err, fqdn))
                self.dev_logging(msg, tango.LogLevel.LOG_INFO)
                                                                                      
        # _se_proxies: the sub-element proxies
        # implementes s a dictionary:
        # keys: sub-element FQDN
@@ -1245,11 +1288,10 @@ class CspMaster(with_metaclass(DeviceMeta, SKAMaster)):
                        # NOTE: in PyTango unsubscription of not-existing event
                        # id raises a KeyError exception not a DevFailed !!
                    except KeyError as key_err:
                        msg = "Can't retrieve the information of key {}".format(key_err)
                        self.dev_logging(msg, tango.LogLevel.LOG_ERROR)
                    except tango.DevFailed as df:
                        msg = ("Failure reason: {} Desc: {}".format(str(df.args[0].reason),
                                                                       str(df.args[0].desc)))
                        msg = ("Failure unsubscribing event {} "
                               "on device {}. Reason: {}".format(event_id,
                                                                 fqdn,
                                                                 key_err))
                        self.dev_logging(msg, tango.LogLevel.LOG_ERROR)
                # remove the attribute entry from the fqdn dictionary
                for attr_name in event_to_remove[fqdn]: