class HealthStateAggregator:
    """
    Health State Aggregator class
    """
    def __init__(self, logger=None):
        if logger == None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger

        self.subarray_ln_health_state_map = {}
        self.mccs_ln_health_event_id = {}
        self.this_server = TangoServerHelper.get_instance()
        self.device_data = DeviceData.get_instance()
        mccs_subarray_ln_fqdn = ""
        property_val = self.this_server.read_property("MccsSubarrayLNFQDN")
        mccs_subarray_ln_fqdn = mccs_subarray_ln_fqdn.join(property_val)
        self.mccs_client = TangoClient(mccs_subarray_ln_fqdn)

    def subscribe(self):
        # Subscribe cspsubarrayHealthState (forwarded attribute) of CspSubarray
        mccs_event_id = self.mccs_client.subscribe_attribute(
            const.EVT_MCCSSA_HEALTH, self.health_state_cb)
        self.mccs_ln_health_event_id[self.mccs_client] = mccs_event_id
        log_msg = f"{const.STR_SUB_ATTR_MCCS_SALN_HEALTH_SUCCESS}{self.mccs_ln_health_event_id}"
        self.logger.debug(log_msg)
        self.logger.info(const.STR_SUB_ATTR_MCCS_SALN_HEALTH_SUCCESS)

    def health_state_cb(self, event):
        """
        Receives the subscribed health states, aggregates them
        to calculate the overall subarray health state.

        :param evt: A event on MCCS Subarray healthState.

        :type: Event object
            It has the following members:

                - date (event timestamp)

                - reception_date (event reception timestamp)

                - type (event type)

                - dev_name (device name)

                - name (attribute name)

                - value (event value)

        :return: None
        """
        device_name = event.device.dev_name()
        if not event.err:
            event_health_state = event.attr_value.value
            self.subarray_ln_health_state_map[device_name] = event_health_state

            log_message = self.generate_health_state_log_msg(
                event_health_state, device_name, event)
            self.this_server.write_attr("activityMessage", log_message, False)
            self.device_data._subarray_health_state = self.calculate_health_state(
                self.subarray_ln_health_state_map.values())
        else:
            log_message = f"{const.ERR_SUBSR_SA_HEALTH_STATE}{device_name}{event}"
            self.this_server.write_attr("activityMessage", log_message, False)

    def generate_health_state_log_msg(self, health_state, device_name, event):
        if isinstance(health_state, HealthState):
            return f"{const.STR_HEALTH_STATE}{device_name}{const.STR_ARROW}{health_state.name.upper()}"
        else:
            return f"{const.STR_HEALTH_STATE_UNKNOWN_VAL}{event}"

    def calculate_health_state(self, health_states):
        """
        Calculates aggregated health state of SubarrayLow.
        """
        unique_states = set(health_states)
        if unique_states == set([HealthState.OK]):
            return HealthState.OK
        elif HealthState.FAILED in unique_states:
            return HealthState.FAILED
        elif HealthState.DEGRADED in unique_states:
            return HealthState.DEGRADED
        else:
            return HealthState.UNKNOWN

    def unsubscribe(self):
        """
        This function unsubscribes all health state events given by the event ids and their
        corresponding DeviceProxy objects.

        :param : None

        :return: None
        """
        for tango_client, event_id in self.mccs_ln_health_event_id.items():
            tango_client.unsubscribe_attribute(event_id)
