boneIO 1.2.0.dev5__tar.gz → 1.2.0.dev7__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 (433) hide show
  1. {boneio-1.2.0.dev5/boneio.egg-info → boneio-1.2.0.dev7}/PKG-INFO +1 -1
  2. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/input/detectors.py +17 -2
  3. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/cloud/data/init-certs-cloud.sh +0 -1
  4. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/inputs.py +15 -3
  5. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/manager.py +97 -58
  6. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/remote.py +106 -6
  7. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/remote/esphome.py +8 -0
  8. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/remote/wled.py +7 -6
  9. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/actions.yaml +48 -1
  10. boneio-1.2.0.dev7/boneio/version.py +2 -0
  11. boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/cssMode-D2_GdEHn.js +4 -0
  12. boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/editor.worker-B4pQIWZD.js +12 -0
  13. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/freemarker2-BopmjG-d.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/freemarker2-Ccev9DQ3.js +1 -1
  14. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/handlebars-B4qyxXfH.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/handlebars-CSWuYUii.js +1 -1
  15. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/html-C-ni_wgU.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/html-BeCDD7uj.js +1 -1
  16. boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/htmlMode-Csqim4tI.js +4 -0
  17. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/index-BCB2NJOT.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/index-C6eDye5h.js +245 -245
  18. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/index-BmuRpNYW.css → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/index-CyjBlAI7.css +1 -1
  19. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/javascript-jjqo-sRZ.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/javascript-CNjo7h5s.js +1 -1
  20. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/json.worker-DaRII17c.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/json.worker-aFakAbRR.js +22 -22
  21. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/jsonMode-5NrAP0iB.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/jsonMode-CrofIOf5.js +1 -1
  22. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/liquid-CoHJfw7h.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/liquid-DhQWiRQL.js +1 -1
  23. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/mdx-Dlx6WfDW.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/mdx-B7NfGq9x.js +1 -1
  24. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/python-DpkV3PqO.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/python-CfAzolFq.js +1 -1
  25. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/razor-CWBrospO.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/razor-nVU9Xllg.js +1 -1
  26. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/tsMode-DBAuWfcD.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/tsMode-DUyiY9xo.js +1 -1
  27. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/typescript-D_Z0ICsW.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/typescript-Cz5XSgIr.js +1 -1
  28. boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BIl4cyR9.js +2 -0
  29. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/xml-BaNYAW9z.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/xml-Bf4znVSR.js +1 -1
  30. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/yaml-t2S2Ivp4.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/yaml-KWLRG-vP.js +1 -1
  31. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/yaml.worker-BTE-_K6g.js → boneio-1.2.0.dev7/boneio/webui/frontend-dist/assets/yaml.worker-DBeHcBRc.js +200 -200
  32. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/index.html +2 -2
  33. {boneio-1.2.0.dev5/boneio/webui/schema → boneio-1.2.0.dev7/boneio/webui/frontend-dist/schem}/adc.schema.json +6 -6
  34. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/areas.schema.json +2 -2
  35. {boneio-1.2.0.dev5/boneio/webui/schema → boneio-1.2.0.dev7/boneio/webui/frontend-dist/schem}/binary_sensor.schema.json +136 -36
  36. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/boneio.schema.json +4 -4
  37. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/config.schema.json +793 -343
  38. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/cover.schema.json +10 -10
  39. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/ds2482.schema.json +2 -2
  40. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/event.schema.json +469 -119
  41. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/ina219.schema.json +10 -10
  42. {boneio-1.2.0.dev5/boneio/webui/schema → boneio-1.2.0.dev7/boneio/webui/frontend-dist/schem}/lm75.schema.json +8 -8
  43. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/logger.schema.json +2 -2
  44. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/mcp23017.schema.json +6 -6
  45. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/mcp9808.schema.json +8 -8
  46. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/modbus.schema.json +8 -8
  47. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/modbus_devices.schema.json +18 -18
  48. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/mqtt.schema.json +6 -6
  49. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/oled.schema.json +6 -6
  50. {boneio-1.2.0.dev5/boneio/webui/schema → boneio-1.2.0.dev7/boneio/webui/frontend-dist/schem}/output.schema.json +10 -10
  51. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/output_group.schema.json +2 -2
  52. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/pca9685.schema.json +6 -6
  53. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/pcf8575.schema.json +6 -6
  54. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/remote_devices.schema.json +50 -50
  55. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/sensor.schema.json +6 -6
  56. {boneio-1.2.0.dev5/boneio/webui/schema → boneio-1.2.0.dev7/boneio/webui/frontend-dist/schem}/virtual_energy_sensor.schema.json +2 -2
  57. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/web.schema.json +10 -10
  58. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/sw.js +1 -1
  59. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/system.py +88 -14
  60. {boneio-1.2.0.dev5/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev7/boneio/webui/schema}/adc.schema.json +6 -6
  61. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/areas.schema.json +2 -2
  62. {boneio-1.2.0.dev5/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev7/boneio/webui/schema}/binary_sensor.schema.json +136 -36
  63. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/boneio.schema.json +4 -4
  64. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/config.schema.json +793 -343
  65. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/cover.schema.json +10 -10
  66. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/ds2482.schema.json +2 -2
  67. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/event.schema.json +469 -119
  68. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/ina219.schema.json +10 -10
  69. {boneio-1.2.0.dev5/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev7/boneio/webui/schema}/lm75.schema.json +8 -8
  70. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/logger.schema.json +2 -2
  71. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/mcp23017.schema.json +6 -6
  72. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/mcp9808.schema.json +8 -8
  73. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/modbus.schema.json +8 -8
  74. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/modbus_devices.schema.json +18 -18
  75. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/mqtt.schema.json +6 -6
  76. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/oled.schema.json +6 -6
  77. {boneio-1.2.0.dev5/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev7/boneio/webui/schema}/output.schema.json +10 -10
  78. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/output_group.schema.json +2 -2
  79. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/pca9685.schema.json +6 -6
  80. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/pcf8575.schema.json +6 -6
  81. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/remote_devices.schema.json +50 -50
  82. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/sensor.schema.json +6 -6
  83. {boneio-1.2.0.dev5/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev7/boneio/webui/schema}/virtual_energy_sensor.schema.json +2 -2
  84. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/web.schema.json +10 -10
  85. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7/boneio.egg-info}/PKG-INFO +1 -1
  86. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio.egg-info/SOURCES.txt +21 -21
  87. boneio-1.2.0.dev5/boneio/version.py +0 -2
  88. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/cssMode-DhVkup0b.js +0 -4
  89. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/editor.worker-DsAeyiJ5.js +0 -12
  90. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/htmlMode-DEZO_LY5.js +0 -4
  91. boneio-1.2.0.dev5/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-vqzQaGvo.js +0 -2
  92. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/LICENSE +0 -0
  93. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/MANIFEST.in +0 -0
  94. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/README.md +0 -0
  95. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/__init__.py +0 -0
  96. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.2/input.yaml +0 -0
  97. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.2/output_24_16.yaml +0 -0
  98. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.2/output_32_10.yaml +0 -0
  99. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.2/output_32_5.yaml +0 -0
  100. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.2/output_cover.yaml +0 -0
  101. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  102. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.3/input.yaml +0 -0
  103. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.3/output_24_16.yaml +0 -0
  104. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.3/output_32_10.yaml +0 -0
  105. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.3/output_32_5.yaml +0 -0
  106. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.3/output_cover.yaml +0 -0
  107. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  108. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.4/input.yaml +0 -0
  109. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.4/output_24_16.yaml +0 -0
  110. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.4/output_32_10.yaml +0 -0
  111. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.4/output_32_5.yaml +0 -0
  112. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.4/output_cover.yaml +0 -0
  113. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  114. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.5/input.yaml +0 -0
  115. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.5/output_24_16.yaml +0 -0
  116. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.5/output_32_10.yaml +0 -0
  117. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.5/output_cover.yaml +0 -0
  118. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  119. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.6/input.yaml +0 -0
  120. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.6/output_24_16.yaml +0 -0
  121. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.6/output_32_10.yaml +0 -0
  122. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.6/output_cover.yaml +0 -0
  123. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  124. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.7/input.yaml +0 -0
  125. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.7/output_24_16.yaml +0 -0
  126. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.7/output_32_10.yaml +0 -0
  127. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.7/output_cover.yaml +0 -0
  128. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  129. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.8/input.yaml +0 -0
  130. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.8/output_24_16.yaml +0 -0
  131. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.8/output_32_10.yaml +0 -0
  132. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.8/output_cover.yaml +0 -0
  133. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  134. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/bonecli.py +0 -0
  135. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/__init__.py +0 -0
  136. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/cover/__init__.py +0 -0
  137. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/cover/cover.py +0 -0
  138. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/cover/previous.py +0 -0
  139. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/cover/time_based.py +0 -0
  140. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/cover/venetian.py +0 -0
  141. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/group/__init__.py +0 -0
  142. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/group/output_group.py +0 -0
  143. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/input/__init__.py +0 -0
  144. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/input/binary_sensor.py +0 -0
  145. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/input/event.py +0 -0
  146. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/output/__init__.py +0 -0
  147. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/output/basic.py +0 -0
  148. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/output/mcp.py +0 -0
  149. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/output/pca.py +0 -0
  150. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/output/pcf.py +0 -0
  151. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/sensor/__init__.py +0 -0
  152. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/components/sensor/virtual_energy.py +0 -0
  153. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/const.py +0 -0
  154. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/__init__.py +0 -0
  155. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/cloud/__init__.py +0 -0
  156. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/cloud/data/__init__.py +0 -0
  157. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
  158. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/cloud/data/docker-compose.yaml +0 -0
  159. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/cloud/registration.py +0 -0
  160. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/cloud/secrets.py +0 -0
  161. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/config/__init__.py +0 -0
  162. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/config/config_helper.py +0 -0
  163. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/config/package-lock.json +0 -0
  164. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/config/package.json +0 -0
  165. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/config/schema_converter.py +0 -0
  166. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/config/yaml_util.py +0 -0
  167. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/discovery.py +0 -0
  168. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/events/__init__.py +0 -0
  169. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/events/bus.py +0 -0
  170. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/__init__.py +0 -0
  171. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/covers.py +0 -0
  172. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/display.py +0 -0
  173. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/modbus.py +0 -0
  174. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/outputs.py +0 -0
  175. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/sensors.py +0 -0
  176. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/manager/update.py +0 -0
  177. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/messaging/__init__.py +0 -0
  178. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/messaging/basic.py +0 -0
  179. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/messaging/basic_mqtt.py +0 -0
  180. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/messaging/local.py +0 -0
  181. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/messaging/mqtt.py +0 -0
  182. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/messaging/queue.py +0 -0
  183. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/remote/__init__.py +0 -0
  184. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/remote/base.py +0 -0
  185. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/remote/mqtt.py +0 -0
  186. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/sensor/__init__.py +0 -0
  187. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/sensor/base.py +0 -0
  188. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/sensor/system.py +0 -0
  189. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/state/__init__.py +0 -0
  190. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/state/manager.py +0 -0
  191. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/system/__init__.py +0 -0
  192. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/system/host_data.py +0 -0
  193. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/system/monitor.py +0 -0
  194. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/utils/__init__.py +0 -0
  195. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/utils/async_updater.py +0 -0
  196. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/utils/filter.py +0 -0
  197. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/utils/font_util.py +0 -0
  198. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/utils/logger.py +0 -0
  199. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/utils/timeperiod.py +0 -0
  200. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/core/utils/util.py +0 -0
  201. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/24x16/adc.yaml +0 -0
  202. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  203. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/24x16/config.yaml +0 -0
  204. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/24x16/event.yaml +0 -0
  205. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/24x16/mqtt.yaml +0 -0
  206. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  207. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/32x10/adc.yaml +0 -0
  208. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  209. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/32x10/config.yaml +0 -0
  210. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/32x10/event.yaml +0 -0
  211. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/32x10/mqtt.yaml +0 -0
  212. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  213. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/__init__.py +0 -0
  214. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover/adc.yaml +0 -0
  215. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  216. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover/config.yaml +0 -0
  217. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover/cover.yaml +0 -0
  218. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover/event.yaml +0 -0
  219. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover/mqtt.yaml +0 -0
  220. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover/outputCover.yaml +0 -0
  221. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover_mix/adc.yaml +0 -0
  222. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  223. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover_mix/config.yaml +0 -0
  224. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover_mix/cover.yaml +0 -0
  225. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover_mix/event.yaml +0 -0
  226. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  227. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  228. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/adc.yaml +0 -0
  229. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  230. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  231. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  232. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  233. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/event_all.yaml +0 -0
  234. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  235. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  236. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  237. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  238. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  239. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  240. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/exceptions.py +0 -0
  241. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/__init__.py +0 -0
  242. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/analog/__init__.py +0 -0
  243. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/analog/adc.py +0 -0
  244. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/display/__init__.py +0 -0
  245. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  246. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/display/oled.py +0 -0
  247. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/__init__.py +0 -0
  248. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  249. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  250. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  251. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  252. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/input/__init__.py +0 -0
  253. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/input/base.py +0 -0
  254. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/gpio/input/manager.py +0 -0
  255. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/i2c/__init__.py +0 -0
  256. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/i2c/bus.py +0 -0
  257. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/i2c/ina219.py +0 -0
  258. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/i2c/ina219_driver.py +0 -0
  259. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/i2c/mcp9808.py +0 -0
  260. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/i2c/pct2075.py +0 -0
  261. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/onewire/__init__.py +0 -0
  262. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/onewire/bus.py +0 -0
  263. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/onewire/dallas.py +0 -0
  264. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/onewire/ds2482.py +0 -0
  265. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/sensor/__init__.py +0 -0
  266. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  267. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/sensor/temperature/base.py +0 -0
  268. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  269. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  270. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/integration/__init__.py +0 -0
  271. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/integration/homeassistant.py +0 -0
  272. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/integration/interlock.py +0 -0
  273. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/__init__.py +0 -0
  274. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/cli.py +0 -0
  275. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/client.py +0 -0
  276. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/coordinator.py +0 -0
  277. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/__init__.py +0 -0
  278. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
  279. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
  280. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  281. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  282. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  283. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  284. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  285. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  286. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  287. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/inverters/sofar.json +0 -0
  288. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/inverters/thessla.json +0 -0
  289. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/other/n4dsc08.json +0 -0
  290. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  291. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/other/wanas415.json +0 -0
  292. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/sensors/cwt.json +0 -0
  293. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
  294. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
  295. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  296. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/sensors/pt100.json +0 -0
  297. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/sensors/sht20.json +0 -0
  298. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/devices/sensors/sht30.json +0 -0
  299. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/__init__.py +0 -0
  300. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/base.py +0 -0
  301. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/derived/__init__.py +0 -0
  302. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/derived/numeric.py +0 -0
  303. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/derived/select.py +0 -0
  304. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/derived/switch.py +0 -0
  305. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/derived/text.py +0 -0
  306. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/sensor/__init__.py +0 -0
  307. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/sensor/binary.py +0 -0
  308. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/sensor/numeric.py +0 -0
  309. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/sensor/text.py +0 -0
  310. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/writeable/__init__.py +0 -0
  311. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/writeable/binary.py +0 -0
  312. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/entities/writeable/numeric.py +0 -0
  313. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/modbus/utils.py +0 -0
  314. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/models/__init__.py +0 -0
  315. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/models/actions.py +0 -0
  316. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/models/events.py +0 -0
  317. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/models/files.py +0 -0
  318. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/models/logs.py +0 -0
  319. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/models/mqtt.py +0 -0
  320. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/models/state.py +0 -0
  321. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/runner.py +0 -0
  322. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/actions_sensor.yaml +0 -0
  323. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/actions_switch.yaml +0 -0
  324. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/filters.yaml +0 -0
  325. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/filters_adc.yaml +0 -0
  326. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/id.yaml +0 -0
  327. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/remote_devices.yaml +0 -0
  328. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/schema.yaml +0 -0
  329. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/temp_unit.yaml +0 -0
  330. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/schema/update_interval.yaml +0 -0
  331. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/app.py +0 -0
  332. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/abap-CRCWOmpq.js +0 -0
  333. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/apex-DnsZk_dE.js +0 -0
  334. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/azcli-1IWB1ccx.js +0 -0
  335. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/bat-DPkNLes8.js +0 -0
  336. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/bicep-Corcdgou.js +0 -0
  337. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/cameligo-CGrWLZr3.js +0 -0
  338. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/clojure-D9WOWImG.js +0 -0
  339. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
  340. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/coffee-B7EJu28W.js +0 -0
  341. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/cpp-SEyurbux.js +0 -0
  342. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/csharp-BoL64M5l.js +0 -0
  343. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/csp-C46ZqvIl.js +0 -0
  344. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/css-DQU6DXDx.js +0 -0
  345. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/cypher-D84EuPTj.js +0 -0
  346. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/dart-D8lhlL1r.js +0 -0
  347. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/dockerfile-DLk6rpji.js +0 -0
  348. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/ecl-BO6FnfXk.js +0 -0
  349. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/elixir-BRjLKONM.js +0 -0
  350. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/flow9-Cac8vKd7.js +0 -0
  351. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/fsharp-fd1GTHhf.js +0 -0
  352. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/go-O9LJTZXk.js +0 -0
  353. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/graphql-LQdxqEYJ.js +0 -0
  354. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/hcl-DxDQ3s82.js +0 -0
  355. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/ini-BvajGCUy.js +0 -0
  356. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/java-SYsfObOQ.js +0 -0
  357. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/julia-DQXNmw_w.js +0 -0
  358. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/kotlin-qQ0MG-9I.js +0 -0
  359. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/less-GGFNNJHn.js +0 -0
  360. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/lexon-Canl7DCW.js +0 -0
  361. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/lua-D28Ae8-K.js +0 -0
  362. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/m3-DPitgjJI.js +0 -0
  363. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/markdown-B811l8j2.js +0 -0
  364. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/mips-CdjsipkG.js +0 -0
  365. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/msdax-CYqgjx_P.js +0 -0
  366. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/mysql-BHd6q0vd.js +0 -0
  367. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/objective-c-B1aVtJYH.js +0 -0
  368. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/pascal-BhNW15KB.js +0 -0
  369. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/pascaligo-5jv8CcQD.js +0 -0
  370. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/perl-DlYyT36c.js +0 -0
  371. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/pgsql-Dy0bjov7.js +0 -0
  372. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/php-120yhfDK.js +0 -0
  373. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/pla-CjnFlu4u.js +0 -0
  374. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/postiats-CQpG440k.js +0 -0
  375. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/powerquery-DdJtto1Z.js +0 -0
  376. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/powershell-Bu_VLpJB.js +0 -0
  377. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/protobuf-IBS6jZEB.js +0 -0
  378. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/pug-kFxLfcjb.js +0 -0
  379. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/qsharp-q7JyzKFN.js +0 -0
  380. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/r-BIFz-_sK.js +0 -0
  381. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/redis-CHOsPHWR.js +0 -0
  382. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/redshift-CBifECDb.js +0 -0
  383. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/restructuredtext-CghPJEOS.js +0 -0
  384. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/ruby-CYWGW-b1.js +0 -0
  385. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/rust-DMDD0SHb.js +0 -0
  386. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/sb-BYAiYHFx.js +0 -0
  387. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/scala-Bqvq8jcR.js +0 -0
  388. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/scheme-Dhb-2j9p.js +0 -0
  389. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/scss-CTwUZ5N7.js +0 -0
  390. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/shell-CsDZo4DB.js +0 -0
  391. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/solidity-CME5AdoB.js +0 -0
  392. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/sophia-RYC1BQQz.js +0 -0
  393. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/sparql-KEyrF7De.js +0 -0
  394. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/sql-BdTr02Mf.js +0 -0
  395. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/st-C7iG7M4S.js +0 -0
  396. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/swift-D7IUmUK8.js +0 -0
  397. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/systemverilog-DgMryOEJ.js +0 -0
  398. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/tcl-PloMZuKG.js +0 -0
  399. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/twig-BfRIq3la.js +0 -0
  400. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/typespec-CzxlYoT_.js +0 -0
  401. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/vb-BwAE3J76.js +0 -0
  402. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/assets/wgsl-B_1kOXbF.js +0 -0
  403. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  404. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  405. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/boneio.svg +0 -0
  406. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  407. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/schem/dallas.schema.json +0 -0
  408. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/frontend-dist/workbox-226dbdbf.js +0 -0
  409. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/middleware/__init__.py +0 -0
  410. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/middleware/auth.py +0 -0
  411. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/__init__.py +0 -0
  412. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/auth.py +0 -0
  413. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/caddy.py +0 -0
  414. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/config.py +0 -0
  415. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/covers.py +0 -0
  416. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/modbus.py +0 -0
  417. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/outputs.py +0 -0
  418. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/remote_devices.py +0 -0
  419. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/sensors.py +0 -0
  420. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/routes/update.py +0 -0
  421. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/schema/dallas.schema.json +0 -0
  422. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/services/__init__.py +0 -0
  423. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/services/logs.py +0 -0
  424. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/web_server.py +0 -0
  425. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio/webui/websocket_manager.py +0 -0
  426. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio.egg-info/dependency_links.txt +0 -0
  427. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio.egg-info/entry_points.txt +0 -0
  428. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio.egg-info/requires.txt +0 -0
  429. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/boneio.egg-info/top_level.txt +0 -0
  430. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/pyproject.toml +0 -0
  431. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/setup.cfg +0 -0
  432. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/setup.py +0 -0
  433. {boneio-1.2.0.dev5 → boneio-1.2.0.dev7}/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.dev5
