boneIO 1.0.0.dev21__tar.gz → 1.0.0.dev23__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 (413) hide show
  1. {boneio-1.0.0.dev21/boneio.egg-info → boneio-1.0.0.dev23}/PKG-INFO +1 -1
  2. {boneio-1.0.0.dev21/boneio/boards/0.4 → boneio-1.0.0.dev23/boneio/boards/0.2}/output_24_16.yaml +2 -2
  3. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_24_16.yaml +2 -2
  4. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/time_based.py +14 -4
  5. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/venetian.py +8 -4
  6. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/binary_sensor.py +2 -2
  7. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/detectors.py +190 -3
  8. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/event.py +74 -1
  9. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/config_helper.py +1 -1
  10. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/covers.py +3 -3
  11. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/display.py +18 -0
  12. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/inputs.py +40 -4
  13. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/manager.py +12 -0
  14. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/sensors.py +20 -0
  15. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/system/host_data.py +1 -1
  16. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/config.yaml +1 -1
  17. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/config.yaml +1 -1
  18. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/config.yaml +1 -1
  19. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/config.yaml +1 -1
  20. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/display/oled.py +1 -1
  21. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/input/base.py +34 -0
  22. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/input/manager.py +39 -0
  23. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/ina219.py +12 -2
  24. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/base.py +1 -1
  25. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/integration/homeassistant.py +32 -6
  26. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/runner.py +1 -2
  27. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/schema.yaml +44 -0
  28. boneio-1.0.0.dev23/boneio/version.py +2 -0
  29. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/cssMode-Cf6c8Rak.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/cssMode-Cu-5LYe_.js +1 -1
  30. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/freemarker2-Dx0BWjru.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/freemarker2-nq6oJG_Y.js +1 -1
  31. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/handlebars-BTuLZVfx.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/handlebars-B5W2-m2x.js +1 -1
  32. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/html-BB3T_3_K.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/html-vUTSIY6B.js +1 -1
  33. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/htmlMode-yP62Fr3K.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/htmlMode-CDTfRhqt.js +1 -1
  34. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/index-GG4_twIa.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/index-BQrDKk-6.js +255 -255
  35. boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/index-CU6eO3xb.css +1 -0
  36. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/javascript-fCd4TqkY.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/javascript-BT4M2_pD.js +1 -1
  37. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/jsonMode-CChUrnET.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/jsonMode-D-E2Vrak.js +1 -1
  38. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/liquid-DdLOtKyT.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/liquid-D1aceO1w.js +1 -1
  39. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/mdx-wnkV-3mF.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/mdx-DohT_XYH.js +1 -1
  40. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/python-BU1BlHpX.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/python-C8fD_30g.js +1 -1
  41. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/razor-DNgLOtn7.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/razor-090nAgDD.js +1 -1
  42. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/tsMode-CINGfPlt.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/tsMode-BAlzCa-y.js +1 -1
  43. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/typescript-CkWSk1mf.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/typescript-C3QTnewR.js +1 -1
  44. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/xml-DlZcKj6v.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/xml-D3NSlFbJ.js +1 -1
  45. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/yaml-CDmetGCQ.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/yaml-1y1ho8Rn.js +1 -1
  46. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/index.html +2 -2
  47. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/adc.schema.json +6 -6
  48. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/areas.schema.json +2 -2
  49. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/binary_sensor.schema.json +18 -18
  50. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/boneio.schema.json +4 -4
  51. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/config.schema.json +309 -198
  52. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/cover.schema.json +10 -10
  53. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/ds2482.schema.json +2 -2
  54. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/event.schema.json +165 -54
  55. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/ina219.schema.json +8 -8
  56. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/lm75.schema.json +6 -6
  57. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/logger.schema.json +2 -2
  58. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/mcp23017.schema.json +4 -4
  59. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/mcp9808.schema.json +6 -6
  60. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/modbus.schema.json +2 -2
  61. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/modbus_devices.schema.json +16 -16
  62. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/mqtt.schema.json +4 -4
  63. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/oled.schema.json +6 -6
  64. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/output.schema.json +6 -6
  65. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/output_group.schema.json +2 -2
  66. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/pca9685.schema.json +4 -4
  67. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/pcf8575.schema.json +4 -4
  68. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/remote_devices.schema.json +20 -20
  69. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/sensor.schema.json +6 -6
  70. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/virtual_energy_sensor.schema.json +2 -2
  71. {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/web.schema.json +4 -4
  72. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/config.py +135 -1
  73. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/update.py +262 -10
  74. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/adc.schema.json +6 -6
  75. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/areas.schema.json +2 -2
  76. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/binary_sensor.schema.json +18 -18
  77. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/boneio.schema.json +4 -4
  78. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/config.schema.json +309 -198
  79. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/cover.schema.json +10 -10
  80. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/ds2482.schema.json +2 -2
  81. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/event.schema.json +165 -54
  82. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/ina219.schema.json +8 -8
  83. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/lm75.schema.json +6 -6
  84. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/logger.schema.json +2 -2
  85. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/mcp23017.schema.json +4 -4
  86. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/mcp9808.schema.json +6 -6
  87. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/modbus.schema.json +2 -2
  88. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/modbus_devices.schema.json +16 -16
  89. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/mqtt.schema.json +4 -4
  90. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/oled.schema.json +6 -6
  91. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/output.schema.json +6 -6
  92. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/output_group.schema.json +2 -2
  93. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/pca9685.schema.json +4 -4
  94. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/pcf8575.schema.json +4 -4
  95. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/remote_devices.schema.json +20 -20
  96. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/sensor.schema.json +6 -6
  97. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/virtual_energy_sensor.schema.json +2 -2
  98. {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/web.schema.json +4 -4
  99. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23/boneio.egg-info}/PKG-INFO +1 -1
  100. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/SOURCES.txt +17 -17
  101. boneio-1.0.0.dev21/boneio/version.py +0 -2
  102. boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/index-cAyuaVJ4.css +0 -1
  103. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/LICENSE +0 -0
  104. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/MANIFEST.in +0 -0
  105. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/README.md +0 -0
  106. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/__init__.py +0 -0
  107. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/input.yaml +0 -0
  108. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_32_10.yaml +0 -0
  109. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_32_5.yaml +0 -0
  110. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_cover.yaml +0 -0
  111. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  112. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/input.yaml +0 -0
  113. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_32_10.yaml +0 -0
  114. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_32_5.yaml +0 -0
  115. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_cover.yaml +0 -0
  116. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  117. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/input.yaml +0 -0
  118. {boneio-1.0.0.dev21/boneio/boards/0.2 → boneio-1.0.0.dev23/boneio/boards/0.4}/output_24_16.yaml +0 -0
  119. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_32_10.yaml +0 -0
  120. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_32_5.yaml +0 -0
  121. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_cover.yaml +0 -0
  122. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  123. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/input.yaml +0 -0
  124. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_24_16.yaml +0 -0
  125. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_32_10.yaml +0 -0
  126. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_cover.yaml +0 -0
  127. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  128. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/input.yaml +0 -0
  129. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_24_16.yaml +0 -0
  130. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_32_10.yaml +0 -0
  131. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_cover.yaml +0 -0
  132. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  133. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/input.yaml +0 -0
  134. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_24_16.yaml +0 -0
  135. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_32_10.yaml +0 -0
  136. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_cover.yaml +0 -0
  137. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  138. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/input.yaml +0 -0
  139. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_24_16.yaml +0 -0
  140. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_32_10.yaml +0 -0
  141. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_cover.yaml +0 -0
  142. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  143. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/bonecli.py +0 -0
  144. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/__init__.py +0 -0
  145. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/__init__.py +0 -0
  146. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/cover.py +0 -0
  147. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/previous.py +0 -0
  148. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/group/__init__.py +0 -0
  149. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/group/output_group.py +0 -0
  150. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/__init__.py +0 -0
  151. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/__init__.py +0 -0
  152. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/basic.py +0 -0
  153. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/mcp.py +0 -0
  154. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/pca.py +0 -0
  155. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/pcf.py +0 -0
  156. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/sensor/__init__.py +0 -0
  157. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/sensor/virtual_energy.py +0 -0
  158. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/const.py +0 -0
  159. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/__init__.py +0 -0
  160. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/__init__.py +0 -0
  161. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/package-lock.json +0 -0
  162. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/package.json +0 -0
  163. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/schema_converter.py +0 -0
  164. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/yaml_util.py +0 -0
  165. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/discovery.py +0 -0
  166. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/events/__init__.py +0 -0
  167. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/events/bus.py +0 -0
  168. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/__init__.py +0 -0
  169. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/modbus.py +0 -0
  170. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/outputs.py +0 -0
  171. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/remote.py +0 -0
  172. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/__init__.py +0 -0
  173. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/basic.py +0 -0
  174. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/basic_mqtt.py +0 -0
  175. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/local.py +0 -0
  176. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/mqtt.py +0 -0
  177. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/queue.py +0 -0
  178. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/__init__.py +0 -0
  179. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/base.py +0 -0
  180. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/esphome.py +0 -0
  181. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/mqtt.py +0 -0
  182. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/sensor/__init__.py +0 -0
  183. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/sensor/base.py +0 -0
  184. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/sensor/system.py +0 -0
  185. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/state/__init__.py +0 -0
  186. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/state/manager.py +0 -0
  187. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/system/__init__.py +0 -0
  188. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/system/monitor.py +0 -0
  189. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/__init__.py +0 -0
  190. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/async_updater.py +0 -0
  191. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/filter.py +0 -0
  192. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/font_util.py +0 -0
  193. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/logger.py +0 -0
  194. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/timeperiod.py +0 -0
  195. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/util.py +0 -0
  196. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/adc.yaml +0 -0
  197. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  198. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/event.yaml +0 -0
  199. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/mqtt.yaml +0 -0
  200. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  201. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/adc.yaml +0 -0
  202. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  203. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/event.yaml +0 -0
  204. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/mqtt.yaml +0 -0
  205. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  206. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/__init__.py +0 -0
  207. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/adc.yaml +0 -0
  208. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  209. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/cover.yaml +0 -0
  210. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/event.yaml +0 -0
  211. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/mqtt.yaml +0 -0
  212. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/outputCover.yaml +0 -0
  213. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/adc.yaml +0 -0
  214. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  215. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/cover.yaml +0 -0
  216. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/event.yaml +0 -0
  217. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  218. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  219. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/adc.yaml +0 -0
  220. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  221. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  222. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  223. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  224. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/event_all.yaml +0 -0
  225. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  226. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  227. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  228. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  229. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  230. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  231. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/exceptions.py +0 -0
  232. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/__init__.py +0 -0
  233. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/analog/__init__.py +0 -0
  234. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/analog/adc.py +0 -0
  235. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/display/__init__.py +0 -0
  236. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  237. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/__init__.py +0 -0
  238. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  239. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  240. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  241. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  242. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/input/__init__.py +0 -0
  243. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/__init__.py +0 -0
  244. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/bus.py +0 -0
  245. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/ina219_driver.py +0 -0
  246. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/mcp9808.py +0 -0
  247. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/pct2075.py +0 -0
  248. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/__init__.py +0 -0
  249. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/bus.py +0 -0
  250. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/dallas.py +0 -0
  251. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/ds2482.py +0 -0
  252. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/__init__.py +0 -0
  253. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  254. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  255. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  256. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/integration/__init__.py +0 -0
  257. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/integration/interlock.py +0 -0
  258. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/__init__.py +0 -0
  259. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/cli.py +0 -0
  260. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/client.py +0 -0
  261. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/coordinator.py +0 -0
  262. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/__init__.py +0 -0
  263. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  264. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  265. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  266. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  267. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  268. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  269. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  270. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/inverters/sofar.json +0 -0
  271. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/inverters/thessla.json +0 -0
  272. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  273. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/other/wanas415.json +0 -0
  274. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/cwt.json +0 -0
  275. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
  276. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  277. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/pt100.json +0 -0
  278. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/sht20.json +0 -0
  279. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/sht30.json +0 -0
  280. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/__init__.py +0 -0
  281. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/base.py +0 -0
  282. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/__init__.py +0 -0
  283. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/numeric.py +0 -0
  284. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/select.py +0 -0
  285. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/switch.py +0 -0
  286. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/text.py +0 -0
  287. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/__init__.py +0 -0
  288. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/binary.py +0 -0
  289. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/numeric.py +0 -0
  290. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/text.py +0 -0
  291. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/writeable/__init__.py +0 -0
  292. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/writeable/binary.py +0 -0
  293. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/writeable/numeric.py +0 -0
  294. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/utils.py +0 -0
  295. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/__init__.py +0 -0
  296. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/actions.py +0 -0
  297. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/events.py +0 -0
  298. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/files.py +0 -0
  299. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/logs.py +0 -0
  300. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/mqtt.py +0 -0
  301. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/state.py +0 -0
  302. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/actions.yaml +0 -0
  303. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/actions_sensor.yaml +0 -0
  304. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/actions_switch.yaml +0 -0
  305. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/filters.yaml +0 -0
  306. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/filters_adc.yaml +0 -0
  307. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/id.yaml +0 -0
  308. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/remote_devices.yaml +0 -0
  309. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/temp_unit.yaml +0 -0
  310. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/update_interval.yaml +0 -0
  311. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/app.py +0 -0
  312. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/abap-CRCWOmpq.js +0 -0
  313. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/apex-DnsZk_dE.js +0 -0
  314. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/azcli-1IWB1ccx.js +0 -0
  315. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/bat-DPkNLes8.js +0 -0
  316. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/bicep-Corcdgou.js +0 -0
  317. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/cameligo-CGrWLZr3.js +0 -0
  318. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/clojure-D9WOWImG.js +0 -0
  319. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
  320. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/coffee-B7EJu28W.js +0 -0
  321. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/cpp-SEyurbux.js +0 -0
  322. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/csharp-BoL64M5l.js +0 -0
  323. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/csp-C46ZqvIl.js +0 -0
  324. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/css-DQU6DXDx.js +0 -0
  325. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/cypher-D84EuPTj.js +0 -0
  326. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/dart-D8lhlL1r.js +0 -0
  327. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/dockerfile-DLk6rpji.js +0 -0
  328. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/ecl-BO6FnfXk.js +0 -0
  329. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/editor.worker-DsAeyiJ5.js +0 -0
  330. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/elixir-BRjLKONM.js +0 -0
  331. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/flow9-Cac8vKd7.js +0 -0
  332. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/fsharp-fd1GTHhf.js +0 -0
  333. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/go-O9LJTZXk.js +0 -0
  334. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/graphql-LQdxqEYJ.js +0 -0
  335. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/hcl-DxDQ3s82.js +0 -0
  336. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/ini-BvajGCUy.js +0 -0
  337. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/java-SYsfObOQ.js +0 -0
  338. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/json.worker-DaRII17c.js +0 -0
  339. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/julia-DQXNmw_w.js +0 -0
  340. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/kotlin-qQ0MG-9I.js +0 -0
  341. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/less-GGFNNJHn.js +0 -0
  342. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/lexon-Canl7DCW.js +0 -0
  343. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/lua-D28Ae8-K.js +0 -0
  344. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/m3-DPitgjJI.js +0 -0
  345. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/markdown-B811l8j2.js +0 -0
  346. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/mips-CdjsipkG.js +0 -0
  347. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/msdax-CYqgjx_P.js +0 -0
  348. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/mysql-BHd6q0vd.js +0 -0
  349. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/objective-c-B1aVtJYH.js +0 -0
  350. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pascal-BhNW15KB.js +0 -0
  351. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pascaligo-5jv8CcQD.js +0 -0
  352. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/perl-DlYyT36c.js +0 -0
  353. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pgsql-Dy0bjov7.js +0 -0
  354. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/php-120yhfDK.js +0 -0
  355. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pla-CjnFlu4u.js +0 -0
  356. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/postiats-CQpG440k.js +0 -0
  357. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/powerquery-DdJtto1Z.js +0 -0
  358. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/powershell-Bu_VLpJB.js +0 -0
  359. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/protobuf-IBS6jZEB.js +0 -0
  360. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pug-kFxLfcjb.js +0 -0
  361. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/qsharp-q7JyzKFN.js +0 -0
  362. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/r-BIFz-_sK.js +0 -0
  363. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/redis-CHOsPHWR.js +0 -0
  364. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/redshift-CBifECDb.js +0 -0
  365. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/restructuredtext-CghPJEOS.js +0 -0
  366. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/ruby-CYWGW-b1.js +0 -0
  367. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/rust-DMDD0SHb.js +0 -0
  368. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sb-BYAiYHFx.js +0 -0
  369. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/scala-Bqvq8jcR.js +0 -0
  370. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/scheme-Dhb-2j9p.js +0 -0
  371. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/scss-CTwUZ5N7.js +0 -0
  372. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/shell-CsDZo4DB.js +0 -0
  373. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/solidity-CME5AdoB.js +0 -0
  374. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sophia-RYC1BQQz.js +0 -0
  375. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sparql-KEyrF7De.js +0 -0
  376. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sql-BdTr02Mf.js +0 -0
  377. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/st-C7iG7M4S.js +0 -0
  378. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/swift-D7IUmUK8.js +0 -0
  379. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/systemverilog-DgMryOEJ.js +0 -0
  380. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/tcl-PloMZuKG.js +0 -0
  381. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/twig-BfRIq3la.js +0 -0
  382. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/typespec-CzxlYoT_.js +0 -0
  383. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/vb-BwAE3J76.js +0 -0
  384. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/wgsl-B_1kOXbF.js +0 -0
  385. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/yaml.worker-BTE-_K6g.js +0 -0
  386. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/boneio.svg +0 -0
  387. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  388. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/dallas.schema.json +0 -0
  389. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/middleware/__init__.py +0 -0
  390. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/middleware/auth.py +0 -0
  391. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/__init__.py +0 -0
  392. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/auth.py +0 -0
  393. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/caddy.py +0 -0
  394. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/covers.py +0 -0
  395. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/modbus.py +0 -0
  396. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/outputs.py +0 -0
  397. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/remote_devices.py +0 -0
  398. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/sensors.py +0 -0
  399. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/system.py +0 -0
  400. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/dallas.schema.json +0 -0
  401. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/services/__init__.py +0 -0
  402. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/services/logs.py +0 -0
  403. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/web_server.py +0 -0
  404. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/websocket_manager.py +0 -0
  405. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/dependency_links.txt +0 -0
  406. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/entry_points.txt +0 -0
  407. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/requires.txt +0 -0
  408. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/top_level.txt +0 -0
  409. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/pyproject.toml +0 -0
  410. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/setup.cfg +0 -0
  411. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/setup.py +0 -0
  412. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/tests/test_i2c_smbus2.py +0 -0
  413. {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/tests/test_py313_compatibility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.0.0.dev21
3
+ Version: 1.0.0.dev23
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
@@ -1,8 +1,8 @@
1
1
  mcp23017:
2
2
  - id: mcp_left
3
- address: 0x20
3
+ address: 0x23
4
4
  - id: mcp_right
5
- address: 0x21
5
+ address: 0x22
6
6
 
7
7
  output_mapping:
8
8
  out_01:
@@ -1,8 +1,8 @@
1
1
  mcp23017:
2
2
  - id: mcp_left
3
- address: 0x20
3
+ address: 0x23
4
4
  - id: mcp_right
5
- address: 0x21
5
+ address: 0x22
6
6
 
7
7
  output_mapping:
8
8
  out_01:
@@ -41,7 +41,13 @@ class TimeBasedCover(BaseCover):
41
41
 
42
42
 
43
43
  def _move_cover(self, direction: str, duration: float, target_position: int | None = None):
44
- """Metoda uruchamiana w oddzielnym wątku do fizycznego ruchu rolety."""
44
+ """Run in sepearate thread.
45
+
46
+ Args:
47
+ direction: Direction of movement (OPEN or CLOSE)
48
+ duration: Full time for 0-100% movement in milliseconds
49
+ target_position: Optional target position (0-100)
50
+ """
45
51
  if direction == OPEN:
46
52
  relay = self._open_relay
47
53
  total_steps = 100 - self._position
@@ -56,18 +62,22 @@ class TimeBasedCover(BaseCover):
56
62
  self._loop.call_soon_threadsafe(lambda: self.send_state(self.state, self.json_position))
57
63
  return
58
64
 
65
+ # Calculate actual duration based on remaining distance
66
+ # duration is full time for 100% movement, scale it by actual distance to travel
67
+ actual_duration = duration * (total_steps / 100.0)
68
+
59
69
  relay.turn_on()
60
70
  start_time = time.monotonic()
61
71
 
62
72
  while not self._stop_event.is_set():
63
73
  current_time = time.monotonic() # Pobierz aktualny czas tylko raz na iterację
64
74
  elapsed_time = (current_time - start_time) * 1000 # Konwersja na milisekundy
65
- progress = elapsed_time / duration
75
+ progress = elapsed_time / actual_duration if actual_duration > 0 else 1.0
66
76
 
67
77
  if direction == OPEN:
68
- self._position = min(100.0, self._initial_position + progress * 100)
78
+ self._position = min(100.0, self._initial_position + progress * total_steps)
69
79
  elif direction == CLOSE:
70
- self._position = max(0.0, self._initial_position - progress * 100)
80
+ self._position = max(0.0, self._initial_position - progress * total_steps)
71
81
 
72
82
  self._last_timestamp = current_time # Użyj pobranego czasu
73
83
  if current_time - self._last_update_time >= 1:
@@ -97,6 +97,10 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
97
97
  )
98
98
  return
99
99
 
100
+ # Calculate actual duration based on remaining distance
101
+ # duration is full time for 100% movement, scale it by actual distance to travel
102
+ actual_duration = duration * (total_steps / 100.0)
103
+
100
104
  relay.turn_on()
101
105
  start_time = time.monotonic()
102
106
  progress = 0.0
@@ -116,15 +120,15 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
116
120
 
117
121
 
118
122
  if elapsed_time < needed_tilt_duration:
119
- tilt_progress = elapsed_time / needed_tilt_duration
123
+ tilt_progress = elapsed_time / needed_tilt_duration if needed_tilt_duration > 0 else 1.0
120
124
  progress = 0.0
121
125
  else:
122
126
  tilt_progress = 1.0
123
- progress = (elapsed_time - needed_tilt_duration) / duration
127
+ progress = (elapsed_time - needed_tilt_duration) / actual_duration if actual_duration > 0 else 1.0
124
128
 
125
129
  if direction == OPEN:
126
130
  # Obliczanie _position dla kierunku OPEN
127
- self._position = min(100.0, self._initial_position + progress * 100)
131
+ self._position = min(100.0, self._initial_position + progress * total_steps)
128
132
 
129
133
  # Obliczanie _tilt_position dla kierunku OPEN
130
134
  if target_tilt_position is not None:
@@ -135,7 +139,7 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
135
139
  )
