ekfsm 1.4.0a43__tar.gz → 1.4.0a60__tar.gz

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.

Files changed (197) hide show
  1. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/PKG-INFO +4 -4
  2. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/devenv.lock +2 -2
  3. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/z1010.yaml +8 -1
  4. ekfsm-1.4.0a60/ekfsm/core/connections.py +19 -0
  5. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/core/sysfs.py +32 -2
  6. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/button.py +15 -0
  7. ekfsm-1.4.0a60/ekfsm/devices/buttonArray.py +206 -0
  8. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/colorLed.py +33 -2
  9. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/coretemp.py +26 -3
  10. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/eeprom.py +4 -4
  11. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/generic.py +41 -12
  12. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/io4edge.py +19 -3
  13. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/ledArray.py +20 -2
  14. ekfsm-1.4.0a60/ekfsm/devices/pixelDisplay.py +137 -0
  15. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/pmbus.py +8 -4
  16. ekfsm-1.4.0a60/ekfsm/devices/smbios.py +60 -0
  17. ekfsm-1.4.0a60/ekfsm/devices/thermal_humidity.py +78 -0
  18. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/watchdog.py +26 -2
  19. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/pyproject.toml +4 -4
  20. ekfsm-1.4.0a60/tests/cctv.py +80 -0
  21. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/cctv.yaml +1 -1
  22. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sq3-only.py +11 -8
  23. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/uv.lock +58 -267
  24. ekfsm-1.4.0a43/ekfsm/devices/buttonArray.py +0 -104
  25. ekfsm-1.4.0a43/ekfsm/devices/pixelDisplay.py +0 -88
  26. ekfsm-1.4.0a43/ekfsm/devices/smbios.py +0 -42
  27. ekfsm-1.4.0a43/ekfsm/devices/thermal_humidity.py +0 -49
  28. ekfsm-1.4.0a43/tests/cctv.py +0 -41
  29. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.env +0 -0
  30. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.envrc +0 -0
  31. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.flake8 +0 -0
  32. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.gitattributes +0 -0
  33. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.gitignore +0 -0
  34. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.gitlab-ci.yml +0 -0
  35. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.readthedocs.yaml +0 -0
  36. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.vscode/launch.json +0 -0
  37. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/.vscode/settings.json +0 -0
  38. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/GitVersion.yml +0 -0
  39. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/LICENSE.md +0 -0
  40. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/README.md +0 -0
  41. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/devenv.nix +0 -0
  42. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/devenv.yaml +0 -0
  43. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/.gitignore +0 -0
  44. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/Makefile +0 -0
  45. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/requirements.txt +0 -0
  46. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/_static/devices.drawio.png +0 -0
  47. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/_static/devices.drawio.svg +0 -0
  48. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/_static/ekfsm_system.drawio.png +0 -0
  49. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/_static/ekfsm_system.drawio.svg +0 -0
  50. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/ccu.rst +0 -0
  51. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/sc5-festival.rst +0 -0
  52. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/sc9-toccata.rst +0 -0
  53. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/se5-club.rst +0 -0
  54. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/sn4-djembe.rst +0 -0
  55. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/snippets/cpci_inventory.rst +0 -0
  56. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/spv-mystic.rst +0 -0
  57. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/sq1-track.rst +0 -0
  58. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/sq3-quartet.rst +0 -0
  59. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/ekf/sur-uart.rst +0 -0
  60. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards/hitron/hdrc-300s.rst +0 -0
  61. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/boards.rst +0 -0
  62. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/conf.py +0 -0
  63. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/index.rst +0 -0
  64. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/intro.rst +0 -0
  65. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/reference/ekfsm.rst +0 -0
  66. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/reference/index.rst +0 -0
  67. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/docs/source/reference/systemconfig.rst +0 -0
  68. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/__init__.py +0 -0
  69. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/ccu.yaml +0 -0
  70. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/sc5-festival.yaml +0 -0
  71. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/sc9-toccata.yaml +0 -0
  72. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/se5-club.yaml +0 -0
  73. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/sn4-djembe.yaml +0 -0
  74. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/spv-mystic.yaml +0 -0
  75. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/sq1-track.yaml +0 -0
  76. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/sq3-quartet.yaml +0 -0
  77. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/srf-fan.yaml +0 -0
  78. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/ekf/sur-uart.yaml +0 -0
  79. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/boards/oem/hitron/hdrc-300s.yaml +0 -0
  80. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/cli.py +0 -0
  81. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/config.py +0 -0
  82. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/core/__init__.py +0 -0
  83. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/core/components.py +0 -0
  84. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/core/probe.py +0 -0
  85. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/core/slots.py +0 -0
  86. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/core/utils.py +0 -0
  87. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/__init__.py +0 -0
  88. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/ekf_ccu_uc.py +0 -0
  89. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/ekf_sur_led.py +0 -0
  90. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/gpio.py +0 -0
  91. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/iio.py +0 -0
  92. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/iio_thermal_humidity.py +0 -0
  93. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/imu.py +0 -0
  94. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/mux.py +0 -0
  95. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/smbus.py +0 -0
  96. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/devices/utils.py +0 -0
  97. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/exceptions.py +0 -0
  98. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/lock.py +0 -0
  99. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/log.py +0 -0
  100. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/py.typed +0 -0
  101. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/simctrl.py +0 -0
  102. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/system.py +0 -0
  103. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/ekfsm/utils.py +0 -0
  104. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/hack/bringup_zip_i2c_devs.sh +0 -0
  105. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/scripts/modify-acpi-table.sh +0 -0
  106. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/__init__.py +0 -0
  107. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/basic_sim.py +0 -0
  108. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/ccu-test.py +0 -0
  109. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/ccu_wokwi_sim.py +0 -0
  110. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/data/cfg_simple.yaml +0 -0
  111. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/locking/lock_tester.py +0 -0
  112. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/locking/test_lock.py +0 -0
  113. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/props.py +0 -0
  114. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/run.py +0 -0
  115. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sc5-hitron-only.yaml +0 -0
  116. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/SQ3.png +0 -0
  117. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/__init__.py +0 -0
  118. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/bus/i2c/drivers/at24/.keep +0 -0
  119. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/bus/i2c/drivers/pca953x/.keep +0 -0
  120. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/bus/i2c/drivers/pca954x/.keep +0 -0
  121. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/class/hwmon/hwmon2/name +0 -0
  122. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/class/hwmon/hwmon2/temp1_input +0 -0
  123. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-10/firmware_node/adr +0 -0
  124. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-10/name +0 -0
  125. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-10/new_device +0 -0
  126. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-11/firmware_node/adr +0 -0
  127. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-11/name +0 -0
  128. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-11/new_device +0 -0
  129. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-12/firmware_node/adr +0 -0
  130. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-12/name +0 -0
  131. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-12/new_device +0 -0
  132. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/firmware_node/adr +0 -0
  133. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/i2c-PRP0002:01/firmware_node/description +0 -0
  134. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/i2c-PRP0002:01/gpiochip1/dev +0 -0
  135. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/i2c-PRP0002:01/name +0 -0
  136. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/i2c-PRP0002:02/eeprom +0 -0
  137. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/i2c-PRP0002:02/firmware_node/description +0 -0
  138. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/i2c-PRP0002:02/name +0 -0
  139. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/name +0 -0
  140. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-14/new_device +0 -0
  141. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-15/firmware_node/adr +0 -0
  142. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-15/name +0 -0
  143. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-15/new_device +0 -0
  144. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-16/firmware_node/adr +0 -0
  145. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-16/name +0 -0
  146. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-16/new_device +0 -0
  147. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-17/firmware_node/adr +0 -0
  148. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-17/name +0 -0
  149. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-17/new_device +0 -0
  150. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/firmware_node/adr +0 -0
  151. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/i2c-PRP0001:01/firmware_node/description +0 -0
  152. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/i2c-PRP0001:01/gpiochip1/dev +0 -0
  153. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/i2c-PRP0001:01/name +0 -0
  154. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/i2c-PRP0001:02/eeprom +0 -0
  155. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/i2c-PRP0001:02/firmware_node/description +0 -0
  156. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/i2c-PRP0001:02/name +0 -0
  157. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/name +0 -0
  158. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-9/new_device +0 -0
  159. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:00/firmware_node/description +0 -0
  160. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:00/name +0 -0
  161. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/firmware_node/description +0 -0
  162. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/curr1_input +0 -0
  163. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/curr2_input +0 -0
  164. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/in1_input +0 -0
  165. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/in2_input +0 -0
  166. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/model +0 -0
  167. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/revision +0 -0
  168. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/serial +0 -0
  169. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/temp1_input +0 -0
  170. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/hwmon/hwmon99/vendor +0 -0
  171. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0001:03/name +0 -0
  172. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0002:00/firmware_node/description +0 -0
  173. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/i2c-PRP0002:00/name +0 -0
  174. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:15.1/i2c_designware.2/i2c-1/new_device +0 -0
  175. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:1f.4/i2c-7/7-0057/eeprom +0 -0
  176. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/pci0000:00/0000:00:1f.4/i2c-7/7-0057/name +0 -0
  177. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/devices/virtual/dmi/id/board_version +0 -0
  178. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/kernel/debug/pmbus/hwmon99/status0_input +0 -0
  179. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/sys/kernel/debug/pmbus/hwmon99/status1_input +0 -0
  180. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/test_system.yaml +0 -0
  181. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sim/test_system_inconsistent.yaml +0 -0
  182. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/sq3-only.yaml +0 -0
  183. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/srf-fan-test.py +0 -0
  184. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/srf-fan-test.yaml +0 -0
  185. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/test_config.py +0 -0
  186. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/test_module_schema.py +0 -0
  187. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/test_sim-ccu-eeprom.py +0 -0
  188. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/test_sim1.py +0 -0
  189. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/test_sim2.py +0 -0
  190. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2-ccu-only.yaml +0 -0
  191. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2-comp1.yaml +0 -0
  192. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2-comp1_smoke.py +0 -0
  193. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2-comp2.yaml +0 -0
  194. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2-comp2_smoke.py +0 -0
  195. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2_ccu_exp.py +0 -0
  196. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2_ccu_imu.py +0 -0
  197. {ekfsm-1.4.0a43 → ekfsm-1.4.0a60}/tests/zip2_psu.py +0 -0