3
+ Version: 1.2.0.dev7
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
@@ -46,6 +46,7 @@ class ClickState:
46
46
  # Long hold periodic events
47
47
  long_hold_periodic_timer: asyncio.TimerHandle | None = None
48
48
  executed_long_actions: set[int] = field(default_factory=set) # Track which long actions already executed
49
+ last_repeat_times: dict[int, float] = field(default_factory=dict) # Track last execution time per repeat action index
49
50
 
50
51
 
51
52
  @dataclass
@@ -361,6 +362,7 @@ class MultiClickDetector:
361
362
 
362
363
  # Reset executed actions for new long press
363
364
  self._state.executed_long_actions = set()
365
+ self._state.last_repeat_times = {}
364
366
 
365
367
  duration = self._loop.time() - self._state.last_press_ts
366
368
 
@@ -468,7 +470,7 @@ class MultiClickDetector:
468
470
  elif event.event_type is event.Type.RISING_EDGE:
469
471
  # Button released (RISING_EDGE on BeagleBone with pull-up)
470
472
 
471
- # Software debounce
473
+ # Software debounce (release-vs-release)
472
474
  if self._state.last_release_ts and (timestamp_s - self._state.last_release_ts) < self._debounce_seconds:
473
475
  delta_ms = (timestamp_s - self._state.last_release_ts) * 1000
