ekfsm package — ekfsm documentation

# ekfsm package

class ekfsm.System(config, abort=False)

  Bases: `SysTree`

  A System represents a CPCI system.

  Once initialised, it will create:

    - a list of boards that are present in the system which can be accessed either by name or by slot number.

    - a list of slots that are present in the system which can be accessed under the slots attribute.

  Visual representation of the system is shown as trees of HW Modules and attached devices.

  Parameters:

    - config (Path)

    - abort (bool)

  name

    The name of the system.

  slots

    A dictionary-like object that contains all slots in the system.

  boards

    A list of all boards in the system.

  master

    The master board of the system.

  master_slot_number

    The slot number of the master board.

  config

    The system configuration.

  ## Accessing boards

  Iterating over the system will iterate over all boards in the system.

  <board_name>

    The board object can be accessed by its name.

  <slot_number>

    The board object can be accessed by its slot number.

  Example

      >>> from ekfsm.system import System
      >>> system = System("path/to/config.yaml")
      >>> print(system) # Print the system configuration as trees of HwModules
      >>> system.print() # same as above
      >>> cpu = system.cpu # Access the CPU board by its name
      >>> cpu = system[0] # Access the CPU board by its slot index (index as in configuration file)
      >>> print(system.slots) # Print all slots in the system
      >>> print(system.boards) # Print all boards in the system
      >>> for b in system: # Iterate over all boards in the system
      >>>    print(b.name + b.slot.name) # Print the name of the board and the slot it is in

  __init__(config, abort=False)
    Parameters:

      - config (`Path`) – Path to the config that specifies the system and how the slots are filled.

      - abort (`bool`) – If True, abort the program if a board cannot be created. If False, leave the slot empty. Default is False.

    Return type:

      None

  _create_hwmodule_from_cfg_file(slot, board_name, path)

    Try to create a HwModule object from a board config file. It does not probe the hardware.

    Return type:

      `HwModule`

    Returns:

      HwModule object.

    Raises:

      - FileNotFoundError – If the board config file does not exist.

      - ConfigError – If the slot type in the config file does not match the slot type.

      - Exception – If something else went wrong.

    Parameters:

      - slot (Slot)

      - board_name (str)

      - path (Path)

  create_hwmodule(slot_entry, slot_number, master)

    Create HwModule object for the slot.

    Parameters:

      - slot_entry (`Munch`) – The slot entry config (usually part of the system configuration).

      - slot_number (`int`) – The slot number of the slot.

      - master (`HwModule` | `None`) – The master board of the system.

    Return type:

      `Tuple`[`HwModule` | `None`, `Slot`]

    Returns:

      HwModule and Slot. HwModule is None if it cannot be created.

  get_module_by_name(name)

    Get the hwmodule by its name.

    Parameters:

      name (`str`) – The name of the hwmodule.

    Return type:

      `HwModule` | `None`

    Returns:

      HwModule

        The hwmodule with the given name.

      None

        If no hwmodule is present with the given name.

  get_module_in_slot(idx)

    Get the hwmodule in the given slot.

    Parameters:

      idx (`int`) – The slot index.

    Return type:

      `HwModule` | `None`

    Returns:

      HwModule

        The hwmodule in the given slot.

      None

        If no hwmodule is present in the given slot.

  reload()

    Reload the current system configuration.

    Important

    This will rebuild all system objects and reinitialize the system tree.

ekfsm.ekfsm_logger(name)

  Create a logger with the name ‘ekfsm:name’

  Returns:

    The logger object.

  Return type:

    `logging.Logger`

  Parameters:

    name (`str`) – The name of the module, class or object that is using the logger.

ekfsm.load_config(config_file)
  Return type:

    `Any`

  Parameters:

    config_file (str)

## Exceptions

exception ekfsm.exceptions.AcquisitionError

  Bases: `EkfSmException`

  Error while handling data acquisition

exception ekfsm.exceptions.ConfigError

  Bases: `EkfSmException`

  Error in configuration

exception ekfsm.exceptions.DataCorruptionError(details=None)

  Bases: `EkfSmException`

  Error while handling data corruption

  Parameters:

    details (str | None)

exception ekfsm.exceptions.EkfSmException

  Bases: `Exception`

  Base class for all exceptions in the EKFSM Library

exception ekfsm.exceptions.FirmwareNodeError

  Bases: `EkfSmException`

  Error while handlig firmware node

exception ekfsm.exceptions.GPIOError(error_type, details=None)

  Bases: `EkfSmException`

  Error while handling GPIO

  Parameters:

    - error_type (ErrorType)

    - details (str | None)

  class ErrorType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

    Bases: `Enum`

    INVALID_PIN = 'Pin not found'
    NO_MAJOR_MINOR = 'No major/minor number found'
    NO_MATCHING_DEVICE = 'No matching device found'

exception ekfsm.exceptions.SYSFSError

  Bases: `EkfSmException`

  Error while handling sysfs pseudo file system

## CLI

### ekfsm-cli

    ekfsm-cli [OPTIONS] COMMAND [ARGS]...

Options

-v, --verbose

  Enable verbose output

-d, --debug

  Enable debug output

-s, --sysfs <sysfs>

  Use custom sysfs dir for simulation mode

-c, --config <config>

  Required Path to configuration file

#### show

Show information about the system

    ekfsm-cli show [OPTIONS]

#### write

Write data to the system

    ekfsm-cli write [OPTIONS]

Options

-s, --serial <serial>

  Write chassis serial number

-u, --unit <unit>

  Write chassis unit

-n, --vendor <vendor>

  Write chassis vendor

-r, --revision <revision>

  Write chassis revision

-m, --model <model>

  Write chassis model

-c, --custom <custom>

  Write chassis custom information

-v, --version <version>

  Write schema version

## Locking