136
140
  elif direction == CLOSE:
137
141
  # Obliczanie _position dla kierunku CLOSE
138
- self._position = max(0.0, self._initial_position - progress * 100)
142
+ self._position = max(0.0, self._initial_position - progress * total_steps)
139
143
 
140
144
  # Obliczanie _tilt_position dla kierunku CLOSE
141
145
  if target_tilt_position is not None:
@@ -54,9 +54,9 @@ class GpioInputBinarySensor(GpioBaseClass):
54
54
  _LOGGER.debug("Configured binary sensor %s on pin %s (inverted=%s)",
55
55
  self._name, self._pin, inverted)
56
56
 
57
- # Send initial state if requested
57
+ # Send initial state if requested - register callback to run after GPIO manager starts
58
58
  if kwargs.get("initial_send", False):
59
- self._loop.call_soon(callback=self._send_initial_state)
59
+ gpio_manager.register_on_start_callback(self._send_initial_state)
60
60
 
61
61
  def _send_initial_state(self) -> None:
62
62
  """Send initial state after setup."""
@@ -39,6 +39,10 @@ class ClickState:
39
39
  # Sequence tracking
40
40
  last_click_type: str | None = None
41
41
  last_click_time: float | None = None
42
+ # Exclusive mode: pending click waiting for sequence window
43
+ pending_click_type: str | None = None
44
+ pending_click_duration: float | None = None
45
+ pending_click_timer: asyncio.TimerHandle | None = None
42
46
 