@@ -1,20 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ekfsm
3
- Version: 1.4.0a43
3
+ Version: 1.4.0a60
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.10
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>=1.6.2
12
+ Requires-Dist: io4edge-client>=2.0.3
13
13
  Requires-Dist: ipdb>=0.13.13
14
14
  Requires-Dist: more-itertools
15
15
  Requires-Dist: munch
16
16
  Requires-Dist: pillow
17
- Requires-Dist: protobuf
17
+ Requires-Dist: protobuf>=6.32.1
18
18
  Requires-Dist: schema>=0.7.7
19
19
  Requires-Dist: smbus2
20
20
  Requires-Dist: termcolor>=3.0.1
@@ -75,10 +75,10 @@
75
75
  ]
76
76
  },
77
77
  "locked": {
78
- "lastModified": 1757588530,
78
+ "lastModified": 1759523803,
79
79
  "owner": "cachix",
80
80
  "repo": "pre-commit-hooks.nix",
81
- "rev": "b084b2c2b6bc23e83bbfe583b03664eb0b18c411",
81
+ "rev": "cfc9f7bb163ad8542029d303e599c0f7eee09835",
82
82
  "type": "github"
83
83
  },
84
84
  "original": {
@@ -42,7 +42,7 @@ children:
42
42
  # - write: write_customer_area
43
43
  # - read: customer_area
44
44
  - device_type: IO4Edge
45
- name: "SMC"
45
+ name: "I4E"
46
46
  provides:
47
47
  management:
48
48
  - identify_firmware
@@ -85,3 +85,10 @@ children:
85
85
  - kick
86
86
  - device_type: ThermalHumidity
87
87
  name: "th"
88
+ - device_type: ButtonArray
89
+ name: "buttons"
90
+ service_suffix: "gpios"
91
+ children:
92
+ - device_type: Button
93
+ name: "eject"
94
+ channel_id: 2
@@ -0,0 +1,19 @@
1
+ from contextlib import contextmanager
2
+
3
+
4
+ class Connectable:
5
+
6
+ def __init__(self, client=None):
7
+ self._client = client
8
+ self._connected = False
9
+
10
+ @contextmanager
11
+ def connect(self):
12
+ if not self._connected:
13
+ client = self._client(self.service_addr, command_timeout=self.timeout)
14
+ self._connected = True
15
+ try:
16
+ yield client
17
+ finally:
18
+ client.close()
19
+ del client
@@ -166,7 +166,7 @@ class SysfsDevice(MutableMapping):
166
166
 
167
167
  def read_int(self, attr) -> int:
168
168
  """
169
- Read a sysfs attribute as an integer
169
+ Read a sysfs attribute stored as a string as an integer
170
170
 
171
171
  Parameters
172
172
  ----------
@@ -186,7 +186,7 @@ class SysfsDevice(MutableMapping):
186
186
  """
187
187
  try:
188
188
  value = self.read_attr_utf8(attr).strip()
189
- return int(value, 16)
189
+ return int(value)
190
190
  except StopIteration as e:
191
191
  raise SysFSError(f"'{attr}' sysfs attribute does not exist") from e
192
192
  except SysFSError:
@@ -194,6 +194,36 @@ class SysfsDevice(MutableMapping):
194
194
  except ValueError as e:
195
195
  raise ConversionError("Failed to convert sysfs value to int") from e
196
196
 
197
+ def read_hex(self, attr) -> int:
198
+ """
199
+ Read a sysfs attribute stored as a hexadecimal integer as integer
200
+
201
+ Parameters
202
+ ----------
203
+ attr: str
204
+ The sysfs attribute to read
205
+
206
+ Returns
207
+ -------
208
+ The sysfs attribute as a hexadecimal integer
209
+
210
+ Raises
211
+ ------
212
+ SysFSError
213
+ If the sysfs attribute does not exist
214
+ ConversionError
215
+ If the sysfs attribute could not be converted to a hexadecimal integer
216
+ """
217
+ try:
218
+ value = self.read_attr_utf8(attr).strip()
219
+ return int(value, 16)
220
+ except StopIteration as e:
221
+ raise SysFSError(f"'{attr}' sysfs attribute does not exist") from e
222
+ except SysFSError:
223
+ raise
224
+ except ValueError as e:
225
+ raise ConversionError("Failed to convert sysfs value to hex int") from e
226
+
197
227
  def read_utf8(self, attr, strip=True) -> str:
198
228
  """
199
229
  Read a sysfs attribute as a UTF-8 encoded string
@@ -1,5 +1,8 @@
1
1
  from typing import Callable
2
2
  from ekfsm.devices.generic import Device
3
+ from ekfsm.log import ekfsm_logger
4
+
5
+ logger = ekfsm_logger(__name__)
3
6
 
4
7
 
5
8
  class Button(Device):
@@ -17,12 +20,15 @@ class Button(Device):
17
20
  *args,
18
21
  **kwargs,
19
22
  ):
23
+ logger.debug(f"Initializing Button '{name}' on channel {channel_id}")
20
24
 
21
25
  super().__init__(name, parent, children, abort, *args, **kwargs)
22
26
 
23
27
  self.channel_id = channel_id
28
+ logger.debug(f"Button '{name}' assigned to channel {channel_id}")
24
29
 
25
30
  self._handler: Callable | None = None
31
+ logger.info(f"Button '{name}' initialized on channel {channel_id}")
26
32
 
27
33
  @property
28
34
  def handler(self):
@@ -43,8 +49,17 @@ class Button(Device):
43
49
  """
44
50
  if callable(func):
45
51
  self._handler = func
52
+ logger.info(
53
+ f"Handler set for button '{self.name}' on channel {self.channel_id}"
54
+ )
55
+ logger.debug(
56
+ f"Handler function: {func.__name__ if hasattr(func, '__name__') else str(func)}"
57
+ )
46
58
  else:
47
59
  self._handler = None
60
+ logger.debug(
61
+ f"Handler cleared for button '{self.name}' on channel {self.channel_id}"
62
+ )
48
63
 
49
64
  def __repr__(self):
50
65
  return f"{self.name}; Channel ID: {self.channel_id}"
@@ -0,0 +1,206 @@
1
+ import threading
2
+ from ekfsm.devices.button import Button
3
+ from ekfsm.devices.generic import Device
4
+ from ekfsm.devices.io4edge import IO4Edge
5
+ from ekfsm.log import ekfsm_logger
6
+ from io4edge_client.binaryiotypeb import Client, Pb
7
+ import io4edge_client.functionblock as fb
8
+
9
+ logger = ekfsm_logger(__name__)
10
+
11
+
12
+ class ButtonArray(Device):
13
+ """
14
+ Device class for handling an io4edge button array.
15
+
16
+ To read button events, call the `read` method in a separate thread.
17
+
18
+ Note
19
+ ----
20
+ Button handlers are called in the context of the `read` method's thread and need to be set in the Button instances.
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ name: str,
26
+ parent: IO4Edge,
27
+ children: list[Device] | None = None,
28
+ abort: bool = False,
29
+ service_suffix: str | None = None,
30
+ keepaliveInterval: int = 10000,
31
+ *args,
32
+ **kwargs,
33
+ ):
34
+ logger.debug(
35
+ f"Initializing ButtonArray '{name}' with parent device {parent.deviceId}"
36
+ )
37
+
38
+ Device.__init__(self, name, parent, children, abort, *args, **kwargs)
39
+
40
+ self.name = name
41
+
42
+ if service_suffix is not None:
43
+ self.service_suffix = service_suffix
44
+ logger.debug(f"Using custom service suffix: {service_suffix}")
45
+ else:
46
+ self.service_suffix = name
47
+ logger.debug(f"Using default service suffix: {name}")
48
+
49
+ self.service_addr = f"{parent.deviceId}-{self.service_suffix}"
50
+ self.timeout = keepaliveInterval / 1000 + 5
51
+
52
+ logger.info(
53
+ f"ButtonArray '{name}' configured with service address: {self.service_addr}"
54
+ )
55
+ logger.debug(
56
+ f"Keepalive interval: {keepaliveInterval}ms, timeout: {self.timeout}s"
57
+ )
58
+
59
+ try:
60
+ self.client = Client(
61
+ self.service_addr, command_timeout=self.timeout, connect=False
62
+ )
63
+ logger.debug(f"IO4Edge client created for service: {self.service_addr}")
64
+ except Exception as e:
65
+ logger.error(
66
+ f"Failed to create IO4Edge client for {self.service_addr}: {e}"
67
+ )
68
+ raise
69
+
70
+ self.subscriptionType = Pb.SubscriptionType.BINARYIOTYPEB_ON_RISING_EDGE
71
+ self.stream_cfg = fb.Pb.StreamControlStart(
72
+ bucketSamples=1, # 1 sample per bucket, also ein event pro bucket
73
+ keepaliveInterval=keepaliveInterval,
74
+ bufferedSamples=2, # 2 samples werden gepuffert
75
+ low_latency_mode=True, # schickt soweit moeglich sofort die Events
76
+ )
77
+ logger.debug(
78
+ "Stream configuration initialized with rising edge subscription and low latency mode"
79
+ )
80
+
81
+ # Log button children count
82
+ button_count = sum(1 for child in (children or []) if isinstance(child, Button))
83
+ logger.info(f"ButtonArray '{name}' initialized with {button_count} button(s)")
84
+
85
+ def read(self, stop_event: threading.Event | None = None, timeout: float = 1):
86
+ """
87
+ Read all button events and dispatch to handlers.
88
+
89
+ Parameters
90
+ ----------
91
+ stop_event : threading.Event, optional
92
+ Event to signal stopping the reading loop. If None, the loop will run indefinitely.
93
+ timeout : float, optional
94
+ Timeout for reading from the stream in seconds. Default is 0.1 seconds.
95
+
96
+ Note
97
+ ----
98
+ This method blocks and should be run in a separate thread.
99
+ """
100
+ button_channels = [
101
+ button for button in self.children if isinstance(button, Button)
102
+ ]
103
+
104
+ if not button_channels:
105
+ logger.warning(
106
+ f"No button children found in ButtonArray '{self.name}', read operation will have no effect"
107
+ )
108
+ return
109
+
110
+ logger.info(
111
+ f"Starting button event reading for {len(button_channels)} buttons on '{self.name}'"
112
+ )
113
+ logger.debug(
114
+ f"Read timeout: {timeout}s, stop_event provided: {stop_event is not None}"
115
+ )
116
+
117
+ try:
118
+ with self.client as client:
119
+ logger.debug(
120
+ f"IO4Edge client connected to service: {self.service_addr}"
121
+ )
122
+
123
+ # Prepare subscription channels
124
+ subscribe_channels = tuple(
125
+ Pb.SubscribeChannel(
126
+ channel=button.channel_id,
127
+ subscriptionType=self.subscriptionType,
128
+ )
129
+ for button in button_channels
130
+ )
131
+
132
+ channel_ids = [button.channel_id for button in button_channels]
133
+ logger.debug(
134
+ f"Subscribing to {len(subscribe_channels)} button channels: {channel_ids}"
135
+ )
136
+
137
+ client.start_stream(
138
+ Pb.StreamControlStart(subscribeChannel=subscribe_channels),
139
+ self.stream_cfg,
140
+ )
141
+ logger.info(
142
+ f"Button event stream started for ButtonArray '{self.name}'"
143
+ )
144
+
145
+ event_count = 0
146
+ try:
147
+ while not (stop_event and stop_event.is_set()):
148
+ try:
149
+ _, samples = client.read_stream(timeout=timeout)
150
+
151
+ for sample in samples.samples:
152
+ for button in button_channels:
153
+ pressed = bool(
154
+ sample.inputs & (1 << button.channel_id)
155
+ )
156
+ if pressed:
157
+ event_count += 1
158
+ button_name = getattr(button, "name", "unnamed")
159
+ logger.debug(
160
+ f"Button press on channel {button.channel_id} ({button_name})"
161
+ )
162
+
163
+ if button.handler:
164
+ try:
165
+ logger.debug(
166
+ f"Calling handler for button on channel {button.channel_id}"
167
+ )
168
+ button.handler()
169
+ except Exception as e:
170
+ logger.error(
171
+ f"Error in button handler for channel {button.channel_id}: {e}"
172
+ )
173
+ else:
174
+ logger.debug(
175
+ f"No handler set for button on channel {button.channel_id}"
176
+ )
177
+
178
+ except TimeoutError:
179
+ # Timeout is expected during normal operation
180
+ continue
181
+ except Exception as e:
182
+ logger.error(
183
+ f"Error reading button events from stream: {e}"
184
+ )
185
+ break
186
+
187
+ except KeyboardInterrupt:
188
+ logger.info(
189
+ f"Button reading interrupted for ButtonArray '{self.name}'"
190
+ )
191
+ finally:
192
+ logger.info(
193
+ f"Button event reading stopped for '{self.name}' after processing {event_count} events"
194
+ )
195
+ if stop_event:
196
+ stop_event.clear()
197
+ logger.debug("Stop event cleared")
198
+
199
+ except Exception as e:
200
+ logger.error(
201
+ f"Failed to establish connection or start stream for ButtonArray '{self.name}': {e}"
202
+ )
203
+ raise
204
+
205
+ def __repr__(self):
206
+ return f"{self.name}; Service Address: {self.service_addr}"
@@ -1,7 +1,10 @@
1
1
  from ekfsm.devices.generic import Device
2
2
  from ekfsm.devices.ledArray import LEDArray
3
+ from ekfsm.log import ekfsm_logger
3
4
  from io4edge_client.api.colorLED.python.colorLED.v1alpha1.colorLED_pb2 import Color
4
5
 
6
+ logger = ekfsm_logger(__name__)
7
+
5
8
 
6
9
  class ColorLED(Device):
7
10
  """
@@ -18,6 +21,7 @@ class ColorLED(Device):
18
21
  *args,
19
22
  **kwargs,
20
23
  ):