示例#2
0
class ObsStateAggregator:
    """
    Observation State Aggregator class
    """
    def __init__(self, logger=None):
        if logger is None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger

        self._mccs_sa_obs_state = None
        self.mccs_obs_state_event_id = {}
        self.this_server = TangoServerHelper.get_instance()
        self.device_data = DeviceData.get_instance()

    def subscribe(self):
        mccs_subarray_ln_fqdn = ""
        property_val = self.this_server.read_property("MccsSubarrayLNFQDN")
        mccs_subarray_ln_fqdn = mccs_subarray_ln_fqdn.join(property_val)
        self.mccs_client = TangoClient(mccs_subarray_ln_fqdn)
        # Subscribe mccsSubarrayObsState (forwarded attribute) of mccsSubarray
        mccs_event_id = self.mccs_client.subscribe_attribute(
            const.EVT_MCCSSA_OBS_STATE, self.observation_state_cb)
        self.mccs_obs_state_event_id[self.mccs_client] = mccs_event_id
        log_msg = f"{const.STR_SUB_ATTR_MCCS_SALN_OBSTATE_SUCCESS}{self.mccs_obs_state_event_id}"
        self.logger.info(log_msg)

    def unsubscribe(self):
        """
        This function unsubscribes all Observation state events given by the event ids and their
        corresponding DeviceProxy objects.

        :param : None

        :return: None
        """
        for tango_client, event_id in self.mccs_obs_state_event_id.items():
            tango_client.unsubscribe_attribute(event_id)

    def observation_state_cb(self, evt):
        """
        Receives the subscribed MCCS Subarray obsState.

        :param evt: A event on MCCS Subarray ObsState.

        :type: Event object
            It has the following members:

                - date (event timestamp)

                - reception_date (event reception timestamp)

                - type (event type)

                - dev_name (device name)

                - name (attribute name)

                - value (event value)

        :return: None

        :raises: KeyError if error occurs while setting SubarrayNode's ObsState.
        """
        try:
            if not evt.err:
                event_observation_state = evt.attr_value.value
                if const.PROP_DEF_VAL_TMMCCS_MID_SALN in evt.attr_name:
                    # Typacasted the event values to obsState ENUM labels.
                    self._mccs_sa_obs_state = ObsState(event_observation_state)
                    self.this_server.write_attr(
                        "activityMessage",
                        f"{const.STR_MCCS_SUBARRAY_OBS_STATE}{event_observation_state}",
                        False)
                else:
                    self.logger.info(const.EVT_UNKNOWN)
                    self.this_server.write_attr("activityMessage",
                                                const.EVT_UNKNOWN, False)
                self.calculate_observation_state()

            else:
                log_msg = f"{const.ERR_SUBSR_MCCSSA_OBS_STATE}{evt}"
                self.logger.info(log_msg)
                self.this_server.write_attr("activityMessage", log_msg, False)
        except KeyError as key_error:
            log_msg = f"{const.ERR_MCCS_SUBARRAY_OBS_STATE}{key_error}"
            self.logger.error(log_msg)
            self.this_server.write_attr(
                "activityMessage",
                f"{const.ERR_MCCS_SUBARRAY_OBS_STATE}{key_error}", False)

    def calculate_observation_state(self):
        """
        Calculates aggregated observation state of Subarray.
        """
        log_msg = f"MCCS ObsState is: {self._mccs_sa_obs_state}"
        self.logger.info(log_msg)
        if self._mccs_sa_obs_state == ObsState.EMPTY:
            if self.device_data.is_release_resources:
                self.logger.info(
                    "Calling ReleaseAllResource command succeeded() method")
                self.this_server.device.release.succeeded()
            elif self.device_data.is_restart_command_executed:
                self.logger.info("Calling Restart command succeeded() method")
                self.this_server.device.restart.succeeded()
        elif self._mccs_sa_obs_state == ObsState.READY:
            if self.device_data.is_scan_completed:
                self.logger.info("Calling EndScan command succeeded() method")
                self.this_server.device.endscan.succeeded()
            else:
                # Configure command success
                self.logger.info(
                    "Calling Configure command succeeded() method")
                self.this_server.device.configure.succeeded()
        elif self._mccs_sa_obs_state == ObsState.IDLE:
            if self.device_data.is_end_command:
                # End command success
                self.logger.info("Calling End command succeeded() method")
                self.this_server.device.end.succeeded()
            elif self.device_data.is_obsreset_command_executed:
                # ObsReset command success
                self.logger.info("Calling ObsReset command succeeded() method")
                self.this_server.device.obsreset.succeeded()
            else:
                # Assign Resource command success
                self.logger.info(
                    "Calling AssignResource command succeeded() method")
                self.this_server.device.assign.succeeded()
        elif self._mccs_sa_obs_state == ObsState.ABORTED:
            try:
                retry_count = 0
                while retry_count < 3:
                    if self.device_data.is_abort_command_executed:
                        # Abort command success
                        self.logger.info(
                            "Calling Abort command succeeded() method")
                        self.this_server.device.abort.succeeded()
                        break
                    sleep(0.1)
                    retry_count += 1
            except Exception as e:
                self.logger(str(e))
