boneio 1.4.4.dev1__tar.gz → 1.5.0.dev1__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 (461) hide show
  1. {boneio-1.4.4.dev1/boneio.egg-info → boneio-1.5.0.dev1}/PKG-INFO +1 -1
  2. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/input/detectors.py +22 -2
  3. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/irrigation/controller.py +114 -12
  4. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/output/remote.py +18 -5
  5. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/cloud/data/docker-compose.yaml +12 -2
  6. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/yaml_util.py +1 -1
  7. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/irrigation.py +27 -0
  8. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/manager.py +15 -6
  9. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/remote.py +27 -3
  10. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/sensors.py +34 -17
  11. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/templates/__init__.py +3 -3
  12. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/lox.py +129 -41
  13. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/remote/wled.py +334 -3
  14. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/sensor/system.py +93 -7
  15. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/MANIFEST.sha256 +3 -3
  16. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +12 -2
  17. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/usr-sbin/oled_msg.py +1 -0
  18. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/usr-sbin/oled_msg.sh +2 -1
  19. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/bootstrap/boneio-migrate +11 -4
  20. boneio-1.5.0.dev1/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +34 -0
  21. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/remote_outputs.yaml +2 -1
  22. boneio-1.5.0.dev1/boneio/version.py +2 -0
  23. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/app.py +4 -0
  24. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/dashboard_cards.py +48 -0
  25. boneio-1.5.0.dev1/boneio/webui/frontend-dist/assets/ConfigEditor-CPp8M41v.js +1 -0
  26. boneio-1.5.0.dev1/boneio/webui/frontend-dist/assets/index-CwwZnggl.js +110 -0
  27. boneio-1.4.4.dev1/boneio/webui/frontend-dist/assets/index-BXbDdVbb.css → boneio-1.5.0.dev1/boneio/webui/frontend-dist/assets/index-DLlP5vtY.css +1 -1
  28. boneio-1.4.4.dev1/boneio/webui/frontend-dist/assets/useTranslation-DUpbl8sU.js → boneio-1.5.0.dev1/boneio/webui/frontend-dist/assets/useTranslation-CWdBD1EW.js +3 -3
  29. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/index.html +3 -3
  30. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/config.schema.json +2 -1
  31. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +2 -1
  32. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/sw.js +1 -1
  33. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/__init__.py +2 -0
  34. boneio-1.5.0.dev1/boneio/webui/routes/dashboard.py +832 -0
  35. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/outputs.py +177 -1
  36. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/system.py +4 -2
  37. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/templates.py +7 -7
  38. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/config.schema.json +2 -1
  39. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/remote_outputs.schema.json +2 -1
  40. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/services/logs.py +14 -2
  41. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1/boneio.egg-info}/PKG-INFO +1 -1
  42. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio.egg-info/SOURCES.txt +6 -4
  43. boneio-1.4.4.dev1/boneio/version.py +0 -2
  44. boneio-1.4.4.dev1/boneio/webui/frontend-dist/assets/ConfigEditor-DqDX4DyY.js +0 -1
  45. boneio-1.4.4.dev1/boneio/webui/frontend-dist/assets/index-DBT9dXd3.js +0 -100
  46. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/LICENSE +0 -0
  47. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/MANIFEST.in +0 -0
  48. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/README.md +0 -0
  49. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/__init__.py +0 -0
  50. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.2/input.yaml +0 -0
  51. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.2/output_24_16.yaml +0 -0
  52. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.2/output_32_10.yaml +0 -0
  53. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.2/output_32_5.yaml +0 -0
  54. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.2/output_cover.yaml +0 -0
  55. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  56. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.3/input.yaml +0 -0
  57. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.3/output_24_16.yaml +0 -0
  58. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.3/output_32_10.yaml +0 -0
  59. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.3/output_32_5.yaml +0 -0
  60. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.3/output_cover.yaml +0 -0
  61. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  62. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.4/input.yaml +0 -0
  63. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.4/output_24_16.yaml +0 -0
  64. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.4/output_32_10.yaml +0 -0
  65. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.4/output_32_5.yaml +0 -0
  66. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.4/output_cover.yaml +0 -0
  67. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  68. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.5/input.yaml +0 -0
  69. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.5/output_24_16.yaml +0 -0
  70. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.5/output_32_10.yaml +0 -0
  71. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.5/output_cover.yaml +0 -0
  72. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  73. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.6/input.yaml +0 -0
  74. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.6/output_24_16.yaml +0 -0
  75. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.6/output_32_10.yaml +0 -0
  76. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.6/output_cover.yaml +0 -0
  77. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  78. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.7/input.yaml +0 -0
  79. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.7/output_24_16.yaml +0 -0
  80. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.7/output_32_10.yaml +0 -0
  81. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.7/output_48_4.yaml +0 -0
  82. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.7/output_cover.yaml +0 -0
  83. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  84. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.8/input.yaml +0 -0
  85. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.8/output_24_16.yaml +0 -0
  86. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.8/output_32_10.yaml +0 -0
  87. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.8/output_48_4.yaml +0 -0
  88. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.8/output_cover.yaml +0 -0
  89. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  90. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/bonecli.py +0 -0
  91. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/__init__.py +0 -0
  92. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/cover/__init__.py +0 -0
  93. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/cover/cover.py +0 -0
  94. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/cover/time_based.py +0 -0
  95. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/cover/venetian.py +0 -0
  96. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/group/__init__.py +0 -0
  97. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/group/output_group.py +0 -0
  98. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/input/__init__.py +0 -0
  99. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/input/binary_sensor.py +0 -0
  100. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/input/event.py +0 -0
  101. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/input/remote/__init__.py +0 -0
  102. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/input/remote/base.py +0 -0
  103. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/input/remote/esphome.py +0 -0
  104. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/irrigation/__init__.py +0 -0
  105. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/irrigation/water_source.py +0 -0
  106. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/output/__init__.py +0 -0
  107. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/output/basic.py +0 -0
  108. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/output/mcp.py +0 -0
  109. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/output/pca.py +0 -0
  110. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/output/pcf.py +0 -0
  111. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/sensor/__init__.py +0 -0
  112. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/sensor/virtual_energy.py +0 -0
  113. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/template/__init__.py +0 -0
  114. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/template/alarm_panel.py +0 -0
  115. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/template/gate_cover.py +0 -0
  116. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/components/template/thermostat.py +0 -0
  117. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/const.py +0 -0
  118. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/__init__.py +0 -0
  119. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/cloud/__init__.py +0 -0
  120. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/cloud/data/__init__.py +0 -0
  121. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
  122. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
  123. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/cloud/registration.py +0 -0
  124. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/cloud/secrets.py +0 -0
  125. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/__init__.py +0 -0
  126. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/config_helper.py +0 -0
  127. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/migrations/__init__.py +0 -0
  128. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
  129. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/migrations/v2_transition.py +0 -0
  130. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/package-lock.json +0 -0
  131. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/package.json +0 -0
  132. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/config/schema_converter.py +0 -0
  133. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/discovery.py +0 -0
  134. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/events/__init__.py +0 -0
  135. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/events/bus.py +0 -0
  136. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/__init__.py +0 -0
  137. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/action_conditions.py +0 -0
  138. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/canopen.py +0 -0
  139. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/covers.py +0 -0
  140. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/display.py +0 -0
  141. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/inputs.py +0 -0
  142. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/modbus.py +0 -0
  143. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/outputs.py +0 -0
  144. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/remote_input_registrar.py +0 -0
  145. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/templates/alarm.py +0 -0
  146. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/templates/gate_cover.py +0 -0
  147. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/templates/thermostat.py +0 -0
  148. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/templates.py +0 -0
  149. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/manager/update.py +0 -0
  150. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/__init__.py +0 -0
  151. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/basic.py +0 -0
  152. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/basic_mqtt.py +0 -0
  153. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/composite.py +0 -0
  154. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/local.py +0 -0
  155. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/mqtt.py +0 -0
  156. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/messaging/queue.py +0 -0
  157. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/remote/__init__.py +0 -0
  158. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/remote/base.py +0 -0
  159. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/remote/can.py +0 -0
  160. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/remote/esphome.py +0 -0
  161. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/remote/mqtt.py +0 -0
  162. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/sensor/__init__.py +0 -0
  163. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/sensor/base.py +0 -0
  164. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/state/__init__.py +0 -0
  165. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/state/manager.py +0 -0
  166. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/system/__init__.py +0 -0
  167. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/system/host_data.py +0 -0
  168. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/system/monitor.py +0 -0
  169. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/__init__.py +0 -0
  170. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/async_updater.py +0 -0
  171. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/conditions.py +0 -0
  172. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/filter.py +0 -0
  173. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/font_util.py +0 -0
  174. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/logger.py +0 -0
  175. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/timeperiod.py +0 -0
  176. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/core/utils/util.py +0 -0
  177. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/24x16/adc.yaml +0 -0
  178. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  179. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/24x16/config.yaml +0 -0
  180. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/24x16/event.yaml +0 -0
  181. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/24x16/mqtt.yaml +0 -0
  182. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  183. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/32x10/adc.yaml +0 -0
  184. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  185. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/32x10/config.yaml +0 -0
  186. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/32x10/event.yaml +0 -0
  187. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/32x10/mqtt.yaml +0 -0
  188. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  189. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/48x4/adc.yaml +0 -0
  190. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
  191. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/48x4/config.yaml +0 -0
  192. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/48x4/event.yaml +0 -0
  193. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/48x4/mqtt.yaml +0 -0
  194. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/48x4/output48x4A.yaml +0 -0
  195. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/__init__.py +0 -0
  196. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/can_master.yaml +0 -0
  197. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/can_slave.yaml +0 -0
  198. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover/adc.yaml +0 -0
  199. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  200. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover/config.yaml +0 -0
  201. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover/cover.yaml +0 -0
  202. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover/event.yaml +0 -0
  203. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover/mqtt.yaml +0 -0
  204. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover/outputCover.yaml +0 -0
  205. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover_mix/adc.yaml +0 -0
  206. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  207. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover_mix/config.yaml +0 -0
  208. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover_mix/cover.yaml +0 -0
  209. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover_mix/event.yaml +0 -0
  210. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  211. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  212. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/adc.yaml +0 -0
  213. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  214. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  215. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  216. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  217. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/event_all.yaml +0 -0
  218. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  219. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  220. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  221. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  222. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  223. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  224. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/exceptions.py +0 -0
  225. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/__init__.py +0 -0
  226. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/analog/__init__.py +0 -0
  227. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/analog/adc.py +0 -0
  228. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/can/__init__.py +0 -0
  229. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/can/bridge.py +0 -0
  230. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/can/client.py +0 -0
  231. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/can/interface.py +0 -0
  232. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/can/node.py +0 -0
  233. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/can/node_id.py +0 -0
  234. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/can/test_od.py +0 -0
  235. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/display/__init__.py +0 -0
  236. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/display/early_oled.py +0 -0
  237. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  238. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/display/oled.py +0 -0
  239. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/__init__.py +0 -0
  240. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  241. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  242. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  243. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  244. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/input/__init__.py +0 -0
  245. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/input/base.py +0 -0
  246. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/gpio/input/manager.py +0 -0
  247. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/i2c/__init__.py +0 -0
  248. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/i2c/bus.py +0 -0
  249. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/i2c/ina219.py +0 -0
  250. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/i2c/ina219_driver.py +0 -0
  251. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/i2c/mcp9808.py +0 -0
  252. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/i2c/pct2075.py +0 -0
  253. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/onewire/__init__.py +0 -0
  254. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/onewire/bus.py +0 -0
  255. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/onewire/dallas.py +0 -0
  256. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/onewire/ds2482.py +0 -0
  257. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/sensor/__init__.py +0 -0
  258. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  259. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/sensor/temperature/base.py +0 -0
  260. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  261. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  262. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/integration/__init__.py +0 -0
  263. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/integration/homeassistant.py +0 -0
  264. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/integration/interlock.py +0 -0
  265. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/integration/lox_template.py +0 -0
  266. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/__init__.py +0 -0
  267. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/actions.py +0 -0
  268. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/docker/daemon.json +0 -0
  269. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
  270. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
  271. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
  272. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
  273. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/journald/journald.conf +0 -0
  274. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
  275. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/sudoers/boneio +0 -0
  276. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
  277. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
  278. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/systemd/boneio.service +0 -0
  279. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
  280. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
  281. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
  282. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
  283. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/bootstrap/install-helper.sh +0 -0
  284. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
  285. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/runner.py +0 -0
  286. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/versions/__init__.py +0 -0
  287. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
  288. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
  289. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
  290. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
  291. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
  292. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
  293. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/__init__.py +0 -0
  294. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/cli.py +0 -0
  295. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/client.py +0 -0
  296. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/coordinator.py +0 -0
  297. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/__init__.py +0 -0
  298. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
  299. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
  300. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  301. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  302. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  303. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  304. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  305. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
  306. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  307. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  308. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/inverters/sofar.json +0 -0
  309. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/inverters/thessla.json +0 -0
  310. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
  311. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/other/n4dsc08.json +0 -0
  312. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  313. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/other/wanas415.json +0 -0
  314. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
  315. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/cwt.json +0 -0
  316. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
  317. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
  318. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/gdfs.json +0 -0
  319. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/gdfx.json +0 -0
  320. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  321. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/pt100.json +0 -0
  322. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/sht20.json +0 -0
  323. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/devices/sensors/sht30.json +0 -0
  324. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/__init__.py +0 -0
  325. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/base.py +0 -0
  326. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/derived/__init__.py +0 -0
  327. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/derived/numeric.py +0 -0
  328. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/derived/select.py +0 -0
  329. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/derived/switch.py +0 -0
  330. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/derived/text.py +0 -0
  331. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/sensor/__init__.py +0 -0
  332. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/sensor/binary.py +0 -0
  333. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/sensor/numeric.py +0 -0
  334. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/sensor/text.py +0 -0
  335. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/writeable/__init__.py +0 -0
  336. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/writeable/binary.py +0 -0
  337. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/entities/writeable/numeric.py +0 -0
  338. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/modbus/utils.py +0 -0
  339. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/models/__init__.py +0 -0
  340. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/models/actions.py +0 -0
  341. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/models/events.py +0 -0
  342. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/models/files.py +0 -0
  343. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/models/logs.py +0 -0
  344. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/models/mqtt.py +0 -0
  345. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/models/state.py +0 -0
  346. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/runner.py +0 -0
  347. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/actions.yaml +0 -0
  348. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/actions_sensor.yaml +0 -0
  349. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/actions_switch.yaml +0 -0
  350. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/condition.yaml +0 -0
  351. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/filters.yaml +0 -0
  352. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/filters_adc.yaml +0 -0
  353. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/id.yaml +0 -0
  354. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/remote_devices.yaml +0 -0
  355. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/remote_inputs.yaml +0 -0
  356. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/schema.yaml +0 -0
  357. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/temp_unit.yaml +0 -0
  358. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/schema/update_interval.yaml +0 -0
  359. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/action_validation.py +0 -0
  360. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/aiConfig-DxFilBWK.js +0 -0
  361. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/aiWizardPrompt-CrWwS7zb.js +0 -0
  362. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
  363. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/editor.worker-BVjSvWeP.js +0 -0
  364. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/json.worker-CqOJL4FD.js +0 -0
  365. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/monaco-B9WiNxkw.css +0 -0
  366. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/monaco-CAZoGZNF.js +0 -0
  367. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/rolldown-runtime-Dw2cE7zH.js +0 -0
  368. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/vendor-BD5Ml_Uz.js +0 -0
  369. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BJd1pjeW.js +0 -0
  370. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/assets/yaml.worker-nZQZSRZ7.js +0 -0
  371. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  372. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  373. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/boneio.svg +0 -0
  374. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  375. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
  376. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
  377. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
  378. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
  379. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
  380. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
  381. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
  382. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
  383. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
  384. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
  385. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
  386. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
  387. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
  388. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
  389. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
  390. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
  391. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
  392. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
  393. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
  394. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
  395. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
  396. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
  397. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
  398. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
  399. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
  400. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
  401. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
  402. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
  403. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
  404. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
  405. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/frontend-dist/workbox-4eca85ba.js +0 -0
  406. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/middleware/__init__.py +0 -0
  407. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/middleware/auth.py +0 -0
  408. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/auth.py +0 -0
  409. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/caddy.py +0 -0
  410. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/can.py +0 -0
  411. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/config.py +0 -0
  412. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/covers.py +0 -0
  413. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/irrigation.py +0 -0
  414. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/migrations.py +0 -0
  415. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/modbus.py +0 -0
  416. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/remote_devices.py +0 -0
  417. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/sensors.py +0 -0
  418. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/timezone_sudoers.py +0 -0
  419. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/tools.py +0 -0
  420. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/routes/update.py +0 -0
  421. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/adc.schema.json +0 -0
  422. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/areas.schema.json +0 -0
  423. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/binary_sensor.schema.json +0 -0
  424. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/boneio.schema.json +0 -0
  425. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/can.schema.json +0 -0
  426. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/cover.schema.json +0 -0
  427. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/dallas.schema.json +0 -0
  428. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/ds2482.schema.json +0 -0
  429. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/event.schema.json +0 -0
  430. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/ina219.schema.json +0 -0
  431. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/irrigation.schema.json +0 -0
  432. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/lm75.schema.json +0 -0
  433. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/logger.schema.json +0 -0
  434. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/lox_udp.schema.json +0 -0
  435. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/mcp23017.schema.json +0 -0
  436. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/mcp9808.schema.json +0 -0
  437. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/modbus.schema.json +0 -0
  438. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/modbus_devices.schema.json +0 -0
  439. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/mqtt.schema.json +0 -0
  440. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/oled.schema.json +0 -0
  441. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/output.schema.json +0 -0
  442. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/output_group.schema.json +0 -0
  443. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/pca9685.schema.json +0 -0
  444. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/pcf8575.schema.json +0 -0
  445. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/remote_devices.schema.json +0 -0
  446. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/remote_inputs.schema.json +0 -0
  447. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/sensor.schema.json +0 -0
  448. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/template.schema.json +0 -0
  449. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
  450. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/schema/web.schema.json +0 -0
  451. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/services/__init__.py +0 -0
  452. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/web_server.py +0 -0
  453. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio/webui/websocket_manager.py +0 -0
  454. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio.egg-info/dependency_links.txt +0 -0
  455. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio.egg-info/entry_points.txt +0 -0
  456. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio.egg-info/requires.txt +0 -0
  457. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/boneio.egg-info/top_level.txt +0 -0
  458. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/pyproject.toml +0 -0
  459. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/setup.cfg +0 -0
  460. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/setup.py +0 -0
  461. {boneio-1.4.4.dev1 → boneio-1.5.0.dev1}/tests/test_py313_compatibility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.4.4.dev1
