Source code for ska_low_mccs.subarray.subarray_health_model

#  -*- coding: utf-8 -*-
#
# This file is part of the SKA Low MCCS project
#
#
# Distributed under the terms of the BSD 3-clause new license.
# See LICENSE for more info.
"""An implementation of a health model for subarrays."""
from __future__ import annotations

from typing import Callable, Optional

from ska_control_model import HealthState
from ska_low_mccs_common.health import BaseHealthModel

from .subarray_health_rules import SubarrayHealthRules

__all__ = ["SubarrayHealthModel"]


[docs] class SubarrayHealthModel(BaseHealthModel): """A health model for subarrays.""" DEGRADED_CRITERIA = 0.05 FAILED_CRITERIA = 0.2
[docs] def __init__( self: SubarrayHealthModel, health_changed_callback: Callable, ignore_power_state: bool = False, thresholds: Optional[dict[str, float]] = None, ) -> None: """ Initialise a new instance. :param health_changed_callback: a callback to be called when the health of the subarray (as evaluated by this model) changes :param ignore_power_state: whether the health model should ignore the power state when computing health. :param thresholds: Thresholds for failed and degraded states. """ self._station_healths: dict[str, Optional[HealthState]] = {} self._subarray_beam_healths: dict[str, Optional[HealthState]] = {} self._station_beam_healths: dict[str, Optional[HealthState]] = {} self._health_rules = SubarrayHealthRules(thresholds) super().__init__(health_changed_callback, ignore_power_state=ignore_power_state)
[docs] def evaluate_health( self: SubarrayHealthModel, ) -> tuple[HealthState, str]: """ Compute overall health of the subarray. The overall health is based on the fault and communication status of the subarray overall, together with the health of its stations and subarray beams. This implementation simply sets the health of the station to the health of its least healthy component. :return: an overall health of the subarray """ subarray_health, subarray_report = super().evaluate_health() for health in [ HealthState.FAILED, HealthState.UNKNOWN, HealthState.DEGRADED, HealthState.OK, ]: if health == subarray_health: return subarray_health, subarray_report result, report = self._health_rules.rules[health]( self._station_healths, self._subarray_beam_healths, ) if result: return health, report return HealthState.UNKNOWN, "No rules matched"
[docs] def resources_changed( self: SubarrayHealthModel, station_trls: set[str], subarray_beam_trls: set[str], station_beam_trls: set[str], ) -> None: """ Handle change in subarray resources. This is a callback hook, called by the component manager when the resources of the subarray changes. :param station_trls: the TRLs of stations assigned to this subarray :param subarray_beam_trls: the TRLs of subarray beams assigned to this subarray :param station_beam_trls: the TRLs of station beams assigned to this subarray """ # We are updating with sets, which are unordered. This makes for # ugly reports, so here we convert to a list and sort before assigning. station_trl_list = sorted(list(station_trls)) subarray_beam_trl_list = sorted(list(subarray_beam_trls)) station_beam_trl_list = sorted(list(station_beam_trls)) self._station_healths = { trl: self._station_healths.get(trl, HealthState.UNKNOWN) for trl in station_trl_list } self._subarray_beam_healths = { trl: self._subarray_beam_healths.get(trl, HealthState.UNKNOWN) for trl in subarray_beam_trl_list } self._station_beam_healths = { trl: self._station_beam_healths.get(trl, HealthState.UNKNOWN) for trl in station_beam_trl_list } self.update_health()
[docs] def station_health_changed( self: SubarrayHealthModel, trl: str, health_state: HealthState | None, ) -> None: """ Handle change in station health. This is a callback hook, called by the component manager when the health of a station changes. :param trl: the TRL of the station whose health has changed :param health_state: the new health state of the station, or None if the subarray beam's health should not be taken into account. """ self._station_healths[trl] = health_state self.update_health()
[docs] def subarray_beam_health_changed( self: SubarrayHealthModel, trl: str, health_state: HealthState | None, ) -> None: """ Handle change in subarray beam health. This is a callback hook, called by the component manager when the health of a subarray beam changes. :param trl: the TRL of the subarray beam whose health has changed :param health_state: the new health state of the subarray beam, or None if the subarray beam's health should not be taken into account. """ self._subarray_beam_healths[trl] = health_state self.update_health()
[docs] def station_beam_health_changed( self: SubarrayHealthModel, trl: str, health_state: HealthState | None, ) -> None: """ Handle change in station beam health. This is a callback hook, called by the component manager when the health of a station beam changes. :param trl: the TRL of the station beam whose health has changed :param health_state: the new health state of the station beam, or None if the station beam's health should not be taken into account. """ self._station_beam_healths[trl] = health_state self.update_health()