Source code for ekfsm.core.slots

from enum import Enum
from ekfsm.core.components import HwModule


from munch import Munch


from typing import Any


[docs] class SlotType(Enum): """ Define the types of slots that can be found in a chassis. The following slot types are defined: - CPCI_S0_UTILITY: CompactPCI Serial Utility Connector - CPCI_S0_SYS: CompactPCI Serial System Slot - CPCI_S0_PER: CompactPCI Serial Peripheral Slot - CPCI_S0_PSU: CompactPCI Serial Power Supply Slot """ CPCI_S0_UTILITY = 1 # CompactPCI Serial Utility Connector CPCI_S0_SYS = 2 # CompactPCI Serial System Slot CPCI_S0_PER = 3 # CompactPCI Serial Peripheral Slot CPCI_S0_PSU = 4 # CompactPCI Serial Power Supply Slot
[docs] @classmethod def from_string(cls, name: str) -> "SlotType": try: return cls[name] except KeyError: raise ValueError(f"Invalid {cls.__name__}: {name}")
[docs] def to_string(self) -> str: return self.name
[docs] class Slot: """ A slot represents a physical slot in a chassis. Parameters ---------- name The name of the slot, e.g. "SlotA" or "CPCI-SYSTEMSLOT" slot_type The type of the slot, e.g. SlotType.CPCI_S0_SYS desired_hwmodule_type The desired type of the hardware module that should be in the slot (currently unused) desired_hwmodule_name The name to be used for the hardware module instance in the slot. (currently unused) master The master board of the system hwmodule The hardware module that is in the slot number The number of the slot attributes Additional attributes """ def __init__( self, name: str, slot_type: SlotType, desired_hwmodule_type: str, desired_hwmodule_name: str, number: int, hwmodule: HwModule | None = None, master: HwModule | None = None, attributes: Munch | None = None, ) -> None: self._name = name self.slot_type = slot_type self._desired_hwmodule_type = desired_hwmodule_type self._desired_hwmodule_name = desired_hwmodule_name self.number = number self.hwmodule = hwmodule self.master = master self.attributes = attributes
[docs] def info(self) -> dict[str, Any]: """ Returns a dictionary with information about the slot. - name (str): The name of the slot - slot_type (str): The type of the slot - number (int): The number of the slot - desired_hwmodule_type (str): The desired type of the hardware module - actual_hwmodule_type (str): The actual type of the hardware module - desired_hwmodule_name (str): The desired name of the hardware module - is_populated (bool): Is the slot populated? - is_correctly_populated (bool): Is the slot correctly populated? """ return { "name": self._name, "slot_type": self.slot_type.to_string(), "number": self.number, "desired_hwmodule_type": self._desired_hwmodule_type, "actual_hwmodule_type": self.hwmodule.board_type if self.hwmodule else None, "desired_hwmodule_name": self._desired_hwmodule_name, "is_populated": self.is_populated, "is_correctly_populated": self.is_correctly_populated, }
def __repr__(self) -> str: return ( f"{self.__class__.__name__}(name={self._name}, slot_type={self.slot_type})" ) @property def name(self) -> str: """ Return the name of the slot. """ return self._name @property def is_populated(self) -> bool: """ Return True if the slot is populated, False otherwise. """ return self.hwmodule is not None @property def is_correctly_populated(self) -> bool: """ Return True if the slot is populated with the desired hardware module type, False otherwise. """ return ( self.hwmodule is not None and self.hwmodule.board_type.lower() == self._desired_hwmodule_type.lower() )
[docs] class Slots(Munch): """ A collection of slots. Slots are stored in a dictionary-like object, where the key is the slot name and the value is the Slot object. Slots can be accessed by name, by number or via an attribute access matching the key. Example ------- >>> from ekfsm..core.slots import Slot, Slots, SlotType >>> slotA = Slot("SlotA", SlotType.CPCI_S0_PER, "Bla", "Blubb", 3) >>> slots = Slots((slotA.name, slotA)) >>> print(slots[name]) >>> print(slots.slotA) # attribute access, same as slots[name] >>> print(slots[3]) # number access, same as slots.slotA """ def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) def __getitem__(self, key: int | str) -> Slot: """ Get a slot by name, number or attribute access. """ if isinstance(key, int): return next(slot for slot in self.values() if slot.number == key) return super().__getitem__(key) def __setitem__(self, key, value): """ Add a Slot object to the collection. Raises ------ ValueError if: - the value is not a Slot object - the key does not match the slot name - the slot already exists in collection - or the slot number is not unique """ if not isinstance(value, Slot): raise ValueError("Only Slot instances can be added to a Slots collection.") elif key != value.name: raise ValueError("Slot name must match key.") elif value in self.values(): raise ValueError("Slot already exists in collection.") elif value.number in [slot.number for slot in self.values()]: raise ValueError("Slot number must be unique.") return super().__setitem__(key, value)
[docs] def add(self, slot: Slot) -> None: """ Add a Slot object to the collection, where the name of the slot object is used as the key. Example ------- >>> from ekfsm.core.slots import Slot, Slots, SlotType >>> slotA = Slot("SlotA", SlotType.CPCI_S0_PER, "Bla", "Blubb", 3) >>> slots = Slots() >>> slots.add(slotA) # add slotA to the collection >>> print(slots.SlotA) # attribute access, same as slots["SlotA"] """ self[slot.name] = slot