boneio 1.5.0.dev3__tar.gz → 1.5.0.dev5__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.
Files changed (470) hide show
  1. {boneio-1.5.0.dev3/boneio.egg-info → boneio-1.5.0.dev5}/PKG-INFO +1 -1
  2. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/input/detectors.py +45 -0
  3. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/output/basic.py +14 -2
  4. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/schema_converter.py +25 -1
  5. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/yaml_util.py +31 -19
  6. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/state/manager.py +26 -1
  7. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/input/manager.py +52 -0
  8. boneio-1.5.0.dev5/boneio/modbus/devices/energy_meters/dts1964_3f.json +247 -0
  9. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/energy_meters/le-03mw.json +369 -365
  10. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/energy_meters/le-03mwct.json +369 -365
  11. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +6 -1
  12. boneio-1.5.0.dev5/boneio/modbus/devices/energy_meters/sdm120.json +130 -0
  13. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/energy_meters/sdm630.json +5 -0
  14. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/energy_meters/socomec_e03.json +74 -11
  15. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/energy_meters/socomec_e23.json +124 -18
  16. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/hvac/eht-topventil-plus.json +37 -8
  17. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/hvac/fujitsu-ac.json +7 -2
  18. {boneio-1.5.0.dev3/boneio/modbus/devices/inverters → boneio-1.5.0.dev5/boneio/modbus/devices/hvac}/thessla.json +7 -2
  19. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/hvac/ventclear.json +8 -3
  20. {boneio-1.5.0.dev3/boneio/modbus/devices/other → boneio-1.5.0.dev5/boneio/modbus/devices/hvac}/wanas415.json +5 -2
  21. boneio-1.5.0.dev5/boneio/modbus/devices/inverters/sofar.json +396 -0
  22. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +7 -2
  23. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/other/n4dsc08.json +7 -2
  24. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/other/r4dcb08.json +70 -9
  25. boneio-1.5.0.dev5/boneio/modbus/devices/sensors/boneio-edge-temp.json +163 -0
  26. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/sensors/cwt.json +28 -4
  27. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +14 -2
  28. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/sensors/gdfs.json +7 -2
  29. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/sensors/gdfx.json +7 -2
  30. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/sensors/liquid-sensor.json +18 -3
  31. boneio-1.5.0.dev5/boneio/modbus/devices/sensors/pt100.json +33 -0
  32. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/sensors/sht20.json +27 -4
  33. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/sensors/sht30.json +27 -4
  34. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/derived/text.py +0 -1
  35. boneio-1.5.0.dev5/boneio/modbus/mock_coordinator.py +283 -0
  36. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/runner.py +11 -0
  37. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/schema.yaml +1 -27
  38. boneio-1.5.0.dev5/boneio/version.py +2 -0
  39. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/app.py +7 -0
  40. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/dashboard_cards.py +39 -0
  41. boneio-1.5.0.dev3/boneio/webui/frontend-dist/assets/ConfigEditor-DaxrGxsh.js → boneio-1.5.0.dev5/boneio/webui/frontend-dist/assets/ConfigEditor-B5IWaYQG.js +1 -1
  42. boneio-1.5.0.dev3/boneio/webui/frontend-dist/assets/aiWizardPrompt-D9Tr5iGZ.js → boneio-1.5.0.dev5/boneio/webui/frontend-dist/assets/aiWizardPrompt-DGU7pfbV.js +1 -1
  43. boneio-1.5.0.dev5/boneio/webui/frontend-dist/assets/index-D6g-vdBv.css +2 -0
  44. boneio-1.5.0.dev3/boneio/webui/frontend-dist/assets/index-B5k6qEwR.js → boneio-1.5.0.dev5/boneio/webui/frontend-dist/assets/index-Uwrd1-uP.js +29 -29
  45. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/index.html +2 -2
  46. {boneio-1.5.0.dev3/boneio/webui → boneio-1.5.0.dev5/boneio/webui/frontend-dist}/schema/config.schema.json +7 -1
  47. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +7 -1
  48. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/sw.js +1 -1
  49. boneio-1.5.0.dev5/boneio/webui/hvac_svg_templates.py +240 -0
  50. boneio-1.5.0.dev5/boneio/webui/modbus_card_templates.py +576 -0
  51. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/__init__.py +3 -0
  52. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/dashboard.py +33 -35
  53. boneio-1.5.0.dev5/boneio/webui/routes/dev_fake_device.py +703 -0
  54. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/modbus.py +40 -1
  55. {boneio-1.5.0.dev3/boneio/webui/frontend-dist → boneio-1.5.0.dev5/boneio/webui}/schema/config.schema.json +7 -1
  56. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/modbus_devices.schema.json +7 -1
  57. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5/boneio.egg-info}/PKG-INFO +1 -1
  58. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio.egg-info/SOURCES.txt +11 -7
  59. boneio-1.5.0.dev3/boneio/modbus/devices/energy_meters/sdm120.json +0 -126
  60. boneio-1.5.0.dev3/boneio/modbus/devices/inverters/sofar.json +0 -267
  61. boneio-1.5.0.dev3/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -148
  62. boneio-1.5.0.dev3/boneio/modbus/devices/sensors/dts1964_3f.json +0 -242
  63. boneio-1.5.0.dev3/boneio/modbus/devices/sensors/pt100.json +0 -21
  64. boneio-1.5.0.dev3/boneio/version.py +0 -2
  65. boneio-1.5.0.dev3/boneio/webui/frontend-dist/assets/index-CJECcrbK.css +0 -2
  66. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/LICENSE +0 -0
  67. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/MANIFEST.in +0 -0
  68. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/README.md +0 -0
  69. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/__init__.py +0 -0
  70. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.2/input.yaml +0 -0
  71. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.2/output_24_16.yaml +0 -0
  72. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.2/output_32_10.yaml +0 -0
  73. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.2/output_32_5.yaml +0 -0
  74. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.2/output_cover.yaml +0 -0
  75. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  76. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.3/input.yaml +0 -0
  77. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.3/output_24_16.yaml +0 -0
  78. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.3/output_32_10.yaml +0 -0
  79. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.3/output_32_5.yaml +0 -0
  80. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.3/output_cover.yaml +0 -0
  81. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  82. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.4/input.yaml +0 -0
  83. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.4/output_24_16.yaml +0 -0
  84. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.4/output_32_10.yaml +0 -0
  85. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.4/output_32_5.yaml +0 -0
  86. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.4/output_cover.yaml +0 -0
  87. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  88. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.5/input.yaml +0 -0
  89. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.5/output_24_16.yaml +0 -0
  90. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.5/output_32_10.yaml +0 -0
  91. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.5/output_cover.yaml +0 -0
  92. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  93. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.6/input.yaml +0 -0
  94. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.6/output_24_16.yaml +0 -0
  95. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.6/output_32_10.yaml +0 -0
  96. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.6/output_cover.yaml +0 -0
  97. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  98. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.7/input.yaml +0 -0
  99. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.7/output_24_16.yaml +0 -0
  100. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.7/output_32_10.yaml +0 -0
  101. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.7/output_48_4.yaml +0 -0
  102. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.7/output_cover.yaml +0 -0
  103. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  104. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.8/input.yaml +0 -0
  105. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.8/output_24_16.yaml +0 -0
  106. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.8/output_32_10.yaml +0 -0
  107. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.8/output_48_4.yaml +0 -0
  108. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.8/output_cover.yaml +0 -0
  109. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  110. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/bonecli.py +0 -0
  111. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/__init__.py +0 -0
  112. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/cover/__init__.py +0 -0
  113. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/cover/cover.py +0 -0
  114. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/cover/time_based.py +0 -0
  115. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/cover/venetian.py +0 -0
  116. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/group/__init__.py +0 -0
  117. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/group/output_group.py +0 -0
  118. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/input/__init__.py +0 -0
  119. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/input/binary_sensor.py +0 -0
  120. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/input/event.py +0 -0
  121. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/input/remote/__init__.py +0 -0
  122. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/input/remote/base.py +0 -0
  123. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/input/remote/esphome.py +0 -0
  124. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/irrigation/__init__.py +0 -0
  125. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/irrigation/controller.py +0 -0
  126. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/irrigation/water_source.py +0 -0
  127. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/output/__init__.py +0 -0
  128. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/output/mcp.py +0 -0
  129. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/output/pca.py +0 -0
  130. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/output/pcf.py +0 -0
  131. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/output/remote.py +0 -0
  132. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/sensor/__init__.py +0 -0
  133. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/sensor/virtual_energy.py +0 -0
  134. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/template/__init__.py +0 -0
  135. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/template/alarm_panel.py +0 -0
  136. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/template/gate_cover.py +0 -0
  137. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/components/template/thermostat.py +0 -0
  138. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/const.py +0 -0
  139. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/__init__.py +0 -0
  140. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/cloud/__init__.py +0 -0
  141. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/cloud/data/__init__.py +0 -0
  142. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
  143. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/cloud/data/docker-compose.yaml +0 -0
  144. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
  145. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/cloud/registration.py +0 -0
  146. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/cloud/secrets.py +0 -0
  147. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/__init__.py +0 -0
  148. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/config_helper.py +0 -0
  149. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/migrations/__init__.py +0 -0
  150. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
  151. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/migrations/v2_transition.py +0 -0
  152. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/package-lock.json +0 -0
  153. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/config/package.json +0 -0
  154. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/discovery.py +0 -0
  155. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/events/__init__.py +0 -0
  156. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/events/bus.py +0 -0
  157. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/__init__.py +0 -0
  158. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/action_conditions.py +0 -0
  159. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/canopen.py +0 -0
  160. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/covers.py +0 -0
  161. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/display.py +0 -0
  162. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/inputs.py +0 -0
  163. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/irrigation.py +0 -0
  164. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/manager.py +0 -0
  165. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/modbus.py +0 -0
  166. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/outputs.py +0 -0
  167. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/remote.py +0 -0
  168. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/remote_input_registrar.py +0 -0
  169. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/sensors.py +0 -0
  170. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/templates/__init__.py +0 -0
  171. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/templates/alarm.py +0 -0
  172. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/templates/gate_cover.py +0 -0
  173. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/templates/thermostat.py +0 -0
  174. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/templates.py +0 -0
  175. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/manager/update.py +0 -0
  176. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/__init__.py +0 -0
  177. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/basic.py +0 -0
  178. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/basic_mqtt.py +0 -0
  179. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/composite.py +0 -0
  180. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/local.py +0 -0
  181. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/lox.py +0 -0
  182. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/mqtt.py +0 -0
  183. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/messaging/queue.py +0 -0
  184. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/remote/__init__.py +0 -0
  185. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/remote/base.py +0 -0
  186. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/remote/can.py +0 -0
  187. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/remote/esphome.py +0 -0
  188. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/remote/mqtt.py +0 -0
  189. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/remote/wled.py +0 -0
  190. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/sensor/__init__.py +0 -0
  191. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/sensor/base.py +0 -0
  192. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/sensor/system.py +0 -0
  193. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/state/__init__.py +0 -0
  194. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/system/__init__.py +0 -0
  195. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/system/host_data.py +0 -0
  196. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/system/monitor.py +0 -0
  197. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/__init__.py +0 -0
  198. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/async_updater.py +0 -0
  199. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/conditions.py +0 -0
  200. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/filter.py +0 -0
  201. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/font_util.py +0 -0
  202. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/logger.py +0 -0
  203. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/timeperiod.py +0 -0
  204. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/core/utils/util.py +0 -0
  205. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/24x16/adc.yaml +0 -0
  206. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  207. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/24x16/config.yaml +0 -0
  208. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/24x16/event.yaml +0 -0
  209. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/24x16/mqtt.yaml +0 -0
  210. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  211. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/32x10/adc.yaml +0 -0
  212. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  213. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/32x10/config.yaml +0 -0
  214. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/32x10/event.yaml +0 -0
  215. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/32x10/mqtt.yaml +0 -0
  216. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  217. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/48x4/adc.yaml +0 -0
  218. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
  219. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/48x4/config.yaml +0 -0
  220. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/48x4/event.yaml +0 -0
  221. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/48x4/mqtt.yaml +0 -0
  222. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/48x4/output48x4A.yaml +0 -0
  223. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/__init__.py +0 -0
  224. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/can_master.yaml +0 -0
  225. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/can_slave.yaml +0 -0
  226. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover/adc.yaml +0 -0
  227. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  228. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover/config.yaml +0 -0
  229. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover/cover.yaml +0 -0
  230. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover/event.yaml +0 -0
  231. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover/mqtt.yaml +0 -0
  232. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover/outputCover.yaml +0 -0
  233. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover_mix/adc.yaml +0 -0
  234. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  235. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover_mix/config.yaml +0 -0
  236. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover_mix/cover.yaml +0 -0
  237. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover_mix/event.yaml +0 -0
  238. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  239. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  240. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/adc.yaml +0 -0
  241. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  242. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  243. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  244. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  245. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/event_all.yaml +0 -0
  246. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  247. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  248. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  249. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  250. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  251. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  252. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/exceptions.py +0 -0
  253. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/__init__.py +0 -0
  254. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/analog/__init__.py +0 -0
  255. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/analog/adc.py +0 -0
  256. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/can/__init__.py +0 -0
  257. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/can/bridge.py +0 -0
  258. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/can/client.py +0 -0
  259. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/can/interface.py +0 -0
  260. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/can/node.py +0 -0
  261. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/can/node_id.py +0 -0
  262. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/can/test_od.py +0 -0
  263. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/display/__init__.py +0 -0
  264. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/display/early_oled.py +0 -0
  265. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  266. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/display/oled.py +0 -0
  267. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/__init__.py +0 -0
  268. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  269. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  270. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  271. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  272. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/input/__init__.py +0 -0
  273. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/gpio/input/base.py +0 -0
  274. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/i2c/__init__.py +0 -0
  275. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/i2c/bus.py +0 -0
  276. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/i2c/ina219.py +0 -0
  277. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/i2c/ina219_driver.py +0 -0
  278. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/i2c/mcp9808.py +0 -0
  279. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/i2c/pct2075.py +0 -0
  280. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/onewire/__init__.py +0 -0
  281. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/onewire/bus.py +0 -0
  282. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/onewire/dallas.py +0 -0
  283. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/onewire/ds2482.py +0 -0
  284. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/sensor/__init__.py +0 -0
  285. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  286. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/sensor/temperature/base.py +0 -0
  287. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  288. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  289. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/integration/__init__.py +0 -0
  290. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/integration/homeassistant.py +0 -0
  291. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/integration/interlock.py +0 -0
  292. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/integration/lox_template.py +0 -0
  293. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/__init__.py +0 -0
  294. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/actions.py +0 -0
  295. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/MANIFEST.sha256 +0 -0
  296. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/docker/daemon.json +0 -0
  297. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
  298. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
  299. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
  300. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
  301. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
  302. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/journald/journald.conf +0 -0
  303. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
  304. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/sudoers/boneio +0 -0
  305. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
  306. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
  307. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/systemd/boneio.service +0 -0
  308. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
  309. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
  310. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
  311. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
  312. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
  313. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
  314. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/bootstrap/boneio-migrate +0 -0
  315. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/bootstrap/install-helper.sh +0 -0
  316. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
  317. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/runner.py +0 -0
  318. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/__init__.py +0 -0
  319. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
  320. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
  321. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
  322. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
  323. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
  324. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
  325. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
  326. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/__init__.py +0 -0
  327. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/cli.py +0 -0
  328. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/client.py +0 -0
  329. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/coordinator.py +0 -0
  330. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/devices/__init__.py +0 -0
  331. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/__init__.py +0 -0
  332. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/base.py +0 -0
  333. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/derived/__init__.py +0 -0
  334. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/derived/numeric.py +0 -0
  335. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/derived/select.py +0 -0
  336. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/derived/switch.py +0 -0
  337. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/sensor/__init__.py +0 -0
  338. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/sensor/binary.py +0 -0
  339. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/sensor/numeric.py +0 -0
  340. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/sensor/text.py +0 -0
  341. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/writeable/__init__.py +0 -0
  342. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/writeable/binary.py +0 -0
  343. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/entities/writeable/numeric.py +0 -0
  344. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/modbus/utils.py +0 -0
  345. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/models/__init__.py +0 -0
  346. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/models/actions.py +0 -0
  347. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/models/events.py +0 -0
  348. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/models/files.py +0 -0
  349. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/models/logs.py +0 -0
  350. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/models/mqtt.py +0 -0
  351. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/models/state.py +0 -0
  352. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/actions.yaml +0 -0
  353. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/actions_sensor.yaml +0 -0
  354. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/actions_switch.yaml +0 -0
  355. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/condition.yaml +0 -0
  356. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/filters.yaml +0 -0
  357. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/filters_adc.yaml +0 -0
  358. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/id.yaml +0 -0
  359. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/remote_devices.yaml +0 -0
  360. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/remote_inputs.yaml +0 -0
  361. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/remote_outputs.yaml +0 -0
  362. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/temp_unit.yaml +0 -0
  363. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/schema/update_interval.yaml +0 -0
  364. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/action_validation.py +0 -0
  365. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  366. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/css.worker-CvXBzhp8.js +0 -0
  367. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/editor.worker-Cn2oRESe.js +0 -0
  368. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/html.worker-BO6WuOEO.js +0 -0
  369. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/json.worker-BkJRGcCJ.js +0 -0
  370. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/monaco-61yH0vfd.js +0 -0
  371. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
  372. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/rolldown-runtime-QTnfLwEv.js +0 -0
  373. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/ts.worker-B0J26iPs.js +0 -0
  374. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/vendor-pmGLHP0_.js +0 -0
  375. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
  376. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/assets/yaml.worker-BKRoXlmz.js +0 -0
  377. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  378. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  379. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/boneio.svg +0 -0
  380. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  381. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
  382. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
  383. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
  384. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
  385. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
  386. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
  387. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
  388. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
  389. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
  390. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
  391. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
  392. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
  393. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
  394. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
  395. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
  396. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
  397. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
  398. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
  399. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
  400. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
  401. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
  402. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
  403. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
  404. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
  405. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
  406. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
  407. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
  408. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
  409. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
  410. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
  411. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/frontend-dist/workbox-4918f2f6.js +0 -0
  412. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/middleware/__init__.py +0 -0
  413. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/middleware/auth.py +0 -0
  414. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/auth.py +0 -0
  415. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/caddy.py +0 -0
  416. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/can.py +0 -0
  417. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/config.py +0 -0
  418. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/covers.py +0 -0
  419. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/irrigation.py +0 -0
  420. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/migrations.py +0 -0
  421. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/outputs.py +0 -0
  422. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/remote_devices.py +0 -0
  423. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/sensors.py +0 -0
  424. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/system.py +0 -0
  425. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/templates.py +0 -0
  426. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/timezone_sudoers.py +0 -0
  427. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/tools.py +0 -0
  428. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/routes/update.py +0 -0
  429. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/adc.schema.json +0 -0
  430. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/areas.schema.json +0 -0
  431. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/binary_sensor.schema.json +0 -0
  432. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/boneio.schema.json +0 -0
  433. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/can.schema.json +0 -0
  434. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/cover.schema.json +0 -0
  435. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/dallas.schema.json +0 -0
  436. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/ds2482.schema.json +0 -0
  437. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/event.schema.json +0 -0
  438. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/ina219.schema.json +0 -0
  439. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/irrigation.schema.json +0 -0
  440. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/lm75.schema.json +0 -0
  441. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/logger.schema.json +0 -0
  442. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/lox_udp.schema.json +0 -0
  443. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/mcp23017.schema.json +0 -0
  444. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/mcp9808.schema.json +0 -0
  445. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/modbus.schema.json +0 -0
  446. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/mqtt.schema.json +0 -0
  447. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/oled.schema.json +0 -0
  448. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/output.schema.json +0 -0
  449. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/output_group.schema.json +0 -0
  450. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/pca9685.schema.json +0 -0
  451. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/pcf8575.schema.json +0 -0
  452. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/remote_devices.schema.json +0 -0
  453. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/remote_inputs.schema.json +0 -0
  454. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/remote_outputs.schema.json +0 -0
  455. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/sensor.schema.json +0 -0
  456. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/template.schema.json +0 -0
  457. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
  458. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/schema/web.schema.json +0 -0
  459. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/services/__init__.py +0 -0
  460. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/services/logs.py +0 -0
  461. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/web_server.py +0 -0
  462. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio/webui/websocket_manager.py +0 -0
  463. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio.egg-info/dependency_links.txt +0 -0
  464. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio.egg-info/entry_points.txt +0 -0
  465. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio.egg-info/requires.txt +0 -0
  466. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/boneio.egg-info/top_level.txt +0 -0
  467. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/pyproject.toml +0 -0
  468. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/setup.cfg +0 -0
  469. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/setup.py +0 -0
  470. {boneio-1.5.0.dev3 → boneio-1.5.0.dev5}/tests/test_py313_compatibility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.5.0.dev3