class ekfsm.lock.Locker(module)

  Bases: `object`

  A class that implements a locking mechanism using file locks.

  Parameters:

    module (`str`) – The name of the module or resource to lock. This will be used to create a unique lock file.

  Example

  with Locker(“mysharedresourcename”).lock():

    # Access the shared resource here pass

  cleanup()
  lock()

ekfsm.lock.locking_cleanup()

  Cleans up all lockfiles and closes all lock file descriptors. Should be called at the end of the program to ensure all locks are released.

ekfsm.lock.locking_configure(enable, lockfile_root='/var/lock/ekfsm')

  Configures the locking mechanism.

  Parameters:

    - enable (`bool`) – Whether to enable or disable locking.

    - lockfile_root (`str`) – The root directory for lockfiles. (default: /var/lock/ekfsm)

# ekfsm.devices package

## I2C Devices using SysFs

### EEPROM

A module containing classes to represent EEPROM devices.

#### Routine Listings

> `EEPROM` `Validatable_EEPROM` `EKF_EEPROM` `validated`

class ekfsm.devices.eeprom.EEPROM(name, parent=None, *args, **kwargs)

  Bases: `Device`

  A class used to represent a generic EEPROM device.

  Parameters:

    - name (`str`) – The name of the EEPROM device.

    - parent (`SysTree` | `None`) – The parent device of the EEPROM in the `Device` tree.

  Caution

  The following conditions must be met for this class to work properly:

    - EEPROM must be I2C accessable

    - EEPROM must have a sysfs device

  Note

  This class should be inherited by classes representing specific EEPROM devices and defining custom storage schemes.

  _update_content()

    Update the content of the EEPROM device.

    Return type:

      `None`

    Note

    - This method should be called whenever the content of the EEPROM is updated (after each write op).

    - Inheriting classes should call this method before updating their own attributes.

  print()
  read()

    Read the content of the EEPROM.

    Return type:

      `bytes`

    Returns:

      The content of the EEPROM.

    Raises:

      - FileNotFoundError – If the EEPROM sysfs file is not found.

      - RuntimeError – If the sysfs device is not found.

  write(data, offset=0)

    Write data to the EEPROM.

    Parameters:

      - data (`bytes`) – The data to write to the EEPROM.

      - offset (`int`) – The offset at which to start writing the data.

    Raises:

      - RuntimeError – If the sysfs device is not found.

      - FileNotFoundError – If the EEPROM sysfs file is not found.

      - DataCorruptionError – If an error occurs during the write operation.

    Return type:

      `None`

    Note

    Operation is checked for data corruption by reading back the written data.

class ekfsm.devices.eeprom.EKF_CCU_EEPROM(*args, **kwargs)

  Bases: `EKF_EEPROM`

  EKF CCU EEPROM - uses the second part of the EEPROM for chassis inventory and customer area

  _update_ccrc()

    Update the CRC value of the EEPROM content.

    Return type:

      `None`

  property ccrc: int

    Gets or sets the CRC value of the EEPROM content.

    Parameters:

      value (optional) – The CRC value to write to the EEPROM.

    Returns:

      - `int` – The CRC value currently stored in the EEPROM if used as getter.

      - `None` – If used as setter.

    Caution

    The setter actually writes the CRC value to the EEPROM.

    Warning

    The setter method should be used with caution as it can lead to data corruption if the CRC value is not correct!

    Note

    The setter is usually triggered automatically after a successful write operation and in most cases, there is no need to call it manually.

  cmodel()

    Get the chassis model.

    Return type:

      `str`

    Returns:

      The model of the chassis.

  crevision()

    Get the revision of the chassis.

    Return type:

      `str`

    Returns:

      The revision of the chassis.

  cserial()

    Get the chassis serial number.

    Return type:

      `int`

    Returns:

      The serial number of the chassis.

  custom_raw_data()

    Get the raw content area data stored in the EEPROM.

    Return type:

      `bytes`

    Returns:

      The data contained in the raw content block of the EEPROM.

    Note

    This area is free for custom data storage and is not included during crc calculations and validations.

    Important

    If custom raw data should be stored on EEPROM and if it should be protected against corruption, it has to be validated manually.

  customer_area()

    Get the customer area of the CCU EEPROM.

    Return type:

      `bytes`

    Returns:

      The customer area of the CCU EEPROM.

  cvendor()

    Get the chassis vendor.

    Return type:

      `str`

    Returns:

      The vendor of the chassis.

  unit()

    Get the subsystem unit number.

    Return type:

      `int`

    Returns:

      The unit number of the subsystem.

  property valid: bool

    Checks if the EEPROM content is valid by comparing the stored CRC value with the computed CRC value.

    Returns:

      True if the EEPROM content is valid, False otherwise.

    Return type:

      `bool`

  version()

    Get the version of the EEPROM data scheme.

    Note

    If undefined, the version is set to 255 and then defaults to 0.

    Return type:

      `int`

    Returns:

      The version of the EEPROM data scheme.

  write(data, offset=0)

    Write data to the EEPROM.

    Parameters:

      - data (`bytes`) – The data to write to the EEPROM.

      - offset (`int`) – The offset at which to start writing the data.

    Raises:

      - RuntimeError – If the sysfs device is not found.

      - FileNotFoundError – If the EEPROM sysfs file is not found.

      - DataCorruptionError – If an error occurs during the write operation.

    Return type:

      `None`

    Note

    Operation is checked for data corruption by reading back the written data.

  write_cmodel(model)

    Write the model of the chassis to EEPROM.

    Parameters:

      model (`str`) – The model of the chassis.

    Return type:

      `None`

  write_crevision(revision)

    Write the chassis revision.

    Parameters:

      revision (`str`) – The revision of the chassis.

    Return type:

      `None`

  write_cserial(serial)

    Write the serial number of the chassis to EEPROM.

    Parameters:

      serial (`int`) – The serial number of the chassis.

    Return type:

      `None`

  write_custom_raw_data(data)

    Write custom data to the raw content area of the EEPROM.

    Parameters:

      data (`bytes`) – The data to write to the raw content area of the EEPROM.

    Return type:

      `None`

  write_customer_area(data)

    Write data to CCU EEPROM customer area.

    Return type:

      `None`

    Parameters:

      data (bytes)

  write_cvendor(vendor)

    Write the vendor of the chassis to EEPROM.

    Parameters:

      vendor (`str`) – The vendor of the chassis.

    Return type:

      `None`

  write_unit(unit)

    Write the subsystem unit number.

    Parameters:

      unit (`int`) – The unit number of the subsystem.

    Return type:

      `None`

  write_version(version)

    Write the version of the EEPROM data scheme.

    Parameters:

      version (`int`) – The version of the EEPROM data scheme.

    Return type:

      `None`