24
+ logger.debug(f"Initializing ColorLED '{name}' on channel {channel_id}")
21
25
 
22
26
  super().__init__(name, parent, children, abort, *args, **kwargs)
23
27
 
@@ -25,6 +29,9 @@ class ColorLED(Device):
25
29
  self.channel_id = channel_id
26
30
 
27
31
  self.client = parent.client
32
+ logger.info(
33
+ f"ColorLED '{name}' initialized on channel {channel_id} with parent LEDArray"
34
+ )
28
35
 
29
36
  def describe(self):
30
37
  pass
@@ -44,7 +51,19 @@ class ColorLED(Device):
44
51
  TimeoutError
45
52
  if the command times out
46
53
  """
47
- return self.client.get(self.channel_id)
54
+ logger.debug(
55
+ f"Getting color LED state for '{self.name}' on channel {self.channel_id}"
56
+ )
57
+ try:
58
+ result = self.client.get(self.channel_id)
59
+ color, blink = result
60
+ logger.debug(f"ColorLED '{self.name}' state: color={color}, blink={blink}")
61
+ return result
62
+ except Exception as e:
63
+ logger.error(
64
+ f"Failed to get ColorLED '{self.name}' state on channel {self.channel_id}: {e}"
65
+ )
66
+ raise
48
67
 
49
68
  def set(self, color: Color, blink: bool) -> None:
50
69
  """