3
+ Version: 1.5.0.dev5
4
4
  Summary: Python App for BoneIO
5
5
  Author-email: Paweł Szafer <pszafer@gmail.com>
6
6
  License: GNU General Public License v3.0
@@ -109,6 +109,7 @@ class MultiClickDetector:
109
109
  self._pin = pin
110
110
  self._max_long_press_seconds = max_long_press_seconds
111
111
  self._state = ClickState()
112
+ self._boot_press_suppressed = False # Set by GpioManager._seed_initial_states
112
113
 
113
114
  # Pre-compute which click types should be delayed in exclusive mode
114
115
  # based on enabled sequences
@@ -491,6 +492,21 @@ class MultiClickDetector:
491
492
  )
492
493
  return
493
494
 
495
+ # Boot-press suppression: if GpioManager detected this pin was
496
+ # LOW at startup, the first FALLING_EDGE is a phantom boot event.
497
+ # Record the timestamp (for debounce) but do NOT schedule timers.
498
+ if self._boot_press_suppressed:
499
+ _LOGGER.info(
500
+ "Suppressing phantom boot press on %s (%s) — recording timestamp only",
501
+ self._name,
502
+ self._pin,
503
+ )
504
+ self._state.last_press_ts = timestamp_s
505
+ self._state.last_press_loop_ts = None
506
+ self._state.last_release_ts = None
507
+ self._boot_press_suppressed = False
508
+ return
509
+
494
510
  _LOGGER.debug("PRESSED: %s (%s)", self._name, self._pin)