43
47
 
44
48
  @dataclass
@@ -64,6 +68,9 @@ class MultiClickDetector:
64
68
  multiclick_window_ms: float = 220.0,
65
69
  hold_threshold_ms: float = 400.0,
66
70
  sequence_window_ms: float = DEFAULT_SEQUENCE_WINDOW_MS,
71
+ sequence_mode: str = "immediate",
72
+ enabled_sequences: set[str] | None = None,
73
+ enable_triple_click: bool = False,
67
74
  name: str = "unknown",
68
75
  pin: str = "unknown",
69
76
  ):
@@ -76,6 +83,9 @@ class MultiClickDetector:
76
83
  multiclick_window_ms: Window for double-click detection
77
84
  hold_threshold_ms: Time threshold for long press
78
85
  sequence_window_ms: Window for sequence detection (e.g., double_then_long)
86
+ sequence_mode: 'immediate' (default) or 'exclusive'
87
+ enabled_sequences: Set of enabled sequence types (e.g., {'double_then_long'})
88
+ enable_triple_click: Enable triple click detection (default: False)
79
89
  name: Name of the input
80
90
  pin: Pin name for logging
81
91
  """
@@ -85,9 +95,23 @@ class MultiClickDetector:
85
95
  self._multiclick_window = multiclick_window_ms / 1000.0
86
96
  self._hold_threshold = hold_threshold_ms / 1000.0
87
97
  self._sequence_window = sequence_window_ms / 1000.0
98
+ self._sequence_mode = sequence_mode
99
+ self._enabled_sequences = enabled_sequences or set()
100
+ self._enable_triple_click = enable_triple_click
88
101
  self._name = name
89
102
  self._pin = pin
90
103
  self._state = ClickState()
104
+
105
+ # Pre-compute which click types should be delayed in exclusive mode
106
+ # based on enabled sequences
107
+ self._delay_click_types: set[str] = set()
108
+ if sequence_mode == "exclusive" and self._enabled_sequences:
109
+ for seq in self._enabled_sequences:
110
+ # Find which click type starts this sequence
111
+ for (first, _second), seq_name in CLICK_SEQUENCES.items():
112
+ if seq_name == seq:
113
+ self._delay_click_types.add(first)
114
+ break
91
115
 
92
116
  def _finalize_clicks(self) -> None:
93
117
  """Finalize a multi-click sequence."""
@@ -100,8 +124,18 @@ class MultiClickDetector:
100
124
  click_type = DOUBLE
101
125
  _LOGGER.info("Detected DOUBLE click on %s (%s)", self._name, self._pin)
102
126
  elif count == 3:
103
- click_type = TRIPLE
104
- _LOGGER.info("Detected TRIPLE click on %s (%s)", self._name, self._pin)
127
+ if self._enable_triple_click:
128
+ click_type = TRIPLE
129
+ _LOGGER.info("Detected TRIPLE click on %s (%s)", self._name, self._pin)
130
+ else:
131
+ # Triple click disabled - emit double + single instead
132
+ _LOGGER.info("Triple click disabled on %s (%s), emitting DOUBLE + SINGLE", self._name, self._pin)
133
+ self._state.click_count = 0
134
+ self._state.finalizer = None
135
+ self._state.finalizer_scheduled_loop_ts = None
136
+ self._emit_click(DOUBLE, None)
137
+ self._emit_click(SINGLE, None)
138
+ return
105
139
  else:
106
140
  click_type = SINGLE # Fallback for 4+ clicks
107
141
  _LOGGER.info("Detected %d clicks on %s (%s), treating as SINGLE", count, self._name, self._pin)
@@ -116,12 +150,22 @@ class MultiClickDetector:
116
150
  def _emit_click(self, click_type: ClickTypes, duration: float | None) -> None:
117
151
  """Emit a click event, checking for sequences first.