474
476
  _LOGGER.debug(
@@ -477,8 +479,20 @@ class MultiClickDetector:
477
479
  delta_ms,
478
480
  )
479
481
  return
482
+
483
+ # Cross-debounce: ignore release too close to press (bounce on rising edge)
484
+ if self._state.last_press_ts and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds:
485
+ delta_ms = (timestamp_s - self._state.last_press_ts) * 1000
486
+ _LOGGER.debug(
487
+ "Ignoring bounced release on %s (%.3f ms since press, debounce %.3f ms)",
488
+ self._name,
489
+ delta_ms,
490
+ self._debounce_seconds * 1000,
491
+ )
492
+ return
480
493
 
481
- _LOGGER.debug("RELEASED: %s (%s)", self._name, self._pin)
494
+ press_duration_ms = (timestamp_s - self._state.last_press_ts) * 1000 if self._state.last_press_ts else 0
495
+ _LOGGER.debug("RELEASED: %s (%s) after %.1f ms", self._name, self._pin, press_duration_ms)
482
496
  self._state.last_release_ts = timestamp_s
483
497
 
484
498
  _LOGGER.debug(
@@ -511,6 +525,7 @@ class MultiClickDetector:
511
525
  # need to give it time to start and read executed_long_actions.
512
526
  def reset_executed_actions():
513
527
  self._state.executed_long_actions = set()
528
+ self._state.last_repeat_times = {}
514
529
  _LOGGER.debug("Reset executed_long_actions for %s", self._name)
515
530
  self._loop.call_later(0.05, reset_executed_actions)
516
531
 
@@ -113,7 +113,6 @@ ${CLOUD_BLOCK}
113
113
 
114
114
  # HTTPS with self-signed certificate (catch-all for hostname and IP access)
115
115
  https:// {
116
- # Wlaczenie on_demand dla wewnetrznego wystawcy pozwala na dynamiczne generowanie certyfikatow dla IP
117
116
  tls internal {
118
117
  on_demand
119
118
  }
@@ -697,14 +697,24 @@ class InputManager:
697
697
 
698
698
  # Execute actions with duration threshold support
699
699
  if actions and event.click_type == LONG:
700
- # Get executed_actions from detector state
700
+ # Get executed_actions and repeat times from detector state
701
701
  detector = getattr(input_instance, '_detector', None)
702
702
  executed_actions = getattr(detector._state, 'executed_long_actions', set()) if detector else set()
703
+ last_repeat_times = getattr(detector._state, 'last_repeat_times', {}) if detector else {}
703
704
 
704
- # Lazy evaluation: Check if there are any actions with duration thresholds
705
- # or any actions without thresholds that haven't been executed yet
705
+ # Lazy evaluation: Check if there are any pending actions
706
+ duration_ms = (event.duration or 0) * 1000
706
707
  has_pending_actions = False
707
708
  for idx, action in enumerate(actions):
709
+ is_repeat = action.get("repeat", False)
710
+ if is_repeat:
711
+ # Repeat actions are always potentially pending (throttled in execute_actions)
712
+ repeat_interval_ms = action.get("repeat_interval", 1000)
713
+ last_time = last_repeat_times.get(idx, 0.0)
714
+ if last_time == 0 or (duration_ms - last_time) >= repeat_interval_ms:
715
+ has_pending_actions = True
716
+ break
717
+ continue
708
718
  if idx in executed_actions:
709
719
  continue # Already executed
710
720
  min_dur = action.get("min_duration")
@@ -730,11 +740,13 @@ class InputManager:
730
740
  actions=actions,
731
741
  duration=event.duration,
732
742
  executed_actions=executed_actions,
743
+ last_repeat_times=last_repeat_times,
733
744
  )