495
511
  self._state.last_press_ts = timestamp_s
496
512
  self._state.last_press_loop_ts = self._loop.time() # Store loop time for duration calc
@@ -552,6 +568,35 @@ class MultiClickDetector:
552
568
 
553
569
  press_duration_ms = (timestamp_s - self._state.last_press_ts) * 1000 if self._state.last_press_ts else 0
554
570
  _LOGGER.debug("RELEASED: %s (%s) after %.1f ms", self._name, self._pin, press_duration_ms)
571
+
572
+ # Guard: stale release from phantom press at boot.
573
+ # If time since press exceeds max_long_press_seconds, the press
574
+ # was a startup artifact (GPIO settling at boot), not a real user
575
+ # action. Reset the detector so the next real press is accepted.
576
+ if self._state.last_press_ts and press_duration_ms > self._max_long_press_seconds * 1000:
577
+ _LOGGER.warning(
578
+ "Stale release on %s (%s): %.1fs since press exceeds max %.0fs. "
579
+ "Likely phantom press from boot. Resetting detector.",
580
+ self._name,
581
+ self._pin,
582
+ press_duration_ms / 1000,
583
+ self._max_long_press_seconds,
584
+ )
585
+ self._state.last_press_ts = None
586
+ self._state.last_press_loop_ts = None
587
+ self._state.last_release_ts = timestamp_s
588
+ self._state.click_count = 0
589
+ if self._state.long_press_timer:
590
+ self._state.long_press_timer.cancel()
591
+ self._state.long_press_timer = None
592
+ self._state.long_press_scheduled_loop_ts = None
593
+ if self._state.long_hold_periodic_timer:
594
+ self._state.long_hold_periodic_timer.cancel()
595
+ self._state.long_hold_periodic_timer = None
596
+ self._state.executed_long_actions = set()
597
+ self._state.last_repeat_times = {}
598
+ return
599
+
555
600
  self._state.last_release_ts = timestamp_s