118
152
 
153
+ In 'immediate' mode: emit events immediately, sequences are additional.
154
+ In 'exclusive' mode: delay single/double, if sequence detected only emit sequence.
155
+
119
156
  Args:
120
157
  click_type: The detected click type (single, double, triple, long)
121
158
  duration: Duration of the click (for long press)
122
159
  """
123
160
  current_time = self._loop.time()
124
161
 
162
+ if self._sequence_mode == "exclusive":
163
+ self._emit_click_exclusive(click_type, duration, current_time)
164
+ else:
165
+ self._emit_click_immediate(click_type, duration, current_time)
166
+
167
+ def _emit_click_immediate(self, click_type: ClickTypes, duration: float | None, current_time: float) -> None:
168
+ """Immediate mode: emit events immediately, sequences are additional."""
125
169
  # Check if this click forms a sequence with the previous one
126
170
  sequence_type = self._check_sequence(click_type, current_time)
127
171
  if sequence_type:
@@ -144,6 +188,138 @@ class MultiClickDetector:
144
188
  self._state.last_click_type = click_type
145
189
  self._state.last_click_time = current_time
146
190
 
191
+ def _emit_click_exclusive(self, click_type: ClickTypes, duration: float | None, current_time: float) -> None:
192
+ """Exclusive mode: delay single/double, if sequence detected only emit sequence.
193
+
194
+ Logic:
195
+ - For single/double: store as pending, start timer for sequence_window
196
+ - For long/single: check if pending exists, if so check for sequence
197
+ - Timer expiry: emit the pending click
198
+
199
+ Supported sequences:
200
+ - double_then_long: double (pending) + long
201
+ - single_then_long: single (pending) + long
202
+ - double_then_single: double (pending) + single
203
+ """
204
+ # Check if there's a pending click and this could form a sequence
205
+ if self._state.pending_click_type:
206
+ # Check if we can form a sequence with current click
207
+ sequence_key = (self._state.pending_click_type, click_type)
208
+ sequence_type = CLICK_SEQUENCES.get(sequence_key)
209
+
210
+ # Only detect sequences that are actually enabled
211
+ if sequence_type and sequence_type in self._enabled_sequences:
212
+ # Cancel pending timer
213
+ if self._state.pending_click_timer:
214
+ self._state.pending_click_timer.cancel()
215
+ self._state.pending_click_timer = None
216
+
217
+ _LOGGER.info(
218
+ "Detected sequence %s on %s (%s) [exclusive mode]",
219
+ sequence_type.upper(), self._name, self._pin
220
+ )
221
+
222
+ # Clear pending state
223
+ self._state.pending_click_type = None
224
+ self._state.pending_click_duration = None
225
+
226
+ # Emit only the sequence, not the base events
227
+ try:
228
+ self._callback(cast(ClickTypes, sequence_type), duration)
229
+ except Exception as exc:
230
+ _LOGGER.error("Error in sequence callback for %s: %s", self._name, exc, exc_info=True)
231
+
232
+ # Clear sequence tracking
233
+ self._state.last_click_type = None
234
+ self._state.last_click_time = None
235
+ return
236
+ else:
237
+ # Sequence not enabled - emit the pending click now and continue
238
+ # Cancel pending timer
239
+ if self._state.pending_click_timer:
240
+ self._state.pending_click_timer.cancel()
241
+ self._state.pending_click_timer = None
242
+
243
+ pending_type = self._state.pending_click_type
244
+ pending_duration = self._state.pending_click_duration
245
+
246
+ _LOGGER.debug(
247
+ "Sequence %s not enabled, emitting pending click %s on %s",
248
+ sequence_type, pending_type, self._name
249
+ )
250
+
251
+ # Clear pending state
252
+ self._state.pending_click_type = None
253
+ self._state.pending_click_duration = None
254
+
255
+ # Emit the pending click
256
+ try:
257
+ self._callback(cast(ClickTypes, pending_type), pending_duration)
258
+ except Exception as exc:
259
+ _LOGGER.error("Error in click callback for %s: %s", self._name, exc, exc_info=True)
260
+
261
+ # Continue to process current click below (don't return)
262
+
263
+ # Only delay click types that can start a configured sequence
264
+ # e.g., if only double_then_long is enabled, only delay 'double', not 'single'
265
+ if click_type in self._delay_click_types:
266
+ # Cancel any existing pending timer
267
+ if self._state.pending_click_timer:
268
+ self._state.pending_click_timer.cancel()
269
+
270
+ # Store pending click
271
+ self._state.pending_click_type = click_type
272
+ self._state.pending_click_duration = duration
273
+
274
+ # Start timer to emit after sequence window
275
+ self._state.pending_click_timer = self._loop.call_later(
276
+ self._sequence_window,
277
+ self._emit_pending_click
278
+ )
279
+ _LOGGER.debug(
280
+ "Pending click %s on %s, waiting %.0fms for sequence",
281
+ click_type, self._name, self._sequence_window * 1000
282
+ )
283
+ return
284
+
285
+ # For long (without pending) or other types: emit immediately
286
+ try:
287
+ self._callback(click_type, duration)
288
+ except Exception as exc:
289
+ _LOGGER.error("Error in click callback for %s: %s", self._name, exc, exc_info=True)
290
+
291
+ # Remember for sequence detection
292
+ self._state.last_click_type = click_type
293
+ self._state.last_click_time = current_time
294
+
295
+ def _emit_pending_click(self) -> None:
296
+ """Emit the pending click after sequence window expired (exclusive mode)."""
297
+ if not self._state.pending_click_type:
298
+ return
299
+
300
+ click_type = cast(ClickTypes, self._state.pending_click_type)
301
+ duration = self._state.pending_click_duration
302
+
303
+ _LOGGER.debug(
304
+ "Sequence window expired, emitting pending click %s on %s",
305
+ click_type, self._name
306
+ )
307
+
308
+ # Clear pending state
309
+ self._state.pending_click_type = None
310
+ self._state.pending_click_duration = None
311
+ self._state.pending_click_timer = None
312
+
313
+ # Emit the click
314
+ try:
315
+ self._callback(click_type, duration)
316
+ except Exception as exc:
317
+ _LOGGER.error("Error in pending click callback for %s: %s", self._name, exc, exc_info=True)
318
+
319
+ # Remember for sequence detection (in case of chained sequences)
320
+ self._state.last_click_type = click_type
321
+ self._state.last_click_time = self._loop.time()
322
+
147
323
  def _check_sequence(self, current_click: ClickTypes, current_time: float) -> ClickTypes | None:
148
324
  """Check if current click forms a sequence with previous click.