734
745
 
735
746
  # Update detector state
736
747
  if detector:
737
748
  detector._state.executed_long_actions = new_executed
749
+ detector._state.last_repeat_times = last_repeat_times
738
750
  elif actions:
739
751
  # Non-long events - execute all actions normally
740
752
  await self._manager.execute_actions(actions=actions)
@@ -433,6 +433,20 @@ class Manager:
433
433
  from boneio.const import TOPIC, REMOTE_OUTPUT, REMOTE_COVER
434
434
  from boneio.core.utils import strip_accents
435
435
 
436
+ def _copy_long_press_meta(parsed_action: dict, action_definition: dict) -> None:
437
+ """Copy long press meta fields (duration thresholds, repeat) to parsed action."""
438
+ for key in ("min_duration", "max_duration"):
439
+ if action_definition.get(key) is not None:
440
+ parsed_action[key] = action_definition[key]
441
+ if action_definition.get("repeat"):
442
+ parsed_action["repeat"] = True
443
+ ri = action_definition.get("repeat_interval", 1000)
444
+ # TimePeriod object from schema validation -> convert to ms
445
+ if hasattr(ri, "total_milliseconds"):
446
+ parsed_action["repeat_interval"] = ri.total_milliseconds
447
+ else:
448
+ parsed_action["repeat_interval"] = ri
449
+
436
450
  parsed_actions = {}
