ekfsm 0.12.0.post1__py3-none-any.whl → 0.13.0a168.post1__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/boards/oem/ekf/se5-club.yaml +41 -0
- ekfsm/boards/oem/ekf/sn4-djembe.yaml +41 -0
- ekfsm/boards/oem/hitron/{hdrc-300.yaml → hdrc-300s.yaml} +6 -2
- ekfsm/cli.py +6 -1
- ekfsm/config.py +1 -0
- ekfsm/core/components.py +14 -5
- ekfsm/core/utils.py +26 -11
- ekfsm/devices/__init__.py +4 -3
- ekfsm/devices/{hwmon.py → coretemp.py} +8 -6
- ekfsm/devices/eeprom.py +41 -4
- ekfsm/devices/ekf_ccu_uc.py +2 -2
- ekfsm/devices/ekf_sur_led.py +2 -2
- ekfsm/devices/generic.py +20 -15
- ekfsm/devices/gpio.py +7 -7
- ekfsm/devices/iio_thermal_humidity.py +2 -2
- ekfsm/devices/mux.py +3 -3
- ekfsm/devices/pmbus.py +196 -14
- ekfsm/devices/smbios.py +4 -2
- ekfsm/devices/smbus.py +24 -0
- ekfsm/simctrl.py +9 -28
- ekfsm/system.py +46 -19
- ekfsm-0.13.0a168.post1.dist-info/METADATA +174 -0
- ekfsm-0.13.0a168.post1.dist-info/RECORD +44 -0
- ekfsm-0.12.0.post1.dist-info/METADATA +0 -86
- ekfsm-0.12.0.post1.dist-info/RECORD +0 -41
- {ekfsm-0.12.0.post1.dist-info → ekfsm-0.13.0a168.post1.dist-info}/WHEEL +0 -0
- {ekfsm-0.12.0.post1.dist-info → ekfsm-0.13.0a168.post1.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
id: 64
|
|
2
|
+
name: "EKF SE5-CLUB"
|
|
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,41 @@
|
|
|
1
|
+
id: 61
|
|
2
|
+
name: "EKF SN4-DJEMBE"
|
|
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:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
id:
|
|
2
|
-
name: "
|
|
1
|
+
id: HDRC300S-110J-D120E(N)
|
|
2
|
+
name: "Hitron HDRC-300S"
|
|
3
3
|
slot_type: CPCI_S0_PSU
|
|
4
4
|
children:
|
|
5
5
|
- device_type: PmBus
|
|
@@ -15,6 +15,10 @@ children:
|
|
|
15
15
|
main:
|
|
16
16
|
- voltage: in1_input
|
|
17
17
|
- current: curr1_input
|
|
18
|
+
- status: status0_input
|
|
18
19
|
sby:
|
|
19
20
|
- voltage: in2_input
|
|
20
21
|
- current: curr2_input
|
|
22
|
+
- status: status1_input
|
|
23
|
+
th:
|
|
24
|
+
- temperature: temp1_input
|
ekfsm/cli.py
CHANGED
|
@@ -75,9 +75,12 @@ def cli(verbose, debug, sysfs, config):
|
|
|
75
75
|
@click.option("--revision", "-r", is_flag=False, help="Write chassis revision")
|
|
76
76
|
@click.option("--model", "-m", is_flag=False, help="Write chassis model")
|
|
77
77
|
@click.option("--custom", "-c", is_flag=False, help="Write chassis custom information")
|
|
78
|
-
|
|
78
|
+
@click.option("--version", "-v", is_flag=False, help="Write schema version", default=1)
|
|
79
|
+
def write(serial, unit, vendor, revision, model, custom, version):
|
|
79
80
|
"""Write data to the system"""
|
|
80
81
|
chassis = sm.ccu.chassis_inventory
|
|
82
|
+
eeprom = sm.ccu.mux.ch00.eeprom
|
|
83
|
+
|
|
81
84
|
if serial:
|
|
82
85
|
chassis.write_serial(serial)
|
|
83
86
|
if unit:
|
|
@@ -90,6 +93,8 @@ def write(serial, unit, vendor, revision, model, custom):
|
|
|
90
93
|
chassis.write_model(model)
|
|
91
94
|
if custom:
|
|
92
95
|
chassis.write_customer_area(custom)
|
|
96
|
+
if version:
|
|
97
|
+
eeprom.write_version(version)
|
|
93
98
|
|
|
94
99
|
|
|
95
100
|
@cli.command()
|
ekfsm/config.py
CHANGED
ekfsm/core/components.py
CHANGED
|
@@ -11,16 +11,17 @@ if TYPE_CHECKING:
|
|
|
11
11
|
from .slots import Slot
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class
|
|
14
|
+
class SysTree(NodeMixin):
|
|
15
15
|
"""
|
|
16
16
|
Base class for all system components including Hardware Modules and Devices.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
def __init__(self, name: str):
|
|
19
|
+
def __init__(self, name: str, abort: bool = False) -> None:
|
|
20
20
|
from ekfsm.log import ekfsm_logger
|
|
21
21
|
|
|
22
22
|
self.logger = ekfsm_logger(name)
|
|
23
23
|
self.name = name
|
|
24
|
+
self.abort = abort
|
|
24
25
|
|
|
25
26
|
def _render_tree(self) -> str:
|
|
26
27
|
output = ""
|
|
@@ -35,18 +36,26 @@ class SystemComponent(NodeMixin):
|
|
|
35
36
|
print(self)
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
class HwModule(
|
|
39
|
+
class HwModule(SysTree):
|
|
39
40
|
"""
|
|
40
41
|
A HwModule represents an instantiation of a specifc hw board type,
|
|
41
42
|
for example an instance of an EKF SC9 board.
|
|
42
43
|
"""
|
|
43
44
|
|
|
44
|
-
def __init__(
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
instance_name: str,
|
|
48
|
+
config: dict,
|
|
49
|
+
slot: Slot,
|
|
50
|
+
abort: bool = False,
|
|
51
|
+
*args,
|
|
52
|
+
**kwargs,
|
|
53
|
+
) -> None:
|
|
45
54
|
from ekfsm.core.utils import deserialize_hardware_tree
|
|
46
55
|
|
|
47
56
|
from .slots import SlotType
|
|
48
57
|
|
|
49
|
-
super().__init__(instance_name)
|
|
58
|
+
super().__init__(instance_name, abort=abort)
|
|
50
59
|
self._slot: Slot = slot
|
|
51
60
|
self.config = config
|
|
52
61
|
|
ekfsm/core/utils.py
CHANGED
|
@@ -16,11 +16,11 @@ class BoardDictImporter:
|
|
|
16
16
|
def __init__(self, nodecls=AnyNode):
|
|
17
17
|
self.nodecls = nodecls
|
|
18
18
|
|
|
19
|
-
def import_(self, logger: logging.Logger, data, parent=None):
|
|
19
|
+
def import_(self, logger: logging.Logger, data, parent=None, abort: bool = False):
|
|
20
20
|
"""Import tree from `data`."""
|
|
21
|
-
return self.__import(logger, data, parent=parent)
|
|
21
|
+
return self.__import(logger, data, parent=parent, abort=abort)
|
|
22
22
|
|
|
23
|
-
def __import(self, logger: logging.Logger, data, parent=None):
|
|
23
|
+
def __import(self, logger: logging.Logger, data, parent=None, abort: bool = False):
|
|
24
24
|
from .components import HwModule
|
|
25
25
|
|
|
26
26
|
device_type = data.get("device_type")
|
|
@@ -30,6 +30,7 @@ class BoardDictImporter:
|
|
|
30
30
|
|
|
31
31
|
children = data.pop("children", [])
|
|
32
32
|
if parent is not None and isinstance(parent, HwModule):
|
|
33
|
+
# ???
|
|
33
34
|
pass
|
|
34
35
|
|
|
35
36
|
node = nodecls(parent=parent, **data)
|
|
@@ -38,11 +39,17 @@ class BoardDictImporter:
|
|
|
38
39
|
for child in children:
|
|
39
40
|
try:
|
|
40
41
|
logger.debug(f"Importing sub device {child}")
|
|
41
|
-
self.__import(logger, child, parent=node)
|
|
42
|
+
self.__import(logger, child, parent=node, abort=abort)
|
|
42
43
|
except Exception as e:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
if abort:
|
|
45
|
+
logger.error(
|
|
46
|
+
f"Failed to import sub device {child}: {e}. aborting"
|
|
47
|
+
)
|
|
48
|
+
raise e
|
|
49
|
+
else:
|
|
50
|
+
logger.error(
|
|
51
|
+
f"Failed to import sub device {child}: {e}. continue anyway"
|
|
52
|
+
)
|
|
46
53
|
return node
|
|
47
54
|
|
|
48
55
|
|
|
@@ -50,7 +57,9 @@ def deserialize_hardware_tree(
|
|
|
50
57
|
logger: logging.Logger, data: dict, parent: "HwModule"
|
|
51
58
|
) -> tuple[str, str, str, list["Device"]]:
|
|
52
59
|
importer = BoardDictImporter()
|
|
60
|
+
abort = parent.abort
|
|
53
61
|
|
|
62
|
+
# better use schema extension for this
|
|
54
63
|
id = data.pop("id", None)
|
|
55
64
|
if id is None:
|
|
56
65
|
raise ConfigError("Board configuration must contain `id`")
|
|
@@ -67,11 +76,17 @@ def deserialize_hardware_tree(
|
|
|
67
76
|
for child in children:
|
|
68
77
|
try:
|
|
69
78
|
logger.debug(f"Importing top level device {child}")
|
|
70
|
-
node = importer.import_(logger, child, parent=parent)
|
|
79
|
+
node = importer.import_(logger, child, parent=parent, abort=abort)
|
|
71
80
|
devices.append(node)
|
|
72
81
|
except Exception as e:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
if abort:
|
|
83
|
+
logger.error(
|
|
84
|
+
f"Failed to import top level device {child}: {e}. aborting"
|
|
85
|
+
)
|
|
86
|
+
raise e
|
|
87
|
+
else:
|
|
88
|
+
logger.error(
|
|
89
|
+
f"Failed to import top level device {child}: {e}. continue anyway"
|
|
90
|
+
)
|
|
76
91
|
|
|
77
92
|
return id, name, slot_type, devices
|
ekfsm/devices/__init__.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from ekfsm.devices.generic import Device
|
|
2
|
-
from ekfsm.devices.
|
|
2
|
+
from ekfsm.devices.coretemp import CoreTemp
|
|
3
3
|
from ekfsm.devices.smbios import SMBIOS
|
|
4
4
|
from .eeprom import EEPROM, EKF_EEPROM, EKF_CCU_EEPROM
|
|
5
|
-
from .pmbus import PmBus
|
|
5
|
+
from .pmbus import PmBus, PsuStatus
|
|
6
6
|
from .gpio import GPIO, EKFIdentificationIOExpander, GPIOExpander
|
|
7
7
|
from .ekf_sur_led import EKFSurLed
|
|
8
8
|
from .ekf_ccu_uc import EKFCcuUc
|
|
@@ -21,8 +21,9 @@ CLASS_MAP = {
|
|
|
21
21
|
"EKF_CCU_EEPROM": EKF_CCU_EEPROM,
|
|
22
22
|
"EKFCcuUc": EKFCcuUc,
|
|
23
23
|
"PmBus": PmBus,
|
|
24
|
+
"PsuStatus": PsuStatus,
|
|
24
25
|
"SMBIOS": SMBIOS,
|
|
25
|
-
"HWMON":
|
|
26
|
+
"HWMON": CoreTemp,
|
|
26
27
|
"EKFSurLed": EKFSurLed,
|
|
27
28
|
"IIOThermalHumidity": IIOThermalHumidity,
|
|
28
29
|
}
|
|
@@ -7,7 +7,7 @@ from ekfsm.core.sysfs import SYSFS_ROOT
|
|
|
7
7
|
from ekfsm.devices.generic import Device
|
|
8
8
|
|
|
9
9
|
# Path to the root of the HWMON sysfs filesystem
|
|
10
|
-
HWMON_ROOT = SYSFS_ROOT / Path(
|
|
10
|
+
HWMON_ROOT = SYSFS_ROOT / Path("class/hwmon")
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def find_core_temp_dir(hwmon_dir) -> Path:
|
|
@@ -24,19 +24,19 @@ def find_core_temp_dir(hwmon_dir) -> Path:
|
|
|
24
24
|
FileNotFoundError: If no coretemp directory is found
|
|
25
25
|
"""
|
|
26
26
|
# List all 'name' files in each subdirectory of hwmon_dir
|
|
27
|
-
name_files = glob.glob(os.path.join(hwmon_dir,
|
|
27
|
+
name_files = glob.glob(os.path.join(hwmon_dir, "*", "name"))
|
|
28
28
|
|
|
29
29
|
# Search for the file containing "coretemp"
|
|
30
30
|
for name_file in name_files:
|
|
31
|
-
with open(name_file,
|
|
32
|
-
if file.readline().strip() ==
|
|
31
|
+
with open(name_file, "r") as file:
|
|
32
|
+
if file.readline().strip() == "coretemp":
|
|
33
33
|
# Return the directory containing this file
|
|
34
34
|
return Path(os.path.dirname(name_file))
|
|
35
35
|
|
|
36
36
|
raise FileNotFoundError("No coretemp directory found")
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
class
|
|
39
|
+
class CoreTemp(Device):
|
|
40
40
|
"""
|
|
41
41
|
A class to represent the HWMON device.
|
|
42
42
|
|
|
@@ -55,7 +55,9 @@ class HWMON(Device):
|
|
|
55
55
|
):
|
|
56
56
|
from ekfsm.core.sysfs import SysFSDevice, SYSFS_ROOT
|
|
57
57
|
|
|
58
|
-
self.sysfs_device: SysFSDevice = SysFSDevice(
|
|
58
|
+
self.sysfs_device: SysFSDevice = SysFSDevice(
|
|
59
|
+
find_core_temp_dir(SYSFS_ROOT / Path("class/hwmon"))
|
|
60
|
+
)
|
|
59
61
|
|
|
60
62
|
super().__init__(name, parent, None, *args, **kwargs)
|
|
61
63
|
|
ekfsm/devices/eeprom.py
CHANGED
|
@@ -14,7 +14,7 @@ from datetime import date
|
|
|
14
14
|
from typing import Any, Callable, Literal, Sequence
|
|
15
15
|
from functools import wraps
|
|
16
16
|
|
|
17
|
-
from ekfsm.core.components import
|
|
17
|
+
from ekfsm.core.components import SysTree
|
|
18
18
|
from ekfsm.core.probe import ProbeableDevice
|
|
19
19
|
|
|
20
20
|
from .generic import Device
|
|
@@ -81,7 +81,7 @@ class EEPROM(Device):
|
|
|
81
81
|
def __init__(
|
|
82
82
|
self,
|
|
83
83
|
name: str,
|
|
84
|
-
parent:
|
|
84
|
+
parent: SysTree | None = None,
|
|
85
85
|
*args,
|
|
86
86
|
**kwargs,
|
|
87
87
|
):
|
|
@@ -740,7 +740,7 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
|
|
|
740
740
|
return get_crc16_xmodem(self._data)
|
|
741
741
|
|
|
742
742
|
def probe(self, *args, **kwargs):
|
|
743
|
-
return self.
|
|
743
|
+
return self.hw_module.id == self.model()
|
|
744
744
|
|
|
745
745
|
|
|
746
746
|
class EKF_CCU_EEPROM(EKF_EEPROM):
|
|
@@ -764,7 +764,7 @@ class EKF_CCU_EEPROM(EKF_EEPROM):
|
|
|
764
764
|
_unit_length = 1
|
|
765
765
|
|
|
766
766
|
_customer_area_start = 190
|
|
767
|
-
_customer_area_length =
|
|
767
|
+
_customer_area_length = 63
|
|
768
768
|
|
|
769
769
|
def __init__(
|
|
770
770
|
self,
|
|
@@ -865,6 +865,7 @@ class EKF_CCU_EEPROM(EKF_EEPROM):
|
|
|
865
865
|
-------
|
|
866
866
|
The vendor of the chassis.
|
|
867
867
|
"""
|
|
868
|
+
|
|
868
869
|
return (
|
|
869
870
|
self._content[
|
|
870
871
|
self._cvendor_index_start : self._cvendor_index_start
|
|
@@ -1002,6 +1003,42 @@ class EKF_CCU_EEPROM(EKF_EEPROM):
|
|
|
1002
1003
|
unit = compute_int_from_bytes([area])
|
|
1003
1004
|
return unit
|
|
1004
1005
|
|
|
1006
|
+
@validated
|
|
1007
|
+
def version(self) -> int:
|
|
1008
|
+
"""
|
|
1009
|
+
Get the version of the EEPROM data scheme.
|
|
1010
|
+
|
|
1011
|
+
Note
|
|
1012
|
+
----
|
|
1013
|
+
If undefined, the version is set to 255 and then defaults to 0.
|
|
1014
|
+
|
|
1015
|
+
Returns
|
|
1016
|
+
-------
|
|
1017
|
+
The version of the EEPROM data scheme.
|
|
1018
|
+
"""
|
|
1019
|
+
version = self._content[self._ccrc_pos_start - 1]
|
|
1020
|
+
return version
|
|
1021
|
+
|
|
1022
|
+
def write_version(self, version: int) -> None:
|
|
1023
|
+
"""
|
|
1024
|
+
Write the version of the EEPROM data scheme.
|
|
1025
|
+
|
|
1026
|
+
Parameters
|
|
1027
|
+
----------
|
|
1028
|
+
version
|
|
1029
|
+
The version of the EEPROM data scheme.
|
|
1030
|
+
"""
|
|
1031
|
+
if version < 0 or version > 255:
|
|
1032
|
+
raise ValueError("Version must be between 0 and 255")
|
|
1033
|
+
|
|
1034
|
+
if version == 255:
|
|
1035
|
+
logger.warning("Version 255 is undefined, setting to 0")
|
|
1036
|
+
version = 0
|
|
1037
|
+
|
|
1038
|
+
version_bytes = version.to_bytes(1, byteorder="little")
|
|
1039
|
+
logger.info(f"Writing version {version}")
|
|
1040
|
+
self.write(version_bytes, self._ccrc_pos_start - 1)
|
|
1041
|
+
|
|
1005
1042
|
def write_unit(self, unit: int) -> None:
|
|
1006
1043
|
"""
|
|
1007
1044
|
Write the subsystem unit number.
|
ekfsm/devices/ekf_ccu_uc.py
CHANGED
|
@@ -2,7 +2,7 @@ from .generic import Device
|
|
|
2
2
|
from smbus2 import SMBus
|
|
3
3
|
from enum import Enum
|
|
4
4
|
from typing import Tuple
|
|
5
|
-
from ekfsm.core.components import
|
|
5
|
+
from ekfsm.core.components import SysTree
|
|
6
6
|
from ..exceptions import AcquisitionError
|
|
7
7
|
from .imu import ImuSample
|
|
8
8
|
import struct
|
|
@@ -35,7 +35,7 @@ class EKFCcuUc(Device):
|
|
|
35
35
|
def __init__(
|
|
36
36
|
self,
|
|
37
37
|
name: str,
|
|
38
|
-
parent:
|
|
38
|
+
parent: SysTree | None,
|
|
39
39
|
*args,
|
|
40
40
|
**kwargs,
|
|
41
41
|
):
|
ekfsm/devices/ekf_sur_led.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .gpio import GPIOExpander
|
|
2
|
-
from ekfsm.core.components import
|
|
2
|
+
from ekfsm.core.components import SysTree
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class EKFSurLed(GPIOExpander):
|
|
@@ -10,7 +10,7 @@ class EKFSurLed(GPIOExpander):
|
|
|
10
10
|
def __init__(
|
|
11
11
|
self,
|
|
12
12
|
name: str,
|
|
13
|
-
parent:
|
|
13
|
+
parent: SysTree | None,
|
|
14
14
|
*args,
|
|
15
15
|
**kwargs,
|
|
16
16
|
):
|
ekfsm/devices/generic.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING
|
|
2
2
|
from munch import Munch
|
|
3
|
-
from ekfsm.core.components import
|
|
3
|
+
from ekfsm.core.components import SysTree
|
|
4
4
|
from ekfsm.core.sysfs import SysFSDevice, sysfs_root
|
|
5
5
|
from ekfsm.exceptions import ConfigError
|
|
6
6
|
from pathlib import Path
|
|
@@ -9,7 +9,7 @@ if TYPE_CHECKING:
|
|
|
9
9
|
from ekfsm.core.components import HwModule
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class Device(
|
|
12
|
+
class Device(SysTree):
|
|
13
13
|
"""
|
|
14
14
|
A generic device.
|
|
15
15
|
"""
|
|
@@ -17,12 +17,13 @@ class Device(SystemComponent):
|
|
|
17
17
|
def __init__(
|
|
18
18
|
self,
|
|
19
19
|
name: str,
|
|
20
|
-
parent:
|
|
20
|
+
parent: SysTree | None = None,
|
|
21
21
|
children: list["Device"] | None = None,
|
|
22
|
+
abort: bool = False,
|
|
22
23
|
*args,
|
|
23
|
-
**kwargs
|
|
24
|
+
**kwargs,
|
|
24
25
|
):
|
|
25
|
-
super().__init__(name)
|
|
26
|
+
super().__init__(name, abort=abort)
|
|
26
27
|
self.parent = parent
|
|
27
28
|
self.device_args = kwargs
|
|
28
29
|
self.logger.debug(f"Device: {name} {kwargs}")
|
|
@@ -30,21 +31,21 @@ class Device(SystemComponent):
|
|
|
30
31
|
if children:
|
|
31
32
|
self.children = children
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
# needs to be set during init because root will be changed after tree is complete
|
|
35
|
+
self.hw_module = self.root
|
|
36
|
+
|
|
37
|
+
# i2c initialization
|
|
38
|
+
if not hasattr(self, "sysfs_device") or self.sysfs_device is None:
|
|
34
39
|
self.sysfs_device: SysFSDevice | None = None
|
|
35
40
|
|
|
41
|
+
# post init
|
|
36
42
|
self._provides_attrs = kwargs.get("provides", {})
|
|
37
|
-
|
|
38
43
|
self.provides = self.__post_init__(Munch(self._provides_attrs))
|
|
39
44
|
|
|
40
45
|
def __post_init__(self, provides: Munch) -> Munch:
|
|
41
|
-
return self.__init_dynamic_attrs__(provides)
|
|
42
|
-
|
|
43
|
-
def __init_dynamic_attrs__(self, provides: Munch) -> Munch:
|
|
44
|
-
|
|
45
46
|
for key, fields in provides.items():
|
|
46
47
|
if isinstance(fields, dict):
|
|
47
|
-
provides[key] = self.
|
|
48
|
+
provides[key] = self.__post_init__(Munch(fields))
|
|
48
49
|
elif isinstance(fields, list | str):
|
|
49
50
|
provides[key] = Munch()
|
|
50
51
|
|
|
@@ -91,14 +92,18 @@ class Device(SystemComponent):
|
|
|
91
92
|
return None
|
|
92
93
|
|
|
93
94
|
@property
|
|
94
|
-
def hw_module(self) ->
|
|
95
|
+
def hw_module(self) -> "HwModule":
|
|
95
96
|
from ekfsm.core.components import HwModule
|
|
96
97
|
|
|
97
|
-
if isinstance(self.
|
|
98
|
-
return self.
|
|
98
|
+
if isinstance(self._hw_module, HwModule):
|
|
99
|
+
return self._hw_module
|
|
99
100
|
else:
|
|
100
101
|
raise RuntimeError("Device is not a child of HwModule")
|
|
101
102
|
|
|
103
|
+
@hw_module.setter
|
|
104
|
+
def hw_module(self, hw_module: "HwModule") -> None:
|
|
105
|
+
self._hw_module = hw_module
|
|
106
|
+
|
|
102
107
|
def get_i2c_chip_addr(self) -> int:
|
|
103
108
|
assert self.parent is not None
|
|
104
109
|
|
ekfsm/devices/gpio.py
CHANGED
|
@@ -8,7 +8,7 @@ from gpiod.chip import LineSettings
|
|
|
8
8
|
from gpiod.line import Direction, Value
|
|
9
9
|
from more_itertools import first_true
|
|
10
10
|
|
|
11
|
-
from ekfsm.core.components import
|
|
11
|
+
from ekfsm.core.components import SysTree
|
|
12
12
|
from ekfsm.exceptions import GPIOError
|
|
13
13
|
from ekfsm.log import ekfsm_logger
|
|
14
14
|
|
|
@@ -55,7 +55,7 @@ class GPIO(Device):
|
|
|
55
55
|
def __init__(
|
|
56
56
|
self,
|
|
57
57
|
name: str,
|
|
58
|
-
parent:
|
|
58
|
+
parent: SysTree | None = None,
|
|
59
59
|
*args,
|
|
60
60
|
**kwargs,
|
|
61
61
|
):
|
|
@@ -83,7 +83,7 @@ class GPIO(Device):
|
|
|
83
83
|
|
|
84
84
|
def _find_gpio_dev(
|
|
85
85
|
self,
|
|
86
|
-
parent:
|
|
86
|
+
parent: SysTree | None = None,
|
|
87
87
|
*args,
|
|
88
88
|
**kwargs,
|
|
89
89
|
) -> tuple[int, int]:
|
|
@@ -186,7 +186,7 @@ class GPIOExpander(GPIO):
|
|
|
186
186
|
def __init__(
|
|
187
187
|
self,
|
|
188
188
|
name: str,
|
|
189
|
-
parent:
|
|
189
|
+
parent: SysTree | None,
|
|
190
190
|
*args,
|
|
191
191
|
**kwargs,
|
|
192
192
|
):
|
|
@@ -203,7 +203,7 @@ class EKFIdentificationIOExpander(GPIOExpander, ProbeableDevice):
|
|
|
203
203
|
def __init__(
|
|
204
204
|
self,
|
|
205
205
|
name: str,
|
|
206
|
-
parent:
|
|
206
|
+
parent: SysTree | None,
|
|
207
207
|
*args,
|
|
208
208
|
**kwargs,
|
|
209
209
|
):
|
|
@@ -212,11 +212,11 @@ class EKFIdentificationIOExpander(GPIOExpander, ProbeableDevice):
|
|
|
212
212
|
def probe(self, *args, **kwargs) -> bool:
|
|
213
213
|
from ekfsm.core import HwModule
|
|
214
214
|
|
|
215
|
-
assert isinstance(self.
|
|
215
|
+
assert isinstance(self.hw_module, HwModule)
|
|
216
216
|
id, _ = self.read_board_id_rev()
|
|
217
217
|
self.logger.debug(f"Probing EKFIdentificationIOExpander: {id}")
|
|
218
218
|
|
|
219
|
-
return self.
|
|
219
|
+
return self.hw_module.id == id
|
|
220
220
|
|
|
221
221
|
def read_board_id_rev(self) -> tuple[int, int]:
|
|
222
222
|
for pin in range(6, 8):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
from ekfsm.core.components import
|
|
3
|
+
from ekfsm.core.components import SysTree
|
|
4
4
|
from ekfsm.log import ekfsm_logger
|
|
5
5
|
|
|
6
6
|
from ..core.sysfs import SysFSDevice
|
|
@@ -18,7 +18,7 @@ class IIOThermalHumidity(Device):
|
|
|
18
18
|
def __init__(
|
|
19
19
|
self,
|
|
20
20
|
name: str,
|
|
21
|
-
parent:
|
|
21
|
+
parent: SysTree | None = None,
|
|
22
22
|
children: list[Device] | None = None,
|
|
23
23
|
*args,
|
|
24
24
|
**kwargs,
|
ekfsm/devices/mux.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from ekfsm.core.components import
|
|
1
|
+
from ekfsm.core.components import SysTree
|
|
2
2
|
|
|
3
3
|
from ..core.sysfs import SysFSDevice
|
|
4
4
|
from .generic import Device
|
|
@@ -9,7 +9,7 @@ class MuxChannel(Device):
|
|
|
9
9
|
self,
|
|
10
10
|
name: str,
|
|
11
11
|
channel_id: int,
|
|
12
|
-
parent:
|
|
12
|
+
parent: "I2CMux",
|
|
13
13
|
children: list[Device] | None = None,
|
|
14
14
|
*args,
|
|
15
15
|
**kwargs,
|
|
@@ -28,7 +28,7 @@ class I2CMux(Device):
|
|
|
28
28
|
def __init__(
|
|
29
29
|
self,
|
|
30
30
|
name: str,
|
|
31
|
-
parent:
|
|
31
|
+
parent: SysTree | None = None,
|
|
32
32
|
children: list[MuxChannel] | None = None,
|
|
33
33
|
*args,
|
|
34
34
|
**kwargs,
|