149
325
 
@@ -166,7 +342,8 @@ class MultiClickDetector:
166
342
  sequence_key = (self._state.last_click_type, current_click)
167
343
  sequence_type = CLICK_SEQUENCES.get(sequence_key)
168
344
 
169
- if sequence_type:
345
+ # Only detect sequences that are actually enabled
346
+ if sequence_type and sequence_type in self._enabled_sequences:
170
347
  # Clear sequence state to prevent chaining
171
348
  self._state.last_click_type = None
172
349
  self._state.last_click_time = None
@@ -227,6 +404,16 @@ class MultiClickDetector:
227
404
  self._state.finalizer = None
228
405
  self._state.finalizer_scheduled_loop_ts = None
229
406
 
407
+ # In exclusive mode: if there's a pending click waiting for sequence,
408
+ # cancel its timer - user is continuing the sequence with this press
409
+ if self._sequence_mode == "exclusive" and self._state.pending_click_timer:
410
+ _LOGGER.debug(
411
+ "Cancelling pending click timer for %s - user continuing sequence",
412
+ self._name
413
+ )
414
+ self._state.pending_click_timer.cancel()
415
+ self._state.pending_click_timer = None
416
+
230
417
  # Schedule a check for a long press
231
418
  scheduled_at = self._loop.time()