3
+ Version: 1.5.0.dev1
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
@@ -467,7 +467,7 @@ class MultiClickDetector:
467
467
  if event.event_type is event.Type.FALLING_EDGE:
468
468
  # Button pressed (FALLING_EDGE on BeagleBone with pull-up)
469
469
 
470
- # Software debounce
470
+ # Software debounce (press-vs-press)
471
471
  if self._state.last_press_ts and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds:
472
472
  delta_ms = (timestamp_s - self._state.last_press_ts) * 1000
473
473
  _LOGGER.debug(
@@ -478,6 +478,19 @@ class MultiClickDetector:
478
478
  )
479
479
  return
480
480
 
481
+ # Cross-debounce: ignore press too close to release (bounce on falling edge
482
+ # after a real release). Without this, releasing a long-held button can
483
+ # generate a bounce FALLING that starts a new phantom press cycle.
484
+ if self._state.last_release_ts and (timestamp_s - self._state.last_release_ts) < self._debounce_seconds:
485
+ delta_ms = (timestamp_s - self._state.last_release_ts) * 1000
486
+ _LOGGER.debug(
487
+ "Ignoring bounced press on %s (%.3f ms since release, debounce %.3f ms)",
488
+ self._name,
489
+ delta_ms,
490
+ self._debounce_seconds * 1000,
491
+ )
492
+ return
493
+
481
494
  _LOGGER.debug("PRESSED: %s (%s)", self._name, self._pin)