@@ -64,7 +83,19 @@ class ColorLED(Device):
64
83
  TimeoutError
65
84
  if the command times out
66
85
  """
67
- self.client.set(self.channel_id, color, blink)
86
+ logger.info(
87
+ f"Setting ColorLED '{self.name}' on channel {self.channel_id}: color={color}, blink={blink}"
88
+ )
89
+ try:
90
+ self.client.set(self.channel_id, color, blink)
91
+ logger.debug(
92
+ f"ColorLED '{self.name}' successfully set to color={color}, blink={blink}"
93
+ )
94
+ except Exception as e:
95
+ logger.error(
96
+ f"Failed to set ColorLED '{self.name}' on channel {self.channel_id}: {e}"
97
+ )
98
+ raise
68
99
 
69
100
  def __repr__(self):
70
101
  return f"{self.name}; Channel ID: {self.channel_id}"
@@ -7,6 +7,9 @@ from pathlib import Path
7
7
  import ekfsm.core
8
8
  from ekfsm.core.sysfs import sysfs_root
9
9
  from ekfsm.devices.generic import Device
10
+ from ekfsm.log import ekfsm_logger
11
+
12
+ logger = ekfsm_logger(__name__)
10
13
 
11
14
  # Path to the root of the HWMON sysfs filesystem
12
15
  HWMON_ROOT = sysfs_root() / Path("class/hwmon")
@@ -55,8 +58,16 @@ class CoreTemp(Device):
55
58
  *args,
56
59
  **kwargs,
57
60
  ):
58
- dir = find_core_temp_dir(sysfs_root() / Path("class/hwmon"))
59
- self.sysfs_device = ekfsm.core.sysfs.SysfsDevice(dir, False)
61
+ logger.debug(f"Initializing CoreTemp device '{name}'")
62
+
63
+ try:
64
+ dir = find_core_temp_dir(sysfs_root() / Path("class/hwmon"))
65
+ logger.debug(f"Found coretemp directory: {dir}")
66
+ self.sysfs_device = ekfsm.core.sysfs.SysfsDevice(dir, False)
67
+ logger.info(f"CoreTemp '{name}' initialized with sysfs device at {dir}")
68
+ except FileNotFoundError as e:
69
+ logger.error(f"Failed to initialize CoreTemp '{name}': {e}")
70
+ raise
60
71
 
61
72
  super().__init__(name, parent, None, abort, *args, **kwargs)
62
73
 
@@ -69,4 +80,16 @@ class CoreTemp(Device):
69
80
  int
70
81
  The CPU temperature in degrees Celsius.
71
82
  """