232
419
  self._state.long_press_scheduled_loop_ts = scheduled_at
@@ -65,6 +65,30 @@ class GpioEventButton(GpioBaseClass):
65
65
  DEFAULT_SEQUENCE_WINDOW_MS
66
66
  )
67
67
 
68
+ # Determine which sequences are enabled based on configured actions OR mqtt_sequences
69
+ # A sequence is enabled if it has actions defined OR is set to publish to MQTT
70
+ enabled_sequences: set[str] = set()
71
+ sequence_types = {'double_then_long', 'single_then_long', 'double_then_single'}
72
+
73
+ # Check actions
74
+ actions = kwargs.get('actions', {})
75
+ if isinstance(actions, dict):
76
+ for seq_type in sequence_types:
77
+ if seq_type in actions and actions[seq_type]:
78
+ enabled_sequences.add(seq_type)
79
+
80
+ # Check mqtt_sequences
81
+ mqtt_sequences = kwargs.get('mqtt_sequences', {})
82
+ if isinstance(mqtt_sequences, dict):
83
+ for seq_type in sequence_types:
84
+ if mqtt_sequences.get(seq_type):
85
+ enabled_sequences.add(seq_type)
86
+
87
+ _LOGGER.debug("Enabled sequences for %s: %s", self._name, enabled_sequences)
88
+
89
+ # Get enable_triple_click setting (default: False)
90
+ enable_triple_click = kwargs.get('enable_triple_click', False)
91
+
68
92
  # Create multiclick detector