556
601
 
557
602
  _LOGGER.debug(
@@ -186,7 +186,13 @@ class BasicOutput(BasicMqtt):
186
186
  """
187
187
  can_turn_on = self.check_interlock()
188
188
  if can_turn_on:
189
- await self._loop.run_in_executor(None, self.turn_on, timestamp)
189
+ try:
190
+ await self._loop.run_in_executor(None, self.turn_on, timestamp)
191
+ except RuntimeError as err:
192
+ if "Executor shutdown" in str(err):
193
+ self.turn_on(timestamp) # Fall back to sync during shutdown
194
+ else:
195
+ raise
190
196
  else:
191
197
  _LOGGER.warning("Interlock active: cannot turn on %s.", self.id)
192
198
  # Workaround for HA is sendind state ON/OFF without physically changing the relay.
@@ -197,7 +203,13 @@ class BasicOutput(BasicMqtt):
197
203
 
198
204
  async def async_turn_off(self, timestamp=None) -> None:
199
205
  """Turn off the relay asynchronously."""
200
- await self._loop.run_in_executor(None, self.turn_off, timestamp)
206
+ try:
207
+ await self._loop.run_in_executor(None, self.turn_off, timestamp)
208
+ except RuntimeError as err:
209
+ if "Executor shutdown" in str(err):
210
+ self.turn_off(timestamp) # Fall back to sync during shutdown
211
+ else:
212
+ raise
201
213
  await self.async_send_state()
202
214
 
203
215
  async def async_toggle(self, timestamp=None) -> None:
@@ -271,7 +271,31 @@ def main():
271
271
  # Load the schema
272
272
  with open(schema_file) as f:
273
273
  schema = yaml.load(f, Loader=BoneIOLoader)
274
-
274
+
275
+ # Dynamically inject modbus device models into the schema.
276
+ # NOTE: This is a standalone copy of the logic from yaml_util.py.
277
+ # We cannot import yaml_util here because it pulls in the full boneIO
278
+ # dependency graph (cerberus, pymodbus, smbus2 …) which is NOT installed
279
+ # in the CI environment that runs this converter script.
280
+ devices_dir = os.path.normpath(
281
+ os.path.join(script_dir, "..", "..", "modbus", "devices")
282
+ )
283
+ models: list[str] = []
284
+ if os.path.isdir(devices_dir):
285
+ for root, dirs, files in os.walk(devices_dir):
286
+ dirs[:] = [d for d in dirs if d != "__pycache__"]
287
+ for fname in files:
288
+ if fname.endswith(".json"):
289
+ models.append(fname[:-5])
290
+ models.sort()
291
+
292
+ try:
293
+ model_field = schema["modbus_devices"]["schema"]["schema"]["model"]
294
+ model_field["allowed"] = models
295
+ print(f"Injected {len(models)} modbus models into schema")
296
+ except (KeyError, TypeError):
297
+ print("WARNING: Could not inject modbus models into schema")
298
+
275
299
  # Convert and save the main schema
276
300
  json_schema = convert_cerberus_to_json_schema(schema)
277
301
  main_schema_file = os.path.join(output_dir, "config.schema.json")
@@ -26,12 +26,39 @@ _SCHEMA_CACHE = None
26
26
  _BOARD_CONFIG_CACHE = {}
27
27
 
28
28
 
29
+ def _get_modbus_device_models() -> list[str]:
30
+ """Scan modbus/devices/ directory and return filenames as model keys.
31
+
32
+ Only does os.walk (no JSON parsing) — <1ms even on BeagleBone.
33
+ """
34
+ devices_dir = os.path.normpath(os.path.join(os.path.dirname(__file__), "../../modbus/devices"))
35
+ models = []
36
+ if os.path.isdir(devices_dir):
37
+ for root, dirs, files in os.walk(devices_dir):
38
+ dirs[:] = [d for d in dirs if d != "__pycache__"]
39
+ for fname in files:
40
+ if fname.endswith(".json"):
41
+ models.append(fname[:-5])
42
+ return sorted(models)
43
+
44
+
45
+ def _inject_modbus_models(schema: dict) -> None:
46
+ """Dynamically set allowed modbus model values from device files."""
47
+ try:
48
+ model_field = schema["modbus_devices"]["schema"]["schema"]["model"]
49
+ model_field["allowed"] = _get_modbus_device_models()
50
+ _LOGGER.debug("Injected %d modbus models into schema", len(model_field["allowed"]))
51
+ except (KeyError, TypeError):
52
+ _LOGGER.warning("Could not inject modbus models into schema")
53
+
54
+
29
55
  def _get_schema():
30
56
  """Get schema from cache or load it if not cached."""
31
57
  global _SCHEMA_CACHE
32
58
  if _SCHEMA_CACHE is None:
33
59
  _LOGGER.debug("Loading schema from file (first time)")
34
60
  _SCHEMA_CACHE = load_yaml_file(schema_file)
61
+ _inject_modbus_models(_SCHEMA_CACHE)
35
62
  return _SCHEMA_CACHE
36
63
 
37
64
 
@@ -653,29 +680,14 @@ class CustomValidator(Validator):
653
680
  raise ValueError(f"Could not parse power value: {value}")
654
681
  num = float(match.group(1))
655
682
  unit = match.group(2) or "w"
656
- if unit in ("w", ""):
683
+ if unit in ("w", "", "wh"):
657
684
  multiplier = 1.0
658
- elif unit == "kw":
659
- multiplier = 1000.0
660
- elif unit == "mw":
661
- multiplier = 1_000_000.0
662
- elif unit == "gw":
663
- multiplier = 1_000_000_000.0
664
- elif unit == "mw":
665
- multiplier = 1_000_000.0
666
- elif unit == "kwh":
667
- # 1 kWh = 1000 W (for 1h). For config, treat as 1000W average.
685
+ elif unit in ("kw", "kwh"):
668
686
  multiplier = 1000.0
669
- elif unit == "mwh":
687
+ elif unit in ("mw", "mwh"):
670
688
  multiplier = 1_000_000.0
671
- elif unit == "gwh":
689
+ elif unit in ("gw", "gwh"):
672
690
  multiplier = 1_000_000_000.0
673
- elif unit == "mw":
674
- multiplier = 1_000_000.0
675
- elif unit == "wh":
676
- multiplier = 1.0
677
- elif unit == "mw" or unit == "mw" or unit == "mw" or unit == "mw" or unit == "mw" or unit == "mw":
678
- multiplier = 1_000_000.0
679
691
  else:
680
692
  _LOGGER.warning(f"Unknown unit for power value: {unit}")
681
693
  raise ValueError(f"Unknown unit for power value: {unit}")
@@ -25,6 +25,7 @@ class StateManager:
25
25
  _LOGGER.info("Loaded state file from %s", self._file)
26
26
  self._file_uptodate = False
27
27
  self._save_attributes_callback = None
28
+ self._shutting_down = False
28
29
 
29
30
  def load_states(self) -> dict:
30
31
  """Load state file.
@@ -105,6 +106,8 @@ class StateManager:
105
106
  if attr_type not in self._state:
106
107
  self._state[attr_type] = {}
107
108
  self._state[attr_type][attribute] = value
109
+ if self._shutting_down:
110
+ return
108
111
  if self._save_attributes_callback is not None:
109
112
  self._save_attributes_callback.cancel()
110
113
  self._save_attributes_callback = None
@@ -182,4 +185,26 @@ class StateManager:
182
185
  # Let's not save state if something happens same time.
183
186
  return False
184
187
  async with self._lock:
185
- return await self._loop.run_in_executor(None, self._save_state)
188
+ try:
189
+ return await self._loop.run_in_executor(None, self._save_state)
190
+ except RuntimeError as err:
191
+ if "Executor shutdown" in str(err):
192
+ # Python 3.13+: executor already closed, fall back to sync
193
+ _LOGGER.debug("Executor shutdown, saving state synchronously")
194
+ return self._save_state()
195
+ raise
196
+
197
+ def cancel_pending_and_save(self) -> None:
198
+ """Cancel any pending deferred save and do a final synchronous write.
199
+
200
+ Must be called during application shutdown BEFORE the event loop
201
+ closes the default executor. This prevents the RuntimeError:
202
+ 'Executor shutdown has been called' on Python 3.13+.
203
+ """
204
+ self._shutting_down = True
205
+ if self._save_attributes_callback is not None:
206
+ self._save_attributes_callback.cancel()
207
+ self._save_attributes_callback = None
208
+ # Final synchronous save to persist any in-memory changes
209
+ self._save_state()
210
+ _LOGGER.debug("StateManager: pending save cancelled, final state written")
@@ -302,6 +302,58 @@ class GpioManager:
302
302
  _LOGGER.error("Error in on-start callback: %s", e)
303
303
  self._on_start_callbacks.clear()
304
304
 
305
+ # Seed detectors with current GPIO state to prevent phantom events
306
+ # at boot. Must run after on-start callbacks so detectors are ready.
307
+ self._seed_initial_states()
308
+
309
+ def _seed_initial_states(self) -> None:
310
+ """Read current GPIO states and seed detectors to prevent phantom presses.
311
+
312
+ At boot, some GPIO pins may already be LOW (e.g. button circuits pulling
313
+ down through pull-up resistors). gpiod generates a FALLING_EDGE for
314
+ this initial state, which the detector interprets as a real button
315
+ press — scheduling a long press timer that fires 400ms later and
316
+ triggers an action.
317
+
318
+ By setting ``_boot_press_suppressed`` on the detector, the first
319
+ FALLING_EDGE records the kernel timestamp (for debounce) but does
320
+ NOT schedule the long press timer. The subsequent RISING_EDGE
321
+ (when the user actually presses) is caught by the stale-release
322
+ guard and handled correctly.
323
+ """
324
+ from boneio.components.input.detectors import MultiClickDetector
325
+
326
+ seeded = 0
327
+ for chip, request in self._requests.items():
328
+ for (c, line), detector in self._detectors.items():
329
+ if c != chip:
330
+ continue
331
+ if not isinstance(detector, MultiClickDetector):
332
+ continue
333
+ try:
334
+ values = request.get_values([line])
335
+ pin_is_low = not bool(values[0])
336
+ except Exception as exc:
337
+ _LOGGER.debug(
338
+ "Could not read initial state for chip%d/line%d: %s",
339
+ chip, line, exc,
340
+ )
341
+ continue
342
+
343
+ if pin_is_low:
344
+ alias = self._aliases.get((chip, line), f"chip{chip}/line{line}")
345
+ _LOGGER.info(
346
+ "GPIO %s is LOW at startup — arming boot press suppression",
347
+ alias,
348
+ )
349
+ detector._boot_press_suppressed = True
350
+ seeded += 1
351
+
352
+ if seeded:
353
+ _LOGGER.info(
354
+ "Armed boot press suppression on %d GPIO detector(s)", seeded
355
+ )
356
+
305
357
  def _handle_gpiod_events(self, chip: int, request: gpiod.LineRequest) -> None:
306
358
  """Handle GPIO events from libgpiod.
307
359
 
@@ -0,0 +1,247 @@
1
+ {
2
+ "model": "DTS1964 3-phase meter",
3
+ "manufacturer": "DTS",
4
+ "description": "DTS1964 3-phase power & energy meter",
5
+ "category": "energy_meters",
6
+ "default_address": 1,
7
+ "default_update_interval": "10s",
8
+ "registers_base": [
9
+ {
10
+ "base": 0,
11
+ "length": 60,
12
+ "register_type": "input",
13
+ "registers": [
14
+ {
15
+ "name": "Voltage_Phase1",
16
+ "address": 0,
17
+ "unit_of_measurement": "V",
18
+ "state_class": "measurement",
19
+ "device_class": "voltage",
20
+ "value_type": "FP32"
21
+ },
22
+ {
23
+ "name": "Voltage_Phase2",
24
+ "address": 2,
25
+ "unit_of_measurement": "V",
26
+ "state_class": "measurement",
27
+ "device_class": "voltage",
28
+ "value_type": "FP32"
29
+ },
30
+ {
31
+ "name": "Voltage_Phase3",
32
+ "address": 4,
33
+ "unit_of_measurement": "V",
34
+ "state_class": "measurement",
35
+ "device_class": "voltage",
36
+ "value_type": "FP32"
37
+ },
38
+ {
39
+ "name": "Voltage_Phase1_to_Phase2",
40
+ "address": 6,
41
+ "unit_of_measurement": "V",
42
+ "state_class": "measurement",
43
+ "device_class": "voltage",
44
+ "value_type": "FP32"
45
+ },
46
+ {
47
+ "name": "Voltage_Phase2_to_Phase3",
48
+ "address": 8,
49
+ "unit_of_measurement": "V",
50
+ "state_class": "measurement",
51
+ "device_class": "voltage",
52
+ "value_type": "FP32"
53
+ },
54
+ {
55
+ "name": "Voltage_Phase3_to_Phase1",
56
+ "address": 10,
57
+ "unit_of_measurement": "V",
58
+ "state_class": "measurement",
59
+ "device_class": "voltage",
60
+ "value_type": "FP32"
61
+ },
62
+ {
63
+ "name": "Current_Phase1",
64
+ "address": 12,
65
+ "unit_of_measurement": "A",
66
+ "state_class": "measurement",
67
+ "device_class": "current",
68
+ "value_type": "FP32"
69
+ },
70
+ {
71
+ "name": "Current_Phase2",
72
+ "address": 14,
73
+ "unit_of_measurement": "A",
74
+ "state_class": "measurement",
75
+ "device_class": "current",
76
+ "value_type": "FP32"
77
+ },
78
+ {
79
+ "name": "Current_Phase3",
80
+ "address": 16,
81
+ "unit_of_measurement": "A",
82
+ "state_class": "measurement",
83
+ "device_class": "current",
84
+ "value_type": "FP32"
85
+ },
86
+ {
87
+ "name": "Power_Phase1",
88
+ "address": 18,
89
+ "unit_of_measurement": "kW",
90
+ "state_class": "measurement",
91
+ "device_class": "power",
92
+ "value_type": "FP32"
93
+ },
94
+ {
95
+ "name": "Power_Phase2",
96
+ "address": 20,
97
+ "unit_of_measurement": "kW",
98
+ "state_class": "measurement",
99
+ "device_class": "power",
100
+ "value_type": "FP32"
101
+ },
102
+ {
103
+ "name": "Power_Phase3",
104
+ "address": 22,
105
+ "unit_of_measurement": "kW",
106
+ "state_class": "measurement",
107
+ "device_class": "power",
108
+ "value_type": "FP32"
109
+ },
110
+ {
111
+ "name": "Total_Power",
112
+ "address": 24,
113
+ "unit_of_measurement": "kW",
114
+ "state_class": "measurement",
115
+ "device_class": "power",
116
+ "value_type": "FP32"
117
+ },
118
+ {
119
+ "name": "Reactive_Power_Phase1",
120
+ "address": 26,
121
+ "unit_of_measurement": "kvar",
122
+ "state_class": "measurement",
123
+ "value_type": "FP32"
124
+ },
125
+ {
126
+ "name": "Reactive_Power_Phase2",
127
+ "address": 28,
128
+ "unit_of_measurement": "kvar",
129
+ "state_class": "measurement",
130
+ "value_type": "FP32"
131
+ },
132
+ {
133
+ "name": "Reactive_Power_Phase3",
134
+ "address": 30,
135
+ "unit_of_measurement": "kvar",
136
+ "state_class": "measurement",
137
+ "value_type": "FP32"
138
+ },
139
+ {
140
+ "name": "Total_Reactive_Power",
141
+ "address": 32,
142
+ "unit_of_measurement": "kvar",
143
+ "state_class": "measurement",
144
+ "value_type": "FP32"
145
+ },
146
+ {
147
+ "name": "Apparent_Power_Phase1",
148
+ "address": 34,
149
+ "unit_of_measurement": "kVA",
150
+ "state_class": "measurement",
151
+ "value_type": "FP32"
152
+ },
153
+ {
154
+ "name": "Apparent_Power_Phase2",
155
+ "address": 36,
156
+ "unit_of_measurement": "kVA",
157
+ "state_class": "measurement",
158
+ "value_type": "FP32"
159
+ },
160
+ {
161
+ "name": "Apparent_Power_Phase3",
162
+ "address": 38,
163
+ "unit_of_measurement": "kVA",
164
+ "state_class": "measurement",
165
+ "value_type": "FP32"
166
+ },
167
+ {
168
+ "name": "Total_Apparent_Power",
169
+ "address": 40,
170
+ "unit_of_measurement": "kVA",
171
+ "state_class": "measurement",
172
+ "value_type": "FP32"
173
+ },
174
+ {
175
+ "name": "Power_Factor_Phase1",
176
+ "address": 42,
177
+ "unit_of_measurement": "",
178
+ "state_class": "measurement",
179
+ "device_class": "power_factor",
180
+ "value_type": "FP32"
181
+ },
182
+ {
183
+ "name": "Power_Factor_Phase2",
184
+ "address": 44,
185
+ "unit_of_measurement": "",
186
+ "state_class": "measurement",
187
+ "device_class": "power_factor",
188
+ "value_type": "FP32"
189
+ },
190
+ {
191
+ "name": "Power_Factor_Phase3",
192
+ "address": 46,
193
+ "unit_of_measurement": "",
194
+ "state_class": "measurement",
195
+ "device_class": "power_factor",
196
+ "value_type": "FP32"
197
+ },
198
+ {
199
+ "name": "Power_Factor_Total",
200
+ "address": 48,
201
+ "unit_of_measurement": "",
202
+ "state_class": "measurement",
203
+ "device_class": "power_factor",
204
+ "value_type": "FP32"
205
+ },
206
+ {
207
+ "name": "Frequency",
208
+ "address": 50,
209
+ "unit_of_measurement": "Hz",
210
+ "state_class": "measurement",
211
+ "device_class": "frequency",
212
+ "value_type": "FP32"
213
+ },
214
+ {
215
+ "name": "Import_Energy_Total",
216
+ "address": 52,
217
+ "unit_of_measurement": "kWh",
218
+ "state_class": "total_increasing",
219
+ "device_class": "energy",
220
+ "value_type": "FP32"
221
+ },
222
+ {
223
+ "name": "Export_Energy_Total",
224
+ "address": 54,
225
+ "unit_of_measurement": "kWh",
226
+ "state_class": "total_increasing",
227
+ "device_class": "energy",
228
+ "value_type": "FP32"
229
+ },
230
+ {
231
+ "name": "Import_Reactive_Energy_Total",
232
+ "address": 56,
233
+ "unit_of_measurement": "kvarh",
234
+ "state_class": "total_increasing",
235
+ "value_type": "FP32"
236
+ },
237
+ {
238
+ "name": "Export_Reactive_Energy_Total",
239
+ "address": 58,
240
+ "unit_of_measurement": "kvarh",
241
+ "state_class": "total_increasing",
242
+ "value_type": "FP32"
243
+ }
244
+ ]
245
+ }
246
+ ]
247
+ }