class ekfsm.devices.eeprom.EKF_EEPROM(*args, **kwargs)

  Bases: `Validatable_EEPROM`, `ProbeableDevice`

  A class used to represent an EKF EEPROM device.

  #### Structure

  The EKF_EEPROM content is structured as follows:

  - Serial number (4 bytes, starts at pos 8):

      The serial number of the device.

  - Manufactured at (2 bytes, starts at pos 12):

      The date the device was manufactured.

  - Repaired at (2 bytes, starts at pos 14):

      The date the device was repaired.

  - Customer serial number (4 bytes, starts at pos 32):

      The customer serial number of the device.

  - Customer configuration block offset pointer (4 bytes, starts at pos 36):

      The offset pointer to the customer configuration block.

  - String array (78 bytes, starts at pos 48):

      An array of strings containing the model, manufacturer, and custom board data of the device.

  - CRC (2 bytes, starts at pos 126):

      The CRC value of the EEPROM content.

  - Raw content (80 bytes, starts at pos 128):

      Free customizable content for other purposes.

  Note

  - As the CRC value is stored at the end of the OEM data space, just before the customer configuration block, the CRC position is manually set and the `_update_content()` method is overridden.

  - The CRC value is computed using the CRC-16/XMODEM algorithm.

  - Dates are stored in a proprietary format (2 bytes) and must be decoded using the `_decode_date()` method.

  See also

  crcmod

  Important

  All data read from the EEPROM should be validated using the @validated decorator. This decorator ensures that the data is not corrupted by checking the CRC value.

  raises DataCorruptionError:

    If the CRC validation fails.

  classmethod _decode_date(encoded_date)

    Decode a date from a proprietary 2-byte format.

    Parameters:

      encoded_date (`Sequence`[`int`]) – The date to decode.

    Raises:

      ValueError – If the date is invalid (e.g., 30th Feb).

    Returns:

      The decoded date.

    Return type:

      `date`

  classmethod _encode_date(date)

    Encode a date into a proprietary 2-byte format.

    Parameters:

      date (`date`) – The date to encode.

    Returns:

      The encoded date.

    Return type:

      `bytes`

  custom_board_data()

    Get the custom board data of the device.

    Note

    This is a custom field that can be set by the user.

    Attention

    This field is optional and may not be present in the EEPROM content.

    Return type:

      `str` | `None`

    Returns:

      The custom board data of the device as a string, or None if the field is not present.

  custom_raw_data()

    Get the raw content area data stored in the EEPROM.

    Return type:

      `bytes`

    Returns:

      The data contained in the raw content block of the EEPROM.

    Note

    This area is free for custom data storage and is not included during crc calculations and validations.

    Important

    If custom raw data should be stored on EEPROM and if it should be protected against corruption, it has to be validated manually.

  custom_serial()

    Get the customer serial number of the device to which the EEPROM is attached (the root device).

    Attention

    This is a custom - non-OEM - serial number that can be set by the user.

    Return type:

      `str`

    Returns:

      The customer serial number of the root device.

  manufactured_at()

    Get the date the device was manufactured.

    Return type:

      `date`

    Returns:

      The date the device was manufactured.

  model()

    Get the model name of the device to which the EEPROM is attached to (the root device).

    Return type:

      `str` | `None`

    Returns:

      The model name of the device.

  probe(*args, **kwargs)

    Probe the hardware device to check if it is present and if it is the correct device.

  repaired_at()

    Get the date the device was repaired.

    Return type:

      `date`

    Returns:

      The most recent date the device was repaired.

  serial()

    Get the serial number of the device to which the EEPROM is attached (the root device).

    Return type:

      `str`

    Returns:

      The serial number of the root device.

  vendor()

    Get the vendor/manufacturer of the device to which the EEPROM is attached to (the root device).

    Return type:

      `str` | `None`

    Returns:

      The name of the vendor/manufacturer of the device.

  write_custom_board_data(data)

    Write custom board data to EEPROM.

    Important

    Due to size limitations, the custom board data should only contain expressive, short content like serials, variants or specific codes.

    Parameters:

      data (`str`) – The custom board data to write to the EEPROM.

    Return type:

      `None`

    Attention

    The model and vendor fields are mandatory and must be set before writing custom board data.

    Raises:

      ValueError – If the model and vendor fields are not set before writing custom board data.

    Parameters:

      data (str)

    Return type:

      None

  write_custom_raw_data(data)

    Write custom data to the raw content area of the EEPROM.

    Parameters:

      data (`bytes`) – The data to write to the raw content area of the EEPROM.

    Return type:

      `None`

  write_custom_serial(serial)

    Write customer serial number of the root device to EEPROM.

    Parameters:

      serial (`int`) – The customer serial number to write to the EEPROM.

    Raises:

      ValueError – If the serial number is not within the bounds of a 32-bit unsigned integer.

    Return type:

      `None`

    Note

    Due to space restrictions on storage, the serial number must be a 32-bit unsigned integer.

  write_repaired_at(date)

    Write the date the device was repaired to EEPROM.

    Parameters:

      date (`date`) – The date the device was repaired.

    Return type:

      `None`

    Note

    The date year must be within the range of 1980-2079.

    Attention

    The date is stored in a proprietary 2-byte format.

    Raises:

      ValueError – If the year is not within the range of 1980-2079.

    Parameters:

      date (date)

    Return type:

      None

  write_serial(serial)

    Write serial number of the root device to EEPROM.

    Parameters:

      serial (`int`) – The serial number to write to the EEPROM.

    Return type:

      `None`