69
93
  self._detector = MultiClickDetector(
70
94
  loop=self._loop,
@@ -73,6 +97,9 @@ class GpioEventButton(GpioBaseClass):
73
97
  multiclick_window_ms=double_click_duration,
74
98
  hold_threshold_ms=long_press_duration,
75
99
  sequence_window_ms=sequence_window_duration,
100
+ sequence_mode=self._sequence_mode,
101
+ enabled_sequences=enabled_sequences,
102
+ enable_triple_click=enable_triple_click,
76
103
  name=self._name,
77
104
  pin=self._pin,
78
105
  )
@@ -116,6 +143,10 @@ class GpioEventButton(GpioBaseClass):
116
143
  double_click_duration: int | float | None = None,
117
144
  long_press_duration: int | float | None = None,
118
145
  sequence_window_duration: int | float | None = None,
146
+ sequence_mode: str | None = None,
147
+ actions: dict | None = None,
148
+ mqtt_sequences: dict | None = None,
149
+ enable_triple_click: bool | None = None,
119
150
  ) -> None:
120
151
  """Update timing parameters for click detection.
121
152
 
@@ -126,7 +157,13 @@ class GpioEventButton(GpioBaseClass):
126
157
  double_click_duration: Time window in ms to detect double click
127
158
  long_press_duration: Time in ms to detect long press
128
159
  sequence_window_duration: Time window in ms to detect sequences
160
+ sequence_mode: 'immediate' or 'exclusive'
161
+ actions: Actions dict to determine enabled sequences
162
+ mqtt_sequences: MQTT sequences dict to determine enabled sequences
163
+ enable_triple_click: Enable triple click detection
129
164
  """
165
+ from boneio.const import CLICK_SEQUENCES
166
+
130
167
  if double_click_duration is not None:
131
168
  value_ms = _to_milliseconds(double_click_duration, DEFAULT_DOUBLE_CLICK_DURATION_MS)