482
495
  self._state.last_press_ts = timestamp_s
483
496
  self._state.last_press_loop_ts = self._loop.time() # Store loop time for duration calc
@@ -618,13 +631,20 @@ class MultiClickDetector:
618
631
  timestamp_s = time.time()
619
632
 
620
633
  if is_pressed:
621
- # Debounce
634
+ # Debounce (press-vs-press)
622
635
  if (
623
636
  self._state.last_press_ts
624
637
  and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds
625
638
  ):
626
639
  return
627
640
 
641
+ # Cross-debounce: ignore press too close to release (bounce)
642
+ if (
643
+ self._state.last_release_ts
644
+ and (timestamp_s - self._state.last_release_ts) < self._debounce_seconds
645
+ ):
646
+ return
647
+
628
648
  _LOGGER.debug("RAW PRESSED: %s (%s)", self._name, self._pin)
629
649
  self._state.last_press_ts = timestamp_s
630
650
  self._state.last_press_loop_ts = self._loop.time()
@@ -469,7 +469,7 @@ class IrrigationController:
469
469
  await self._advance_to_next_zone(force=True)
470
470
 
471
471
  async def start_full_cycle(self) -> None:
472
- _LOGGER.debug(
472
+ _LOGGER.info(
473
473
  "Irrigation %s start_full_cycle: state=%s standby=%s skip_next=%s",
474
474
  self.id,
475
475
  self._state.value,
@@ -486,6 +486,11 @@ class IrrigationController:
486
486
  return
487
487
 
488
488
  if self._state in (ControllerState.RUNNING, ControllerState.PAUSED):
489
+ _LOGGER.info(
490
+ "Irrigation %s: already %s, shutting down before new cycle",
491
+ self.id,
492
+ self._state.value,
493
+ )
489
494
  await self.shutdown()
490
495
 
491
496
  self._single_zone_mode = False
@@ -548,7 +553,7 @@ class IrrigationController:
548
553
  eligible = self._eligible_zones()
549
554
  if scheduled:
550
555
  self._apply_skip_counters()
551
- _LOGGER.debug(
556
+ _LOGGER.info(
552
557
  "Irrigation %s _start_cycle_from_eligible: %d eligible zones: %s",
553
558
  self.id,
554
559
  len(eligible),
@@ -1121,31 +1126,128 @@ class IrrigationController:
1121
1126
  return earliest
1122
1127
 
1123
1128
  def start_schedules(self) -> None:
1129
+ """Start all schedule loops as asyncio tasks.
1130
+
1131
+ Cancels any existing schedule tasks first, then creates new ones.
1132
+ Each schedule entry gets its own long-lived asyncio.Task that
1133
+ sleeps until the next fire time.
1134
+ """
1124
1135
  self.stop_schedules()
1136
+ if not self._schedule:
1137
+ _LOGGER.debug("Irrigation %s: no schedules configured", self.id)
1138
+ return
1125
1139
  for idx, schedule in enumerate(self._schedule):
1126
- task = asyncio.create_task(self._run_schedule_loop(idx, schedule))
1140
+ task = asyncio.create_task(
1141
+ self._run_schedule_loop(idx, schedule),
1142
+ name=f"irrigation_{self.id}_schedule_{idx}",
1143
+ )
1127
1144
  self._schedule_tasks.append(task)
1145
+ _LOGGER.info(
1146
+ "Irrigation %s: schedule task #%d started (time=%s, days=%s)",
1147
+ self.id,
1148
+ idx,
1149
+ schedule.get("time", "06:00"),
1150
+ schedule.get("days", "daily"),
1151
+ )
1128
1152
 
1129
1153
  def stop_schedules(self) -> None:
1154
+ """Cancel all schedule tasks."""
1155
+ if self._schedule_tasks:
1156
+ _LOGGER.info(
1157
+ "Irrigation %s: stopping %d schedule task(s)",
1158
+ self.id,
1159
+ len(self._schedule_tasks),
1160
+ )
1130
1161
  for task in self._schedule_tasks:
1131
1162
  task.cancel()
1132
1163
  self._schedule_tasks = []
1133
1164
 
1134
1165
  async def _run_schedule_loop(self, schedule_idx: int, schedule: dict[str, Any]) -> None:
1166
+ """Run a single schedule entry in a loop.
1167
+
1168
+ Sleeps until the next fire time, then starts a full irrigation cycle.
1169
+ This task runs for the entire lifetime of the controller.
1170
+
1171
+ CRITICAL: This method must NEVER raise an unhandled exception,
1172
+ as that would permanently kill the schedule task with no recovery.
1173
+ All exceptions are caught, logged, and the loop continues with
1174
+ a back-off delay.
1175
+
1176
+ Args:
1177
+ schedule_idx: Index of this schedule in the schedule list.
1178
+ schedule: Schedule configuration dict with 'time' and 'days'.
1179
+ """
1135
1180
  time_str = schedule.get("time", "06:00")
1136
1181
  days = str(schedule.get("days", "daily")).strip().lower()
1182
+ consecutive_errors = 0
1183
+
1184
+ _LOGGER.info(
1185
+ "Irrigation %s: schedule loop #%d started (time=%s, days=%s)",
1186
+ self.id,
1187
+ schedule_idx,
1188
+ time_str,
1189
+ days,
1190
+ )
1191
+
1137
1192
  while True:
1138
- next_run = _next_fire_time(time_str, days)
1139
- wait_s = max(1.0, (next_run - utcnow()).total_seconds())
1140
- await asyncio.sleep(wait_s)
1193
+ try:
1194
+ next_run = _next_fire_time(time_str, days)
1195
+ now = utcnow()
1196
+ wait_s = max(1.0, (next_run - now).total_seconds())
1197
+
1198
+ # Convert to local for human-readable log
1199
+ local_tz = _local_now().tzinfo
1200
+ next_run_local = next_run.astimezone(local_tz)
1201
+ _LOGGER.info(
1202
+ "Irrigation %s: schedule #%d next fire at %s (in %.0f seconds)",
1203
+ self.id,
1204
+ schedule_idx,
1205
+ next_run_local.strftime("%Y-%m-%d %H:%M:%S %Z"),
1206
+ wait_s,
1207
+ )
1141
1208
 
1142
- if bool(schedule.get("skip", False)):
1143
- schedule["skip"] = False
1144
- self._save(f"schedule/{schedule_idx}/skip", False)
1145
- await self.publish_all_states()
1146
- continue
1209
+ await asyncio.sleep(wait_s)
1147
1210
 
1148
- await self.start_full_cycle()
1211
+ # Reset error counter on successful wake-up
1212
+ consecutive_errors = 0
1213
+
1214
+ if bool(schedule.get("skip", False)):
1215
+ _LOGGER.info(
1216
+ "Irrigation %s: schedule #%d skipped (one-time skip)",
1217
+ self.id,
1218
+ schedule_idx,
1219
+ )
1220
+ schedule["skip"] = False
1221
+ self._save(f"schedule/{schedule_idx}/skip", False)
1222
+ await self.publish_all_states()
1223
+ continue
1224
+
1225
+ _LOGGER.info(
1226
+ "Irrigation %s: schedule #%d firing — starting full cycle",
1227
+ self.id,
1228
+ schedule_idx,
1229
+ )
1230
+ await self.start_full_cycle()
1231
+
1232
+ except asyncio.CancelledError:
1233
+ _LOGGER.info(
1234
+ "Irrigation %s: schedule loop #%d cancelled",
1235
+ self.id,
1236
+ schedule_idx,
1237
+ )
1238
+ raise
1239
+ except Exception:
1240
+ consecutive_errors += 1
1241
+ backoff_s = min(300, 30 * consecutive_errors)
1242
+ _LOGGER.exception(
1243
+ "Irrigation %s: schedule loop #%d encountered an error "
1244
+ "(attempt %d, retrying in %ds)",
1245
+ self.id,
1246
+ schedule_idx,
1247
+ consecutive_errors,
1248
+ backoff_s,
1249
+ )
1250
+ await asyncio.sleep(backoff_s)
1149
1251
 
1150
1252
  def _local_now() -> datetime:
1151
1253
  """Return the current time in the system's local timezone.
@@ -178,14 +178,27 @@ class RemoteOutputBase:
178
178
  def _sync_initial_state(self) -> None:
179
179
  """Sync initial state from device manager's current known states.
180
180
 
181
- Reads _light_states or _switch_states from the ESPHome device
182
- to populate brightness and on/off state immediately, without
183
- waiting for the next state change event.
181
+ Reads cached states from ESPHome (_light_states / _switch_states)
182
+ or WLED (_cached_state) to populate brightness and on/off state
183
+ immediately, without waiting for the next state change event.
184
184
  """
185
185
  if self._device_manager is None:
186
186
  return
187
187
 
188
- # Try light state first
188
+ # WLED: sync from WebSocket cached state
189
+ get_output_is_on = getattr(self._device_manager, "get_output_is_on", None)
190
+ if get_output_is_on is not None:
191
+ is_on = get_output_is_on(self._output_id)
192
+ if is_on is not None:
193
+ self.on_remote_state_change(is_on)
194
+ _LOGGER.debug(
195
+ "Synced initial WLED state for '%s': on=%s",
196
+ self._id,
197
+ is_on,
198
+ )
199
+ return
200
+
201
+ # ESPHome: try light state first
189
202
  light_states = getattr(self._device_manager, "_light_states", {})
190
203
  _LOGGER.debug(
191
204
  "Sync initial state for '%s': output_id='%s', light_states_keys=%s, switch_states_keys=%s",
@@ -208,7 +221,7 @@ class RemoteOutputBase:
208
221
  )
209
222
  return
210
223
 
211
- # Try switch state
224
+ # ESPHome: try switch state
212
225
  switch_states = getattr(self._device_manager, "_switch_states", {})
213
226
  if self._output_id in switch_states:
214
227
  is_on = switch_states[self._output_id]
@@ -9,17 +9,22 @@ services:
9
9
  - ./node-red/settings.js:/data/settings.js:ro
10
10
  extra_hosts:
11
11
  - "host.docker.internal:host-gateway"
12
+ logging:
13
+ driver: json-file
14
+ options:
15
+ max-size: "5m"
16
+ max-file: "2"
12
17
  networks:
13
18
  - edge
14
19
  caddy:
15
20
  image: caddy:2-alpine
16
21
  restart: unless-stopped
17
- hostname: ${HOSTNAME}
22
+ hostname: ${HOSTNAME:-boneio}
18
23
  ports:
19
24
  - "${HTTP_PORT:-8091}:80"
20
25
  - "${HTTPS_PORT:-8443}:443"
21
26
  environment:
22
- - HOST_HOSTNAME=${HOSTNAME}
27
+ - HOST_HOSTNAME=${HOSTNAME:-boneio}
23
28
  volumes:
24
29
  - ./caddy/502.html:/srv/502.html:ro
25
30
  - ./caddy/init-certs.sh:/init-certs.sh:ro
@@ -30,6 +35,11 @@ services:
30
35
  command: ["/init-certs.sh"]
31
36
  extra_hosts:
32
37
  - "host.docker.internal:host-gateway"
38
+ logging:
39
+ driver: json-file
40
+ options:
41
+ max-size: "5m"
42
+ max-file: "2"
33
43
  networks:
34
44
  - edge
35
45
 
@@ -895,7 +895,7 @@ def _try_load_cached_config(config_file: str) -> dict | None:
895
895
  _LOGGER.debug("Schema file changed, cache invalidated")
896
896
  return None
897
897
 
898
- _LOGGER.info("Loading validated config from cache (skipping Cerberus validation)")
898
+ _LOGGER.debug("Loading validated config from cache (skipping Cerberus validation)")
899
899
  return cached["data"]
900
900
  except (FileNotFoundError, pickle.UnpicklingError, OSError, EOFError) as e:
901
901
  _LOGGER.debug("Config cache not available: %s", e)
@@ -176,10 +176,37 @@ class IrrigationManager:
176
176
  self._publish_discovery(ctrl)
177
177
 
178
178
  async def start(self) -> None:
179
+ """Start irrigation controllers — called once on first MQTT connection.
180
+
181
+ Subscribes MQTT command topics, starts schedule tasks, and publishes
182
+ initial states.
183
+ """
179
184
  for ctrl in self._controllers.values():
180
185
  await self._subscribe_controller(ctrl)
181
186
  ctrl.start_schedules()
182
187
  await ctrl.publish_all_states()
188
+ _LOGGER.info(
189
+ "Irrigation controller '%s' started with %d schedule(s), %d zone(s)",
190
+ ctrl.id,
191
+ len(ctrl._schedule),
192
+ len(ctrl.zones),
193
+ )
194
+
195
+ async def reconnect(self) -> None:
196
+ """Handle MQTT reconnect — re-subscribe topics and re-publish states.
197
+
198
+ IMPORTANT: This does NOT restart schedule tasks. Schedule tasks are
199
+ long-lived asyncio.Tasks that sleep until the next fire time.
200
+ Restarting them on every MQTT reconnect would cancel the pending sleep
201
+ and recalculate the next fire time from "now", potentially skipping
202
+ a schedule that was about to fire.
203
+
204
+ Only MQTT subscriptions and state publication are refreshed.
205
+ """
206
+ _LOGGER.info("Irrigation MQTT reconnect: re-subscribing topics and re-publishing states")
207
+ for ctrl in self._controllers.values():
208
+ await self._subscribe_controller(ctrl)
209
+ await ctrl.publish_all_states()
183
210
 
184
211
  async def stop(self) -> None:
185
212
  for topic in list(self._subscribed_topics):
@@ -855,6 +855,8 @@ class Manager:
855
855
  """Resolve a boneIO entity by type and ID for condition evaluation.
856
856
 
857
857
  Used by the conditions system to check entity states.
858
+ Remote outputs from ``remote_outputs`` config are registered in
859
+ OutputManager, so they are resolved via ``entity_type='output'``.
858
860
 
859
861
  Args:
860
862
  entity_type: Entity type ('binary_sensor', 'cover', 'output', 'light')
@@ -865,13 +867,13 @@ class Manager:
865
867
  """
866
868
  if entity_type in ("output", "light"):
867
869
  return self.outputs.get_output(entity_id) or self.outputs.get_output_group(entity_id)
868
- elif entity_type == "cover":
870
+ if entity_type == "cover":
869
871
  return self.covers.get_cover(entity_id)
870
- elif entity_type == "binary_sensor":
872
+ if entity_type == "binary_sensor":
871
873
  return self.inputs.get_input(entity_id)
872
- else:
873
- _LOGGER.warning("Unknown entity type for condition: %s", entity_type)
874
- return None
874
+ _LOGGER.warning("Unknown entity type for condition: %s", entity_type)
875
+ return None
876
+
875
877
 
876
878
  async def execute_actions(
877
879
  self,
@@ -1691,6 +1693,13 @@ class Manager:
1691
1693
  """Function to invoke when connection to MQTT is (re-)established.
1692
1694
 
1693
1695
  Sends online status to MQTT and starts template MQTT subscriptions.
1696
+
1697
+ IMPORTANT: This is called on every MQTT reconnect, not just the first
1698
+ connection. Schedule tasks must NOT be restarted here — they are
1699
+ long-lived ``asyncio.Task``s that sleep until the next fire time.
1700
+ Restarting them on reconnect would cancel the pending sleep and
1701
+ recalculate the next fire time from "now", potentially skipping
1702
+ a schedule that was about to fire.
1694
1703
  """
1695
1704
  _LOGGER.info("Sending online state.")
1696
1705
  topic = f"{self._config_helper.topic_prefix}/{STATE}"
@@ -1701,7 +1710,7 @@ class Manager:
1701
1710
 
1702
1711
  # Start template entities (subscribe to MQTT command topics)
1703
1712
  await self.templates.start()
1704
- await self.irrigation.start()
1713
+ await self.irrigation.reconnect()
1705
1714
 
1706
1715
  async def receive_message(self, topic: str, message: str) -> None:
1707
1716
  """Callback for receiving MQTT messages.
@@ -309,11 +309,11 @@ class RemoteDeviceManager:
309
309
  """Initialize remote devices in background.
310
310
 
311
311
  Configures devices from pending config (importing ESPHome/WLED modules
312
- only at this point) and starts persistent ESPHome connections.
312
+ only at this point) and starts persistent ESPHome and WLED connections.
313
313
  This runs as a background task so it does not block application startup.
314
314
 
315
315
  Args:
316
- delay_seconds: Seconds to wait before starting ESPHome connections
316
+ delay_seconds: Seconds to wait before starting connections
317
317
  """
318
318
  # 1. Configure devices (this triggers lazy module imports)
319
319
  if self._pending_config:
@@ -322,7 +322,10 @@ class RemoteDeviceManager:
322
322
  self._pending_config = None
323
323
  self._initialized = True
324
324
 
325
- # 2. Start ESPHome connections after delay
325
+ # 2. Start WLED WebSocket listeners immediately (lightweight)
326
+ self._start_wled_ws_listeners()
327
+
328
+ # 3. Start ESPHome connections after delay
326
329
  esphome_devices = [
327
330
  (device_id, device)
328
331
  for device_id, device in self._devices.items()
@@ -345,6 +348,24 @@ class RemoteDeviceManager:
345
348
  except Exception as e:
346
349
  _LOGGER.error("Failed to start connection for ESPHome device '%s': %s", device_id, e)
347
350
 
351
+ def _start_wled_ws_listeners(self) -> None:
352
+ """Start WebSocket listeners for all WLED devices.
353
+
354
+ Each WLED device gets a background task that maintains a persistent
355
+ WebSocket connection for real-time state updates.
356
+ """
357
+ wled_devices = [
358
+ (device_id, device)
359
+ for device_id, device in self._devices.items()
360
+ if device.protocol == RemoteDeviceProtocol.WLED
361
+ ]
362
+
363
+ for device_id, device in wled_devices:
364
+ try:
365
+ cast(Any, device).start_ws_listener()
366
+ except Exception as e:
367
+ _LOGGER.error("Failed to start WLED WS for '%s': %s", device_id, e)
368
+
348
369
  async def stop_all_connections(self) -> None:
349
370
  """Stop all persistent connections.
350
371
 
@@ -686,6 +707,9 @@ class RemoteDeviceManager:
686
707
  if remote_devices_config:
687
708
  self._configure_devices(remote_devices_config)
688
709
 
710
+ # Start WLED WS listeners immediately
711
+ self._start_wled_ws_listeners()
712
+
689
713
  # Start ESPHome connections immediately (no delay for reload)
690
714
  await self._start_esphome_connections_immediate()
691
715
 
@@ -843,29 +843,40 @@ class SensorManager:
843
843
 
844
844
  Creates sensors for monitoring system resources and sends
845
845
  HA autodiscovery messages for each.
846
+
847
+ For disk sensors, auto-detects mounted partitions:
848
+ - eMMC (/dev/mmcblk1) → "eMMC Usage"
849
+ - SD card (/dev/mmcblk0) → "SD Card Usage"
850
+ - Other root partitions → "System Disk Usage"
846
851
  """
847
852
  from boneio.core.sensor.system import (
848
853
  CpuUsageSensor,
849
854
  DiskUsageSensor,
850
855
  MemoryUsageSensor,
856
+ detect_disk_sensors,
851
857
  )
852
858
  from boneio.integration.homeassistant import ha_sensor_system_availabilty_message
853
859
 
854
- # Disk Usage Sensor
855
- disk_sensor = DiskUsageSensor(
856
- manager=self._manager,
857
- message_bus=self._manager._message_bus,
858
- topic_prefix=self._manager._topic_prefix,
859
- )
860
- self._system_sensors.append(disk_sensor)
861
- payload = ha_sensor_system_availabilty_message(
862
- id=disk_sensor.id,
863
- name=disk_sensor.name,
864
- config_helper=self._manager._config_helper,
865
- unit_of_measurement="%",
866
- icon="mdi:harddisk",
867
- )
868
- self._manager.publish_ha_discovery(id=disk_sensor.id, ha_type=SENSOR, payload=payload)
860
+ # Disk Usage Sensors — auto-detect all connected disks
861
+ disk_configs = detect_disk_sensors()
862
+ for disk_cfg in disk_configs:
863
+ disk_sensor = DiskUsageSensor(
864
+ manager=self._manager,
865
+ message_bus=self._manager._message_bus,
866
+ topic_prefix=self._manager._topic_prefix,
867
+ mount_point=disk_cfg["mount_point"],
868
+ sensor_id=disk_cfg["id"],
869
+ name=disk_cfg["name"],
870
+ )
871
+ self._system_sensors.append(disk_sensor)
872
+ payload = ha_sensor_system_availabilty_message(
873
+ id=disk_sensor.id,
874
+ name=disk_sensor.name,
875
+ config_helper=self._manager._config_helper,
876
+ unit_of_measurement="%",
877
+ icon=disk_cfg["icon"],
878
+ )
879
+ self._manager.publish_ha_discovery(id=disk_sensor.id, ha_type=SENSOR, payload=payload)
869
880
 
870
881
  # Memory Usage Sensor
871
882
  memory_sensor = MemoryUsageSensor(
@@ -1382,14 +1393,20 @@ class SensorManager:
1382
1393
  # System sensors
1383
1394
  from boneio.integration.homeassistant import ha_sensor_system_availabilty_message
1384
1395
 
1385
- _icon_map = {"disk_usage": "mdi:harddisk", "memory_usage": "mdi:memory", "cpu_usage": "mdi:cpu-64-bit"}
1396
+ _icon_map = {
1397
+ "disk_usage": "mdi:harddisk",
1398
+ "emmc_usage": "mdi:harddisk",
1399
+ "sd_card_usage": "mdi:micro-sd",
1400
+ "memory_usage": "mdi:memory",
1401
+ "cpu_usage": "mdi:cpu-64-bit",
1402
+ }
1386
1403
  for sensor in self._system_sensors:
1387
1404
  payload = ha_sensor_system_availabilty_message(
1388
1405
  id=sensor.id,
1389
1406
  name=sensor.name,
1390
1407
  config_helper=self._manager._config_helper,
1391
1408
  unit_of_measurement="%",
1392
- icon=_icon_map.get(sensor.id, "mdi:chip"),
1409
+ icon=_icon_map.get(sensor.id, "mdi:harddisk"),
1393
1410
  )
1394
1411
  self._manager.publish_ha_discovery(id=sensor.id, ha_type=SENSOR, payload=payload)
1395
1412
 
@@ -65,17 +65,17 @@ class TemplateManager:
65
65
  # -- Sub-manager accessors -----------------------------------------------
66
66
 
67
67
  @property
68
- def thermostats(self) -> ThermostatManager:
68
+ def thermostat_manager(self) -> ThermostatManager:
69
69
  """Thermostat sub-manager."""
70
70
  return self._thermostats
71
71
 
72
72
  @property
73
- def alarms(self) -> AlarmManager:
73
+ def alarm_manager(self) -> AlarmManager:
74
74
  """Alarm panel sub-manager."""
75
75
  return self._alarms
76
76
 
77
77
  @property
78
- def gates(self) -> GateCoverManager:
78
+ def gate_manager(self) -> GateCoverManager:
79
79
  """Gate cover sub-manager."""
80
80
  return self._gates
81
81