class ekfsm.devices.eeprom.Validatable_EEPROM(crc_pos='end', crc_length=2, *args, **kwargs)

  Bases: `EEPROM`, `ABC`

  Abstract class used to represent an EEPROM device using CRC to validate its content.

  Parameters:

    - crc_pos (`Literal`[`'start'`, `'end'`]) – The position of the CRC value in the EEPROM content (‘start’ or ‘end’).

    - crc_length (`int`) – The length of the CRC value in number of bytes (defaults to 2).

  Note

  - Derived classes must implement a method to compute the CRC value of the EEPROM content.

  - If the CRC position differs from the shipped schema (‘start’ | ‘end’), the derived class must override the `_update_content()` method.

  - Validity of individual content fields stored/returned by attributes, methods or properties can be achieved by using the `validated()` decorator.

  See also

  `Validatable_EEPROM._compute_crc`

    Method to compute the CRC value of the EEPROM content.

  abstract _compute_crc()

    This method should be implemented by derived classes to compute the CRC value of the EEPROM content.

    Return type:

      `int`

    Returns:

      The computed CRC value.

  _update_content()

    Update the content of the EEPROM device (checksum excluded).

    Return type:

      `None`

  _update_crc()

    Update the CRC value of the EEPROM content.

    Return type:

      `None`

  property crc: int

    Gets or sets the CRC value of the EEPROM content.

    Parameters:

      value (optional) – The CRC value to write to the EEPROM.

    Returns:

      - `int` – The CRC value currently stored in the EEPROM if used as getter.

      - `None` – If used as setter.

    Caution

    The setter actually writes the CRC value to the EEPROM.

    Warning

    The setter method should be used with caution as it can lead to data corruption if the CRC value is not correct!

    Note

    The setter is usually triggered automatically after a successful write operation and in most cases, there is no need to call it manually.

  property valid: bool

    Checks if the EEPROM content is valid by comparing the stored CRC value with the computed CRC value.

    Returns:

      True if the EEPROM content is valid, False otherwise.

    Return type:

      `bool`

  write(data, offset=0)

    Write data to the EEPROM.

    Parameters:

      - data (`bytes`) – The data to write to the EEPROM.

      - offset (`int`) – The offset at which to start writing the data.

    Raises:

      - RuntimeError – If the sysfs device is not found.

      - FileNotFoundError – If the EEPROM sysfs file is not found.

      - DataCorruptionError – If an error occurs during the write operation.

    Return type:

      `None`

    Note

    Operation is checked for data corruption by reading back the written data.

ekfsm.devices.eeprom.validated(func)

  A decorator to validate the CRC of the EEPROM content before executing a method.

  Parameters:

    func (`Callable`[`...`, `Any`]) – The method to validate.

  Return type:

    `Callable`[`...`, `Any`]

  Note

  This decorator should be used on methods that read data from an EEPROM.

### GPIO

class ekfsm.devices.gpio.EKFIdSimGpio(coding_gnd, coding_vcc, coding_6, coding_7)

  Bases: `SimGpio`

  get_pin(pin)
    Return type:

      `bool`

    Parameters:

      pin (int)

  num_lines()
    Return type:

      `int`

  set_direction(pin, direction)
    Return type:

      `None`

    Parameters:

      - pin (int)

      - direction (bool)

  set_pin(pin, value)
    Return type:

      `None`

    Parameters:

      - pin (int)

      - value (bool)

class ekfsm.devices.gpio.EKFIdentificationIOExpander(name, parent, *args, **kwargs)

  Bases: `GPIOExpander`, `ProbeableDevice`

  Parameters:

    - name (str)

    - parent (SysTree | None)

  static _get_board_rev(bits)

    Convert 2-bit sum values to board revision number.

    Return type:

      `int`

    Parameters:

      bits (list[int])

  probe(*args, **kwargs)

    Probe the hardware device to check if it is present and if it is the correct device.

    Return type:

      `bool`

  read_board_id_rev()
    Return type:

      `tuple`[`int`, `int`]

  read_id_gpio_inputs()
    Return type:

      `int`

  revision()
    Return type:

      `str`

class ekfsm.devices.gpio.GPIO(name, parent=None, *args, **kwargs)

  Bases: `Device`

  Parameters:

    - name (str)

    - parent (SysTree | None)

  get_lines(lines)
    Parameters:

      lines (list[int])

  get_pin(pin)

    Get the value of a GPIO pin.

    Parameters:

      pin (`int`) – The pin number.

    Returns:

      The value of the pin.

    Return type:

      `bool`

  init_dev()
  num_lines()

    Get number of GPIO lines available on the device.

    Return type:

      `int`

  set_direction(pin, direction)

    Set the direction of a GPIO pin.

    Parameters:

      - pin (`int`) – The pin number.

      - direction (`bool`) – The direction to set. True for output, False for input.

    Return type:

      `None`

  set_pin(pin, value)

    Set the value of a GPIO pin.

    Parameters:

      - pin (`int`) – The pin number.

      - value (`bool`) – The value to set.

    Return type:

      `None`

class ekfsm.devices.gpio.GPIOExpander(name, parent, *args, **kwargs)

  Bases: `GPIO`

  Parameters:

    - name (str)

    - parent (SysTree | None)

class ekfsm.devices.gpio.SimGpio

  Bases: `ABC`

  abstract get_pin(pin)
    Return type:

      `bool`

    Parameters:

      pin (int)

  abstract num_lines()
    Return type:

      `int`

  abstract set_direction(pin, direction)
    Return type:

      `None`

    Parameters:

      - pin (int)

      - direction (bool)

  abstract set_pin(pin, value)
    Return type:

      `None`

    Parameters:

      - pin (int)

      - value (bool)