132
169
  self._detector._multiclick_window = value_ms / 1000.0
@@ -140,4 +177,40 @@ class GpioEventButton(GpioBaseClass):
140
177
  if sequence_window_duration is not None:
141
178
  value_ms = _to_milliseconds(sequence_window_duration, DEFAULT_SEQUENCE_WINDOW_MS)
142
179
  self._detector._sequence_window = value_ms / 1000.0
143
- _LOGGER.debug("Updated sequence_window_duration to %dms for %s", value_ms, self._name)
180
+ _LOGGER.debug("Updated sequence_window_duration to %dms for %s", value_ms, self._name)
181
+
182
+ if sequence_mode is not None:
183
+ self._sequence_mode = sequence_mode
184
+ self._detector._sequence_mode = sequence_mode
185
+ _LOGGER.debug("Updated sequence_mode to %s for %s", sequence_mode, self._name)
186
+
187
+ if enable_triple_click is not None:
188
+ self._detector._enable_triple_click = enable_triple_click
189
+ _LOGGER.debug("Updated enable_triple_click to %s for %s", enable_triple_click, self._name)
190
+
191
+ # Update enabled sequences based on actions and mqtt_sequences
192
+ sequence_types = {'double_then_long', 'single_then_long', 'double_then_single'}
193
+ enabled_sequences: set[str] = set()
194
+
195
+ if actions is not None and isinstance(actions, dict):
196
+ for seq_type in sequence_types:
197
+ if seq_type in actions and actions[seq_type]:
198
+ enabled_sequences.add(seq_type)
199
+
200
+ if mqtt_sequences is not None and isinstance(mqtt_sequences, dict):
201
+ for seq_type in sequence_types:
202
+ if mqtt_sequences.get(seq_type):
203
+ enabled_sequences.add(seq_type)
204
+
205
+ if actions is not None or mqtt_sequences is not None:
206
+ self._detector._enabled_sequences = enabled_sequences
207
+
208
+ # Recompute delay_click_types
209
+ self._detector._delay_click_types = set()
210
+ if self._detector._sequence_mode == "exclusive" and enabled_sequences:
211
+ for seq in enabled_sequences:
212
+ for (first, _second), seq_name in CLICK_SEQUENCES.items():
213
+ if seq_name == seq:
214
+ self._detector._delay_click_types.add(first)
215
+ break
216
+ _LOGGER.debug("Updated enabled_sequences to %s for %s", enabled_sequences, self._name)
@@ -146,7 +146,7 @@ class ConfigHelper:
146
146
  return "https" if self._proxy_port else "http"
147
147
 
148
148
  @property
149
- def ha_configuration_port(self) -> int:
149
+ def web_configuration_port(self) -> int:
150
150
  """Get port for HA discovery URL. Uses proxy_port if set, otherwise web_port."""
151
151
  return self._proxy_port if self._proxy_port else self._web_port
152
152
 
@@ -216,7 +216,7 @@ class CoverManager:
216
216
  restored_state=restored_state,
217
217
  tilt_duration=tilt_duration,
218
218
  actuator_activation_duration=config.get("actuator_activation_duration", TimePeriod(milliseconds=0)),
219
- **{k: v for k, v in config.items() if k not in ("platform", "actuator_activation_duration", "tilt_duration", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
219
+ **{k: v for k, v in config.items() if k not in ("id", "platform", "actuator_activation_duration", "tilt_duration", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
220
220
  )
221
221
  availability_msg_func = ha_cover_with_tilt_availabilty_message
222
222
  elif platform == "time_based":
@@ -236,7 +236,7 @@ class CoverManager:
236
236
  event_bus=self._manager._event_bus,
237
237
  topic_prefix=self._manager._topic_prefix,
238
238
  restored_state=restored_state,
239
- **{k: v for k, v in config.items() if k not in ("platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
239
+ **{k: v for k, v in config.items() if k not in ("id", "platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
240
240
  )
241
241
  availability_msg_func = ha_cover_availabilty_message
242
242
  elif platform == "previous":
@@ -256,7 +256,7 @@ class CoverManager:
256
256
  event_bus=self._manager._event_bus,
257
257
  topic_prefix=self._manager._topic_prefix,
258
258
  restored_state=restored_state,
259
- **{k: v for k, v in config.items() if k not in ("platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
259
+ **{k: v for k, v in config.items() if k not in ("id", "platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
260
260
  )
261
261
  availability_msg_func = ha_cover_availabilty_message
262
262
 
@@ -190,10 +190,28 @@ class DisplayManager:
190
190
 
191
191
  except (GPIOInputException, I2CError) as err:
192
192
  _LOGGER.error("Can't configure OLED display: %s", err)
193
+ # Store error in manager for WebUI display
194
+ self._manager._hardware_errors.append({
195
+ 'type': 'display',
196
+ 'id': 'oled',
197
+ 'name': 'OLED Display',
198
+ 'address': 0x3C,
199
+ 'error': str(err),
200
+ 'message': f"OLED display at address 0x3C: {err}",
201
+ })
193
202
  except ImportError as err:
194
203
  _LOGGER.error("Failed to import OLED modules: %s", err)
195
204
  except Exception as err:
196
205
  _LOGGER.error("Unexpected error configuring OLED: %s", err)
206
+ # Store error in manager for WebUI display
207
+ self._manager._hardware_errors.append({
208
+ 'type': 'display',
209
+ 'id': 'oled',
210
+ 'name': 'OLED Display',
211
+ 'address': 0x3C,
212
+ 'error': str(err),
213
+ 'message': f"OLED display: {err}",
214
+ })
197
215
 
198
216
  def get_oled(self) -> Any | None:
199
217
  """Get OLED display instance.