示例#3
0
class AssignedResourcesMaintainer:
    """
    Assigned Resources Maintainer class for tmc Low.
    """
    def __init__(self, logger=None):
        if logger == None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger

        self.mccs_ln_asigned_res_event_id = {}
        self.this_server = TangoServerHelper.get_instance()
        self.device_data = DeviceData.get_instance()
        mccs_subarray_ln_fqdn = self.this_server.read_property(
            "MccsSubarrayLNFQDN")[0]
        self.mccs_client = TangoClient(mccs_subarray_ln_fqdn)

    def subscribe(self):
        # Subscribe assignedResources (forwarded attribute) of MccsSubarrayLeafNode
        mccs_event_id = self.mccs_client.subscribe_attribute(
            const.EVT_MCCSSA_ASSIGNED_RESOURCES, self.assigned_resources_cb)
        self.mccs_ln_asigned_res_event_id[self.mccs_client] = mccs_event_id
        log_msg = f"{const.STR_SUB_ATTR_MCCS_SALN_ASSIGNED_RESOURCES_SUCCESS}" \
                f"{self.mccs_ln_asigned_res_event_id}"
        self.logger.info(log_msg)
        self.logger.info(
            const.STR_SUB_ATTR_MCCS_SALN_ASSIGNED_RESOURCES_SUCCESS)

    def assigned_resources_cb(self, event):
        """
        Receives the subscribed assigned_resources attribute value.

        :param evt: Tango event on MCCS Subarray assigned_resources attribute.

        :type: Event object
            It has the following members:

                - date (event timestamp) 

                - reception_date (event reception timestamp)

                - type (event type)

                - dev_name (device name)

                - name (attribute name)

                - value (event value)

        :return: None
        """
        device_name = event.device.dev_name()
        log_msg = "Event on assigned_resources attribute is: {}".format(
            str(event))
        self.logger.info(log_msg)
        if not event.err:
            self.device_data.assignd_resources_by_mccs = event.attr_value.value
            log_msg = "Event on assigned_resources attribute is: {}".format(
                str(event))
            self.logger.info(log_msg)
            self.update_assigned_resources_attribute(
                self.device_data.assignd_resources_by_mccs)
            self.logger.info(
                const.STR_SUB_ATTR_MCCS_SALN_ASSIGNED_RESOURCES_SUCCESS)
            log_msg = "MccsSubarray.assigned_resources attribute value is: {}".format(
                str(self.device_data.assignd_resources_by_mccs))
            self.logger.info(log_msg)
        else:
            log_message = f"{const.ERR_SUBSR_MCCSSA_ASSIGNED_RES_ATTR}{device_name}{event}"
            self.logger.info(log_message)
            self.this_server.write_attr("activityMessage", log_message, False)

    def update_assigned_resources_attribute(self, mccs_assigned_resources):
        """
        This method updates the SubarrayNode.assigned_resources attribute.
        """
        if mccs_assigned_resources:
            input_json_arg = json.loads(mccs_assigned_resources)
            del input_json_arg["interface"]
            json_argument = {}
            json_argument[
                "interface"] = "https://schema.skatelescope.org/ska-low-tmc-assignedresources/1.0"
            json_argument["mccs"] = input_json_arg
            self.this_server.write_attr("assigned_resources",
                                        json.dumps(json_argument))
            log_msg = "assigned_resources attribute value is: {}".format(
                str(json.dumps(json_argument)))
            self.logger.info(log_msg)

    def unsubscribe(self):
        """
        This function unsubscribes MccsSubarray.assigned_resources attribute.

        :param : None

        :return: None
        """
        for tango_client, event_id in self.mccs_ln_asigned_res_event_id.items(
        ):
            tango_client.unsubscribe_attribute(event_id)