ekfsm.devices.gpio.find_gpio_dev_with_major_minor(major, minor)
  Return type:

    `Path` | `None`

  Parameters:

    - major (int)

    - minor (int)

ekfsm.devices.gpio.get_gpio_major_minor(path)
  Return type:

    `tuple`[`int`, `int`]

  Parameters:

    path (Path)

### EKF SUR LED

class ekfsm.devices.ekf_sur_led.EKFSurLed(name, parent, *args, **kwargs)

  Bases: `GPIOExpander`

  A class to represent the EKF-SUR-LED devices.

  Parameters:

    - name (str)

    - parent (SysTree | None)

  set(led, color)

    Set the color of a LED.

    Parameters:

      - led (`int`) – The LED number (0 or 1).

      - color (`str`) – The color of the LED. Possible values: “off”, “red”, “blue”, “green”, “yellow”, “purple”, “cyan”, “white”

### PMBUS

class ekfsm.devices.pmbus.PmBus(name, parent=None, children=None, *args, **kwargs)

  Bases: `Device`, `ProbeableDevice`

  This class represents a PMBus device (e.g. a PSU).

  Parameters:

    - name (str)

    - parent (SysTree | None)

    - children (list[Device] | None)

  curr1_input()

    Get input current of PSU page 1.

    Return type:

      `float`

    Returns:

      Input current in amperes

  curr2_input()

    Get input current of PSU page 2.

    Return type:

      `float`

    Returns:

      Input current in amperes

  in1_input()

    Get input voltage of PSU page 1.

    Return type:

      `float`

    Returns:

      Input voltage in volts

  in2_input()

    Get input voltage of PSU page 2.

    Return type:

      `float`

    Returns:

      Input voltage in volts

  model()

    Get the model of the PSU.

    Return type:

      `str`

    Returns:

      PSU model

  probe(*args, **kwargs)

    Probe the hardware device to check if it is present and if it is the correct device.

    Return type:

      `bool`

  revision()

    Get the revision of the PSU.

    Return type:

      `str`

    Returns:

      PSU revision

  serial()

    Get the serial number of the PSU.

    Return type:

      `str`

    Returns:

      PSU serial number

  status0_input()

    Get the status of PSU page 1.

    Return type:

      `PsuStatus`

    Returns:

      PSU status as defined in PsuStatus

  status1_input()

    Get the status of PSU page 2.

    Return type:

      `PsuStatus`

    Returns:

      PSU status as defined in PsuStatus

  temp1_input()

    Get the PSU temperature.

    Return type:

      `float`

    Returns:

      PSU temperature in degrees celsius

  vendor()

    Get the vendor of the PSU.

    Return type:

      `str`

    Returns:

      PSU vendor