72
- return self.sysfs.read_int("temp1_input") / 1000
83
+ logger.debug(f"Reading CPU temperature for CoreTemp '{self.name}'")
84
+ try:
85
+ temp_raw = self.sysfs.read_float("temp1_input")
86
+ temp_celsius = temp_raw / 1000
87
+ logger.debug(
88
+ f"CoreTemp '{self.name}' raw reading: {temp_raw}, temperature: {temp_celsius}°C"
89
+ )
90
+ return temp_celsius
91
+ except Exception as e:
92
+ logger.error(
93
+ f"Failed to read CPU temperature for CoreTemp '{self.name}': {e}"
94
+ )
95
+ raise
@@ -520,8 +520,8 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
520
520
  The date the device was manufactured.
521
521
  """
522
522
  area = self._content[self._date_mft_index_start : self._date_mft_index_end]
523
- encoded_mft_date = area[::-1]
524
- return self._decode_date(encoded_mft_date)
523
+ # encoded_mft_date = area[::-1]
524
+ return self._decode_date(area)
525
525
 
526
526
  @validated
527
527
  def repaired_at(self) -> date:
@@ -533,8 +533,8 @@ class EKF_EEPROM(Validatable_EEPROM, ProbeableDevice):
533
533
  The most recent date the device was repaired.
534
534
  """
