boneio 1.2.0.dev21__tar.gz → 1.2.0.dev25__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 (447) hide show
  1. {boneio-1.2.0.dev21/boneio.egg-info → boneio-1.2.0.dev25}/PKG-INFO +1 -1
  2. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/cover.py +37 -6
  3. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/time_based.py +3 -3
  4. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/const.py +28 -0
  5. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/covers.py +27 -3
  6. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/manager.py +4 -1
  7. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/remote.py +1 -0
  8. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/esphome.py +41 -13
  9. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/display/oled.py +254 -7
  10. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/actions.yaml +13 -1
  11. boneio-1.2.0.dev25/boneio/version.py +2 -0
  12. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/cssMode-B9wgS3nc.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/cssMode-CNfUxfgr.js +1 -1
  13. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/freemarker2-BWuFrqIE.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/freemarker2-DWjclh22.js +1 -1
  14. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/handlebars-v7145UWi.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/handlebars-i2k_xWAf.js +1 -1
  15. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/html-CcwKUEPK.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/html-5waqLOui.js +1 -1
  16. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/htmlMode-BSmyjXrA.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/htmlMode-Bwf-0-Bn.js +1 -1
  17. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/index-B6BS4-3O.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/index-CRX9Ew8L.js +5 -5
  18. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/javascript-BPdWBFmL.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/javascript-Kj8C4y4i.js +1 -1
  19. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/jsonMode-CFXuuy9f.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/jsonMode-CHLWjsUA.js +1 -1
  20. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/liquid-CFKk38kG.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/liquid-3gxkDJwa.js +1 -1
  21. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/mdx-BNyJdH4w.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/mdx-CvlTe6nf.js +1 -1
  22. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/python-D_-BuVF5.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/python-BK_KcnMp.js +1 -1
  23. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/razor-DYq6eRVD.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/razor-DiDDF06t.js +1 -1
  24. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/tsMode-DwwcYdMs.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/tsMode-B_ZhXLqZ.js +1 -1
  25. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/typescript-6vakCrf3.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/typescript-FjIJU2QD.js +1 -1
  26. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/xml-DfD5mx75.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/xml-DiHsfIX6.js +1 -1
  27. boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/yaml-MkFkM5Hn.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/yaml-GoVS_T5n.js +1 -1
  28. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/index.html +1 -1
  29. {boneio-1.2.0.dev21/boneio/webui → boneio-1.2.0.dev25/boneio/webui/frontend-dist}/schema/binary_sensor.schema.json +20 -0
  30. {boneio-1.2.0.dev21/boneio/webui → boneio-1.2.0.dev25/boneio/webui/frontend-dist}/schema/config.schema.json +90 -0
  31. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/event.schema.json +70 -0
  32. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/sw.js +1 -1
  33. {boneio-1.2.0.dev21/boneio/webui/frontend-dist → boneio-1.2.0.dev25/boneio/webui}/schema/binary_sensor.schema.json +20 -0
  34. {boneio-1.2.0.dev21/boneio/webui/frontend-dist → boneio-1.2.0.dev25/boneio/webui}/schema/config.schema.json +90 -0
  35. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/event.schema.json +70 -0
  36. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25/boneio.egg-info}/PKG-INFO +1 -1
  37. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/SOURCES.txt +16 -16
  38. boneio-1.2.0.dev21/boneio/version.py +0 -2
  39. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/LICENSE +0 -0
  40. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/MANIFEST.in +0 -0
  41. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/README.md +0 -0
  42. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/__init__.py +0 -0
  43. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/input.yaml +0 -0
  44. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_24_16.yaml +0 -0
  45. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_32_10.yaml +0 -0
  46. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_32_5.yaml +0 -0
  47. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_cover.yaml +0 -0
  48. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  49. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/input.yaml +0 -0
  50. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_24_16.yaml +0 -0
  51. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_32_10.yaml +0 -0
  52. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_32_5.yaml +0 -0
  53. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_cover.yaml +0 -0
  54. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  55. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/input.yaml +0 -0
  56. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_24_16.yaml +0 -0
  57. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_32_10.yaml +0 -0
  58. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_32_5.yaml +0 -0
  59. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_cover.yaml +0 -0
  60. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  61. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/input.yaml +0 -0
  62. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_24_16.yaml +0 -0
  63. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_32_10.yaml +0 -0
  64. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_cover.yaml +0 -0
  65. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  66. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/input.yaml +0 -0
  67. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_24_16.yaml +0 -0
  68. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_32_10.yaml +0 -0
  69. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_cover.yaml +0 -0
  70. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  71. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/input.yaml +0 -0
  72. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_24_16.yaml +0 -0
  73. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_32_10.yaml +0 -0
  74. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_cover.yaml +0 -0
  75. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  76. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/input.yaml +0 -0
  77. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_24_16.yaml +0 -0
  78. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_32_10.yaml +0 -0
  79. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_cover.yaml +0 -0
  80. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  81. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/bonecli.py +0 -0
  82. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/__init__.py +0 -0
  83. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/__init__.py +0 -0
  84. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/venetian.py +0 -0
  85. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/group/__init__.py +0 -0
  86. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/group/output_group.py +0 -0
  87. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/__init__.py +0 -0
  88. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/binary_sensor.py +0 -0
  89. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/detectors.py +0 -0
  90. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/event.py +0 -0
  91. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/__init__.py +0 -0
  92. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/basic.py +0 -0
  93. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/mcp.py +0 -0
  94. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/pca.py +0 -0
  95. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/pcf.py +0 -0
  96. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/sensor/__init__.py +0 -0
  97. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/sensor/virtual_energy.py +0 -0
  98. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/__init__.py +0 -0
  99. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/alarm_panel.py +0 -0
  100. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/gate_cover.py +0 -0
  101. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/thermostat.py +0 -0
  102. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/__init__.py +0 -0
  103. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/__init__.py +0 -0
  104. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/__init__.py +0 -0
  105. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
  106. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/docker-compose.yaml +0 -0
  107. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
  108. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/registration.py +0 -0
  109. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/secrets.py +0 -0
  110. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/__init__.py +0 -0
  111. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/config_helper.py +0 -0
  112. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/migrations/__init__.py +0 -0
  113. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
  114. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/migrations/v2_transition.py +0 -0
  115. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/package-lock.json +0 -0
  116. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/package.json +0 -0
  117. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/schema_converter.py +0 -0
  118. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/yaml_util.py +0 -0
  119. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/discovery.py +0 -0
  120. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/events/__init__.py +0 -0
  121. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/events/bus.py +0 -0
  122. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/__init__.py +0 -0
  123. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/display.py +0 -0
  124. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/inputs.py +0 -0
  125. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/modbus.py +0 -0
  126. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/outputs.py +0 -0
  127. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/sensors.py +0 -0
  128. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/__init__.py +0 -0
  129. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/alarm.py +0 -0
  130. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/gate_cover.py +0 -0
  131. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/thermostat.py +0 -0
  132. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates.py +0 -0
  133. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/update.py +0 -0
  134. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/__init__.py +0 -0
  135. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/basic.py +0 -0
  136. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/basic_mqtt.py +0 -0
  137. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/local.py +0 -0
  138. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/mqtt.py +0 -0
  139. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/queue.py +0 -0
  140. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/__init__.py +0 -0
  141. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/base.py +0 -0
  142. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/mqtt.py +0 -0
  143. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/wled.py +0 -0
  144. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/sensor/__init__.py +0 -0
  145. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/sensor/base.py +0 -0
  146. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/sensor/system.py +0 -0
  147. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/state/__init__.py +0 -0
  148. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/state/manager.py +0 -0
  149. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/system/__init__.py +0 -0
  150. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/system/host_data.py +0 -0
  151. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/system/monitor.py +0 -0
  152. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/__init__.py +0 -0
  153. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/async_updater.py +0 -0
  154. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/filter.py +0 -0
  155. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/font_util.py +0 -0
  156. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/logger.py +0 -0
  157. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/timeperiod.py +0 -0
  158. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/util.py +0 -0
  159. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/adc.yaml +0 -0
  160. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  161. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/config.yaml +0 -0
  162. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/event.yaml +0 -0
  163. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/mqtt.yaml +0 -0
  164. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  165. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/adc.yaml +0 -0
  166. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  167. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/config.yaml +0 -0
  168. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/event.yaml +0 -0
  169. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/mqtt.yaml +0 -0
  170. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  171. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/__init__.py +0 -0
  172. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/adc.yaml +0 -0
  173. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  174. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/config.yaml +0 -0
  175. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/cover.yaml +0 -0
  176. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/event.yaml +0 -0
  177. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/mqtt.yaml +0 -0
  178. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/outputCover.yaml +0 -0
  179. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/adc.yaml +0 -0
  180. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  181. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/config.yaml +0 -0
  182. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/cover.yaml +0 -0
  183. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/event.yaml +0 -0
  184. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  185. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  186. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/adc.yaml +0 -0
  187. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  188. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  189. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  190. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  191. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/event_all.yaml +0 -0
  192. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  193. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  194. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  195. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  196. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  197. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  198. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/exceptions.py +0 -0
  199. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/__init__.py +0 -0
  200. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/analog/__init__.py +0 -0
  201. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/analog/adc.py +0 -0
  202. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/display/__init__.py +0 -0
  203. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  204. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/__init__.py +0 -0
  205. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  206. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  207. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  208. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  209. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/input/__init__.py +0 -0
  210. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/input/base.py +0 -0
  211. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/input/manager.py +0 -0
  212. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/__init__.py +0 -0
  213. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/bus.py +0 -0
  214. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/ina219.py +0 -0
  215. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/ina219_driver.py +0 -0
  216. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/mcp9808.py +0 -0
  217. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/pct2075.py +0 -0
  218. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/__init__.py +0 -0
  219. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/bus.py +0 -0
  220. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/dallas.py +0 -0
  221. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/ds2482.py +0 -0
  222. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/__init__.py +0 -0
  223. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  224. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/base.py +0 -0
  225. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  226. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  227. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/integration/__init__.py +0 -0
  228. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/integration/homeassistant.py +0 -0
  229. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/integration/interlock.py +0 -0
  230. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/__init__.py +0 -0
  231. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/cli.py +0 -0
  232. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/client.py +0 -0
  233. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/coordinator.py +0 -0
  234. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/__init__.py +0 -0
  235. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
  236. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
  237. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  238. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  239. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  240. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  241. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  242. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  243. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  244. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/inverters/sofar.json +0 -0
  245. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/inverters/thessla.json +0 -0
  246. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/other/n4dsc08.json +0 -0
  247. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  248. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/other/wanas415.json +0 -0
  249. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
  250. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/cwt.json +0 -0
  251. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
  252. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
  253. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/gdfs.json +0 -0
  254. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/gdfx.json +0 -0
  255. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  256. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/pt100.json +0 -0
  257. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/sht20.json +0 -0
  258. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/sht30.json +0 -0
  259. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/__init__.py +0 -0
  260. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/base.py +0 -0
  261. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/__init__.py +0 -0
  262. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/numeric.py +0 -0
  263. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/select.py +0 -0
  264. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/switch.py +0 -0
  265. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/text.py +0 -0
  266. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/__init__.py +0 -0
  267. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/binary.py +0 -0
  268. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/numeric.py +0 -0
  269. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/text.py +0 -0
  270. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/writeable/__init__.py +0 -0
  271. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/writeable/binary.py +0 -0
  272. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/writeable/numeric.py +0 -0
  273. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/utils.py +0 -0
  274. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/__init__.py +0 -0
  275. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/actions.py +0 -0
  276. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/events.py +0 -0
  277. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/files.py +0 -0
  278. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/logs.py +0 -0
  279. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/mqtt.py +0 -0
  280. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/state.py +0 -0
  281. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/runner.py +0 -0
  282. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/actions_sensor.yaml +0 -0
  283. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/actions_switch.yaml +0 -0
  284. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/filters.yaml +0 -0
  285. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/filters_adc.yaml +0 -0
  286. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/id.yaml +0 -0
  287. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/remote_devices.yaml +0 -0
  288. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/schema.yaml +0 -0
  289. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/temp_unit.yaml +0 -0
  290. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/update_interval.yaml +0 -0
  291. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/app.py +0 -0
  292. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/abap-CRCWOmpq.js +0 -0
  293. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/apex-DnsZk_dE.js +0 -0
  294. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/azcli-1IWB1ccx.js +0 -0
  295. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/bat-DPkNLes8.js +0 -0
  296. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/bicep-Corcdgou.js +0 -0
  297. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/cameligo-CGrWLZr3.js +0 -0
  298. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/clojure-D9WOWImG.js +0 -0
  299. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
  300. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/coffee-B7EJu28W.js +0 -0
  301. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/cpp-SEyurbux.js +0 -0
  302. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/csharp-BoL64M5l.js +0 -0
  303. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/csp-C46ZqvIl.js +0 -0
  304. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/css-DQU6DXDx.js +0 -0
  305. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/cypher-D84EuPTj.js +0 -0
  306. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/dart-D8lhlL1r.js +0 -0
  307. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/dockerfile-DLk6rpji.js +0 -0
  308. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/ecl-BO6FnfXk.js +0 -0
  309. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/editor.worker-B4pQIWZD.js +0 -0
  310. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/elixir-BRjLKONM.js +0 -0
  311. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/flow9-Cac8vKd7.js +0 -0
  312. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/fsharp-fd1GTHhf.js +0 -0
  313. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/go-O9LJTZXk.js +0 -0
  314. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/graphql-LQdxqEYJ.js +0 -0
  315. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/hcl-DxDQ3s82.js +0 -0
  316. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/index-BkP1mrhT.css +0 -0
  317. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/ini-BvajGCUy.js +0 -0
  318. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/java-SYsfObOQ.js +0 -0
  319. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/json.worker-aFakAbRR.js +0 -0
  320. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/julia-DQXNmw_w.js +0 -0
  321. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/kotlin-qQ0MG-9I.js +0 -0
  322. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/less-GGFNNJHn.js +0 -0
  323. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/lexon-Canl7DCW.js +0 -0
  324. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/lua-D28Ae8-K.js +0 -0
  325. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/m3-DPitgjJI.js +0 -0
  326. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/markdown-B811l8j2.js +0 -0
  327. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/mips-CdjsipkG.js +0 -0
  328. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/msdax-CYqgjx_P.js +0 -0
  329. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/mysql-BHd6q0vd.js +0 -0
  330. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/objective-c-B1aVtJYH.js +0 -0
  331. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pascal-BhNW15KB.js +0 -0
  332. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pascaligo-5jv8CcQD.js +0 -0
  333. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/perl-DlYyT36c.js +0 -0
  334. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pgsql-Dy0bjov7.js +0 -0
  335. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/php-120yhfDK.js +0 -0
  336. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pla-CjnFlu4u.js +0 -0
  337. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/postiats-CQpG440k.js +0 -0
  338. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/powerquery-DdJtto1Z.js +0 -0
  339. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/powershell-Bu_VLpJB.js +0 -0
  340. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/protobuf-IBS6jZEB.js +0 -0
  341. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pug-kFxLfcjb.js +0 -0
  342. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/qsharp-q7JyzKFN.js +0 -0
  343. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/r-BIFz-_sK.js +0 -0
  344. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/redis-CHOsPHWR.js +0 -0
  345. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/redshift-CBifECDb.js +0 -0
  346. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/restructuredtext-CghPJEOS.js +0 -0
  347. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/ruby-CYWGW-b1.js +0 -0
  348. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/rust-DMDD0SHb.js +0 -0
  349. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sb-BYAiYHFx.js +0 -0
  350. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/scala-Bqvq8jcR.js +0 -0
  351. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/scheme-Dhb-2j9p.js +0 -0
  352. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/scss-CTwUZ5N7.js +0 -0
  353. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/shell-CsDZo4DB.js +0 -0
  354. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/solidity-CME5AdoB.js +0 -0
  355. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sophia-RYC1BQQz.js +0 -0
  356. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sparql-KEyrF7De.js +0 -0
  357. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sql-BdTr02Mf.js +0 -0
  358. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/st-C7iG7M4S.js +0 -0
  359. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/swift-D7IUmUK8.js +0 -0
  360. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/systemverilog-DgMryOEJ.js +0 -0
  361. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/tcl-PloMZuKG.js +0 -0
  362. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/twig-BfRIq3la.js +0 -0
  363. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/typespec-CzxlYoT_.js +0 -0
  364. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/vb-BwAE3J76.js +0 -0
  365. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/wgsl-B_1kOXbF.js +0 -0
  366. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BIl4cyR9.js +0 -0
  367. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/yaml.worker-DBeHcBRc.js +0 -0
  368. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  369. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  370. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio.svg +0 -0
  371. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  372. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
  373. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
  374. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
  375. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
  376. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
  377. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
  378. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
  379. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
  380. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
  381. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
  382. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
  383. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
  384. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
  385. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
  386. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
  387. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
  388. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
  389. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
  390. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
  391. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
  392. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
  393. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
  394. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
  395. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
  396. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/workbox-226dbdbf.js +0 -0
  397. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/middleware/__init__.py +0 -0
  398. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/middleware/auth.py +0 -0
  399. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/__init__.py +0 -0
  400. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/auth.py +0 -0
  401. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/caddy.py +0 -0
  402. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/config.py +0 -0
  403. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/covers.py +0 -0
  404. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/modbus.py +0 -0
  405. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/outputs.py +0 -0
  406. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/remote_devices.py +0 -0
  407. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/sensors.py +0 -0
  408. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/system.py +0 -0
  409. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/templates.py +0 -0
  410. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/tools.py +0 -0
  411. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/update.py +0 -0
  412. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/adc.schema.json +0 -0
  413. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/areas.schema.json +0 -0
  414. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/boneio.schema.json +0 -0
  415. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/cover.schema.json +0 -0
  416. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/dallas.schema.json +0 -0
  417. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/ds2482.schema.json +0 -0
  418. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/ina219.schema.json +0 -0
  419. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/lm75.schema.json +0 -0
  420. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/logger.schema.json +0 -0
  421. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/mcp23017.schema.json +0 -0
  422. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/mcp9808.schema.json +0 -0
  423. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/modbus.schema.json +0 -0
  424. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/modbus_devices.schema.json +0 -0
  425. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/mqtt.schema.json +0 -0
  426. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/oled.schema.json +0 -0
  427. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/output.schema.json +0 -0
  428. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/output_group.schema.json +0 -0
  429. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/pca9685.schema.json +0 -0
  430. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/pcf8575.schema.json +0 -0
  431. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/remote_devices.schema.json +0 -0
  432. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/sensor.schema.json +0 -0
  433. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/template.schema.json +0 -0
  434. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
  435. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/web.schema.json +0 -0
  436. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/services/__init__.py +0 -0
  437. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/services/logs.py +0 -0
  438. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/web_server.py +0 -0
  439. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/websocket_manager.py +0 -0
  440. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/dependency_links.txt +0 -0
  441. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/entry_points.txt +0 -0
  442. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/requires.txt +0 -0
  443. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/top_level.txt +0 -0
  444. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/pyproject.toml +0 -0
  445. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/setup.cfg +0 -0
  446. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/setup.py +0 -0
  447. {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/tests/test_py313_compatibility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.2.0.dev21
3
+ Version: 1.2.0.dev25
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
@@ -16,11 +16,11 @@ from boneio.const import (
16
16
  OPEN,
17
17
  OPENING,
18
18
  )
19
- from boneio.core.events import EventBus, async_track_point_in_time, utcnow
19
+ from boneio.core.events import EventBus
20
20
  from boneio.core.messaging import BasicMqtt
21
21
  from boneio.core.utils import TimePeriod
22
22
  from boneio.models import CoverState, PositionDict
23
- from boneio.components.output import MCPOutput
23
+ from boneio.components.output import BasicOutput
24
24
  from boneio.models.events import CoverEvent
25
25
 
26
26
  _LOGGER = logging.getLogger(__name__)
@@ -30,8 +30,8 @@ class BaseCoverABC(ABC):
30
30
 
31
31
  @abstractmethod
32
32
  def __init__(self, id: str,
33
- open_relay: MCPOutput,
34
- close_relay: MCPOutput,
33
+ open_relay: BasicOutput,
34
+ close_relay: BasicOutput,
35
35
  state_save: Callable,
36
36
  open_time: TimePeriod,
37
37
  close_time: TimePeriod,
@@ -147,8 +147,8 @@ class BaseVenetianCoverABC:
147
147
 
148
148
  class BaseCover(BaseCoverABC, BasicMqtt):
149
149
  def __init__(self, id: str,
150
- open_relay: MCPOutput,
151
- close_relay: MCPOutput,
150
+ open_relay: BasicOutput,
151
+ close_relay: BasicOutput,
152
152
  state_save: Callable,
153
153
  open_time: TimePeriod,
154
154
  close_time: TimePeriod,
@@ -265,6 +265,10 @@ class BaseCover(BaseCoverABC, BasicMqtt):
265
265
  _LOGGER.debug("Toggle cover %s from input.", self._id)
266
266
  if self._current_operation != IDLE:
267
267
  await self.stop()
268
+ elif self._position >= 100:
269
+ await self.close()
270
+ elif self._position <= 0:
271
+ await self.open()
268
272
  elif self._last_operation == CLOSING:
269
273
  await self.open()
270
274
  else:
@@ -284,6 +288,33 @@ class BaseCover(BaseCoverABC, BasicMqtt):
284
288
  else:
285
289
  await self.close()
286
290
 
291
+ async def smart_toggle(self, always_open_till: int = 50) -> None:
292
+ """Smart toggle with position threshold.
293
+
294
+ If cover is moving → stop.
295
+ If position <= always_open_till → open (to 100%).
296
+ If position > always_open_till → normal toggle (based on last_operation).
297
+
298
+ Args:
299
+ always_open_till: Position threshold (0-100%). Below or equal this
300
+ value the cover will always open. Above it, normal toggle applies.
301
+ """
302
+ _LOGGER.debug(
303
+ "Smart toggle cover %s (position=%d%%, threshold=%d%%)",
304
+ self._id, self._position, always_open_till,
305
+ )
306
+ if self._current_operation != IDLE:
307
+ await self.stop()
308
+ elif self._position <= always_open_till:
309
+ await self.open()
310
+ elif self._position >= 100:
311
+ await self.close()
312
+ elif self._position <= 0:
313
+ await self.open()
314
+ elif self._last_operation == CLOSING:
315
+ await self.open()
316
+ else:
317
+ await self.close()
287
318
 
288
319
  @property
289
320
  def state(self) -> str:
@@ -10,7 +10,7 @@ from boneio.const import CLOSE, CLOSING, IDLE, OPEN, OPENING, STOP
10
10
  from boneio.components.cover.cover import BaseCover
11
11
  from boneio.core.events import EventBus
12
12
  from boneio.core.utils import TimePeriod
13
- from boneio.components.output import MCPOutput
13
+ from boneio.components.output import BasicOutput
14
14
 
15
15
  _LOGGER = logging.getLogger(__name__)
16
16
  DEFAULT_RESTORED_STATE = {"position": 100}
@@ -19,8 +19,8 @@ class TimeBasedCover(BaseCover):
19
19
  """Time-based cover algorithm similar to ESPHome."""
20
20
  def __init__(
21
21
  self,
22
- open_relay: MCPOutput,
23
- close_relay: MCPOutput,
22
+ open_relay: BasicOutput,
23
+ close_relay: BasicOutput,
24
24
  state_save: Callable,
25
25
  open_time: TimePeriod,
26
26
  close_time: TimePeriod,
@@ -181,11 +181,39 @@ cover_actions = {
181
181
  "STOP": "stop",
182
182
  "TOGGLE_OPEN": "toggle_open",
183
183
  "TOGGLE_CLOSE": "toggle_close",
184
+ "SMART_TOGGLE": "smart_toggle",
184
185
  "TILT": "set_tilt",
185
186
  'TILT_OPEN': 'tilt_open',
186
187
  'TILT_CLOSE': 'tilt_close',
187
188
  }
188
189
 
190
+ # Map of cover action method name -> accepted extra_data keys.
191
+ # Actions not listed here (open, close, toggle, stop, etc.) accept no extra params.
192
+ _COVER_ACTION_PARAMS: dict[str, set[str]] = {
193
+ "smart_toggle": {"always_open_till"},
194
+ "set_cover_position": {"position"},
195
+ "set_tilt": {"tilt_position"},
196
+ "set_cover_tilt_position": {"tilt_position"},
197
+ }
198
+
199
+
200
+ def filter_cover_extra_data(action_name: str, extra_data: dict) -> dict:
201
+ """Filter extra_data to only include params accepted by the cover action.
202
+
203
+ Args:
204
+ action_name: The cover method name (e.g. 'open', 'toggle', 'smart_toggle')
205
+ extra_data: Raw extra_data dict from action config
206
+
207
+ Returns:
208
+ Filtered dict with only accepted params for the action.
209
+ """
210
+ if not extra_data:
211
+ return {}
212
+ allowed = _COVER_ACTION_PARAMS.get(action_name)
213
+ if allowed is None:
214
+ return {}
215
+ return {k: v for k, v in extra_data.items() if k in allowed}
216
+
189
217
  INA219 = "ina219"
190
218
  VIRTUAL_ENERGY_SENSOR = "virtual_energy_sensor"
191
219
  PINS = {
@@ -13,7 +13,7 @@ import json
13
13
  import logging
14
14
  from typing import TYPE_CHECKING, Any
15
15
 
16
- from boneio.const import COVER, DEVICE_CLASS, ID, NAME, RESTORE_STATE, SHOW_HA, cover_actions
16
+ from boneio.const import COVER, DEVICE_CLASS, ID, NAME, RESTORE_STATE, SHOW_HA, cover_actions, filter_cover_extra_data
17
17
  from boneio.core.utils import TimePeriod, strip_accents
18
18
  from boneio.exceptions import CoverConfigurationException
19
19
  from boneio.integration import ha_cover_availabilty_message
@@ -72,6 +72,28 @@ class CoverManager:
72
72
  config = self._manager._config_helper.reload_config()
73
73
  self._config_covers = config.get(COVER, [])
74
74
  self._manager._config_helper.clear_autodiscovery_type(ha_type=COVER)
75
+
76
+ # Remove covers that are no longer in config
77
+ new_ids = set()
78
+ for _cfg in self._config_covers:
79
+ if _cfg.get(ID):
80
+ new_ids.add(strip_accents(_cfg[ID]))
81
+ else:
82
+ _open = str(_cfg.get("open_relay", ""))
83
+ _close = str(_cfg.get("close_relay", ""))
84
+ new_ids.add(f"cover_{_open}_{_close}".lower().replace(" ", "_"))
85
+
86
+ removed_ids = [cid for cid in self._covers if cid not in new_ids]
87
+ for cid in removed_ids:
88
+ _LOGGER.info("Cover %s removed from config, cleaning up", cid)
89
+ cover = self._covers.pop(cid)
90
+ # Stop cover movement if running
91
+ try:
92
+ asyncio.ensure_future(cover.stop())
93
+ except Exception:
94
+ pass
95
+ # Remove HA autodiscovery
96
+ self._remove_cover_ha_discovery(cid)
75
97
 
76
98
  for _config in self._config_covers:
77
99
  # Get relay outputs for cover
@@ -365,8 +387,10 @@ class CoverManager:
365
387
 
366
388
  try:
367
389
  _f = getattr(cover, action_to_execute)
368
- if extra_data:
369
- await _f(**extra_data)
390
+ # Filter extra_data to only pass params accepted by the action
391
+ filtered = filter_cover_extra_data(action_to_execute, extra_data or {})
392
+ if filtered:
393
+ await _f(**filtered)
370
394
  else:
371
395
  await _f()
372
396
  except Exception as err:
@@ -28,6 +28,7 @@ from boneio.const import (
28
28
  STATE,
29
29
  TOGGLE,
30
30
  cover_actions,
31
+ filter_cover_extra_data,
31
32
  output_actions,
32
33
  )
33
34
  from boneio.core.config import ConfigHelper
@@ -669,6 +670,8 @@ class Manager:
669
670
  continue
670
671
  action_to_execute = action_definition.get("action_to_execute")
671
672
  extra_data = action_definition.get("extra_data", {})
673
+ # Filter extra_data to only pass params accepted by each action
674
+ filtered_data = filter_cover_extra_data(action_to_execute, extra_data)
672
675
  _LOGGER.debug(
673
676
  "Executing action %s for cover %s. Duration: %s",
674
677
  action_to_execute,
@@ -676,7 +679,7 @@ class Manager:
676
679
  time.time() - start_time,
677
680
  )
678
681
  _f = getattr(cover, action_to_execute)
679
- await _f(**extra_data)
682
+ await _f(**filtered_data)
680
683
 
681
684
  elif action == OUTPUT_OVER_MQTT:
682
685
  boneio_id = action_definition.get("boneio_id")
@@ -587,6 +587,7 @@ class RemoteDeviceManager:
587
587
  return await device.control_cover(
588
588
  cover_id=cover_id,
589
589
  action=action,
590
+ **kwargs,
590
591
  )
591
592
 
592
593
  # For MQTT devices, use standard control_cover
@@ -364,7 +364,10 @@ class ESPHomeRemoteDevice(RemoteDevice):
364
364
  "current_operation": current_op,
365
365
  "last_known_operation": last_op,
366
366
  }
367
- _LOGGER.debug("Cover '%s' position: %.2f", cover_id, state.position)
367
+ _LOGGER.debug(
368
+ "Cover '%s' state update: position=%.2f, current_op=%s, last_op=%s",
369
+ cover_id, state.position, current_op, last_op,
370
+ )
368
371
  break
369
372
  except Exception as e:
370
373
  _LOGGER.debug("Error processing state change: %s", e)
@@ -854,27 +857,52 @@ class ESPHomeRemoteDevice(RemoteDevice):
854
857
  self._client.cover_command(cover_key, position=0.0)
855
858
  elif action_upper == "STOP":
856
859
  self._client.cover_command(cover_key, stop=True)
857
- elif action_upper == "TOGGLE":
858
- # Toggle based on current operation or last known operation
860
+ elif action_upper in ("TOGGLE", "SMART_TOGGLE"):
861
+ # Toggle based on current operation, position, or last known operation
859
862
  state = self._cover_states.get(cover_id, {})
860
863
  current_op = state.get("current_operation", 0) # 0=IDLE, 1=OPENING, 2=CLOSING
861
864
  last_op = state.get("last_known_operation", 2)
862
865
  cover_pos = state.get("position")
866
+ always_open_till = kwargs.get("always_open_till", 50) if action_upper == "SMART_TOGGLE" else None
863
867
  _LOGGER.debug(
864
- "TOGGLE cover '%s': key=%s, state=%s, current_op=%s, last_op=%s, position=%s, all_states=%s",
865
- cover_id, cover_key, state, current_op, last_op, cover_pos,
866
- {k: v for k, v in self._cover_states.items()},
868
+ "ESPHome %s cover '%s': current_op=%s, last_op=%s, position=%s, always_open_till=%s",
869
+ action_upper, cover_id, current_op, last_op, cover_pos, always_open_till,
867
870
  )
868
871
 
869
872
  if current_op != 0: # If moving, stop it
870
- _LOGGER.debug("TOGGLE -> STOP (cover is moving, current_op=%s)", current_op)
873
+ _LOGGER.debug("%s -> STOP (cover is moving, current_op=%s)", action_upper, current_op)
871
874
  self._client.cover_command(cover_key, stop=True)
872
- elif last_op == 2: # If last operation was CLOSING, open it
873
- _LOGGER.debug("TOGGLE -> OPEN (last_op=CLOSING)")
874
- self._client.cover_command(cover_key, position=1.0)
875
- else: # Otherwise close it
876
- _LOGGER.debug("TOGGLE -> CLOSE (last_op=%s)", last_op)
877
- self._client.cover_command(cover_key, position=0.0)
875
+ elif cover_pos is not None:
876
+ # Position is known — use it for smarter decisions
877
+ pos_pct = int(cover_pos * 100)
878
+ if always_open_till is not None and pos_pct <= always_open_till:
879
+ # SMART_TOGGLE: below threshold → always open
880
+ _LOGGER.debug("SMART_TOGGLE -> OPEN (pos=%d%% <= threshold=%d%%)", pos_pct, always_open_till)
881
+ self._client.cover_command(cover_key, position=1.0)
882
+ elif cover_pos >= 0.99:
883
+ # Fully open → close
884
+ _LOGGER.debug("%s -> CLOSE (fully open, pos=%.2f)", action_upper, cover_pos)
885
+ self._client.cover_command(cover_key, position=0.0)
886
+ elif cover_pos <= 0.01:
887
+ # Fully closed → open
888
+ _LOGGER.debug("%s -> OPEN (fully closed, pos=%.2f)", action_upper, cover_pos)
889
+ self._client.cover_command(cover_key, position=1.0)
890
+ elif last_op == 2:
891
+ # Last was closing → open
892
+ _LOGGER.debug("%s -> OPEN (last_op=CLOSING)", action_upper)
893
+ self._client.cover_command(cover_key, position=1.0)
894
+ else:
895
+ # Last was opening → close
896
+ _LOGGER.debug("%s -> CLOSE (last_op=%s)", action_upper, last_op)
897
+ self._client.cover_command(cover_key, position=0.0)
898
+ else:
899
+ # No position known — use last_op only
900
+ if last_op == 2:
901
+ _LOGGER.debug("%s -> OPEN (no position, last_op=CLOSING)", action_upper)
902
+ self._client.cover_command(cover_key, position=1.0)
903
+ else:
904
+ _LOGGER.debug("%s -> CLOSE (no position, last_op=%s)", action_upper, last_op)
905
+ self._client.cover_command(cover_key, position=0.0)
878
906
  elif action_upper == "TOGGLE_OPEN":
879
907
  state = self._cover_states.get(cover_id, {})
880
908
  current_op = state.get("current_operation", 0)
@@ -2,6 +2,7 @@
2
2
 
3
3
  import asyncio
4
4
  import logging
5
+ import subprocess
5
6
  from itertools import cycle
6
7
  from typing import TYPE_CHECKING
7
8
 
@@ -13,7 +14,7 @@ from luma.oled.device import sh1106
13
14
  from PIL import Image, ImageDraw
14
15
  from PIL.ImageDraw import ImageDraw as ImageDrawType
15
16
 
16
- from boneio.const import OLED_PIN, UPTIME, WHITE
17
+ from boneio.const import LONG, OLED_PIN, SINGLE, UPTIME, WHITE
17
18
  from boneio.core.events import EventBus, async_track_point_in_time, utcnow
18
19
  from boneio.core.system import HostData
19
20
  from boneio.core.utils.font_util import make_font
@@ -102,6 +103,24 @@ class Oled:
102
103
  self._cancel_sleep_handle = None
103
104
  self._sleep_timeout = sleep_timeout
104
105
 
106
+ # Shutdown confirmation state machine
107
+ # States: None -> "wait_release" -> "confirm" -> "progress" -> shutdown
108
+ # - First long press → show confirm screen, enter "wait_release"
109
+ # - Release after first long → enter "confirm" (waiting for second long)
110
+ # - Second long press → enter "progress" with filling progress bar
111
+ # - Hold 5s → execute shutdown
112
+ # - Single click or 10s timeout → cancel
113
+ self._shutdown_state: str | None = None
114
+ self._shutdown_cancel_handle = None
115
+ # Timer to detect button release (no LONG event for 300ms = released)
116
+ self._shutdown_release_timer: asyncio.TimerHandle | None = None
117
+ # Last seen long press duration — used to detect new press cycle (duration resets)
118
+ self._shutdown_last_long_duration: float = 0.0
119
+ # Duration (seconds) the user must hold the button to confirm shutdown
120
+ self._shutdown_hold_duration: float = 5.0
121
+ # Timeout (seconds) to cancel shutdown confirmation if no action
122
+ self._shutdown_confirm_timeout: float = 10.0
123
+
105
124
  # Initialize I2C display
106
125
  try:
107
126
  # Use luma.oled for now, but could be refactored to use SMBus2I2C
@@ -219,14 +238,98 @@ class Oled:
219
238
  # Display the centered QR code
220
239
  self._device.display(display_image)
221
240
 
222
- async def _handle_button_press(self, event: dict) -> None:
223
- """Handle button press event from input."""
224
- _LOGGER.debug(f"OLED button pressed event received: {event}")
241
+ async def _handle_button_press(self, event) -> None:
242
+ """Handle button press event from input.
243
+
244
+ Supports shutdown flow via long press:
245
+ 1. First long press → show confirmation screen
246
+ 2. User releases button → state moves to "confirm"
247
+ 3. Second long press (held 5s) → progress bar fills, then shutdown
248
+ 4. Any single click or 10s timeout → cancel shutdown
249
+
250
+ The detector emits periodic LONG events (every 200ms) with growing
251
+ duration while the button is held. A new press cycle is detected
252
+ when duration resets (new duration < last tracked duration).
253
+
254
+ Args:
255
+ event: InputEvent from EventBus with click_type and duration
256
+ """
257
+ click_type = getattr(event, "click_type", None)
258
+ duration = getattr(event, "duration", None) or 0.0
259
+
260
+ _LOGGER.debug("OLED button event: click_type=%s, duration=%.2f, shutdown_state=%s",
261
+ click_type, duration, self._shutdown_state)
262
+
263
+ # --- Shutdown state machine ---
264
+
265
+ if self._shutdown_state == "wait_release":
266
+ # Absorb periodic LONG events from the first long press.
267
+ # Detector does NOT emit SINGLE after long press release.
268
+ # Detect release via timer: each LONG resets a 300ms timer.
269
+ # When no more LONG events arrive, timer fires → "confirm".
270
+ if click_type == LONG:
271
+ self._shutdown_last_long_duration = duration
272
+ # Reset release-detection timer
273
+ self._reset_release_timer()
274
+ return
275
+ elif click_type == SINGLE:
276
+ # Shouldn't happen after long, but handle gracefully
277
+ self._cancel_release_timer()
278
+ self._shutdown_state = "confirm"
279
+ self._shutdown_last_long_duration = 0.0
280
+ return
281
+ # Ignore other events
282
+ return
283
+
284
+ if self._shutdown_state == "confirm":
285
+ if click_type == LONG:
286
+ # Second long press — enter progress mode
287
+ self._shutdown_state = "progress"
288
+ self._cancel_shutdown_timeout()
289
+ self._shutdown_last_long_duration = duration
290
+ self._draw_shutdown_progress(duration)
291
+ if duration >= self._shutdown_hold_duration:
292
+ await self._execute_shutdown()
293
+ return
294
+ elif click_type == SINGLE:
295
+ # Single click cancels shutdown confirmation
296
+ self._cancel_shutdown()
297
+ return
298
+ # Ignore other events during confirm
299
+ return
300
+
301
+ if self._shutdown_state == "progress":
302
+ if click_type == LONG:
303
+ if duration < self._shutdown_last_long_duration:
304
+ # Duration reset — user released and pressed again, cancel
305
+ self._cancel_shutdown()
306
+ return
307
+ # Still holding — update progress bar
308
+ self._shutdown_last_long_duration = duration
309
+ self._draw_shutdown_progress(duration)
310
+ if duration >= self._shutdown_hold_duration:
311
+ await self._execute_shutdown()
312
+ return
313
+ else:
314
+ # Released (single) or other — cancel
315
+ self._cancel_shutdown()
316
+ return
317
+
318
+ # --- Normal mode ---
225
319
  if self._sleep:
226
- # Display is sleeping - wake it up
227
320
  self.wake_up()
228
- else:
229
- # Display is active - go to next screen
321
+ return
322
+
323
+ if click_type == LONG and duration < 1.0:
324
+ # First long press event — show confirmation, enter wait_release
325
+ self._shutdown_state = "wait_release"
326
+ self._shutdown_last_long_duration = duration
327
+ self._draw_shutdown_confirm()
328
+ self._start_shutdown_timeout()
329
+ self._reset_release_timer()
330
+ return
331
+
332
+ if click_type == SINGLE:
230
333
  self._next_screen()
231
334
 
232
335
  def _next_screen(self) -> None:
@@ -240,6 +343,150 @@ class Oled:
240
343
  self._current_screen = next(self._screen_cycle)
241
344
  self.render_display()
242
345
 
346
+ # --- Shutdown helper methods ---
347
+
348
+ def _draw_shutdown_confirm(self) -> None:
349
+ """Draw shutdown confirmation screen on OLED.
350
+
351
+ Shows a warning message asking the user to hold the button
352
+ for 5 seconds to confirm system shutdown.
353
+ """
354
+ with canvas(self._device) as draw:
355
+ # Warning triangle
356
+ draw.polygon([(64, 2), (54, 18), (74, 18)], outline=WHITE)
357
+ draw.text((61, 5), "!", font=fonts["small"], fill=WHITE)
358
+ # Message
359
+ draw.text((10, 24), "Shutdown system?", font=fonts["small"], fill=WHITE)
360
+ draw.text((4, 38), "Hold button 5s to confirm", font=fonts["extraSmall"], fill=WHITE)
361
+ draw.text((8, 52), "Click to cancel (10s)", font=fonts["extraSmall"], fill=WHITE)
362
+
363
+ def _draw_shutdown_progress(self, duration: float) -> None:
364
+ """Draw shutdown progress bar on OLED.
365
+
366
+ Shows a progress bar that fills proportionally to how long
367
+ the user has been holding the button vs the required duration.
368
+
369
+ Args:
370
+ duration: How long the button has been held (seconds)
371
+ """
372
+ progress = min(duration / self._shutdown_hold_duration, 1.0)
373
+ bar_x, bar_y = 10, 34
374
+ bar_w, bar_h = 108, 14
375
+ fill_w = int(bar_w * progress)
376
+
377
+ with canvas(self._device) as draw:
378
+ draw.text((20, 4), "Shutting down...", font=fonts["small"], fill=WHITE)
379
+ draw.text((28, 18), f"{int(progress * 100)}%", font=fonts["small"], fill=WHITE)
380
+ # Progress bar outline
381
+ draw.rectangle([bar_x, bar_y, bar_x + bar_w, bar_y + bar_h], outline=WHITE)
382
+ # Progress bar fill
383
+ if fill_w > 0:
384
+ draw.rectangle([bar_x + 1, bar_y + 1, bar_x + fill_w - 1, bar_y + bar_h - 1], fill=WHITE)
385
+ draw.text((22, 54), "Release to cancel", font=fonts["extraSmall"], fill=WHITE)
386
+
387
+ def _start_shutdown_timeout(self) -> None:
388
+ """Start a 10-second timeout that cancels the shutdown confirmation.
389
+
390
+ If the user doesn't interact within the timeout period,
391
+ the shutdown flow is cancelled and the normal screen is restored.
392
+ """
393
+ self._cancel_shutdown_timeout()
394
+ loop = self._event_bus._loop
395
+
396
+ def _timeout_callback() -> None:
397
+ """Cancel shutdown after timeout expires."""
398
+ _LOGGER.info("Shutdown confirmation timed out, cancelling")
399
+ self._shutdown_state = None
400
+ self._shutdown_cancel_handle = None
401
+ self.render_display()
402
+
403
+ self._shutdown_cancel_handle = loop.call_later(
404
+ self._shutdown_confirm_timeout, _timeout_callback
405
+ )
406
+
407
+ def _cancel_shutdown_timeout(self) -> None:
408
+ """Cancel the pending shutdown timeout timer."""
409
+ if self._shutdown_cancel_handle is not None:
410
+ self._shutdown_cancel_handle.cancel()
411
+ self._shutdown_cancel_handle = None
412
+
413
+ def _reset_release_timer(self) -> None:
414
+ """Reset the 300ms release-detection timer.
415
+
416
+ Called on each periodic LONG event during wait_release state.
417
+ If no more LONG events arrive within 300ms, the timer fires
418
+ and transitions to 'confirm' state (button was released).
419
+ """
420
+ self._cancel_release_timer()
421
+ loop = self._event_bus._loop
422
+
423
+ def _on_release_detected() -> None:
424
+ """No LONG event for 300ms — button was released."""
425
+ self._shutdown_release_timer = None
426
+ if self._shutdown_state == "wait_release":
427
+ _LOGGER.debug("OLED button release detected (no LONG for 300ms)")
428
+ self._shutdown_state = "confirm"
429
+ self._shutdown_last_long_duration = 0.0
430
+ # Timeout already running from first long press
431
+
432
+ self._shutdown_release_timer = loop.call_later(0.3, _on_release_detected)
433
+
434
+ def _cancel_release_timer(self) -> None:
435
+ """Cancel the pending release-detection timer."""
436
+ if self._shutdown_release_timer is not None:
437
+ self._shutdown_release_timer.cancel()
438
+ self._shutdown_release_timer = None
439
+
440
+ def _cancel_shutdown(self) -> None:
441
+ """Cancel the shutdown flow and return to normal display.
442
+
443
+ Resets the shutdown state machine and restores the current screen.
444
+ """
445
+ _LOGGER.info("Shutdown cancelled by user")
446
+ self._cancel_shutdown_timeout()
447
+ self._cancel_release_timer()
448
+ self._shutdown_state = None
449
+ self._shutdown_last_long_duration = 0.0
450
+ self.render_display()
451
+
452
+ async def _execute_shutdown(self) -> None:
453
+ """Execute system shutdown.
454
+
455
+ Draws a final 'Goodbye' message on the OLED, then runs
456
+ 'sudo shutdown -h now' to power off the device.
457
+ """
458
+ _LOGGER.warning("System shutdown initiated from OLED button")
459
+ self._shutdown_state = None
460
+ self._shutdown_last_long_duration = 0.0
461
+ self._cancel_shutdown_timeout()
462
+
463
+ # Draw goodbye screen
464
+ with canvas(self._device) as draw:
465
+ draw.text((20, 10), "Goodbye!", font=fonts["big"], fill=WHITE)
466
+ draw.text((15, 35), "System shutting down...", font=fonts["extraSmall"], fill=WHITE)
467
+
468
+ # Small delay so the user sees the message
469
+ await asyncio.sleep(1)
470
+
471
+ try:
472
+ subprocess.run(
473
+ ["sudo", "shutdown", "-h", "now"],
474
+ check=True,
475
+ capture_output=True,
476
+ text=True,
477
+ )
478
+ except subprocess.CalledProcessError as e:
479
+ _LOGGER.error("Failed to shutdown device: %s", e.stderr)
480
+ # Show error on OLED and return to normal
481
+ with canvas(self._device) as draw:
482
+ draw.text((10, 20), "Shutdown failed!", font=fonts["small"], fill=WHITE)
483
+ draw.text((10, 40), str(e.stderr)[:20], font=fonts["extraSmall"], fill=WHITE)
484
+ await asyncio.sleep(3)
485
+ self.render_display()
486
+ except Exception as e:
487
+ _LOGGER.error("Error shutting down device: %s", e)
488
+ self.render_display()
489
+
243
490
  def render_display(self) -> None:
244
491
  """Render display - main method that decides what to display."""
245
492
 
@@ -35,7 +35,7 @@ schema:
35
35
  action: ['cover', 'cover_over_mqtt', 'remote_cover']
36
36
  forbidden_if:
37
37
  action: ['output', 'mqtt', 'mqtt_output', 'remote_output']
38
- allowed: ['TOGGLE', 'OPEN', 'CLOSE', 'STOP', 'TOGGLE_OPEN', 'TOGGLE_CLOSE', 'TILT', 'TILT_OPEN', 'TILT_CLOSE']
38
+ allowed: ['TOGGLE', 'OPEN', 'CLOSE', 'STOP', 'TOGGLE_OPEN', 'TOGGLE_CLOSE', 'SMART_TOGGLE', 'TILT', 'TILT_OPEN', 'TILT_CLOSE']
39
39
  coerce: action_field
40
40
  default: TOGGLE
41
41
  case_insensitive: true
@@ -58,6 +58,18 @@ schema:
58
58
  required: False
59
59
  meta:
60
60
  label: Tilt position to set cover to. 0 means closed, 100 means opened.
61
+ always_open_till:
62
+ type: integer
63
+ required: False
64
+ min: 0
65
+ max: 100
66
+ default: 50
67
+ meta:
68
+ label: Smart toggle threshold (0-100%).
69
+ description: |
70
+ Position threshold for SMART_TOGGLE action.
71
+ If cover position is at or below this value, it will always open.
72
+ Above this value, normal toggle behavior applies.
61
73
  action_output:
62
74
  type: string
63
75
  required_if:
@@ -0,0 +1,2 @@
1
+ # flake8: noqa
2
+ __version__ = "1.2.0dev25"