ekfsm 0.11.0b1.post3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ekfsm might be problematic. Click here for more details.

ekfsm/__init__.py ADDED
@@ -0,0 +1,13 @@
1
+ from .core.slots import Slot
2
+ from .system import System
3
+ from .core import HwModule
4
+ from .core.slots import SlotType
5
+ from .exceptions import ConfigError
6
+
7
+ __all__ = (
8
+ "System",
9
+ "ConfigError",
10
+ "HwModule",
11
+ "Slot",
12
+ "SlotType",
13
+ )
@@ -0,0 +1,68 @@
1
+ id: 206
2
+ name: "EKF CCU"
3
+ slot_type: CPCI_S0_UTILITY
4
+ children:
5
+ - device_type: I2CMux
6
+ name: "MUX"
7
+ addr: 0x70
8
+ slot_coding_mask: 0x07
9
+ children:
10
+ - device_type: MuxChannel
11
+ name: "CH00"
12
+ channel_id: 0
13
+ children:
14
+ - device_type: EKFIdentificationIOExpander
15
+ name: "GPIO"
16
+ addr: 0x3D
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: EKF_CCU_EEPROM
21
+ name: "EEPROM"
22
+ addr: 0x55
23
+ provides:
24
+ inventory:
25
+ - vendor
26
+ - serial
27
+ - model
28
+ - repaired_at
29
+ - manufactured_at
30
+ chassis_inventory:
31
+ - revision: crevision
32
+ - write_revision: write_crevision
33
+ - vendor: cvendor
34
+ - write_vendor: write_cvendor
35
+ - serial: cserial
36
+ - write_serial: write_cserial
37
+ - model: cmodel
38
+ - write_model: write_cmodel
39
+ - unit
40
+ - write_unit
41
+ custom_eeprom:
42
+ - write: write_customer_area
43
+ - read: customer_area
44
+ - device_type: MuxChannel
45
+ name: "CH01"
46
+ channel_id: 1
47
+ children:
48
+ - device_type: EKFCcuUc
49
+ name: "UC"
50
+ addr: 0x28
51
+ provides:
52
+ management:
53
+ - identify_firmware
54
+ - load_firmware
55
+ - load_parameterset
56
+ - get_parameterset
57
+ - restart
58
+ vin:
59
+ - voltage: vin_voltage
60
+ th:
61
+ - temperature
62
+ - humidity
63
+ fan:
64
+ - fan_status
65
+ - push_temperature
66
+ sysstate:
67
+ - wd_trigger
68
+ - sw_shutdown
@@ -0,0 +1,30 @@
1
+ id: "SC5-FESTIVAL"
2
+ name: "EKF SC5-Festival"
3
+ slot_type: CPCI_S0_SYS
4
+ children:
5
+ - device_type: EKF_EEPROM
6
+ name: "EEPROM"
7
+ addr: 0x57
8
+ provides:
9
+ inventory:
10
+ - vendor
11
+ - serial
12
+ - model
13
+ - repaired_at
14
+ - manufactured_at
15
+ - device_type: SMBIOS
16
+ name: "SMBIOS"
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: HWMON
21
+ name: "HWMON"
22
+ provides:
23
+ th:
24
+ - cputemp
25
+ bus_masters:
26
+ i2c:
27
+ CPCI_S0_PSU: "devices/pci0000:00/0000:00:15.1/i2c_designware.1"
28
+ CPCI_S0_PER: "devices/pci0000:00/0000:00:15.1/i2c_designware.1"
29
+ CPCI_S0_UTILITY: "devices/pci0000:00/0000:00:15.1/i2c_designware.1"
30
+ MASTER_LOCAL_DEFAULT: "devices/pci0000:00/0000:00:1f.4"
@@ -0,0 +1,31 @@
1
+ id: "SC9-TOCCATA"
2
+ name: "EKF SC9-TOCCATA"
3
+ slot_type: CPCI_S0_SYS
4
+ children:
5
+ - device_type: EKF_EEPROM
6
+ name: "EEPROM"
7
+ addr: 0x57
8
+ provides:
9
+ inventory:
10
+ - vendor
11
+ - serial
12
+ - model
13
+ - repaired_at
14
+ - manufactured_at
15
+ - device_type: SMBIOS
16
+ name: "SMBIOS"
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: HWMON
21
+ name: "HWMON"
22
+ provides:
23
+ th:
24
+ - cputemp
25
+
26
+ bus_masters:
27
+ i2c:
28
+ CPCI_S0_PSU: "devices/pci0000:00/0000:00:15.1/i2c_designware.2"
29
+ CPCI_S0_PER: "devices/pci0000:00/0000:00:15.1/i2c_designware.2"
30
+ CPCI_S0_UTILITY: "devices/pci0000:00/0000:00:15.1/i2c_designware.2"
31
+ MASTER_LOCAL_DEFAULT: "devices/pci0000:00/0000:00:1f.4"
@@ -0,0 +1,68 @@
1
+ id: 62
2
+ name: "EKF SPV-MYSTIC"
3
+ slot_type: CPCI_S0_PER
4
+ children:
5
+ - device_type: I2CMux
6
+ name: "MUX"
7
+ addr: 0x70
8
+ slot_coding_mask: 0x07
9
+ children:
10
+ - device_type: MuxChannel
11
+ name: "CH00"
12
+ channel_id: 0
13
+ children:
14
+ - device_type: EKFIdentificationIOExpander
15
+ name: "GPIO"
16
+ addr: 0x3D
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: EKF_EEPROM
21
+ name: "EEPROM"
22
+ addr: 0x55
23
+ provides:
24
+ inventory:
25
+ - vendor
26
+ - serial
27
+ - model
28
+ - repaired_at
29
+ - manufactured_at
30
+ - device_type: MuxChannel
31
+ name: "CH01"
32
+ channel_id: 1
33
+ children:
34
+ - device_type: GPIO
35
+ name: "GPIO"
36
+ addr: 0x3D
37
+ provides:
38
+ gpio0:
39
+ - num_lines
40
+ - set_pin
41
+ - get_pin
42
+ - set_direction
43
+ - device_type: MuxChannel
44
+ name: "CH02"
45
+ channel_id: 2
46
+ children:
47
+ - device_type: GPIO
48
+ name: "GPIO"
49
+ addr: 0x3D
50
+ provides:
51
+ gpio1:
52
+ - num_lines
53
+ - set_pin
54
+ - get_pin
55
+ - set_direction
56
+ - device_type: MuxChannel
57
+ name: "CH03"
58
+ channel_id: 3
59
+ children:
60
+ - device_type: GPIO
61
+ name: "GPIO"
62
+ addr: 0x3D
63
+ provides:
64
+ gpio2:
65
+ - num_lines
66
+ - set_pin
67
+ - get_pin
68
+ - set_direction
@@ -0,0 +1,41 @@
1
+ id: 68
2
+ name: "EKF SQ1-TRACK"
3
+ slot_type: CPCI_S0_PER
4
+ children:
5
+ - device_type: I2CMux
6
+ name: "MUX"
7
+ addr: 0x70
8
+ slot_coding_mask: 0x07
9
+ children:
10
+ - device_type: MuxChannel
11
+ name: "CH00"
12
+ channel_id: 0
13
+ children:
14
+ - device_type: EKFIdentificationIOExpander
15
+ name: "GPIO"
16
+ addr: 0x3D
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: EKF_EEPROM
21
+ name: "EEPROM"
22
+ addr: 0x55
23
+ provides:
24
+ inventory:
25
+ - vendor
26
+ - serial
27
+ - model
28
+ - repaired_at
29
+ - manufactured_at
30
+ - device_type: MuxChannel
31
+ name: "CH01"
32
+ channel_id: 1
33
+ children:
34
+ - device_type: MuxChannel
35
+ name: "CH02"
36
+ channel_id: 2
37
+ children:
38
+ - device_type: MuxChannel
39
+ name: "CH03"
40
+ channel_id: 3
41
+ children:
@@ -0,0 +1,48 @@
1
+ id: 43
2
+ name: "EKF SRF-FAN"
3
+ slot_type: CPCI_S0_PER
4
+ children:
5
+ - device_type: I2CMux
6
+ name: "MUX"
7
+ addr: 0x70
8
+ slot_coding_mask: 0x07
9
+ children:
10
+ - device_type: MuxChannel
11
+ name: "CH00"
12
+ channel_id: 0
13
+ children:
14
+ - device_type: EKFIdentificationIOExpander
15
+ name: "GPIO"
16
+ addr: 0x3D
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: EKF_EEPROM
21
+ name: "EEPROM"
22
+ addr: 0x55
23
+ provides:
24
+ inventory:
25
+ - vendor
26
+ - serial
27
+ - model
28
+ - repaired_at
29
+ - manufactured_at
30
+ custom:
31
+ - serial: custom_serial
32
+ - content: custom_board_data
33
+ - raw: custom_raw_data
34
+ - write_serial: write_custom_serial
35
+ - write_content: write_custom_board_data
36
+ - write_raw: write_custom_raw_data
37
+ - device_type: MuxChannel
38
+ name: "CH01"
39
+ channel_id: 1
40
+ children:
41
+ - device_type: MuxChannel
42
+ name: "CH02"
43
+ channel_id: 2
44
+ children:
45
+ - device_type: MuxChannel
46
+ name: "CH03"
47
+ channel_id: 3
48
+ children:
@@ -0,0 +1,72 @@
1
+ id: 67
2
+ name: "EKF SUR-UART"
3
+ slot_type: CPCI_S0_PER
4
+ children:
5
+ - device_type: I2CMux
6
+ name: "MUX"
7
+ addr: 0x70
8
+ slot_coding_mask: 0x07
9
+ children:
10
+ - device_type: MuxChannel
11
+ name: "CH00"
12
+ channel_id: 0
13
+ children:
14
+ - device_type: EKFIdentificationIOExpander
15
+ name: "GPIO"
16
+ addr: 0x3D
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: EKF_EEPROM
21
+ name: "EEPROM"
22
+ addr: 0x55
23
+ provides:
24
+ inventory:
25
+ - vendor
26
+ - serial
27
+ - model
28
+ - repaired_at
29
+ - manufactured_at
30
+ - device_type: MuxChannel
31
+ name: "CH01"
32
+ channel_id: 1
33
+ children:
34
+ - device_type: IIOThermalHumidity
35
+ name: "TH"
36
+ addr: 0x40
37
+ provides:
38
+ th:
39
+ - temperature
40
+ - humidity
41
+ - device_type: MuxChannel
42
+ name: "CH02"
43
+ channel_id: 2
44
+ children:
45
+ - device_type: EKFSurLed
46
+ name: "LEDA"
47
+ addr: 0x3D
48
+ provides:
49
+ led_a:
50
+ - set
51
+ - device_type: EKFSurLed
52
+ name: "LEDB"
53
+ addr: 0x3E
54
+ provides:
55
+ led_b:
56
+ - set
57
+ - device_type: MuxChannel
58
+ name: "CH03"
59
+ channel_id: 3
60
+ children:
61
+ - device_type: EKFSurLed
62
+ name: "LEDC"
63
+ addr: 0x3D
64
+ provides:
65
+ led_c:
66
+ - set
67
+ - device_type: EKFSurLed
68
+ name: "LEDD"
69
+ addr: 0x3E
70
+ provides:
71
+ led_d:
72
+ - set
@@ -0,0 +1,20 @@
1
+ id: HDRC300
2
+ name: "HITRON HDRC-300"
3
+ slot_type: CPCI_S0_PSU
4
+ children:
5
+ - device_type: PmBus
6
+ name: "PMBUS"
7
+ addr: 0x18
8
+ slot_coding_mask: 0x07
9
+ provides:
10
+ inventory:
11
+ - vendor
12
+ - model
13
+ - revision
14
+ - serial
15
+ main:
16
+ - voltage: in1_input
17
+ - current: curr1_input
18
+ sby:
19
+ - voltage: in2_input
20
+ - current: curr2_input
ekfsm/cli.py ADDED
@@ -0,0 +1,111 @@
1
+ #! /usr/bin/env python3
2
+ # import os
3
+ # import sys
4
+ import click
5
+ import logging
6
+ from pathlib import Path
7
+
8
+ from ekfsm.system import System
9
+ from ekfsm.log import ekfsm_logger
10
+ from ekfsm.simctrl import enable_simulation
11
+ from ekfsm.simctrl import register_gpio_simulations
12
+
13
+
14
+ logging.basicConfig(level=logging.WARNING, format="%(levelname)s: %(message)s")
15
+ logger = ekfsm_logger(__name__)
16
+
17
+ sm: System | None = None
18
+
19
+
20
+ @click.group()
21
+ @click.option("--verbose", "-v", is_flag=True, help="Enable verbose output")
22
+ @click.option("--debug", "-d", is_flag=True, help="Enable debug output")
23
+ @click.option(
24
+ "--sysfs",
25
+ "-s",
26
+ help="Use custom sysfs dir for simulation mode",
27
+ is_flag=False,
28
+ flag_value="tests/sim/sys",
29
+ type=click.Path(exists=True),
30
+ )
31
+ @click.option(
32
+ "--config",
33
+ "-c",
34
+ type=click.Path(exists=True),
35
+ required=True,
36
+ help="Path to configuration file",
37
+ )
38
+ def cli(verbose, debug, sysfs, config):
39
+ global sm
40
+ """POSIX-compliant CLI tool with subcommands"""
41
+ if verbose:
42
+ logging.getLogger().setLevel(logging.INFO)
43
+ logger.info("Verbose output enabled")
44
+ if debug:
45
+ logging.getLogger().setLevel(logging.DEBUG)
46
+ logger.setLevel(logging.DEBUG)
47
+ logger.debug("Debug output enabled")
48
+ if sysfs:
49
+ logger.warning("Simulation mode enabled")
50
+ enable_simulation(Path(sysfs))
51
+ register_gpio_simulations()
52
+
53
+ sm = System(config)
54
+
55
+
56
+ @cli.command()
57
+ @click.option(
58
+ "--serial",
59
+ "-s",
60
+ is_flag=False,
61
+ prompt=True,
62
+ type=int,
63
+ help="Write chassis serial number",
64
+ )
65
+ @click.option(
66
+ "--unit", "-u", is_flag=False, prompt=True, type=int, help="Write chassis unit"
67
+ )
68
+ @click.option(
69
+ "--vendor",
70
+ "-n",
71
+ is_flag=False,
72
+ help="Write chassis vendor",
73
+ default="EKF Elektronik",
74
+ )
75
+ @click.option("--revision", "-r", is_flag=False, help="Write chassis revision")
76
+ @click.option("--model", "-m", is_flag=False, help="Write chassis model")
77
+ @click.option("--custom", "-c", is_flag=False, help="Write chassis custom information")
78
+ def write(serial, unit, vendor, revision, model, custom):
79
+ """Write data to the system"""
80
+ chassis = sm.ccu.chassis_inventory
81
+ if serial:
82
+ chassis.write_serial(serial)
83
+ if unit:
84
+ chassis.write_unit(unit)
85
+ if vendor:
86
+ chassis.write_vendor(vendor)
87
+ if revision:
88
+ chassis.write_revision(revision)
89
+ if model:
90
+ chassis.write_model(model)
91
+ if custom:
92
+ chassis.write_customer_area(custom)
93
+
94
+
95
+ @cli.command()
96
+ def show():
97
+ """Show information about the system"""
98
+ sm.print()
99
+
100
+
101
+ # Attach subgroups to main CLI
102
+ cli.add_command(write)
103
+ cli.add_command(show)
104
+
105
+
106
+ def main():
107
+ cli(auto_envvar_prefix="EKFSM")
108
+
109
+
110
+ if __name__ == "__main__":
111
+ main()
ekfsm/config.py ADDED
@@ -0,0 +1,37 @@
1
+ import yamale # type: ignore
2
+ import yaml
3
+ import munch
4
+
5
+ from typing import Any, List, Tuple
6
+
7
+ schema_str = """
8
+ system_config:
9
+ name: str()
10
+ slots: list(include('slot'))
11
+ ---
12
+ slot:
13
+ name: str()
14
+ slot_type: regex('^CPCI_S0_(PER|SYS|PSU|UTILITY)$')
15
+ desired_hwmodule_type: str()
16
+ desired_hwmodule_name: str()
17
+ attributes: map(required=False)
18
+ """
19
+
20
+
21
+ def _validate_config(config_file: str) -> None:
22
+ schema = yamale.make_schema(content=schema_str)
23
+ data = yamale.make_data(config_file)
24
+ yamale.validate(schema, data)
25
+
26
+
27
+ def _parse_config(config_file: str) -> Any | munch.Munch | List | Tuple:
28
+ with open(config_file) as file:
29
+ config = yaml.safe_load(file)
30
+ munchified_config = munch.munchify(config)
31
+ return munchified_config
32
+
33
+
34
+ def load_config(config_file: str) -> Any:
35
+ _validate_config(config_file)
36
+ config = _parse_config(config_file)
37
+ return config
ekfsm/core/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ from .slots import Slot, SlotType, Slots # noqa: F401
2
+ from .sysfs import SysFSDevice, SysFSAttribute # noqa: F401
3
+ from .components import HwModule # noqa: F401
4
+ from .probe import ProbeableDevice # noqa: F401
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from anytree import LevelGroupOrderIter, NodeMixin, RenderTree, findall
6
+ from munch import Munch
7
+
8
+ if TYPE_CHECKING:
9
+ from ekfsm.devices.generic import Device
10
+
11
+ from .slots import Slot
12
+
13
+
14
+ class SystemComponent(NodeMixin):
15
+ """
16
+ Base class for all system components including Hardware Modules and Devices.
17
+ """
18
+
19
+ def __init__(self, name: str):
20
+ from ekfsm.log import ekfsm_logger
21
+
22
+ self.logger = ekfsm_logger(name)
23
+ self.name = name
24
+
25
+ def _render_tree(self) -> str:
26
+ output = ""
27
+ for pre, _, node in RenderTree(self):
28
+ output += f"{pre}{repr(node)}" + "\n"
29
+ return output
30
+
31
+ def __str__(self):
32
+ return self._render_tree()
33
+
34
+ def print(self) -> None:
35
+ print(self)
36
+
37
+
38
+ class HwModule(SystemComponent):
39
+ """
40
+ A HwModule represents an instantiation of a specifc hw board type,
41
+ for example an instance of an EKF SC9 board.
42
+ """
43
+
44
+ def __init__(self, instance_name: str, config: dict, slot: Slot) -> None:
45
+ from ekfsm.core.utils import deserialize_hardware_tree
46
+
47
+ from .slots import SlotType
48
+
49
+ super().__init__(instance_name)
50
+ self._slot: Slot = slot
51
+ self.config = config
52
+
53
+ self.id, self.board_type, slot_type, self.children = deserialize_hardware_tree(
54
+ self.logger, self.config, parent=self
55
+ )
56
+
57
+ self.slot_type = SlotType.from_string(slot_type)
58
+
59
+ for children in LevelGroupOrderIter(self):
60
+ for child in children:
61
+ for sub_child in child.children:
62
+ setattr(child, sub_child.name.lower(), sub_child)
63
+
64
+ # If the device provides functions, add function and corresponding attributes to this hw module
65
+ self._create_functions_from_node_providers(sub_child)
66
+
67
+ @property
68
+ def is_master(self) -> bool:
69
+ slot_attributes = self.slot.attributes
70
+ if slot_attributes is not None and hasattr(slot_attributes, "is_master"):
71
+ return slot_attributes.is_master
72
+ return False
73
+
74
+ def _create_functions_from_node_providers(self, device: Device) -> None:
75
+ providers: Munch | None = getattr(device, "provides", None)
76
+
77
+ if providers is not None:
78
+ for key, value in providers.items():
79
+ if key not in self.__dict__:
80
+ provider = Munch()
81
+ else:
82
+ provider = getattr(self, key)
83
+
84
+ provider.update(value)
85
+
86
+ setattr(self, key, provider)
87
+
88
+ def probe(self, *args, **kwargs) -> bool:
89
+ from ekfsm.core.probe import ProbeableDevice
90
+
91
+ nodes = findall(self, lambda node: isinstance(node, ProbeableDevice))
92
+ for node in nodes:
93
+ if node.probe(*args, **kwargs):
94
+ return True
95
+
96
+ return False
97
+
98
+ def info(self) -> dict[str, Any]:
99
+ """
100
+ Returns a dictionary with information about the hardware module.
101
+ """
102
+ return {
103
+ "name": self.instance_name,
104
+ "slot": self.slot,
105
+ }
106
+
107
+ @property
108
+ def instance_name(self) -> str:
109
+ if self.name is None:
110
+ raise RuntimeError("instance name not set")
111
+ return self.name
112
+
113
+ @property
114
+ def slot(self) -> Slot:
115
+ if self._slot is None:
116
+ raise RuntimeError("slot not set")
117
+ return self._slot
118
+
119
+ def __repr__(self) -> str:
120
+ return f"{self.__class__.__name__}(name={self.name}, type={self.board_type})"
ekfsm/core/probe.py ADDED
@@ -0,0 +1,10 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class ProbeableDevice(ABC):
5
+ @abstractmethod
6
+ def probe(self, *args, **kwargs) -> bool:
7
+ """
8
+ Probe the hardware device to check if it is present and if it is the correct device.
9
+ """
10
+ pass