535
535
  area = self._content[self._date_rep_index_start : self._date_rep_index_end]
536
- encoded_rep_date = area[::-1]
537
- return self._decode_date(encoded_rep_date)
536
+ # encoded_rep_date = area[::-1]
537
+ return self._decode_date(area)
538
538
 
539
539
  @validated
540
540
  def write_repaired_at(self, date: date) -> None:
@@ -63,7 +63,9 @@ class Device(SysTree):
63
63
  try:
64
64
  func = list(interface.values())[0]
65
65
  except IndexError:
66
- raise ConfigError(f"{self.name}: No function given for interface {name}.")
66
+ raise ConfigError(
67
+ f"{self.name}: No function given for interface {name}."
68
+ )
67
69
 
68
70
  if not hasattr(self, func):
69
71
  if abort:
@@ -114,10 +116,14 @@ class Device(SysTree):
114
116
  return self.sysfs.read_float(attr)
115
117
  case "int":
116
118
  return self.sysfs.read_int(attr)
119
+ case "hex":
120
+ return self.sysfs.read_hex(attr)
117
121
  case _:
118
122
  raise UnsupportedModeError(f"Mode {mode} is not supported")
119
123
 
120
- def read_attr_or_default(self, attr: str, mode: str = "utf", strip: bool = True, default=None):
124
+ def read_attr_or_default(
125
+ self, attr: str, mode: str = "utf", strip: bool = True, default=None
126
+ ):
121
127
  try:
122
128
  return self.read_attr(attr, mode, strip)
123
129
  except UnsupportedModeError:
@@ -149,7 +155,11 @@ class Device(SysTree):
149
155
  None:
150
156
  If the sysfs device is not set or the attribute does not exist.
151
157
  """
152
- if self.sysfs_device is not None and len(attr) != 0 and attr in [x.name for x in self.sysfs_device.attributes]:
158
+ if (
159
+ self.sysfs_device is not None
160
+ and len(attr) != 0
161
+ and attr in [x.name for x in self.sysfs_device.attributes]
162
+ ):
153
163
  return self.sysfs_device.read_attr_bytes(attr)
154
164
  return None
155
165
 
@@ -222,7 +232,9 @@ class Device(SysTree):
222
232
 
223
233
  chip_addr = self.device_args.get("addr")
224
234
  if chip_addr is None:
225
- raise ConfigError(f"{self.name}: Chip address not provided in board definition")
235
+ raise ConfigError(
236
+ f"{self.name}: Chip address not provided in board definition"
237
+ )
226
238
 
227
239
  if not hasattr(self.parent, "sysfs_device") or self.parent.sysfs_device is None:
228
240
  # our device is the top level device of the slot
@@ -230,12 +242,16 @@ class Device(SysTree):
230
242
  slot_attributes = self.hw_module.slot.attributes
231
243
 
232
244
  if slot_attributes is None:
233
- raise ConfigError(f"{self.name}: Slot attributes not provided in system configuration")
245
+ raise ConfigError(
246
+ f"{self.name}: Slot attributes not provided in system configuration"
247
+ )
234
248
 
235
249
  if not self.hw_module.is_master:
236
250
  # slot coding is only used for non-master devices
237
251
  if not hasattr(slot_attributes, "slot_coding"):
238
- raise ConfigError(f"{self.name}: Slot coding not provided in slot attributes")
252
+ raise ConfigError(
253
+ f"{self.name}: Slot coding not provided in slot attributes"
254
+ )
239
255
 
240
256
  slot_coding_mask = 0xFF
241
257
 
@@ -246,7 +262,9 @@ class Device(SysTree):
246
262
 
247
263
  return chip_addr
248
264
 
249
- def get_i2c_sysfs_device(self, addr: int, driver_required=True, find_driver: Callable | None = None) -> SysfsDevice:
265
+ def get_i2c_sysfs_device(
266
+ self, addr: int, driver_required=True, find_driver: Callable | None = None
267
+ ) -> SysfsDevice:
250
268
  from ekfsm.core.components import HWModule
251
269
 
252
270
  parent = self.parent
@@ -275,8 +293,12 @@ class Device(SysTree):
275
293
  # regular I2C devices that follow the `${I2C_BUS}-${ADDR}` pattern. To address this issue, we
276
294
  # initialize the ACPI _STR object for each PRP device with the necessary information, which is
277
295
  # accessible in the `${DEVICE_SYSFS_PATH}/firmware_node/description` file.
278
- if (entry / "firmware_node").exists() and (entry / "firmware_node" / "description").exists():
279
- description = (entry / "firmware_node/description").read_text().strip()
296
+ if (entry / "firmware_node").exists() and (
297
+ entry / "firmware_node" / "description"
298
+ ).exists():
299
+ description = (
300
+ (entry / "firmware_node/description").read_text().strip()
301
+ )
280
302
  acpi_addr = int(description.split(" - ")[0], 16)
281
303
 
282
304
  if acpi_addr == addr:
@@ -289,11 +311,16 @@ class Device(SysTree):
289
311
  if acpi_addr == addr:
290
312
  return SysfsDevice(entry, driver_required, find_driver)
291
313
 
292
- raise FileNotFoundError(f"Device with address 0x{addr:x} not found in {i2c_bus_path}")
314
+ raise FileNotFoundError(
315
+ f"Device with address 0x{addr:x} not found in {i2c_bus_path}"
316
+ )
293
317
 
294
318
  @staticmethod
295
319
  def __master_i2c_get_config(master: "HWModule") -> dict:
296
- if master.config.get("bus_masters") is not None and master.config["bus_masters"].get("i2c") is not None:
320
+ if (
321
+ master.config.get("bus_masters") is not None
322
+ and master.config["bus_masters"].get("i2c") is not None
323
+ ):
297
324
  return master.config["bus_masters"]["i2c"]
298
325
  else:
299
326
  raise ConfigError("Master definition incomplete")
@@ -310,7 +337,9 @@ class Device(SysTree):
310
337
  else:
311
338
  # another board is the master
312
339
  if self.hw_module.slot.master is None:
313
- raise ConfigError(f"{self.name}: Master board not found in slot attributes")
340
+ raise ConfigError(
341
+ f"{self.name}: Master board not found in slot attributes"
342
+ )
314
343
 
315
344
  master = self.hw_module.slot.master
316
345
  master_key = self.hw_module.slot.slot_type.name