ekfsm 1.3.0a26__py3-none-any.whl → 1.4.0__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/sq3-quartet.yaml +51 -37
- ekfsm/boards/oem/ekf/z1010.yaml +94 -0
- ekfsm/core/components.py +3 -4
- ekfsm/core/connections.py +19 -0
- ekfsm/core/slots.py +7 -2
- ekfsm/core/sysfs.py +32 -2
- ekfsm/core/utils.py +34 -10
- ekfsm/devices/__init__.py +16 -0
- ekfsm/devices/button.py +65 -0
- ekfsm/devices/buttonArray.py +206 -0
- ekfsm/devices/colorLed.py +101 -0
- ekfsm/devices/coretemp.py +26 -3
- ekfsm/devices/eeprom.py +4 -4
- ekfsm/devices/generic.py +41 -12
- ekfsm/devices/io4edge.py +110 -0
- ekfsm/devices/ledArray.py +54 -0
- ekfsm/devices/pixelDisplay.py +137 -0
- ekfsm/devices/pmbus.py +8 -4
- ekfsm/devices/smbios.py +20 -2
- ekfsm/devices/thermal_humidity.py +78 -0
- ekfsm/devices/watchdog.py +76 -0
- ekfsm/system.py +41 -12
- {ekfsm-1.3.0a26.dist-info → ekfsm-1.4.0.dist-info}/METADATA +5 -2
- {ekfsm-1.3.0a26.dist-info → ekfsm-1.4.0.dist-info}/RECORD +26 -16
- {ekfsm-1.3.0a26.dist-info → ekfsm-1.4.0.dist-info}/WHEEL +0 -0
- {ekfsm-1.3.0a26.dist-info → ekfsm-1.4.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from ekfsm.devices.generic import Device
|
|
2
|
+
from ekfsm.devices.io4edge import IO4Edge
|
|
3
|
+
from ekfsm.log import ekfsm_logger
|
|
4
|
+
from io4edge_client.pixelDisplay import Client
|
|
5
|
+
from PIL import Image
|
|
6
|
+
|
|
7
|
+
logger = ekfsm_logger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PixelDisplay(Device):
|
|
11
|
+
"""
|
|
12
|
+
Device class for handling a pixel display.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
name: str,
|
|
18
|
+
parent: IO4Edge,
|
|
19
|
+
children: list[Device] | None = None,
|
|
20
|
+
abort: bool = False,
|
|
21
|
+
service_suffix: str | None = None,
|
|
22
|
+
*args,
|
|
23
|
+
**kwargs,
|
|
24
|
+
):
|
|
25
|
+
logger.debug(
|
|
26
|
+
f"Initializing PixelDisplay '{name}' with parent device {parent.deviceId}"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
super().__init__(name, parent, children, abort, *args, **kwargs)
|
|
30
|
+
|
|
31
|
+
self.name = name
|
|
32
|
+
|
|
33
|
+
if service_suffix is not None:
|
|
34
|
+
self.service_suffix = service_suffix
|
|
35
|
+
logger.debug(f"Using custom service suffix: {service_suffix}")
|
|
36
|
+
else:
|
|
37
|
+
self.service_suffix = name
|
|
38
|
+
logger.debug(f"Using default service suffix: {name}")
|
|
39
|
+
|
|
40
|
+
self.service_addr = f"{parent.deviceId}-{self.service_suffix}"
|
|
41
|
+
logger.info(
|
|
42
|
+
f"PixelDisplay '{name}' configured with service address: {self.service_addr}"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
self.client = Client(self.service_addr, connect=False)
|
|
47
|
+
logger.debug(
|
|
48
|
+
f"PixelDisplay client created for service: {self.service_addr}"
|
|
49
|
+
)
|
|
50
|
+
except Exception as e:
|
|
51
|
+
logger.error(
|
|
52
|
+
f"Failed to create PixelDisplay client for {self.service_addr}: {e}"
|
|
53
|
+
)
|
|
54
|
+
raise
|
|
55
|
+
|
|
56
|
+
def describe(self) -> dict:
|
|
57
|
+
"""
|
|
58
|
+
Returns a description of the pixel display.
|
|
59
|
+
"""
|
|
60
|
+
logger.debug(f"Getting PixelDisplay description for '{self.name}'")
|
|
61
|
+
try:
|
|
62
|
+
describe = self.client.describe()
|
|
63
|
+
desc = {
|
|
64
|
+
"height": describe.height_pixel,
|
|
65
|
+
"width": describe.width_pixel,
|
|
66
|
+
"max_num_of_pixel": describe.max_num_of_pixel,
|
|
67
|
+
}
|
|
68
|
+
logger.debug(f"PixelDisplay '{self.name}' description: {desc}")
|
|
69
|
+
return desc
|
|
70
|
+
except Exception as e:
|
|
71
|
+
logger.error(
|
|
72
|
+
f"Failed to get PixelDisplay description for '{self.name}': {e}"
|
|
73
|
+
)
|
|
74
|
+
raise
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def height(self) -> int:
|
|
78
|
+
"""
|
|
79
|
+
Returns the height of the pixel display in pixels.
|
|
80
|
+
"""
|
|
81
|
+
return self.describe()["height"]
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def width(self) -> int:
|
|
85
|
+
"""
|
|
86
|
+
Returns the width of the pixel display in pixels.
|
|
87
|
+
"""
|
|
88
|
+
return self.describe()["width"]
|
|
89
|
+
|
|
90
|
+
def off(self) -> None:
|
|
91
|
+
"""
|
|
92
|
+
Turn off the pixel display.
|
|
93
|
+
@raises RuntimeError: if the command fails
|
|
94
|
+
@raises TimeoutError: if the command times out
|
|
95
|
+
"""
|
|
96
|
+
logger.info(f"Turning off PixelDisplay '{self.name}'")
|
|
97
|
+
try:
|
|
98
|
+
self.client.set_display_off()
|
|
99
|
+
logger.debug(f"PixelDisplay '{self.name}' successfully turned off")
|
|
100
|
+
except Exception as e:
|
|
101
|
+
logger.error(f"Failed to turn off PixelDisplay '{self.name}': {e}")
|
|
102
|
+
raise
|
|
103
|
+
|
|
104
|
+
def display_image(self, path: str) -> None:
|
|
105
|
+
"""
|
|
106
|
+
Display an image on the pixel display.
|
|
107
|
+
@raises RuntimeError: if the command fails
|
|
108
|
+
@raises TimeoutError: if the command times out
|
|
109
|
+
"""
|
|
110
|
+
logger.info(f"Displaying image '{path}' on PixelDisplay '{self.name}'")
|
|
111
|
+
try:
|
|
112
|
+
with Image.open(path) as img:
|
|
113
|
+
img = img.convert("RGB")
|
|
114
|
+
pix = img.load()
|
|
115
|
+
logger.debug(
|
|
116
|
+
f"Image '{path}' loaded and converted to RGB for PixelDisplay '{self.name}'"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
with self.client as client:
|
|
120
|
+
logger.debug(f"Sending pixel data to PixelDisplay '{self.name}'")
|
|
121
|
+
for i in range(0, 320, 16):
|
|
122
|
+
pix_area = []
|
|
123
|
+
for k in range(0, 16):
|
|
124
|
+
for j in range(0, 240):
|
|
125
|
+
pix_area.append(pix[j, i + k])
|
|
126
|
+
client.set_pixel_area(0, i, 239, pix_area)
|
|
127
|
+
logger.debug(
|
|
128
|
+
f"Image successfully displayed on PixelDisplay '{self.name}'"
|
|
129
|
+
)
|
|
130
|
+
except Exception as e:
|
|
131
|
+
logger.error(
|
|
132
|
+
f"Failed to display image '{path}' on PixelDisplay '{self.name}': {e}"
|
|
133
|
+
)
|
|
134
|
+
raise
|
|
135
|
+
|
|
136
|
+
def __repr__(self):
|
|
137
|
+
return f"{self.name}; Service Address: {self.service_addr}"
|
ekfsm/devices/pmbus.py
CHANGED
|
@@ -52,7 +52,9 @@ def retry(max_attempts=5, delay=0.5):
|
|
|
52
52
|
except Exception as e:
|
|
53
53
|
attempts += 1
|
|
54
54
|
if attempts == max_attempts:
|
|
55
|
-
logger.exception(
|
|
55
|
+
logger.exception(
|
|
56
|
+
f"Failed to execute {func.__name__} after {max_attempts} attempts: {e}"
|
|
57
|
+
)
|
|
56
58
|
raise e
|
|
57
59
|
logger.info(f"Retrying execution of {func.__name__} in {delay}s...")
|
|
58
60
|
sleep(delay)
|
|
@@ -121,7 +123,9 @@ class PMBus(Device, ProbeableDevice):
|
|
|
121
123
|
attrs = list_sysfs_attributes(entry)
|
|
122
124
|
self.sysfs_device.extend_attributes(attrs)
|
|
123
125
|
|
|
124
|
-
debug_attrs_path = sysfs_root().joinpath(
|
|
126
|
+
debug_attrs_path = sysfs_root().joinpath(
|
|
127
|
+
f"kernel/debug/pmbus/{entry.name}"
|
|
128
|
+
)
|
|
125
129
|
debug_attrs = list_sysfs_attributes(debug_attrs_path)
|
|
126
130
|
self.sysfs_device.extend_attributes(debug_attrs)
|
|
127
131
|
except FileNotFoundError:
|
|
@@ -194,7 +198,7 @@ class PMBus(Device, ProbeableDevice):
|
|
|
194
198
|
-------
|
|
195
199
|
PSU status as defined in PSUStatus
|
|
196
200
|
"""
|
|
197
|
-
status = self.sysfs.
|
|
201
|
+
status = self.sysfs.read_hex("status0_input")
|
|
198
202
|
return PSUStatus(status)
|
|
199
203
|
|
|
200
204
|
@retry()
|
|
@@ -206,7 +210,7 @@ class PMBus(Device, ProbeableDevice):
|
|
|
206
210
|
-------
|
|
207
211
|
PSU status as defined in PSUStatus
|
|
208
212
|
"""
|
|
209
|
-
status = self.sysfs.
|
|
213
|
+
status = self.sysfs.read_hex("status1_input")
|
|
210
214
|
return PSUStatus(status)
|
|
211
215
|
|
|
212
216
|
# Temperature Interface
|
ekfsm/devices/smbios.py
CHANGED
|
@@ -2,9 +2,12 @@ from pathlib import Path
|
|
|
2
2
|
|
|
3
3
|
from ekfsm.core.components import HWModule
|
|
4
4
|
from ekfsm.core.sysfs import SysfsDevice, sysfs_root
|
|
5
|
+
from ekfsm.log import ekfsm_logger
|
|
5
6
|
|
|
6
7
|
from .generic import Device
|
|
7
8
|
|
|
9
|
+
logger = ekfsm_logger(__name__)
|
|
10
|
+
|
|
8
11
|
|
|
9
12
|
class SMBIOS(Device):
|
|
10
13
|
"""
|
|
@@ -26,7 +29,15 @@ class SMBIOS(Device):
|
|
|
26
29
|
*args,
|
|
27
30
|
**kwargs,
|
|
28
31
|
):
|
|
29
|
-
|
|
32
|
+
logger.debug(f"Initializing SMBIOS device '{name}'")
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
dmi_path = sysfs_root() / Path("devices/virtual/dmi/id")
|
|
36
|
+
self.sysfs_device: SysfsDevice | None = SysfsDevice(dmi_path, False)
|
|
37
|
+
logger.info(f"SMBIOS '{name}' initialized with DMI table at {dmi_path}")
|
|
38
|
+
except Exception as e:
|
|
39
|
+
logger.error(f"Failed to initialize SMBIOS '{name}' with DMI table: {e}")
|
|
40
|
+
raise
|
|
30
41
|
|
|
31
42
|
super().__init__(name, parent, None, abort, *args, **kwargs)
|
|
32
43
|
|
|
@@ -39,4 +50,11 @@ class SMBIOS(Device):
|
|
|
39
50
|
str
|
|
40
51
|
The board revision.
|
|
41
52
|
"""
|
|
42
|
-
|
|
53
|
+
logger.debug(f"Reading board revision for SMBIOS '{self.name}'")
|
|
54
|
+
try:
|
|
55
|
+
revision = self.sysfs.read_utf8("board_version")
|
|
56
|
+
logger.debug(f"SMBIOS '{self.name}' board revision: {revision}")
|
|
57
|
+
return revision
|
|
58
|
+
except Exception as e:
|
|
59
|
+
logger.error(f"Failed to read board revision for SMBIOS '{self.name}': {e}")
|
|
60
|
+
raise
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from ekfsm.devices.generic import Device
|
|
2
|
+
from ekfsm.devices.io4edge import IO4Edge
|
|
3
|
+
from ekfsm.log import ekfsm_logger
|
|
4
|
+
from io4edge_client.analogintypeb import Client
|
|
5
|
+
|
|
6
|
+
logger = ekfsm_logger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ThermalHumidity(Device):
|
|
10
|
+
"""
|
|
11
|
+
Device class for handling a thermal humidity sensor.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
name: str,
|
|
17
|
+
parent: IO4Edge,
|
|
18
|
+
children: list[Device] | None = None,
|
|
19
|
+
abort: bool = False,
|
|
20
|
+
service_suffix: str | None = None,
|
|
21
|
+
*args,
|
|
22
|
+
**kwargs,
|
|
23
|
+
):
|
|
24
|
+
logger.debug(
|
|
25
|
+
f"Initializing ThermalHumidity sensor '{name}' with parent device {parent.deviceId}"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
super().__init__(name, parent, children, abort, *args, **kwargs)
|
|
29
|
+
|
|
30
|
+
self.name = name
|
|
31
|
+
|
|
32
|
+
if service_suffix is not None:
|
|
33
|
+
self.service_suffix = service_suffix
|
|
34
|
+
logger.debug(f"Using custom service suffix: {service_suffix}")
|
|
35
|
+
else:
|
|
36
|
+
self.service_suffix = name
|
|
37
|
+
logger.debug(f"Using default service suffix: {name}")
|
|
38
|
+
|
|
39
|
+
self.service_addr = f"{parent.deviceId}-{self.service_suffix}"
|
|
40
|
+
logger.info(
|
|
41
|
+
f"ThermalHumidity '{name}' configured with service address: {self.service_addr}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
self.client = Client(self.service_addr, connect=False)
|
|
46
|
+
logger.debug(
|
|
47
|
+
f"ThermalHumidity client created for service: {self.service_addr}"
|
|
48
|
+
)
|
|
49
|
+
except Exception as e:
|
|
50
|
+
logger.error(
|
|
51
|
+
f"Failed to create ThermalHumidity client for {self.service_addr}: {e}"
|
|
52
|
+
)
|
|
53
|
+
raise
|
|
54
|
+
|
|
55
|
+
def temperature(self) -> float:
|
|
56
|
+
"""
|
|
57
|
+
Get the temperature in Celsius.
|
|
58
|
+
|
|
59
|
+
Raises
|
|
60
|
+
------
|
|
61
|
+
RuntimeError
|
|
62
|
+
if the command fails
|
|
63
|
+
TimeoutError
|
|
64
|
+
if the command times out
|
|
65
|
+
"""
|
|
66
|
+
logger.debug(f"Reading temperature from ThermalHumidity sensor '{self.name}'")
|
|
67
|
+
try:
|
|
68
|
+
temp = self.client.value()
|
|
69
|
+
logger.debug(f"ThermalHumidity '{self.name}' temperature: {temp}°C")
|
|
70
|
+
return temp
|
|
71
|
+
except Exception as e:
|
|
72
|
+
logger.error(
|
|
73
|
+
f"Failed to read temperature from ThermalHumidity '{self.name}': {e}"
|
|
74
|
+
)
|
|
75
|
+
raise
|
|
76
|
+
|
|
77
|
+
def __repr__(self):
|
|
78
|
+
return f"{self.name}; Service Address: {self.service_addr}"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from ekfsm.devices.generic import Device
|
|
2
|
+
from ekfsm.devices.io4edge import IO4Edge
|
|
3
|
+
from ekfsm.log import ekfsm_logger
|
|
4
|
+
from io4edge_client.watchdog import Client
|
|
5
|
+
|
|
6
|
+
logger = ekfsm_logger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Watchdog(Device):
|
|
10
|
+
"""
|
|
11
|
+
Device class for handling an application watchdog.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
name: str,
|
|
17
|
+
parent: IO4Edge,
|
|
18
|
+
children: list[Device] | None = None,
|
|
19
|
+
abort: bool = False,
|
|
20
|
+
service_suffix: str | None = None,
|
|
21
|
+
*args,
|
|
22
|
+
**kwargs,
|
|
23
|
+
):
|
|
24
|
+
logger.debug(
|
|
25
|
+
f"Initializing Watchdog '{name}' with parent device {parent.deviceId}"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
super().__init__(name, parent, children, abort, *args, **kwargs)
|
|
29
|
+
|
|
30
|
+
self.name = name
|
|
31
|
+
|
|
32
|
+
if service_suffix is not None:
|
|
33
|
+
self.service_suffix = service_suffix
|
|
34
|
+
logger.debug(f"Using custom service suffix: {service_suffix}")
|
|
35
|
+
else:
|
|
36
|
+
self.service_suffix = name
|
|
37
|
+
logger.debug(f"Using default service suffix: {name}")
|
|
38
|
+
|
|
39
|
+
self.service_addr = f"{parent.deviceId}-{self.service_suffix}"
|
|
40
|
+
logger.info(
|
|
41
|
+
f"Watchdog '{name}' configured with service address: {self.service_addr}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
self.client = Client(self.service_addr, connect=False)
|
|
46
|
+
logger.debug(f"Watchdog client created for service: {self.service_addr}")
|
|
47
|
+
except Exception as e:
|
|
48
|
+
logger.error(
|
|
49
|
+
f"Failed to create Watchdog client for {self.service_addr}: {e}"
|
|
50
|
+
)
|
|
51
|
+
raise
|
|
52
|
+
|
|
53
|
+
def describe(self):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
def kick(self) -> None:
|
|
57
|
+
"""
|
|
58
|
+
Kick the watchdog.
|
|
59
|
+
|
|
60
|
+
Raises
|
|
61
|
+
------
|
|
62
|
+
RuntimeError
|
|
63
|
+
if the command fails
|
|
64
|
+
TimeoutError
|
|
65
|
+
if the command times out
|
|
66
|
+
"""
|
|
67
|
+
logger.debug(f"Kicking watchdog '{self.name}' on service {self.service_addr}")
|
|
68
|
+
try:
|
|
69
|
+
self.client.kick()
|
|
70
|
+
logger.debug(f"Watchdog '{self.name}' kick successful")
|
|
71
|
+
except Exception as e:
|
|
72
|
+
logger.error(f"Failed to kick watchdog '{self.name}': {e}")
|
|
73
|
+
raise
|
|
74
|
+
|
|
75
|
+
def __repr__(self):
|
|
76
|
+
return f"{self.name}; Service Address: {self.service_addr}"
|
ekfsm/system.py
CHANGED
|
@@ -173,13 +173,17 @@ class System(SysTree):
|
|
|
173
173
|
board_type = slot_entry.desired_hwmodule_type
|
|
174
174
|
board_name = slot_entry.desired_hwmodule_name
|
|
175
175
|
|
|
176
|
-
self.logger.debug(
|
|
176
|
+
self.logger.debug(
|
|
177
|
+
f"Creating HWModule {board_type} (desired name: {board_name}) in slot {slot.name}"
|
|
178
|
+
)
|
|
177
179
|
|
|
178
180
|
if board_type != "":
|
|
179
181
|
# try to create first the desired board
|
|
180
182
|
path = find_board_config(board_type)
|
|
181
183
|
if path is None:
|
|
182
|
-
self.logger.error(
|
|
184
|
+
self.logger.error(
|
|
185
|
+
f"No board config found for {board_type} (desired name: {board_name})"
|
|
186
|
+
)
|
|
183
187
|
return None, slot
|
|
184
188
|
|
|
185
189
|
try:
|
|
@@ -199,11 +203,15 @@ class System(SysTree):
|
|
|
199
203
|
|
|
200
204
|
# try to probe desired board type
|
|
201
205
|
if hwmod.probe():
|
|
202
|
-
self.logger.info(
|
|
206
|
+
self.logger.info(
|
|
207
|
+
f"Found desired board type {hwmod.board_type} for slot {slot.name}"
|
|
208
|
+
)
|
|
203
209
|
return hwmod, slot
|
|
204
210
|
|
|
205
211
|
# try all other boards types. Maybe someone inserted the wrong board
|
|
206
|
-
self.logger.info(
|
|
212
|
+
self.logger.info(
|
|
213
|
+
f"Probing failed. Trying all other board types for slot {slot.name}"
|
|
214
|
+
)
|
|
207
215
|
for path in all_board_cfg_files():
|
|
208
216
|
try:
|
|
209
217
|
hwmod = self._create_hwmodule_from_cfg_file(slot, board_name, path)
|
|
@@ -212,16 +220,22 @@ class System(SysTree):
|
|
|
212
220
|
# ??? should we log this?
|
|
213
221
|
continue
|
|
214
222
|
except Exception as e:
|
|
215
|
-
self.logger.debug(
|
|
223
|
+
self.logger.debug(
|
|
224
|
+
f"failed to create HWmodule {path} for slot {slot.name}: {e}"
|
|
225
|
+
)
|
|
216
226
|
continue
|
|
217
227
|
|
|
218
228
|
if hwmod.probe():
|
|
219
|
-
self.logger.info(
|
|
229
|
+
self.logger.info(
|
|
230
|
+
f"Found other board type {hwmod.board_type} for slot {slot.name}"
|
|
231
|
+
)
|
|
220
232
|
return hwmod, slot
|
|
221
233
|
|
|
222
234
|
return None, slot
|
|
223
235
|
|
|
224
|
-
def _create_slot(
|
|
236
|
+
def _create_slot(
|
|
237
|
+
self, slot_entry: Munch, slot_number: int, master: HWModule | None
|
|
238
|
+
) -> Slot:
|
|
225
239
|
attributes = None
|
|
226
240
|
if "attributes" in slot_entry:
|
|
227
241
|
attributes = slot_entry.attributes
|
|
@@ -237,7 +251,9 @@ class System(SysTree):
|
|
|
237
251
|
attributes,
|
|
238
252
|
)
|
|
239
253
|
|
|
240
|
-
def _create_hwmodule_from_cfg_file(
|
|
254
|
+
def _create_hwmodule_from_cfg_file(
|
|
255
|
+
self, slot: Slot, board_name: str, path: Path
|
|
256
|
+
) -> HWModule:
|
|
241
257
|
"""
|
|
242
258
|
Try to create a HWModule object from a board config file.
|
|
243
259
|
It does not probe the hardware.
|
|
@@ -261,7 +277,9 @@ class System(SysTree):
|
|
|
261
277
|
cfg = munchify(yaml_data)
|
|
262
278
|
# only instantiate if slot type matches
|
|
263
279
|
if cfg.slot_type != slot.slot_type.to_string():
|
|
264
|
-
raise ConfigError(
|
|
280
|
+
raise ConfigError(
|
|
281
|
+
f"Slot type mismatch for slot {slot.name}: {cfg.slot_type} != {slot.slot_type}"
|
|
282
|
+
)
|
|
265
283
|
|
|
266
284
|
hwmod = HWModule(
|
|
267
285
|
instance_name=board_name,
|
|
@@ -289,7 +307,11 @@ class System(SysTree):
|
|
|
289
307
|
If no HWModule is present in the given slot.
|
|
290
308
|
"""
|
|
291
309
|
return next(
|
|
292
|
-
(
|
|
310
|
+
(
|
|
311
|
+
v.hwmodule
|
|
312
|
+
for k, v in self.slots.items()
|
|
313
|
+
if getattr(v, "number", None) == idx
|
|
314
|
+
),
|
|
293
315
|
None,
|
|
294
316
|
)
|
|
295
317
|
|
|
@@ -310,7 +332,12 @@ class System(SysTree):
|
|
|
310
332
|
If no HWModule is present with the given name.
|
|
311
333
|
"""
|
|
312
334
|
return next(
|
|
313
|
-
(
|
|
335
|
+
(
|
|
336
|
+
b
|
|
337
|
+
for b in self.boards
|
|
338
|
+
if getattr(b, "instance_name", None) is not None
|
|
339
|
+
and getattr(b, "instance_name").lower() == name.lower()
|
|
340
|
+
),
|
|
314
341
|
None,
|
|
315
342
|
)
|
|
316
343
|
|
|
@@ -334,7 +361,9 @@ class System(SysTree):
|
|
|
334
361
|
if (hw_module := self.get_module_by_name(name)) is not None:
|
|
335
362
|
return hw_module
|
|
336
363
|
|
|
337
|
-
raise AttributeError(
|
|
364
|
+
raise AttributeError(
|
|
365
|
+
f"'{type(self).__name__}' object has no board with name '{name}'"
|
|
366
|
+
)
|
|
338
367
|
|
|
339
368
|
def __repr__(self):
|
|
340
369
|
return f"System (name={self.name})"
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ekfsm
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: The EKF System Management Library (ekfsm) is a sensor monitoring suite for Compact PCI Serial devices.
|
|
5
5
|
Author-email: Jan Jansen <jan@ekf.de>, Klaus Popp <klaus.popp@ci4rail.com>, Felix Päßler <fp@ekf.de>
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
7
|
Requires-Dist: anytree
|
|
8
8
|
Requires-Dist: click>=8.0.1
|
|
9
9
|
Requires-Dist: crcmod
|
|
10
10
|
Requires-Dist: gpiod>=2.1.0
|
|
11
11
|
Requires-Dist: hexdump
|
|
12
|
+
Requires-Dist: io4edge-client>=2.0.3
|
|
12
13
|
Requires-Dist: ipdb>=0.13.13
|
|
13
14
|
Requires-Dist: more-itertools
|
|
14
15
|
Requires-Dist: munch
|
|
16
|
+
Requires-Dist: pillow
|
|
17
|
+
Requires-Dist: protobuf>=6.32.1
|
|
15
18
|
Requires-Dist: schema>=0.7.7
|
|
16
19
|
Requires-Dist: smbus2
|
|
17
20
|
Requires-Dist: termcolor>=3.0.1
|
|
@@ -6,7 +6,7 @@ ekfsm/lock.py,sha256=dnPjLXWfWIRnLcGec8g-imuqbmqqXWza8OGhS9Aqydk,3236
|
|
|
6
6
|
ekfsm/log.py,sha256=_GC8Y7a4fFV4_DNicbwQ-5rRzNQU6WSotXd2etXSrZk,866
|
|
7
7
|
ekfsm/py.typed,sha256=1gNRtmxvYcVqDDEyAzBLnD8dAOweUfYxW2ZPdJzN1fg,102
|
|
8
8
|
ekfsm/simctrl.py,sha256=WXPpWIju6b8Ch7FZW1PaPrWn7D7fP6gw37-ri-OJERE,5382
|
|
9
|
-
ekfsm/system.py,sha256=
|
|
9
|
+
ekfsm/system.py,sha256=c3jbQa_DxZVur8MsD8gYgK6jkAV55U19MipiDqemzRg,12130
|
|
10
10
|
ekfsm/utils.py,sha256=eOgr4da-dxoMQ6ymjgx_nyBbea8Ck_LAQ8uLM4JgH3c,1179
|
|
11
11
|
ekfsm/boards/oem/ekf/ccu.yaml,sha256=qgr7YZO0kEddD9K6tv6222NyozkRNuF7NFw6hyX0XgE,2094
|
|
12
12
|
ekfsm/boards/oem/ekf/sc5-festival.yaml,sha256=_0kS5GegfyOt5CTJc9kY6HJbr9yZo4i18sVo6F4KE9c,772
|
|
@@ -15,32 +15,42 @@ ekfsm/boards/oem/ekf/se5-club.yaml,sha256=j3u6sDwXMUBM0LNKwVm920w3T3tzjia2BRTQb2
|
|
|
15
15
|
ekfsm/boards/oem/ekf/sn4-djembe.yaml,sha256=ddLDdw7JpPpvR3TmlcTxNVNTOueTl6_A9LSveFrtz3E,1051
|
|
16
16
|
ekfsm/boards/oem/ekf/spv-mystic.yaml,sha256=zcLiNE7wVdXIT4vkwEYSqQ8ff-KEjCHfHnQzzPXJQ4E,1804
|
|
17
17
|
ekfsm/boards/oem/ekf/sq1-track.yaml,sha256=YU83BQjGu-4ejirwnGxd38sJme859kdRovkZyiOJciU,1050
|
|
18
|
-
ekfsm/boards/oem/ekf/sq3-quartet.yaml,sha256=
|
|
18
|
+
ekfsm/boards/oem/ekf/sq3-quartet.yaml,sha256=JaHJn_lph2iwLz6cwXu0bjRMgj33OXt1-VBNGFu0U3s,1330
|
|
19
19
|
ekfsm/boards/oem/ekf/srf-fan.yaml,sha256=Mcu1Q8B1Ih10hoc_hbkGlppBmbOFcufsVUR42iW4Rwc,1368
|
|
20
20
|
ekfsm/boards/oem/ekf/sur-uart.yaml,sha256=VaNP2BSlNTi1lDco16Ma9smPEAMaVKvx-ZNDcm3QptM,1890
|
|
21
|
+
ekfsm/boards/oem/ekf/z1010.yaml,sha256=oz1BI2dGlk3vn0g58-QGC1k35-V0Svh4ESpwHlneJBs,2560
|
|
21
22
|
ekfsm/boards/oem/hitron/hdrc-300s.yaml,sha256=SwBHTWVqENBun_iZattPbvA9koc-LOI_MIXjLahKyyI,548
|
|
22
23
|
ekfsm/core/__init__.py,sha256=xfuU072JY_--561hfSS8ToBM-wgswY4Z-YwDMZkVA6c,348
|
|
23
|
-
ekfsm/core/components.py,sha256=
|
|
24
|
+
ekfsm/core/components.py,sha256=iTetqtzNjEEj6FDJNfvXxW_cNNRlLX5_WgB5z3g3zqg,3883
|
|
25
|
+
ekfsm/core/connections.py,sha256=ffvqohwFxUnJTFeHG_O7SmXtNGOZqqTZ9cOfGvHC2P8,458
|
|
24
26
|
ekfsm/core/probe.py,sha256=DgJvkvMjVk09n0Rzn13ybRvidrmFn_D2PD56XS-KgxU,262
|
|
25
|
-
ekfsm/core/slots.py,sha256=
|
|
26
|
-
ekfsm/core/sysfs.py,sha256=
|
|
27
|
-
ekfsm/core/utils.py,sha256=
|
|
28
|
-
ekfsm/devices/__init__.py,sha256=
|
|
29
|
-
ekfsm/devices/
|
|
30
|
-
ekfsm/devices/
|
|
27
|
+
ekfsm/core/slots.py,sha256=qmxfssVitsMFZYbJRCpOOsvEGqh8JVYdRS-_5BliOF4,6580
|
|
28
|
+
ekfsm/core/sysfs.py,sha256=1UJ19ZISCnQ4Zz3fwZmad7dle85mhNugF4beTVdapQE,8228
|
|
29
|
+
ekfsm/core/utils.py,sha256=AjVj_QCb9umUmZZsGFPyCISdOKYlhRRSOTVjPu_gxyA,4678
|
|
30
|
+
ekfsm/devices/__init__.py,sha256=EDFzBuUHt_3_6JD4cageHWZfoMn3WUIIDZk4yEOWgfg,1451
|
|
31
|
+
ekfsm/devices/button.py,sha256=JZr9v8_z12GlVBQ-4b08AY40cqy4mErvZtxt_q4pbr8,1893
|
|
32
|
+
ekfsm/devices/buttonArray.py,sha256=YwRRUY-7f2QEc5bE_qXWg4zulupn7mrcpco3pARf9N0,8141
|
|
33
|
+
ekfsm/devices/colorLed.py,sha256=i6RXR8QZq3ukGPd3PszAHH_p5_JesDbm2EaLKIM-Yls,2824
|
|
34
|
+
ekfsm/devices/coretemp.py,sha256=rurB6eq7yIdwupusla4DzAWOz4i4Xe1RgOoeuMlaJX8,2897
|
|
35
|
+
ekfsm/devices/eeprom.py,sha256=p-ACUn1f9xH-Hjx4oLPmXGRHLbNf94q99EPLfWtV-2M,33070
|
|
31
36
|
ekfsm/devices/ekf_ccu_uc.py,sha256=hjs5r7TKsrFhyyGKClgSFBpchQpFcE7fTZeuLrYiflY,15905
|
|
32
37
|
ekfsm/devices/ekf_sur_led.py,sha256=qpCn7qj4v27QjxB5xTC5wIXKfefpveOd3FPK3JElyVk,1997
|
|
33
|
-
ekfsm/devices/generic.py,sha256=
|
|
38
|
+
ekfsm/devices/generic.py,sha256=4fwwnUyToQ7bvQ7U3tZ7Huynu7ruf2Fog_KAqkO3yN0,13365
|
|
34
39
|
ekfsm/devices/gpio.py,sha256=37P7uu-ncg0TWf0Xs1iZM-PrX7F_09asd4IhWj6z21Y,10058
|
|
35
40
|
ekfsm/devices/iio.py,sha256=1Jyh5wJ53DxvpWNBqYW07kkaAN9446ebWGCMk2UIuWM,1265
|
|
36
41
|
ekfsm/devices/iio_thermal_humidity.py,sha256=KCeEqBlczroxp-hjsiRlXQdmmnJR9Ck3d3ztths5Vvc,1547
|
|
37
42
|
ekfsm/devices/imu.py,sha256=GwJrnC-WztpE5oGnkIp-laFkSp3_gbSp9YpJ8jBsUOs,423
|
|
43
|
+
ekfsm/devices/io4edge.py,sha256=PBjWygDWSUpB0prmYyjUi2cBxQsDyeeqiw3ykfIrdmQ,3406
|
|
44
|
+
ekfsm/devices/ledArray.py,sha256=NdZ3zQpApL___-r_bv5YPBQsabo5qQxvXil2pfOZv6Y,1616
|
|
38
45
|
ekfsm/devices/mux.py,sha256=QpVWsD43Mx1mtCDG_nOxtHeIeU2Cigc62UljJ_utSXQ,1974
|
|
39
|
-
ekfsm/devices/
|
|
40
|
-
ekfsm/devices/
|
|
46
|
+
ekfsm/devices/pixelDisplay.py,sha256=Td-MhNYzJVcDrFzjTcnyrOYpXn2oz5w9YOttJqHZMD4,4573
|
|
47
|
+
ekfsm/devices/pmbus.py,sha256=-3p-D0w4smzRCeqZWCure8I2Lx4y310kG1U0Rmr890c,7104
|
|
48
|
+
ekfsm/devices/smbios.py,sha256=rH60ixqSGv_b5TgloJjH_kwZShefFnlCebQDpdQZx7M,1803
|
|
41
49
|
ekfsm/devices/smbus.py,sha256=kbtjEnfrVI6lbfqAbojVqO5nnnpa6HanLf0X2iZjgCg,500
|
|
50
|
+
ekfsm/devices/thermal_humidity.py,sha256=t848kJArG0VAEX5nOnRKomdFdx4wxFflBGMsg_wgZKw,2386
|
|
42
51
|
ekfsm/devices/utils.py,sha256=qeDNpTpQ3bLGYERAH5lMsifmOaEcQ32FOwEt8tvmjWU,174
|
|
43
|
-
ekfsm
|
|
44
|
-
ekfsm-1.
|
|
45
|
-
ekfsm-1.
|
|
46
|
-
ekfsm-1.
|
|
52
|
+
ekfsm/devices/watchdog.py,sha256=SEsF9dztlLfUSvD5r9yMWegXtsefwGXY3W1oJE63OMs,2224
|
|
53
|
+
ekfsm-1.4.0.dist-info/METADATA,sha256=3zvr5flteMv9NFVXJEe_uI2fZWbwpk2gHqgY9eP3q0Y,6722
|
|
54
|
+
ekfsm-1.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
55
|
+
ekfsm-1.4.0.dist-info/entry_points.txt,sha256=WhUR4FzuxPoGrbTOKLsNJO7NAnk2qd4T30fqzN1yLw8,45
|
|
56
|
+
ekfsm-1.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|