boneio 1.3.1.dev2__tar.gz → 1.4.0__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 (462) hide show
  1. {boneio-1.3.1.dev2/boneio.egg-info → boneio-1.4.0}/PKG-INFO +1 -1
  2. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/cover.py +22 -11
  3. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/time_based.py +2 -2
  4. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/venetian.py +165 -77
  5. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/group/output_group.py +9 -2
  6. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/__init__.py +6 -0
  7. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/detectors.py +87 -0
  8. boneio-1.4.0/boneio/components/input/remote/__init__.py +22 -0
  9. boneio-1.4.0/boneio/components/input/remote/base.py +337 -0
  10. boneio-1.4.0/boneio/components/input/remote/esphome.py +94 -0
  11. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/irrigation/controller.py +363 -47
  12. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/irrigation/water_source.py +39 -6
  13. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/basic.py +22 -28
  14. boneio-1.4.0/boneio/components/output/remote.py +762 -0
  15. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/alarm_panel.py +68 -18
  16. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/yaml_util.py +3 -0
  17. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/covers.py +1 -1
  18. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/inputs.py +252 -79
  19. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/irrigation.py +124 -54
  20. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/manager.py +562 -128
  21. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/remote.py +63 -2
  22. boneio-1.4.0/boneio/core/manager/remote_input_registrar.py +236 -0
  23. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/alarm.py +15 -10
  24. boneio-1.4.0/boneio/core/messaging/lox.py +326 -0
  25. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/esphome.py +520 -275
  26. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/wled.py +36 -0
  27. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/sensor/base.py +7 -2
  28. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/sensor/system.py +24 -8
  29. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/early_oled.py +22 -16
  30. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/oled.py +7 -3
  31. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/input/base.py +4 -2
  32. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/dallas.py +25 -22
  33. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/integration/homeassistant.py +183 -7
  34. boneio-1.4.0/boneio/integration/lox_template.py +367 -0
  35. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/MANIFEST.sha256 +1 -1
  36. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/sudoers/boneio +1 -1
  37. boneio-1.4.0/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +35 -0
  38. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/coordinator.py +75 -2
  39. boneio-1.4.0/boneio/modbus/devices/hvac/eht-topventil-plus.json +311 -0
  40. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/__init__.py +2 -0
  41. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/state.py +14 -1
  42. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/runner.py +6 -1
  43. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/actions.yaml +49 -0
  44. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/remote_devices.yaml +0 -2
  45. boneio-1.4.0/boneio/schema/remote_inputs.yaml +128 -0
  46. boneio-1.4.0/boneio/schema/remote_outputs.yaml +188 -0
  47. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/schema.yaml +75 -2
  48. boneio-1.4.0/boneio/version.py +2 -0
  49. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/action_validation.py +1 -1
  50. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/app.py +30 -20
  51. boneio-1.4.0/boneio/webui/dashboard_cards.py +310 -0
  52. boneio-1.4.0/boneio/webui/frontend-dist/assets/ConfigEditor-DqDX4DyY.js +1 -0
  53. boneio-1.4.0/boneio/webui/frontend-dist/assets/aiConfig-DxFilBWK.js +2 -0
  54. boneio-1.4.0/boneio/webui/frontend-dist/assets/aiWizardPrompt-CrWwS7zb.js +2 -0
  55. boneio-1.4.0/boneio/webui/frontend-dist/assets/index-BXbDdVbb.css +2 -0
  56. boneio-1.4.0/boneio/webui/frontend-dist/assets/index-CtW_O-75.js +100 -0
  57. boneio-1.4.0/boneio/webui/frontend-dist/assets/useTranslation-DUpbl8sU.js +13 -0
  58. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/index.html +4 -4
  59. {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/binary_sensor.schema.json +120 -0
  60. {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/config.schema.json +1030 -2
  61. {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/cover.schema.json +22 -0
  62. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/event.schema.json +420 -0
  63. {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/irrigation.schema.json +27 -0
  64. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +4 -1
  65. {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/remote_devices.schema.json +0 -1
  66. boneio-1.4.0/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +197 -0
  67. boneio-1.4.0/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +225 -0
  68. {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/template.schema.json +27 -0
  69. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/sw.js +1 -1
  70. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/can.py +15 -16
  71. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/config.py +87 -25
  72. boneio-1.4.0/boneio/webui/routes/irrigation.py +721 -0
  73. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/modbus.py +54 -0
  74. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/outputs.py +40 -0
  75. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/remote_devices.py +4 -3
  76. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/sensors.py +5 -2
  77. {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/binary_sensor.schema.json +120 -0
  78. {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/config.schema.json +1030 -2
  79. {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/cover.schema.json +22 -0
  80. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/event.schema.json +420 -0
  81. {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/irrigation.schema.json +27 -0
  82. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/modbus_devices.schema.json +4 -1
  83. {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/remote_devices.schema.json +0 -1
  84. boneio-1.4.0/boneio/webui/schema/remote_inputs.schema.json +197 -0
  85. boneio-1.4.0/boneio/webui/schema/remote_outputs.schema.json +225 -0
  86. {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/template.schema.json +27 -0
  87. {boneio-1.3.1.dev2 → boneio-1.4.0/boneio.egg-info}/PKG-INFO +1 -1
  88. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/SOURCES.txt +20 -7
  89. {boneio-1.3.1.dev2 → boneio-1.4.0}/pyproject.toml +1 -0
  90. boneio-1.3.1.dev2/boneio/core/messaging/lox.py +0 -221
  91. boneio-1.3.1.dev2/boneio/core/messaging/loxone.py +0 -181
  92. boneio-1.3.1.dev2/boneio/integration/lox_template.py +0 -243
  93. boneio-1.3.1.dev2/boneio/version.py +0 -2
  94. boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/ConfigEditor-wi_Mieo6.js +0 -1
  95. boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/aiConfig-LL3nlemJ.js +0 -2
  96. boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/aiWizardPrompt-CmumVq54.js +0 -2
  97. boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/index-C_7FDXG5.js +0 -44
  98. boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/index-C_S5rhz7.css +0 -2
  99. boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/useTranslation-BsWm27qn.js +0 -13
  100. boneio-1.3.1.dev2/boneio/webui/routes/irrigation.py +0 -323
  101. {boneio-1.3.1.dev2 → boneio-1.4.0}/LICENSE +0 -0
  102. {boneio-1.3.1.dev2 → boneio-1.4.0}/MANIFEST.in +0 -0
  103. {boneio-1.3.1.dev2 → boneio-1.4.0}/README.md +0 -0
  104. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/__init__.py +0 -0
  105. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/input.yaml +0 -0
  106. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_24_16.yaml +0 -0
  107. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_32_10.yaml +0 -0
  108. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_32_5.yaml +0 -0
  109. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_cover.yaml +0 -0
  110. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  111. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/input.yaml +0 -0
  112. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_24_16.yaml +0 -0
  113. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_32_10.yaml +0 -0
  114. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_32_5.yaml +0 -0
  115. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_cover.yaml +0 -0
  116. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  117. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/input.yaml +0 -0
  118. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_24_16.yaml +0 -0
  119. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_32_10.yaml +0 -0
  120. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_32_5.yaml +0 -0
  121. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_cover.yaml +0 -0
  122. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  123. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/input.yaml +0 -0
  124. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_24_16.yaml +0 -0
  125. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_32_10.yaml +0 -0
  126. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_cover.yaml +0 -0
  127. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  128. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/input.yaml +0 -0
  129. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_24_16.yaml +0 -0
  130. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_32_10.yaml +0 -0
  131. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_cover.yaml +0 -0
  132. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  133. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/input.yaml +0 -0
  134. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_24_16.yaml +0 -0
  135. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_32_10.yaml +0 -0
  136. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_48_4.yaml +0 -0
  137. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_cover.yaml +0 -0
  138. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  139. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/input.yaml +0 -0
  140. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_24_16.yaml +0 -0
  141. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_32_10.yaml +0 -0
  142. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_48_4.yaml +0 -0
  143. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_cover.yaml +0 -0
  144. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  145. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/bonecli.py +0 -0
  146. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/__init__.py +0 -0
  147. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/__init__.py +0 -0
  148. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/group/__init__.py +0 -0
  149. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/binary_sensor.py +0 -0
  150. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/event.py +0 -0
  151. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/irrigation/__init__.py +0 -0
  152. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/__init__.py +0 -0
  153. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/mcp.py +0 -0
  154. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/pca.py +0 -0
  155. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/pcf.py +0 -0
  156. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/sensor/__init__.py +0 -0
  157. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/sensor/virtual_energy.py +0 -0
  158. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/__init__.py +0 -0
  159. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/gate_cover.py +0 -0
  160. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/thermostat.py +0 -0
  161. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/const.py +0 -0
  162. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/__init__.py +0 -0
  163. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/__init__.py +0 -0
  164. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/__init__.py +0 -0
  165. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
  166. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/docker-compose.yaml +0 -0
  167. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
  168. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/registration.py +0 -0
  169. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/secrets.py +0 -0
  170. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/__init__.py +0 -0
  171. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/config_helper.py +0 -0
  172. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/migrations/__init__.py +0 -0
  173. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
  174. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/migrations/v2_transition.py +0 -0
  175. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/package-lock.json +0 -0
  176. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/package.json +0 -0
  177. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/schema_converter.py +0 -0
  178. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/discovery.py +0 -0
  179. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/events/__init__.py +0 -0
  180. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/events/bus.py +0 -0
  181. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/__init__.py +0 -0
  182. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/action_conditions.py +0 -0
  183. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/canopen.py +0 -0
  184. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/display.py +0 -0
  185. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/modbus.py +0 -0
  186. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/outputs.py +0 -0
  187. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/sensors.py +0 -0
  188. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/__init__.py +0 -0
  189. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/gate_cover.py +0 -0
  190. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/thermostat.py +0 -0
  191. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates.py +0 -0
  192. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/update.py +0 -0
  193. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/__init__.py +0 -0
  194. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/basic.py +0 -0
  195. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/basic_mqtt.py +0 -0
  196. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/composite.py +0 -0
  197. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/local.py +0 -0
  198. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/mqtt.py +0 -0
  199. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/queue.py +0 -0
  200. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/__init__.py +0 -0
  201. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/base.py +0 -0
  202. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/can.py +0 -0
  203. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/mqtt.py +0 -0
  204. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/sensor/__init__.py +0 -0
  205. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/state/__init__.py +0 -0
  206. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/state/manager.py +0 -0
  207. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/system/__init__.py +0 -0
  208. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/system/host_data.py +0 -0
  209. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/system/monitor.py +0 -0
  210. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/__init__.py +0 -0
  211. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/async_updater.py +0 -0
  212. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/conditions.py +0 -0
  213. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/filter.py +0 -0
  214. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/font_util.py +0 -0
  215. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/logger.py +0 -0
  216. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/timeperiod.py +0 -0
  217. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/util.py +0 -0
  218. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/adc.yaml +0 -0
  219. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  220. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/config.yaml +0 -0
  221. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/event.yaml +0 -0
  222. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/mqtt.yaml +0 -0
  223. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  224. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/adc.yaml +0 -0
  225. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  226. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/config.yaml +0 -0
  227. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/event.yaml +0 -0
  228. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/mqtt.yaml +0 -0
  229. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  230. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/adc.yaml +0 -0
  231. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
  232. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/config.yaml +0 -0
  233. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/event.yaml +0 -0
  234. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/mqtt.yaml +0 -0
  235. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/output48x4A.yaml +0 -0
  236. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/__init__.py +0 -0
  237. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/can_master.yaml +0 -0
  238. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/can_slave.yaml +0 -0
  239. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/adc.yaml +0 -0
  240. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  241. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/config.yaml +0 -0
  242. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/cover.yaml +0 -0
  243. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/event.yaml +0 -0
  244. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/mqtt.yaml +0 -0
  245. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/outputCover.yaml +0 -0
  246. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/adc.yaml +0 -0
  247. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  248. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/config.yaml +0 -0
  249. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/cover.yaml +0 -0
  250. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/event.yaml +0 -0
  251. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  252. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  253. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/adc.yaml +0 -0
  254. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  255. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  256. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  257. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  258. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/event_all.yaml +0 -0
  259. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  260. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  261. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  262. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  263. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  264. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  265. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/exceptions.py +0 -0
  266. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/__init__.py +0 -0
  267. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/analog/__init__.py +0 -0
  268. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/analog/adc.py +0 -0
  269. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/__init__.py +0 -0
  270. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/bridge.py +0 -0
  271. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/client.py +0 -0
  272. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/interface.py +0 -0
  273. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/node.py +0 -0
  274. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/node_id.py +0 -0
  275. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/test_od.py +0 -0
  276. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/__init__.py +0 -0
  277. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  278. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/__init__.py +0 -0
  279. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  280. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  281. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  282. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  283. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/input/__init__.py +0 -0
  284. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/input/manager.py +0 -0
  285. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/__init__.py +0 -0
  286. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/bus.py +0 -0
  287. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/ina219.py +0 -0
  288. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/ina219_driver.py +0 -0
  289. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/mcp9808.py +0 -0
  290. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/pct2075.py +0 -0
  291. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/__init__.py +0 -0
  292. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/bus.py +0 -0
  293. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/ds2482.py +0 -0
  294. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/__init__.py +0 -0
  295. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  296. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/base.py +0 -0
  297. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  298. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  299. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/integration/__init__.py +0 -0
  300. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/integration/interlock.py +0 -0
  301. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/__init__.py +0 -0
  302. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/actions.py +0 -0
  303. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/daemon.json +0 -0
  304. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
  305. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
  306. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
  307. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/journald/journald.conf +0 -0
  308. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
  309. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
  310. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/systemd/boneio.service +0 -0
  311. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
  312. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
  313. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
  314. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
  315. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
  316. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
  317. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/bootstrap/boneio-migrate +0 -0
  318. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/bootstrap/install-helper.sh +0 -0
  319. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
  320. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/runner.py +0 -0
  321. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/__init__.py +0 -0
  322. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
  323. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
  324. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
  325. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/__init__.py +0 -0
  326. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/cli.py +0 -0
  327. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/client.py +0 -0
  328. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/__init__.py +0 -0
  329. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
  330. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
  331. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  332. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  333. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  334. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  335. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  336. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  337. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  338. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/inverters/sofar.json +0 -0
  339. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/inverters/thessla.json +0 -0
  340. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
  341. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/n4dsc08.json +0 -0
  342. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  343. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/wanas415.json +0 -0
  344. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
  345. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/cwt.json +0 -0
  346. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
  347. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
  348. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/gdfs.json +0 -0
  349. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/gdfx.json +0 -0
  350. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  351. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/pt100.json +0 -0
  352. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/sht20.json +0 -0
  353. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/sht30.json +0 -0
  354. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/__init__.py +0 -0
  355. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/base.py +0 -0
  356. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/__init__.py +0 -0
  357. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/numeric.py +0 -0
  358. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/select.py +0 -0
  359. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/switch.py +0 -0
  360. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/text.py +0 -0
  361. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/__init__.py +0 -0
  362. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/binary.py +0 -0
  363. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/numeric.py +0 -0
  364. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/text.py +0 -0
  365. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/writeable/__init__.py +0 -0
  366. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/writeable/binary.py +0 -0
  367. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/writeable/numeric.py +0 -0
  368. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/utils.py +0 -0
  369. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/actions.py +0 -0
  370. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/events.py +0 -0
  371. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/files.py +0 -0
  372. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/logs.py +0 -0
  373. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/mqtt.py +0 -0
  374. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/actions_sensor.yaml +0 -0
  375. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/actions_switch.yaml +0 -0
  376. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/condition.yaml +0 -0
  377. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/filters.yaml +0 -0
  378. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/filters_adc.yaml +0 -0
  379. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/id.yaml +0 -0
  380. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/temp_unit.yaml +0 -0
  381. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/update_interval.yaml +0 -0
  382. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
  383. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/editor.worker-BVjSvWeP.js +0 -0
  384. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/json.worker-CqOJL4FD.js +0 -0
  385. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/monaco-B9WiNxkw.css +0 -0
  386. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/monaco-CAZoGZNF.js +0 -0
  387. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/rolldown-runtime-Dw2cE7zH.js +0 -0
  388. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/vendor-BD5Ml_Uz.js +0 -0
  389. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BJd1pjeW.js +0 -0
  390. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/yaml.worker-nZQZSRZ7.js +0 -0
  391. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  392. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  393. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio.svg +0 -0
  394. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  395. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
  396. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
  397. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
  398. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
  399. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
  400. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
  401. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
  402. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
  403. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
  404. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
  405. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
  406. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
  407. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
  408. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
  409. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
  410. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
  411. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
  412. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
  413. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
  414. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
  415. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
  416. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
  417. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/workbox-4eca85ba.js +0 -0
  418. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/middleware/__init__.py +0 -0
  419. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/middleware/auth.py +0 -0
  420. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/__init__.py +0 -0
  421. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/auth.py +0 -0
  422. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/caddy.py +0 -0
  423. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/covers.py +0 -0
  424. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/migrations.py +0 -0
  425. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/system.py +0 -0
  426. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/templates.py +0 -0
  427. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/timezone_sudoers.py +0 -0
  428. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/tools.py +0 -0
  429. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/update.py +0 -0
  430. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/adc.schema.json +0 -0
  431. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/areas.schema.json +0 -0
  432. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/boneio.schema.json +0 -0
  433. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/can.schema.json +0 -0
  434. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/dallas.schema.json +0 -0
  435. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/ds2482.schema.json +0 -0
  436. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/ina219.schema.json +0 -0
  437. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/lm75.schema.json +0 -0
  438. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/logger.schema.json +0 -0
  439. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/lox_udp.schema.json +0 -0
  440. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/mcp23017.schema.json +0 -0
  441. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/mcp9808.schema.json +0 -0
  442. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/modbus.schema.json +0 -0
  443. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/mqtt.schema.json +0 -0
  444. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/oled.schema.json +0 -0
  445. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/output.schema.json +0 -0
  446. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/output_group.schema.json +0 -0
  447. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/pca9685.schema.json +0 -0
  448. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/pcf8575.schema.json +0 -0
  449. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/sensor.schema.json +0 -0
  450. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
  451. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/web.schema.json +0 -0
  452. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/services/__init__.py +0 -0
  453. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/services/logs.py +0 -0
  454. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/web_server.py +0 -0
  455. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/websocket_manager.py +0 -0
  456. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/dependency_links.txt +0 -0
  457. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/entry_points.txt +0 -0
  458. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/requires.txt +0 -0
  459. {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/top_level.txt +0 -0
  460. {boneio-1.3.1.dev2 → boneio-1.4.0}/setup.cfg +0 -0
  461. {boneio-1.3.1.dev2 → boneio-1.4.0}/setup.py +0 -0
  462. {boneio-1.3.1.dev2 → boneio-1.4.0}/tests/test_py313_compatibility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.3.1.dev2
3
+ Version: 1.4.0
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
@@ -21,7 +21,7 @@ from boneio.const import (
21
21
  from boneio.core.events import EventBus
22
22
  from boneio.core.messaging import BasicMqtt
23
23
  from boneio.core.utils import TimePeriod
24
- from boneio.models import CoverState, PositionDict
24
+ from boneio.models import CoverState, PositionDict, SavedPositionDict
25
25
  from boneio.models.events import CoverEvent
26
26
 
27
27
  _LOGGER = logging.getLogger(__name__)
@@ -40,7 +40,7 @@ class BaseCoverABC(ABC):
40
40
  open_time: TimePeriod,
41
41
  close_time: TimePeriod,
42
42
  event_bus: EventBus,
43
- position: int = 100,
43
+ position: float = 100.0,
44
44
  **kwargs,
45
45
  ) -> None:
46
46
  pass
@@ -106,14 +106,12 @@ class BaseCoverABC(ABC):
106
106
  pass
107
107
 
108
108
  @abstractmethod
109
- async def run_cover(
110
- self, current_operation: str, target_position: float | None = None, target_tilt: float | None = None
111
- ) -> None:
109
+ async def run_cover(self, current_operation: str, target_position: int | None = None, **kwargs) -> None:
112
110
  """This function is called to run cover after calling open, close, toggle, toggle_open, toggle_close, set_cover_position"""
113
111
  pass
114
112
 
115
113
  @abstractmethod
116
- async def send_state(self, state: str, position: float) -> None:
114
+ def send_state(self, state: str, json_position: PositionDict) -> None:
117
115
  pass
118
116
 
119
117
 
@@ -159,7 +157,7 @@ class BaseCover(BaseCoverABC, BasicMqtt):
159
157
  open_time: TimePeriod,
160
158
  close_time: TimePeriod,
161
159
  event_bus: EventBus,
162
- position: int = 100,
160
+ position: float = 100.0,
163
161
  name: str | None = None,
164
162
  **kwargs,
165
163
  ) -> None:
@@ -175,7 +173,7 @@ class BaseCover(BaseCoverABC, BasicMqtt):
175
173
  self._open_time = open_time.total_milliseconds
176
174
  self._close_time = close_time.total_milliseconds
177
175
  self._position = position
178
- self._initial_position = None
176
+ self._initial_position: float = position
179
177
  self._current_operation = IDLE
180
178
  self._last_operation = CLOSING
181
179
  _LOGGER.debug(
@@ -188,12 +186,18 @@ class BaseCover(BaseCoverABC, BasicMqtt):
188
186
 
189
187
  self._last_timestamp = time.time()
190
188
 
191
- self._last_update_time = 0
189
+ self._last_update_time = 0.0
192
190
  self._closed = position <= 0
193
191
 
194
192
  self._movement_thread = None
195
193
  self._stop_event = threading.Event()
196
194
 
195
+ # Flag set by action executor to signal this call originates from a button action.
196
+ # Used by VenetianCover to conditionally skip tilt restore.
197
+ self._from_action: bool = False
198
+ # When True, tilt restore is explicitly requested by the action definition.
199
+ self._action_tilt_restore: bool = False
200
+
197
201
  self._event_bus.add_sigterm_listener(self.on_exit)
198
202
 
199
203
  with suppress(RuntimeError):
@@ -356,7 +360,8 @@ class BaseCover(BaseCoverABC, BasicMqtt):
356
360
 
357
361
  @property
358
362
  def position(self) -> int:
359
- return round(self._position, 0)
363
+ """Return current cover position as integer (0-100)."""
364
+ return round(self._position)
360
365
 
361
366
  @property
362
367
  def json_position(self) -> PositionDict:
@@ -384,6 +389,12 @@ class BaseCover(BaseCoverABC, BasicMqtt):
384
389
  self._message_bus.send_message(topic=f"{self._send_topic}/state", payload=state)
385
390
  self._message_bus.send_message(topic=f"{self._send_topic}/pos", payload=json.dumps(json_position))
386
391
 
392
+ @property
393
+ def saved_position(self) -> SavedPositionDict:
394
+ """Raw float position for disk persistence."""
395
+ return {"position": self._position}
396
+
387
397
  def send_state_and_save(self, json_position: PositionDict):
398
+ """Send state to MQTT/WebSocket and save raw float position to disk."""
388
399
  self.send_state(self.state, json_position)
389
- self._state_save(json_position)
400
+ self._state_save(self.saved_position)
@@ -31,7 +31,7 @@ class TimeBasedCover(BaseCover):
31
31
  restored_state: dict = DEFAULT_RESTORED_STATE,
32
32
  **kwargs,
33
33
  ) -> None:
34
- position = int(restored_state.get("position", DEFAULT_RESTORED_STATE["position"]))
34
+ position = float(restored_state.get("position", DEFAULT_RESTORED_STATE["position"]))
35
35
  super().__init__(
36
36
  open_relay=open_relay,
37
37
  close_relay=close_relay,
@@ -113,7 +113,7 @@ class TimeBasedCover(BaseCover):
113
113
  self._loop.call_soon_threadsafe(lambda: self.send_state_and_save(self.json_position))
114
114
  self._last_update_time = time.monotonic() # Upewnij się, że aktualizacja jest wysłana na końcu ruchu
115
115
 
116
- async def run_cover(self, current_operation: str, target_position: int | None = None) -> None:
116
+ async def run_cover(self, current_operation: str, target_position: int | None = None, **kwargs) -> None:
117
117
  if self._movement_thread and self._movement_thread.is_alive():
118
118
  _LOGGER.warning("Cover movement already in progress. Stopping first.")
119
119
  await self.stop()
@@ -8,7 +8,7 @@ import time
8
8
  from boneio.components.cover.cover import BaseCover, BaseVenetianCoverABC
9
9
  from boneio.const import CLOSE, CLOSING, IDLE, OPEN, OPENING, STOP
10
10
  from boneio.core.utils import TimePeriod
11
- from boneio.models import PositionDict
11
+ from boneio.models import PositionDict, SavedPositionDict
12
12
 
13
13
  _LOGGER = logging.getLogger(__name__)
14
14
  COVER_MOVE_UPDATE_INTERVAL = 50 # ms
@@ -25,26 +25,28 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
25
25
  tilt_duration: TimePeriod, # ms
26
26
  actuator_activation_duration: TimePeriod, # ms
27
27
  restored_state: dict = DEFAULT_RESTORED_STATE,
28
+ tilt_restore_after_close: bool = False,
28
29
  **kwargs,
29
30
  ) -> None:
30
- self._tilt_duration = (
31
- tilt_duration.total_milliseconds
32
- ) # Czas trwania ruchu lameli
33
- self._initial_tilt_position = int(
34
- restored_state.get("tilt", DEFAULT_RESTORED_STATE["tilt"])
35
- )
31
+ """Initialize venetian cover.
36
32
 
37
- position = int(
38
- restored_state.get("position", DEFAULT_RESTORED_STATE["position"])
39
- )
33
+ Args:
34
+ tilt_duration: Duration for full tilt movement.
35
+ actuator_activation_duration: Actuator activation time (unused).
36
+ restored_state: Persisted position/tilt from disk.
37
+ tilt_restore_after_close: If True, restore previous tilt
38
+ position after closing the cover (UI/HA calls).
39
+ """
40
+ self._tilt_duration = tilt_duration.total_milliseconds # Czas trwania ruchu lameli
41
+ self._initial_tilt_position = float(restored_state.get("tilt", DEFAULT_RESTORED_STATE["tilt"]))
42
+
43
+ position = float(restored_state.get("position", DEFAULT_RESTORED_STATE["position"]))
40
44
  # --- TILT ---
41
- self._tilt_position = int(
42
- restored_state.get("tilt", DEFAULT_RESTORED_STATE["tilt"])
43
- )
45
+ self._tilt_position = float(restored_state.get("tilt", DEFAULT_RESTORED_STATE["tilt"]))
46
+
47
+ self._tilt_restore_after_close = tilt_restore_after_close
48
+ self._tilt_before_close: float | None = None
44
49
 
45
- # self._actuator_activation_duration = (
46
- # actuator_activation_duration.total_milliseconds
47
- # ) # ms
48
50
  self._last_tilt_update = 0.0
49
51
 
50
52
  super().__init__(
@@ -52,8 +54,15 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
52
54
  **kwargs,
53
55
  )
54
56
  _LOGGER.debug(
55
- "VenetianCover %s initialized: open_time=%dms, close_time=%dms, tilt_duration=%dms, position=%d%%, tilt=%d%%",
56
- self._id, self._open_time, self._close_time, self._tilt_duration, position, self._tilt_position
57
+ "VenetianCover %s initialized: open_time=%dms, close_time=%dms, tilt_duration=%dms, "
58
+ "position=%d%%, tilt=%d%%, tilt_restore=%s",
59
+ self._id,
60
+ self._open_time,
61
+ self._close_time,
62
+ self._tilt_duration,
63
+ position,
64
+ self._tilt_position,
65
+ self._tilt_restore_after_close,
57
66
  )
58
67
 
59
68
  def _move_cover(
@@ -69,20 +78,12 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
69
78
  if direction == OPEN:
70
79
  relay = self._open_relay
71
80
  total_steps = 100 - self._position
72
- total_tilt_step = (
73
- tilt_delta
74
- if target_tilt_position is not None
75
- else 100 - self._initial_tilt_position
76
- )
81
+ total_tilt_step = tilt_delta if target_tilt_position is not None else 100 - self._initial_tilt_position
77
82
 
78
83
  elif direction == CLOSE:
79
84
  relay = self._close_relay
80
85
  total_steps = self._position
81
- total_tilt_step = (
82
- tilt_delta
83
- if target_tilt_position is not None
84
- else self._initial_tilt_position
85
- )
86
+ total_tilt_step = tilt_delta if target_tilt_position is not None else self._initial_tilt_position
86
87
  else:
87
88
  return
88
89
  if target_tilt_position is not None:
@@ -93,9 +94,7 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
93
94
 
94
95
  if total_steps == 0 or duration == 0:
95
96
  self._current_operation = IDLE
96
- self._loop.call_soon_threadsafe(
97
- self.send_state, self.state, self.json_position
98
- )
97
+ self._loop.call_soon_threadsafe(self.send_state, self.state, self.json_position)
99
98
  return
100
99
 
101
100
  # Calculate actual duration based on remaining distance
@@ -111,17 +110,11 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
111
110
  needed_tilt_duration = tilt_duration * (total_tilt_step / 100)
112
111
  if target_tilt_position is None:
113
112
  tilt_delta = 1.0
114
-
115
113
 
116
114
  while not self._stop_event.is_set():
117
- current_time = (
118
- time.monotonic()
119
- ) # Pobierz aktualny czas tylko raz na iterację
120
- elapsed_time = (
121
- current_time - start_time
122
- ) * 1000 # Konwersja na milisekundy
123
-
124
-
115
+ current_time = time.monotonic() # Pobierz aktualny czas tylko raz na iterację
116
+ elapsed_time = (current_time - start_time) * 1000 # Konwersja na milisekundy
117
+
125
118
  if elapsed_time < needed_tilt_duration:
126
119
  tilt_progress = elapsed_time / needed_tilt_duration if needed_tilt_duration > 0 else 1.0
127
120
  progress = 0.0
@@ -135,8 +128,10 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
135
128
 
136
129
  # Obliczanie _tilt_position dla kierunku OPEN
137
130
  if target_tilt_position is not None:
138
- self._tilt_position = min(target_tilt_position, self._initial_tilt_position + tilt_progress * tilt_delta)
139
- else: # Fallback jeśli nie ma target_tilt_position
131
+ self._tilt_position = min(
132
+ target_tilt_position, self._initial_tilt_position + tilt_progress * tilt_delta
133
+ )
134
+ else: # Fallback jeśli nie ma target_tilt_position
140
135
  self._tilt_position = min(
141
136
  100.0, self._initial_tilt_position + tilt_progress * (100 - self._initial_tilt_position)
142
137
  )
@@ -146,24 +141,23 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
146
141
 
147
142
  # Obliczanie _tilt_position dla kierunku CLOSE
148
143
  if target_tilt_position is not None:
149
- self._tilt_position = max(target_tilt_position, self._initial_tilt_position - tilt_progress * tilt_delta)
150
- else: # Fallback jeśli nie ma target_tilt_position
144
+ self._tilt_position = max(
145
+ target_tilt_position, self._initial_tilt_position - tilt_progress * tilt_delta
146
+ )
147
+ else: # Fallback jeśli nie ma target_tilt_position
151
148
  self._tilt_position = max(
152
149
  0.0, self._initial_tilt_position - tilt_progress * self._initial_tilt_position
153
150
  )
154
151
 
155
152
  self._last_timestamp = time.time() # Wall clock for display
156
153
  if current_time - self._last_update_time >= 1:
157
- self._loop.call_soon_threadsafe(
158
- self.send_state, self.state, self.json_position
159
- )
154
+ self._loop.call_soon_threadsafe(self.send_state, self.state, self.json_position)
160
155
  self._last_update_time = current_time
161
156
 
162
- if target_tilt_position is not None and ((
163
- direction == OPEN and self._tilt_position >= target_tilt_position
164
- ) or (
165
- direction == CLOSE and self._tilt_position <= target_tilt_position
166
- )):
157
+ if target_tilt_position is not None and (
158
+ (direction == OPEN and self._tilt_position >= target_tilt_position)
159
+ or (direction == CLOSE and self._tilt_position <= target_tilt_position)
160
+ ):
167
161
  break
168
162
 
169
163
  if target_position is not None and (
@@ -183,12 +177,32 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
183
177
  # Send relay state to WebSocket (not MQTT - that's handled by output_type check)
184
178
  self._loop.call_soon_threadsafe(lambda r=relay: asyncio.ensure_future(r.async_send_state()))
185
179
  self._current_operation = IDLE
186
- self._loop.call_soon_threadsafe(
187
- self.send_state_and_save, self.json_position
188
- )
189
- self._last_update_time = (
190
- time.monotonic()
191
- ) # Upewnij się, że aktualizacja jest wysłana na końcu ruchu
180
+ self._loop.call_soon_threadsafe(self.send_state_and_save, self.json_position)
181
+ self._last_update_time = time.monotonic() # Upewnij się, że aktualizacja jest wysłana na końcu ruchu
182
+
183
+ # Tilt restore: schedule tilt recovery on the event loop.
184
+ # Skip when position reached 0% (fully closed) or 100% (fully open)
185
+ # at extremes, restoring tilt contradicts user intent.
186
+ if self._tilt_restore_after_close and self._tilt_before_close is not None:
187
+ restore_tilt = self._tilt_before_close
188
+ self._tilt_before_close = None
189
+ at_extreme = self._position <= 0 or self._position >= 100
190
+ if not at_extreme and restore_tilt > 0 and abs(self._tilt_position - restore_tilt) >= 1:
191
+ _LOGGER.info(
192
+ "VenetianCover %s: restoring tilt from %d%% to %d%%",
193
+ self._id,
194
+ round(self._tilt_position),
195
+ round(restore_tilt),
196
+ )
197
+ self._loop.call_soon_threadsafe(
198
+ lambda t=restore_tilt: asyncio.ensure_future(self.set_tilt(int(round(t))))
199
+ )
200
+ elif at_extreme:
201
+ _LOGGER.debug(
202
+ "VenetianCover %s: skipping tilt restore at extreme position %d%%",
203
+ self._id,
204
+ round(self._position),
205
+ )
192
206
 
193
207
  async def set_tilt(self, tilt_position: int) -> None:
194
208
  """Setting tilt position."""
@@ -200,31 +214,36 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
200
214
 
201
215
  tilt_diff = abs(self._tilt_position - tilt_position)
202
216
  estimated_time_s = tilt_diff / 100 * self._tilt_duration / 1000
203
-
217
+
204
218
  if tilt_position > self._tilt_position:
205
219
  _LOGGER.info(
206
220
  "Setting tilt %s from %d%% to %d%% (OPENING). Estimated time: %.2fs (tilt_duration=%dms)",
207
- self._id, self._tilt_position, tilt_position, estimated_time_s, self._tilt_duration
208
- )
209
- await self.run_cover(
210
- current_operation=OPENING, target_tilt_position=tilt_position
221
+ self._id,
222
+ self._tilt_position,
223
+ tilt_position,
224
+ estimated_time_s,
225
+ self._tilt_duration,
211
226
  )
227
+ await self.run_cover(current_operation=OPENING, target_tilt_position=tilt_position)
212
228
  elif tilt_position < self._tilt_position:
213
229
  _LOGGER.info(
214
230
  "Setting tilt %s from %d%% to %d%% (CLOSING). Estimated time: %.2fs (tilt_duration=%dms)",
215
- self._id, self._tilt_position, tilt_position, estimated_time_s, self._tilt_duration
216
- )
217
- await self.run_cover(
218
- current_operation=CLOSING, target_tilt_position=tilt_position
231
+ self._id,
232
+ self._tilt_position,
233
+ tilt_position,
234
+ estimated_time_s,
235
+ self._tilt_duration,
219
236
  )
237
+ await self.run_cover(current_operation=CLOSING, target_tilt_position=tilt_position)
220
238
 
221
239
  @property
222
240
  def json_position(self) -> PositionDict:
223
- return {"position": round(self.position, 0), "tilt": self.tilt}
241
+ """Return position dict with int values for API/MQTT/WebUI."""
242
+ return {"position": self.position, "tilt": self.tilt}
224
243
 
225
244
  @property
226
245
  def tilt(self) -> int:
227
- return int(round(self._tilt_position, 0))
246
+ return round(self._tilt_position)
228
247
 
229
248
  @property
230
249
  def tilt_position(self) -> int:
@@ -245,6 +264,11 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
245
264
  def kind(self) -> str:
246
265
  return "venetian"
247
266
 
267
+ @property
268
+ def saved_position(self) -> SavedPositionDict:
269
+ """Raw float position for disk persistence (includes tilt)."""
270
+ return {"position": self._position, "tilt": self._tilt_position}
271
+
248
272
  async def set_cover_tilt_position(self, position: int) -> None:
249
273
  """Set cover tilt position (required by BaseVenetianCoverABC)."""
250
274
  await self.set_tilt(position)
@@ -254,7 +278,10 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
254
278
  estimated_time_s = (100 - self._tilt_position) / 100 * self._tilt_duration / 1000
255
279
  _LOGGER.info(
256
280
  "Opening tilt cover %s from %d%%. Estimated time: %.2fs (tilt_duration=%dms)",
257
- self._id, self._tilt_position, estimated_time_s, self._tilt_duration
281
+ self._id,
282
+ self._tilt_position,
283
+ estimated_time_s,
284
+ self._tilt_duration,
258
285
  )
259
286
  await self.set_tilt(tilt_position=100)
260
287
 
@@ -263,16 +290,76 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
263
290
  estimated_time_s = self._tilt_position / 100 * self._tilt_duration / 1000
264
291
  _LOGGER.info(
265
292
  "Closing tilt cover %s from %d%%. Estimated time: %.2fs (tilt_duration=%dms)",
266
- self._id, self._tilt_position, estimated_time_s, self._tilt_duration
293
+ self._id,
294
+ self._tilt_position,
295
+ estimated_time_s,
296
+ self._tilt_duration,
267
297
  )
268
298
  await self.set_tilt(tilt_position=0)
269
299
 
300
+ def _save_tilt_for_restore(self) -> None:
301
+ """Save current tilt position for later restoration.
302
+
303
+ Called before any closing movement. Determines whether to save
304
+ based on the call source:
305
+ - UI/HA calls: uses tilt_restore_after_close setting
306
+ - Action calls: uses _action_tilt_restore flag (set by executor)
307
+ """
308
+ if self._from_action:
309
+ should_restore = self._action_tilt_restore
310
+ else:
311
+ should_restore = self._tilt_restore_after_close
312
+
313
+ if should_restore and self._tilt_position > 0:
314
+ self._tilt_before_close = self._tilt_position
315
+ _LOGGER.debug(
316
+ "VenetianCover %s: saving tilt=%d%% before close",
317
+ self._id,
318
+ round(self._tilt_position),
319
+ )
320
+ else:
321
+ self._tilt_before_close = None
322
+
323
+ async def close(self) -> None:
324
+ """Close venetian cover.
325
+
326
+ If tilt_restore_after_close is enabled, saves the current tilt
327
+ position so it can be restored after the closing movement finishes.
328
+ """
329
+ self._save_tilt_for_restore()
330
+ await super().close()
331
+
332
+ async def set_cover_position(self, position: int) -> None:
333
+ """Set cover position with tilt restore support.
334
+
335
+ When moving to a lower position (closing direction) and
336
+ tilt_restore_after_close is enabled, saves the current tilt
337
+ so it can be restored after the movement finishes.
338
+
339
+ Args:
340
+ position: Target position (0-100).
341
+ """
342
+ if position < self._position:
343
+ self._save_tilt_for_restore()
344
+ else:
345
+ self._tilt_before_close = None
346
+ await super().set_cover_position(position)
347
+
348
+ async def open(self) -> None:
349
+ """Open venetian cover.
350
+
351
+ Clears any saved tilt-before-close value since opening
352
+ resets the tilt to 100% naturally.
353
+ """
354
+ self._tilt_before_close = None
355
+ await super().open()
356
+
270
357
  def update_config_times(self, config: dict) -> None:
271
358
  """Update cover timing configuration.
272
-
359
+
273
360
  Args:
274
361
  config: Dictionary with timing values as TimePeriod objects.
275
- Keys: open_time, close_time, tilt_duration
362
+ Keys: open_time, close_time, tilt_duration, tilt_restore_after_close
276
363
  """
277
364
  if "open_time" in config:
278
365
  self._open_time = config["open_time"].total_milliseconds
@@ -280,17 +367,20 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
280
367
  self._close_time = config["close_time"].total_milliseconds
281
368
  if "tilt_duration" in config and config["tilt_duration"]:
282
369
  self._tilt_duration = config["tilt_duration"].total_milliseconds
370
+ if "tilt_restore_after_close" in config:
371
+ self._tilt_restore_after_close = bool(config["tilt_restore_after_close"])
283
372
 
284
373
  async def run_cover(
285
374
  self,
286
375
  current_operation: str,
287
376
  target_position: int | None = None,
288
377
  target_tilt_position: int | None = None,
378
+ **kwargs,
289
379
  ) -> None:
290
380
  if self._movement_thread and self._movement_thread.is_alive():
291
381
  _LOGGER.warning("Cover movement is already in progress. Stopping first.")
292
382
  await self.stop()
293
-
383
+
294
384
  # If STOP was requested, don't start new movement
295
385
  if current_operation == STOP:
296
386
  await self.stop()
@@ -300,9 +390,7 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
300
390
  self._initial_position = self._position
301
391
  self._initial_tilt_position = self._tilt_position
302
392
  self._stop_event.clear()
303
- self._last_update_time = (
304
- time.monotonic()
305
- ) # Inicjalizacja czasu ostatniej aktualizacji
393
+ self._last_update_time = time.monotonic() # Inicjalizacja czasu ostatniej aktualizacji
306
394
 
307
395
  if current_operation == OPENING:
308
396
  self._movement_thread = threading.Thread(
@@ -84,7 +84,7 @@ class OutputGroup(BasicOutput):
84
84
  self._state = state
85
85
  self._loop.create_task(self.async_send_state())
86
86
 
87
- async def async_turn_on(self, timestamp=None) -> None:
87
+ async def async_turn_on(self, timestamp=None) -> bool:
88
88
  """Turn on all members in the group.
89
89
 
90
90
  Executes turn_on sequentially to prevent I2C bus contention
@@ -92,9 +92,16 @@ class OutputGroup(BasicOutput):
92
92
 
93
93
  Args:
94
94
  timestamp: Optional timestamp for the operation
95
+
96
+ Returns:
97
+ True if all members were turned on, False if any was blocked.
95
98
  """
99
+ all_ok = True
96
100
  for x in self._group_members:
97
- await x.async_turn_on(timestamp=timestamp)
101
+ result = await x.async_turn_on(timestamp=timestamp)
102
+ if not result:
103
+ all_ok = False
104
+ return all_ok
98
105
 
99
106
  async def async_turn_off(self, timestamp=None) -> None:
100
107
  """Turn off all members in the group.
@@ -2,12 +2,18 @@
2
2
 
3
3
  This module provides high-level input components that combine
4
4
  hardware GPIO drivers with business logic, MQTT, and Home Assistant integration.
5
+
6
+ Sub-packages:
7
+ remote: Virtual inputs from remote devices (ESPHome API, CAN bus, …)
5
8
  """
6
9
 
7
10
  from boneio.components.input.binary_sensor import GpioInputBinarySensor
8
11
  from boneio.components.input.event import GpioEventButton
12
+ from boneio.components.input.remote import ESPHomeBinarySensorInput, RemoteInputBase
9
13
 
10
14
  __all__ = [
11
15
  "GpioInputBinarySensor",
12
16
  "GpioEventButton",
17
+ "ESPHomeBinarySensorInput",
18
+ "RemoteInputBase",
13
19
  ]
@@ -603,6 +603,93 @@ class MultiClickDetector:
603
603
  )
604
604
 
605
605
 
606
+ def handle_raw_state(self, is_pressed: bool) -> None:
607
+ """Process a raw state change for virtual/remote inputs.
608
+
609
+ Uses wall-clock time instead of kernel GPIO timestamps.
610
+ Suitable for ESPHome binary sensors and other network-based inputs
611
+ that don't generate gpiod edge events.
612
+
613
+ Args:
614
+ is_pressed: True if the input is now active (pressed)
615
+ """
616
+ import time
617
+
618
+ timestamp_s = time.time()
619
+
620
+ if is_pressed:
621
+ # Debounce
622
+ if (
623
+ self._state.last_press_ts
624
+ and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds
625
+ ):
626
+ return
627
+
628
+ _LOGGER.debug("RAW PRESSED: %s (%s)", self._name, self._pin)
629
+ self._state.last_press_ts = timestamp_s
630
+ self._state.last_press_loop_ts = self._loop.time()
631
+ self._state.last_release_ts = None
632
+
633
+ if self._state.finalizer:
634
+ self._state.finalizer.cancel()
635
+ self._state.finalizer = None
636
+ self._state.finalizer_scheduled_loop_ts = None
637
+
638
+ if self._sequence_mode == "exclusive" and self._state.pending_click_timer:
639
+ self._state.pending_click_timer.cancel()
640
+ self._state.pending_click_timer = None
641
+
642
+ self._state.long_press_scheduled_loop_ts = self._loop.time()
643
+ self._state.long_press_timer = self._loop.call_later(
644
+ self._hold_threshold,
645
+ self._detect_long_press,
646
+ )
647
+ else:
648
+ # Debounce
649
+ if (
650
+ self._state.last_release_ts
651
+ and (timestamp_s - self._state.last_release_ts)
652
+ < self._debounce_seconds
653
+ ):
654
+ return
655
+ if (
656
+ self._state.last_press_ts
657
+ and (timestamp_s - self._state.last_press_ts)
658
+ < self._debounce_seconds
659
+ ):
660
+ return
661
+
662
+ _LOGGER.debug("RAW RELEASED: %s (%s)", self._name, self._pin)
663
+ self._state.last_release_ts = timestamp_s
664
+
665
+ if self._state.long_hold_periodic_timer:
666
+ self._state.long_hold_periodic_timer.cancel()
667
+ self._state.long_hold_periodic_timer = None
668
+
669
+ if self._state.last_press_loop_ts:
670
+ duration = self._loop.time() - self._state.last_press_loop_ts
671
+ self._emit_click(LONG, duration)
672
+
673
+ def _reset():
674
+ self._state.executed_long_actions = set()
675
+ self._state.last_repeat_times = {}
676
+
677
+ self._loop.call_later(0.05, _reset)
678
+
679
+ if self._state.long_press_timer:
680
+ self._state.long_press_timer.cancel()
681
+ self._state.long_press_timer = None
682
+ self._state.long_press_scheduled_loop_ts = None
683
+
684
+ self._state.click_count += 1
685
+
686
+ self._state.finalizer_scheduled_loop_ts = self._loop.time()
687
+ self._state.finalizer = self._loop.call_later(
688
+ self._multiclick_window,
689
+ self._finalize_clicks,
690
+ )
691
+
692
+
606
693
  class BinarySensorDetector:
607
694
  """Detects binary state changes (PRESSED/RELEASED) with software debounce."""
608
695