437
451
  for click_type in actions:
438
452
  if click_type not in parsed_actions:
@@ -455,11 +469,7 @@ class Manager:
455
469
  "pin": stripped_entity_id,
456
470
  "action_to_execute": action_to_execute,
457
471
  }
458
- # Copy duration thresholds for long press actions
459
- if action_definition.get("min_duration") is not None:
460
- parsed_action["min_duration"] = action_definition["min_duration"]
461
- if action_definition.get("max_duration") is not None:
462
- parsed_action["max_duration"] = action_definition["max_duration"]
472
+ _copy_long_press_meta(parsed_action, action_definition)
463
473
  _LOGGER.debug(
464
474
  "Parsed OUTPUT action for %s: output=%s, action=%s, min_dur=%s, max_dur=%s",
465
475
  pin, stripped_entity_id, action_to_execute,
@@ -486,11 +496,7 @@ class Manager:
486
496
  "action_to_execute": action_to_execute,
487
497
  "extra_data": extra_data,
488
498
  }
489
- # Copy duration thresholds for long press actions
490
- if action_definition.get("min_duration") is not None:
491
- parsed_action["min_duration"] = action_definition["min_duration"]
492
- if action_definition.get("max_duration") is not None:
493
- parsed_action["max_duration"] = action_definition["max_duration"]
499
+ _copy_long_press_meta(parsed_action, action_definition)
494
500
  parsed_actions[click_type].append(parsed_action)
495
501
  continue
496
502
  _LOGGER.warning("Device %s for action not found. Omitting.", entity_id)
@@ -504,11 +510,7 @@ class Manager:
504
510
  "action_mqtt_msg": action_mqtt_msg,
505
511
  "action_topic": action_topic,
506
512
  }
507
- # Copy duration thresholds for long press actions
508
- if action_definition.get("min_duration") is not None:
509
- parsed_action["min_duration"] = action_definition["min_duration"]
510
- if action_definition.get("max_duration") is not None:
511
- parsed_action["max_duration"] = action_definition["max_duration"]
513
+ _copy_long_press_meta(parsed_action, action_definition)
512
514
  parsed_actions[click_type].append(parsed_action)
513
515
  continue
514
516
  _LOGGER.warning("MQTT action missing topic or message for %s", pin)
@@ -523,11 +525,7 @@ class Manager:
523
525
  "boneio_id": boneio_id,
524
526
  "action_output": action_output,
525
527
  }
526
- # Copy duration thresholds for long press actions
527
- if action_definition.get("min_duration") is not None:
528
- parsed_action["min_duration"] = action_definition["min_duration"]
529
- if action_definition.get("max_duration") is not None:
530
- parsed_action["max_duration"] = action_definition["max_duration"]
528
+ _copy_long_press_meta(parsed_action, action_definition)
531
529
  parsed_actions[click_type].append(parsed_action)
532
530
  continue
533
531
  _LOGGER.warning("OUTPUT_OVER_MQTT action missing data for %s", pin)
@@ -542,11 +540,7 @@ class Manager:
542
540
  "boneio_id": boneio_id,
543
541
  "action_cover": action_cover,
544
542
  }
545
- # Copy duration thresholds for long press actions
546
- if action_definition.get("min_duration") is not None:
547
- parsed_action["min_duration"] = action_definition["min_duration"]
548
- if action_definition.get("max_duration") is not None:
549
- parsed_action["max_duration"] = action_definition["max_duration"]
543
+ _copy_long_press_meta(parsed_action, action_definition)
550
544
  parsed_actions[click_type].append(parsed_action)