class ekfsm.devices.pmbus.PsuStatus(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

  Bases: `IntFlag`

  Represents the status of a PSU according to STATUS_BYTE register.

  See also

  External Documentation: PMBus Power System Management Protocol Specification - Part II - Revision 1.4, Fig. 60

  Example

      >>> from ekfsm.devices.pmbus import PsuStatus
      >>> status = PsuStatus(0x1F)
      >>> status
      <PsuStatus.OUTPUT_OVERCURRENT|INPUT_UNDERVOLTAGE|TEMP_ANORMALY|COMMUNICATION_ERROR|ERROR: 31>
      >>> PsuStatus.OUTPUT_OVERCURRENT in status
      True
      >>> # OK is always present
      >>> PsuStatus.OK in status
      True
      >>> # Instead, check if status is OK
      >>> status = PsuStatus(0x00)
      >>> status
      <PsuStatus.OK: 0>
      >>> PsuStatus.OUTPUT_OVERCURRENT in status
      False

  COMMUNICATION_ERROR = 2
  ERROR = 1
  INPUT_UNDERVOLTAGE = 8
  OK = 0
  OUTPUT_OVERCURRENT = 16
  OUTPUT_OVERVOLTAGE = 32
  TEMP_ANORMALY = 4
  static _generate_next_value_(name, start, count, last_values)

    Generate the next value when not given.

    name: the name of the member start: the initial start value or None count: the number of existing members last_values: the last value assigned or None

  classmethod _iter_member_(value)

    Extract all members from the value in definition order.

ekfsm.devices.pmbus.retry(max_attempts=5, delay=0.5)

  Retry decorator.

  Decorator that retries a function a number of times before giving up.

  This is useful for functions that may fail due to transient errors.

  Note

  This is needed for certain PMBus commands that may fail due to transient errors because page switching timing is not effectively handled by older kernel versions.

  Important

  This decorator is thread-safe, meaning a read attempt is atomic and cannot be interupted by scheduler.

  Parameters:

    - max_attempts – The maximum number of attempts before giving up.

    - delay – The delay in seconds between attempts.

### IIO Thermal and Humidity Sensor

class ekfsm.devices.iio_thermal_humidity.IIOThermalHumidity(name, parent=None, children=None, *args, **kwargs)

  Bases: `Device`

  Device for IIO thermal and/or humidity sensors.

  Parameters:

    - name (`str`) – The name of the device.

    - parent (`SysTree` | `None`) – The parent device of the IIOThermalHumidity device. If None, no parent is created.

    - children (`list`[`Device`] | `None`) – The children of the IIOThermalHumidity device. If None, no children are created.

  humidity()
    Return type:

      `float`

  temperature()
    Return type:

      `float`

### I2C MUX

class ekfsm.devices.mux.I2CMux(name, parent=None, children=None, *args, **kwargs)

  Bases: `Device`

  This class represents an I2C multiplexer device.

  Parameters:

    - name (`str`) – The name of the device.

    - parent (`SysTree` | `None`) – The parent device of the I2CMux device. If None, no parent is created.

    - children (`list`[`MuxChannel`] | `None`) – The children of the I2CMux device. If None, no children are created.

class ekfsm.devices.mux.MuxChannel(name, channel_id, parent, children=None, *args, **kwargs)

  Bases: `Device`

  A MuxChannel is a device that represents a channel on an I2C multiplexer. It is a child of the I2CMux device. The MuxChannel device is used to access the I2C bus on the channel.

  Parameters:

    - name (`str`) – The name of the device.

    - channel_id (`int`) – The channel ID of the device.

    - parent (`I2CMux`) – The parent device of the MuxChannel.

    - children (`list`[`Device`] | `None`) – The children of the MuxChannel device. If None, no children are created.

## I2C Devices using SMBus directly

### EKF CCU Microcontroller

class ekfsm.devices.ekf_ccu_uc.CcuCommands(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

  Bases: `Enum`

  CCU_HUMIDITY = 20
  CCU_TEMPERATURE = 19
  FAN_STATUS = 17
  GET_PARAMETERSET_BEGIN = 132
  GET_PARAMETERSET_FOLLOW = 133
  IDENTIFY_FIRMWARE_TITLE = 128
  IDENTIFY_FIRMWARE_VERSION = 129
  IMU_SAMPLES = 16
  LOAD_FIRMWARE_CHUNK = 130
  LOAD_PARAMETERSET = 131
  NOP = 1
  PUSH_TEMPERATURE = 21
  RESTART = 143
  SW_SHUTDOWN = 22
  VIN_VOLTAGE = 18
  WD_TRIGGER = 23

class ekfsm.devices.ekf_ccu_uc.EKFCcuUc(name, parent, *args, **kwargs)

  Bases: `Device`

  A class to communicate with I2C microcontroller on the EKF CCU.

  Parameters:

    - name (str)

    - parent (SysTree | None)

  fan_status(fan)

    Get the status of a fan.

    Parameters:

      fan (`int`) – The fan number (0-2).

    Return type:

      `Tuple`[`float`, `float`, `int`]

    Returns:

      - desired (`float`) – The desired speed.

      - actual (`float`) – The actual speed.

      - diag (`int`) – The diagnostic value.

    Note

    The diagnostic value is a bitfield with the following meaning:

    > - bit 0: 0 = fan status is invalid, 1 = fan status is valid

    > - bit 1: 0 = no error detected, 1 = fan is stuck

  get_parameterset()

    Get the CCU parameterset in JSON format.

    A typical parameterset looks like this:

        {
            "version":      "factory",
            "parameters":   {
                    "num-fans":     "2",
                    "fan-temp2rpm": "25:2800;50:5000;100:6700",
                    "fan-rpm2duty": "2800:55;5000:88;6700:100",
                    "fan-defrpm":   "5500",
                    "fan-ppr":      "2",
                    "fan-push-tout":        "4000",
                    "pon-min-temp": "-25",
                    "pon-max-temp": "70",
                    "shutdn-delay": "120",
                    "wd-tout":      "0",
                    "pwrcycle-time":        "10"
            },
            "unsupported_parameters":       [],
            "missing_parameters":   ["num-fans", "fan-temp2rpm", "fan-rpm2duty", "fan-defrpm", "fan-ppr",                     "fan-push-tout", "pon-min-temp", "pon-max-temp", "shutdn-delay", "wd-tout", "pwrcycle-time"],
            "invalid_parameters":   [],
            "reboot_required":      false
        }

    version is the version of the parameterset. If no parameterset has been loaded by the user, the version is factory, otherwise it is the version of the loaded parameterset.

    parameters contains the current values of all parameters of the parameterset.

    unsupported_parameters contains the names of parameters that might have been downloaded, but are not supported by the CCU firmware.

    missing_parameters contains the names of parameters that have not been downloaded yet. Those parameters will have their default values.

    invalid_parameters contains the names of parameters that have been downloaded, but have invalid values. Those parameters will have their default values.

    reboot_required is a flag that indicates if a reboot is required to apply the parameterset.

    Returns:

      The parameterset in JSON format.

    Return type:

      `str`

  humidity()

    Get the relative humidity from the CCU thermal/humidity sensor. The humidity is read once per second.

    Returns:

      The relative humidity in percent.

    Return type:

      `float`

    Raises:

      AcquisitionError – If the humidity cannot be read, for example, because the sensor is not working.

  identify_firmware()

    Get the firmware title and version of the CCU.

    Return type:

      `Tuple`[`str`, `str`]

    Returns:

      - title (`str`) – The firmware title.

      - version (`str`) – The firmware version.

  imu_sample()

    Read the next IMU sample from the CCU’s IMU sample FIFO.

    If no sample is available, this method returns None. The second return value indicates if more samples are available in the FIFO.

    The CCU periodically samples the accelerometer and gyroscope data from the IMU and places it into a FIFO of 256 entries. Application must periodically read the samples from the FIFO to avoid overflow.

    FIFO overflow is indicated in the sample by the lost attribute.

    Note that the x, y, and z axes of the accelerometer and gyroscope are aligned to the mounting of the IMU on the CCU board. Please correct the axes if necessary to match the orientation of the IMU in your application.

    Return type:

      `Tuple`[`ImuSample` | `None`, `bool`]

    Returns:

      - imu_data (`ImuSample | None`) – The IMU sample, or None if no sample is available.

      - more_samples (`bool`) – True if more samples are available in the FIFO, False otherwise.

  load_firmware(firmware, progress_callback=None)

    Load firmware into the CCU.

    The firmware must be the binary firmware file containing the application partition, typically named fw-ccu-mm-default.bin, where mm is the major version of the CCU hardware.

    The download can take several minutes, that is why a progress callback can be provided.

    When the download is complete and successful, the CCU will restart. To check if the firmware was loaded successfully, call `identify_firmware()` after the restart.

    Parameters:

      - firmware (`bytes`) – The firmware binary data.

      - progress_callback – A callback function that is called with the current progress in bytes.

    Return type:

      `None`

  load_parameterset(_cfg)

    Load a parameterset into the CCU.

    The parameterset must be a JSON string containing the parameterset, for example:

        {
            "version": "1.0.0",
            "parameters":   {
                "fan-defrpm": "6000"
            }
        }

    This would load a parameterset with just one parameter, the default fan speed. All other parameters will be set to their default values.

    In order to apply the parameterset, the CCU must be restarted.

    Parameters:

      _cfg (`str`) – The parameterset in JSON format.

    Return type:

      `None`

  push_temperature(fan, temp)

    Tell FAN controller the external temperature, usually the CPU temperature.

    Parameters:

      - fan (`int`) – The fan number (0-2), or -1 to set the external temperature of all fans.

      - temp (`float`) – The external temperature in degrees Celsius.

    Return type:

      `None`

    Important

    If push_temperature is no more called for a certain time (configurable with fan-push-tout parameter), the fan controller will fallback to it’s default fan speed (configurable with the fan-defrpm parameter).

  restart()

    Restart the CCU.

    Return type:

      `None`

  sw_shutdown()

    Tell CCU that the system is going to shutdown. This cause the CCU’s system state controller to enter shutdown state and power off the system after a certain time (parameter shutdn-delay).

    Return type:

      `None`

  temperature()

    Get the temperature from the CCU thermal/humidity sensor. The temperature is read once per second.

    Returns:

      The temperature in degrees Celsius.

    Return type:

      `float`

    Raises:

      AcquisitionError – If the temperature cannot be read, for example, because the sensor is not working.

  vin_voltage()

    Get the system input voltage from the CCU (the pimary voltage of the PSU). The voltage is read every 100ms.

    Returns:

      The system input voltage in volts.

    Return type:

      `float`

    Raises:

      AcquisitionError – If the voltage cannot be read, for example, because the ADC is not working.

  wd_trigger()

    Trigger the CCU’s application watchdog. This will reset the watchdog timer.

    The CCU watchdog is only enabled when the parameter wd-tout is set to a value greater than 0. Triggering the watchdog when the timeout is 0 will have no effect.

    If the watchdog is not reset within the timeout, the CCU will power cycle the system.

    Return type:

      `None`

## Devices using SysFs

### CoreTemp

class ekfsm.devices.coretemp.CoreTemp(name, parent, *args, **kwargs)

  Bases: `Device`

  This class provides an interface to read the CPU core temperature from the HWMON device.

  Note: Currently, only the average temperature over all cores is read from the HWMON device.

  Parameters:

    - name (str)

    - parent (Device)

  cputemp()

    Get the CPU temperature from the HWMON device.

    Returns:

      The CPU temperature in degrees Celsius.

    Return type:

      `int`

ekfsm.devices.coretemp.find_core_temp_dir(hwmon_dir)

  Find the directory containing the coretemp hwmon device.

  Return type:

    `Path`

  Args:

    hwmon_dir: Path to the hwmon directory

  Returns:

    Path to the directory containing the coretemp hwmon device

  Raises:

    FileNotFoundError: If no coretemp directory is found

### SMBIOS

class ekfsm.devices.smbios.SMBIOS(name, parent=None, *args, **kwargs)

  Bases: `Device`

  A class to represent the SMBIOS device.

  A SMBIOS device is a virtual device that is used to read system configuration values from the DMI table.

  Note: Currently, only the board version / revision is read from the DMI table.

  Parameters:

    - name (str)

    - parent (HwModule | None)

  revision()

    Get the board revision from the DMI table.

    Returns:

      The board revision.

    Return type:

      `str`

## Base Classes and Utilities

class ekfsm.devices.generic.Device(name, parent=None, children=None, abort=False, *args, **kwargs)

  Bases: `SysTree`

  A generic device.

  Parameters:

    - name (str)

    - parent (SysTree | None)

    - children (list[Device] | None)

    - abort (bool)

  get_i2c_bus_number()

    Get the I2C bus number of the device. Works for devices that do not have a sysfs_device attribute.

    Return type:

      `int`

  get_i2c_chip_addr()
    Return type:

      `int`

  get_i2c_sysfs_device(addr)
    Return type:

      `SysFSDevice`

    Parameters:

      addr (int)

  property hw_module: HwModule

    Get or set the HwModule instance that this device belongs to.

    Parameters:

      hw_module (optional) – The HwModule instance to set.

    Returns:

      - `HwModule` – The HwModule instance that this device belongs to.

      - `None` – If used as a setter.

  read_sysfs_attr_bytes(attr)

    Read a sysfs attribute as bytes.

    Parameters:

      attr (`str`) – The sysfs attribute to read.

    Return type:

      `bytes` | `None`

    Returns:

      - content (`bytes`) – The contents of the sysfs attribute as bytes.

      - `None` – If the sysfs device is not set or the attribute does not exist.

  read_sysfs_attr_utf8(attr)

    Read a sysfs attribute as UTF-8 string.

    Parameters:

      attr (`str`) – The sysfs attribute to read.

    Return type:

      `str` | `None`

    Returns:

      - content (`str`) – The contents of the sysfs attribute as UTF-8 string.

      - `None` – If the sysfs device is not set or the attribute does not exist.

  write_sysfs_attr(attr, data)

    Write data to a sysfs attribute.

    Parameters:

      - attr (`str`) – The sysfs attribute to write to.

      - data (`str` | `bytes`) – The data to write to the sysfs attribute.

    Return type:

      `None`

ekfsm.devices.utils.compute_int_from_bytes(data)
  Return type:

    `int`

  Parameters:

    data (Sequence[int])

ekfsm.devices.utils.get_crc16_xmodem(data)
  Return type:

    `int`

  Parameters:

    data (bytes)

ekfsm.devices.iio.iio_get_in_value(dev, attrset)

  Calculate a value from an IIO in_* attribute set, using the _raw, _scale and _offset attributes (if present). Typical name of attrset are “in_temp” or “in_voltage0”.

  Formula according to https://wiki.st.com/stm32mpu/wiki/How_to_use_the_IIO_user_space_interface

  Parameters:

    - dev (`SysFSDevice`) – sysfs device object pointing to the iio directory

    - attrset (`str`) – name of the attribute set to read from (e.g. “in_temp”)

  Returns:

    calculated value from the attribute set (no unit conversion)

  Return type:

    `float`

  Raises:

    FileNotFoundError – if the neiter _input nor _raw attribute is found

class ekfsm.devices.imu.ImuSample(accel, gyro, lost)

  Bases: `object`

  Class to store IMU data sample

  Parameters:

    - accel (`list`[`float`]) – Accelerometer data in m/s^2, [x, y, z]

    - gyro (`list`[`float`]) – Gyroscope data in degrees/s, [x, y, z]

    - lost (`bool`) – True if data was lost before that sample

# ekfsm.core package

class ekfsm.core.components.HwModule(instance_name, config, slot, abort=False, *args, **kwargs)

  Bases: `SysTree`

  A HwModule represents an instantiation of a specifc hw board type, for example an instance of an EKF SC9 board.

  Parameters:

    - instance_name (str)

    - config (dict)

    - slot (Slot)

    - abort (bool)

  info()

    Returns a dictionary with information about the hardware module.

    Return type:

      `dict`[`str`, `Any`]

  property instance_name: str
  property is_master: bool
  probe(*args, **kwargs)
    Return type:

      `bool`

  property slot: Slot

class ekfsm.core.components.SysTree(name, abort=False)

  Bases: `NodeMixin`

  Base class for all system components including Hardware Modules and Devices.

  Parameters:

    - name (str)

    - abort (bool)

  print()
    Return type:

      `None`

class ekfsm.core.probe.ProbeableDevice

  Bases: `ABC`

  abstract probe(*args, **kwargs)

    Probe the hardware device to check if it is present and if it is the correct device.

    Return type:

      `bool`

class ekfsm.core.slots.Slot(name, slot_type, desired_hwmodule_type, desired_hwmodule_name, number, hwmodule=None, master=None, attributes=None)

  Bases: `object`

  A slot represents a physical slot in a chassis.

  Parameters:

    - name (`str`) – The name of the slot, e.g. “SlotA” or “CPCI-SYSTEMSLOT”

    - slot_type (`SlotType`) – The type of the slot, e.g. SlotType.CPCI_S0_SYS

    - desired_hwmodule_type (`str`) – The desired type of the hardware module that should be in the slot (currently unused)

    - desired_hwmodule_name (`str`) – The name to be used for the hardware module instance in the slot. (currently unused)

    - master (`HwModule` | `None`) – The master board of the system

    - hwmodule (`HwModule` | `None`) – The hardware module that is in the slot

    - number (`int`) – The number of the slot

    - attributes (`Munch` | `None`) – Additional attributes

  info()

    Returns a dictionary with information about the slot. :rtype: `dict`[`str`, `Any`]

    - 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 type:

      dict[str, Any]

  property is_correctly_populated: bool

    Return True if the slot is populated with the desired hardware module type, False otherwise.

  property is_populated: bool

    Return True if the slot is populated, False otherwise.

  property name: str

    Return the name of the slot.

class ekfsm.core.slots.SlotType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

  Bases: `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_PER = 3
  CPCI_S0_PSU = 4
  CPCI_S0_SYS = 2
  CPCI_S0_UTILITY = 1
  classmethod from_string(name)
    Return type:

      `SlotType`

    Parameters:

      name (str)

  to_string()
    Return type:

      `str`

class ekfsm.core.slots.Slots(*args, **kwargs)

  Bases: `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

  add(slot)

    Add a Slot object to the collection, where the name of the slot object is used as the key.

    Return type:

      `None`

    Parameters:

      slot (Slot)

    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"]

class ekfsm.core.sysfs.SysFSAttribute(path)

  Bases: `object`

  A SysFSAttribute is a singular sysfs attribute located somewhere in /sys.

  Parameters:

    path (Path)

  path

    Path to the underlying file for the SysFSAttribute instance.

  is_sysfs_attr()
    Return type:

      `bool`

  read_bytes()
    Return type:

      `bytes`

  read_utf8()
    Return type:

      `str`

  write(data, offset=0)
    Return type:

      `None`

    Parameters:

      - data (str | bytes | None)

      - offset (int)

class ekfsm.core.sysfs.SysFSDevice(base_dir)

  Bases: `object`

  Parameters:

    base_dir (Path)

  post()
    Return type:

      `None`

  pre()
    Return type:

      `None`

  read_attr_bytes(attr)
    Return type:

      `bytes`

    Parameters:

      attr (str)

  read_attr_utf8(attr)
    Return type:

      `str`

    Parameters:

      attr (str)

  write_attr(attr, data, offset=0)
    Return type:

      `None`

    Parameters:

      - attr (str)

      - data (str | bytes)

      - offset (int)

ekfsm.core.sysfs.file_is_sysfs_attr(path)
  Return type:

    `bool`

  Parameters:

    path (Path)

ekfsm.core.sysfs.list_sysfs_attributes(path)
  Return type:

    `list`[`SysFSAttribute`]

  Parameters:

    path (Path)

ekfsm.core.sysfs.set_sysfs_root(path)
  Return type:

    `None`

  Parameters:

    path (Path)

ekfsm.core.sysfs.sysfs_root()
  Return type:

    `Path`

class ekfsm.core.utils.BoardDictImporter(nodecls=<class 'anytree.node.anynode.AnyNode'>)

  Bases: `object`

  import_(logger, data, parent=None, abort=False)

    Import tree from data.

    Parameters:

      - logger (Logger)

      - abort (bool)

ekfsm.core.utils.deserialize_hardware_tree(logger, data, parent)
  Return type:

    `tuple`[`str`, `str`, `str`, `list`[`Device`]]

  Parameters:

    - logger (Logger)

    - data (dict)

    - parent (HwModule)