551
545
  continue
552
546
  _LOGGER.warning("COVER_OVER_MQTT action missing data for %s", pin)
@@ -563,11 +557,16 @@ class Manager:
563
557
  "output_id": output_id,
564
558
  "action_output": action_output,
565
559
  }
566
- # Copy duration thresholds for long press actions
567
- if action_definition.get("min_duration") is not None:
568
- parsed_action["min_duration"] = action_definition["min_duration"]
569
- if action_definition.get("max_duration") is not None:
570
- parsed_action["max_duration"] = action_definition["max_duration"]
560
+ # Copy optional light/WLED parameters
561
+ for opt_key in (
562
+ "brightness", "color_temp", "rgb", "transition",
563
+ "effect", "palette", "effect_speed", "effect_intensity",
564
+ "colors", "presets",
565
+ ):
566
+ val = action_definition.get(opt_key)
567
+ if val is not None:
568
+ parsed_action[opt_key] = val
569
+ _copy_long_press_meta(parsed_action, action_definition)
571
570
  parsed_actions[click_type].append(parsed_action)
572
571
  continue
573
572
  _LOGGER.warning("REMOTE_OUTPUT action missing remote_device or output_id for %s", pin)
@@ -586,11 +585,7 @@ class Manager:
586
585
  "action_cover": action_cover,
587
586
  "extra_data": extra_data,
588
587
  }
589
- # Copy duration thresholds for long press actions
590
- if action_definition.get("min_duration") is not None:
591
- parsed_action["min_duration"] = action_definition["min_duration"]
592
- if action_definition.get("max_duration") is not None:
593
- parsed_action["max_duration"] = action_definition["max_duration"]
588
+ _copy_long_press_meta(parsed_action, action_definition)
594
589
  parsed_actions[click_type].append(parsed_action)
595
590
  continue
596
591
  _LOGGER.warning("REMOTE_COVER action missing remote_device or cover_id for %s", pin)
@@ -602,6 +597,7 @@ class Manager:
602
597
  actions: list,
603
598
  duration: float | None = None,
604
599
  executed_actions: set[int] | None = None,
600
+ last_repeat_times: dict[int, float] | None = None,
605
601
  ) -> set[int]:
606
602
  """Execute list of actions.
607
603
 
@@ -609,20 +605,26 @@ class Manager:
609
605
  actions: List of actions to execute
610
606
  duration: Current duration in seconds (for long press threshold checking)
611
607
  executed_actions: Set of action indices already executed (for long press)
608
+ last_repeat_times: Dict mapping action index to last execution duration_ms (for repeat throttling)
612
609
 
613
610
  Returns:
614
611
  Set of action indices that were executed
615
612
  """
616
613
  if executed_actions is None:
617
614
  executed_actions = set()
615
+ if last_repeat_times is None:
616
+ last_repeat_times = {}
618
617
 
619
618
  duration_ms = (duration or 0) * 1000 # Convert to ms
620
619
 
621
620
  start_time = time.time()
622
621
 
623
622
  for idx, action_definition in enumerate(actions):
624
- # Skip if already executed
625
- if idx in executed_actions:
623
+ is_repeat = action_definition.get("repeat", False)
624
+ repeat_interval_ms = action_definition.get("repeat_interval", 1000)
625
+
626
+ # Skip if already executed (unless it's a repeat action)
627
+ if idx in executed_actions and not is_repeat:
626
628
  _LOGGER.debug("Action %d already executed, skipping", idx)
627
629
  continue
628
630
 
@@ -631,8 +633,8 @@ class Manager:
631
633
  max_dur = action_definition.get("max_duration") # ms
632
634
 
633
635
  _LOGGER.debug(
634
- "Checking action %d: min_dur=%s, max_dur=%s, duration_ms=%.1f, executed=%s",
635
- idx, min_dur, max_dur, duration_ms, executed_actions
636
+ "Checking action %d: min_dur=%s, max_dur=%s, duration_ms=%.1f, repeat=%s, executed=%s",
637
+ idx, min_dur, max_dur, duration_ms, is_repeat, executed_actions
636
638
  )
637
639
 
638
640
  if min_dur is not None or max_dur is not None:
@@ -645,12 +647,26 @@ class Manager:
645
647
  continue # Duration too long
646
648
  _LOGGER.debug("Action %d: duration %.1fms in range [%s, %s), executing", idx, duration_ms, min_dur, max_dur)
647
649
  else:
648
- # Action without thresholds - execute only once (on first long event)
649
- # Check if THIS specific action was already executed, not just any action
650
- if idx in executed_actions:
651
- _LOGGER.debug("Action %d: no thresholds, already executed, skipping", idx)
652
- continue
653
- _LOGGER.debug("Action %d: no thresholds, not yet executed, executing", idx)
650
+ if is_repeat:
651
+ # Repeat action - check interval throttling
652
+ now_ms = duration_ms
653
+ last_time = last_repeat_times.get(idx, 0.0)
654
+ if last_time > 0 and (now_ms - last_time) < repeat_interval_ms:
655
+ _LOGGER.debug(
656
+ "Action %d: repeat throttled (%.1fms since last, interval=%dms)",
657
+ idx, now_ms - last_time, repeat_interval_ms
658
+ )
659
+ continue
660
+ _LOGGER.debug(
661
+ "Action %d: repeat action, interval ok (%.1fms since last, interval=%dms)",
662
+ idx, now_ms - last_time, repeat_interval_ms
663
+ )
664
+ else:
665
+ # Action without thresholds - execute only once (on first long event)
666
+ if idx in executed_actions:
667
+ _LOGGER.debug("Action %d: no thresholds, already executed, skipping", idx)
668
+ continue
669
+ _LOGGER.debug("Action %d: no thresholds, not yet executed, executing", idx)
654
670
  action = action_definition.get("action")
655
671
 
656
672
  if action == MQTT:
@@ -722,19 +738,39 @@ class Manager:
722
738
  remote_device_id = action_definition.get("remote_device")
723
739
  output_id = action_definition.get("output_id")
724
740
  action_output = action_definition.get("action_output", "TOGGLE")
725
- await self.remote_devices.control_output(
726
- device_id=remote_device_id,
727
- output_id=output_id,
728
- action=action_output,
729
- brightness=action_definition.get("brightness"),
730
- color_temp=action_definition.get("color_temp"),
731
- rgb=action_definition.get("rgb"),
732
- transition=action_definition.get("transition"),
733
- effect=action_definition.get("effect"),
734
- palette=action_definition.get("palette"),
735
- effect_speed=action_definition.get("effect_speed"),
736
- effect_intensity=action_definition.get("effect_intensity"),
737
- )
741
+
742
+ if action_output == "CYCLE_COLOR":
743
+ await self.remote_devices.cycle_color(
744
+ device_id=remote_device_id,
745
+ output_id=output_id,
746
+ colors=action_definition.get("colors", []),
747
+ action_idx=idx,
748
+ transition=action_definition.get("transition"),
749
+ )
750
+
751
+ elif action_output == "CYCLE_PRESET":
752
+ await self.remote_devices.cycle_preset(
753
+ device_id=remote_device_id,
754
+ output_id=output_id,
755
+ presets=action_definition.get("presets", []),
756
+ action_idx=idx,
757
+ transition=action_definition.get("transition"),
758
+ )
759
+
760
+ else:
761
+ await self.remote_devices.control_output(
762
+ device_id=remote_device_id,
763
+ output_id=output_id,
764
+ action=action_output,
765
+ brightness=action_definition.get("brightness"),
766
+ color_temp=action_definition.get("color_temp"),
767
+ rgb=action_definition.get("rgb"),
768
+ transition=action_definition.get("transition"),
769
+ effect=action_definition.get("effect"),
770
+ palette=action_definition.get("palette"),
771
+ effect_speed=action_definition.get("effect_speed"),
772
+ effect_intensity=action_definition.get("effect_intensity"),
773
+ )
738
774
 
739
775
  elif action == REMOTE_COVER:
740
776
  # Control cover on remote device (BoneIO MQTT or ESPHome API)
@@ -750,6 +786,9 @@ class Manager:
750
786
  )
751
787
 
752
788
  # Mark action as executed
789
+ if is_repeat:
790
+ # For repeat actions, track timing instead of marking as permanently executed
791
+ last_repeat_times[idx] = duration_ms
753
792
  executed_actions.add(idx)
754
793
 
755
794
  return executed_actions
@@ -64,6 +64,9 @@ class RemoteDeviceManager:
64
64
  self._autodiscovered_devices: dict[str, MQTTRemoteDevice] = {}
65
65
  # Track devices that manage this boneIO (received via discovery/managed_by topic)
66
66
  self._managed_by_devices: dict[str, dict[str, Any]] = {}
67
+ # Cycle state for CYCLE_COLOR and CYCLE_PRESET actions
68
+ # Key: "device_id:output_id:type:action_idx", Value: current index
69
+ self._cycle_state: dict[str, int] = {}
67
70
 
68
71
  if remote_devices_config:
69
72
  self._configure_devices(remote_devices_config)
@@ -335,14 +338,18 @@ class RemoteDeviceManager:
335
338
  """Stop all persistent connections.
336
339
 
337
340
  This should be called during application shutdown.
341
+ Closes ESPHome connections and WLED aiohttp sessions.
338
342
  """
339
343
  for device_id, device in self._devices.items():
340
- if isinstance(device, ESPHomeRemoteDevice):
341
- try:
344
+ try:
345
+ if isinstance(device, ESPHomeRemoteDevice):
342
346
  await device.disconnect()
343
347
  _LOGGER.info("Stopped connection for ESPHome device '%s'", device_id)
344
- except Exception as e:
345
- _LOGGER.error("Failed to stop connection for ESPHome device '%s': %s", device_id, e)
348
+ elif isinstance(device, WLEDRemoteDevice):
349
+ await device.close()
350
+ _LOGGER.info("Closed session for WLED device '%s'", device_id)
351
+ except Exception as e:
352
+ _LOGGER.error("Failed to stop connection for device '%s': %s", device_id, e)
346
353
 
347
354
  def get_device(self, device_id: str) -> RemoteDevice | None:
348
355
  """Get remote device by ID.
@@ -372,7 +379,7 @@ class RemoteDeviceManager:
372
379
  color_temp: int | None = None,
373
380
  rgb: list[int] | tuple[int, int, int] | None = None,
374
381
  transition: float | None = None,
375
- effect: int | None = None,
382
+ effect: int | str | None = None,
376
383
  palette: int | None = None,
377
384
  effect_speed: int | None = None,
378
385
  effect_intensity: int | None = None,
@@ -391,7 +398,7 @@ class RemoteDeviceManager:
391
398
  color_temp: Color temperature in mireds - only for ESPHome lights
392
399
  rgb: RGB color as [R, G, B] list or tuple (0-255 each) - for ESPHome/WLED lights
393
400
  transition: Transition time in seconds - for ESPHome/WLED lights
394
- effect: WLED effect ID
401
+ effect: Effect name (str for ESPHome) or effect ID (int for WLED)
395
402
  palette: WLED color palette ID
396
403
  effect_speed: WLED effect speed (0-255)
397
404
  effect_intensity: WLED effect intensity (0-255)
@@ -413,6 +420,8 @@ class RemoteDeviceManager:
413
420
  rgb_tuple: tuple[int, int, int] | None = None
414
421
  if rgb and len(rgb) >= 3:
415
422
  rgb_tuple = (int(rgb[0]), int(rgb[1]), int(rgb[2]))
423
+ # For ESPHome, effect must be a string
424
+ esphome_effect = str(effect) if effect is not None else None
416
425
  return await device.control_light(
417
426
  light_id=output_id,
418
427
  action=action,
@@ -420,6 +429,7 @@ class RemoteDeviceManager:
420
429
  color_temp=color_temp,
421
430
  rgb=rgb_tuple,
422
431
  transition=transition if transition is not None else 0.0,
432
+ effect=esphome_effect,
423
433
  )
424
434
  # Otherwise treat as switch
425
435
  _LOGGER.debug("Controlling ESPHome switch '%s' on device '%s'", output_id, device_id)
@@ -456,6 +466,96 @@ class RemoteDeviceManager:
456
466
  message_bus=self._message_bus,
457
467
  )
458
468
 
469
+ async def cycle_color(
470
+ self,
471
+ device_id: str,
472
+ output_id: str,
473
+ colors: list[list[int]],
474
+ action_idx: int = 0,
475
+ transition: float | None = None,
476
+ ) -> bool:
477
+ """Cycle through a list of RGB colors on a remote device light.
478
+
479
+ Each call advances to the next color in the list, wrapping around.
480
+
481
+ Args:
482
+ device_id: ID of the remote device
483
+ output_id: ID of the light to control
484
+ colors: List of RGB colors, each as [R, G, B] (0-255)
485
+ action_idx: Action index for unique cycle state tracking
486
+ transition: Transition time in seconds
487
+
488
+ Returns:
489
+ True if command was sent successfully
490
+ """
491
+ if not colors:
492
+ _LOGGER.warning("CYCLE_COLOR: no colors defined for %s:%s", device_id, output_id)
493
+ return False
494
+
495
+ cycle_key = f"{device_id}:{output_id}:color:{action_idx}"
496
+ cycle_idx = self._cycle_state.get(cycle_key, 0) % len(colors)
497
+ rgb = colors[cycle_idx]
498
+ self._cycle_state[cycle_key] = cycle_idx + 1
499
+
500
+ _LOGGER.debug(
501
+ "CYCLE_COLOR: %s:%s -> color %d/%d = %s",
502
+ device_id, output_id, cycle_idx + 1, len(colors), rgb
503
+ )
504
+
505
+ return await self.control_output(
506
+ device_id=device_id,
507
+ output_id=output_id,
508
+ action="ON",
509
+ rgb=rgb,
510
+ transition=transition,
511
+ )
512
+
513
+ async def cycle_preset(
514
+ self,
515
+ device_id: str,
516
+ output_id: str,
517
+ presets: list[str | int],
518
+ action_idx: int = 0,
519
+ transition: float | None = None,
520
+ ) -> bool:
521
+ """Cycle through a list of effects/presets on a remote device light.
522
+
523
+ Each call advances to the next preset in the list, wrapping around.
524
+ For ESPHome: presets are effect name strings.
525
+ For WLED: presets are effect IDs (integers).
526
+
527
+ Args:
528
+ device_id: ID of the remote device
529
+ output_id: ID of the light to control
530
+ presets: List of effect names (str) or effect IDs (int)
531
+ action_idx: Action index for unique cycle state tracking
532
+ transition: Transition time in seconds
533
+
534
+ Returns:
535
+ True if command was sent successfully
536
+ """
537
+ if not presets:
538
+ _LOGGER.warning("CYCLE_PRESET: no presets defined for %s:%s", device_id, output_id)
539
+ return False
540
+
541
+ cycle_key = f"{device_id}:{output_id}:preset:{action_idx}"
542
+ cycle_idx = self._cycle_state.get(cycle_key, 0) % len(presets)
543
+ preset = presets[cycle_idx]
544
+ self._cycle_state[cycle_key] = cycle_idx + 1
545
+
546
+ _LOGGER.debug(
547
+ "CYCLE_PRESET: %s:%s -> preset %d/%d = %s",
548
+ device_id, output_id, cycle_idx + 1, len(presets), preset
549
+ )
550
+
551
+ return await self.control_output(
552
+ device_id=device_id,
553
+ output_id=output_id,
554
+ action="ON",
555
+ effect=preset,
556
+ transition=transition,
557
+ )
558
+
459
559
  async def control_cover(
460
560
  self,
461
561
  device_id: str,
@@ -505,6 +505,9 @@ class ESPHomeRemoteDevice(RemoteDevice):
505
505
  if (mode & LightColorCapability.RGB) and (mode & LightColorCapability.WHITE):
506
506
  supports_rgbw = True
507
507
 
508
+ # Get effects list from LightInfo
509
+ effects_list = list(getattr(entity, 'effects', []))
510
+
508
511
  light_data = {
509
512
  "id": entity.object_id,
510
513
  "name": entity.name,
@@ -515,6 +518,7 @@ class ESPHomeRemoteDevice(RemoteDevice):
515
518
  "supports_rgbw": supports_rgbw,
516
519
  "min_mireds": getattr(entity, 'min_mireds', None),
517
520
  "max_mireds": getattr(entity, 'max_mireds', None),
521
+ "effects": effects_list,
518
522
  }
519
523
 
520
524
  result["lights"].append(light_data)
@@ -625,6 +629,7 @@ class ESPHomeRemoteDevice(RemoteDevice):
625
629
  color_temp: int | None = None,
626
630
  rgb: tuple[int, int, int] | None = None,
627
631
  transition: float = 0.0,
632
+ effect: str | None = None,
628
633
  ) -> bool:
629
634
  """Control a light on the ESPHome device.
630
635
 
@@ -635,6 +640,7 @@ class ESPHomeRemoteDevice(RemoteDevice):
635
640
  color_temp: Color temperature in mireds
636
641
  rgb: RGB color tuple (0-255 each)
637
642
  transition: Transition time in seconds
643
+ effect: Effect name string (e.g. "Rainbow", "Strobe")
638
644
 
639
645
  Returns:
640
646
  True if command was sent successfully
@@ -669,6 +675,8 @@ class ESPHomeRemoteDevice(RemoteDevice):
669
675
  cmd_kwargs["color_temperature"] = color_temp
670
676
  if rgb is not None:
671
677
  cmd_kwargs["rgb"] = tuple(c / 255.0 for c in rgb)
678
+ if effect is not None:
679
+ cmd_kwargs["effect"] = effect
672
680
  self._client.light_command(light_key, **cmd_kwargs)
673
681
 
674
682
  elif action_upper == "TOGGLE":
@@ -135,6 +135,13 @@ class WLEDRemoteDevice(RemoteDevice):
135
135
  return seg
136
136
  return None
137
137
 
138
+ async def close(self) -> None:
139
+ """Close aiohttp session."""
140
+ if self._session and not self._session.closed:
141
+ await self._session.close()
142
+ self._session = None
143
+ _LOGGER.debug("Closed aiohttp session for WLED '%s'", self._name)
144
+
138
145
  async def _get_session(self) -> aiohttp.ClientSession:
139
146
  """Get or create aiohttp session."""
140
147
  if self._session is None or self._session.closed:
@@ -425,12 +432,6 @@ class WLEDRemoteDevice(RemoteDevice):
425
432
  _LOGGER.error("WLED discovery unexpected error for %s: %s", self._host, e)
426
433
  return {"error": str(e)}
427
434
 
428
- async def close(self) -> None:
429
- """Close HTTP session."""
430
- if self._session and not self._session.closed:
431
- await self._session.close()
432
- self._session = None
433
-
434
435
  def to_dict(self) -> dict[str, Any]:
435
436
  """Convert to dictionary representation.
436
437