boneio 1.5.0.dev7__tar.gz → 1.5.0.dev9__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 (508) hide show
  1. {boneio-1.5.0.dev7/boneio.egg-info → boneio-1.5.0.dev9}/PKG-INFO +1 -1
  2. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/config_helper.py +57 -19
  3. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/discovery.py +2 -2
  4. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/inputs.py +13 -4
  5. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/irrigation.py +1 -1
  6. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/manager.py +5 -5
  7. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/update.py +1 -1
  8. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/mqtt.py +1 -1
  9. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/remote/wled.py +9 -1
  10. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/integration/homeassistant.py +9 -9
  11. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/integration/lox_template.py +2 -2
  12. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/boneio-edge-temp.json +1 -1
  13. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/base.py +1 -1
  14. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/runner.py +2 -1
  15. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/schema.yaml +13 -0
  16. boneio-1.5.0.dev9/boneio/version.py +2 -0
  17. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/BindingMatrix-CFdSjHx2.js +1 -0
  18. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/ConfigEditor-7BXEIoby.js +1 -0
  19. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/EditItemDialog-KRY9Nr7Q.js +66 -0
  20. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/EntityCard-C_zsxPTw.js +1 -0
  21. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/EntityGrid-uCBLaMe9.js +1 -0
  22. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/HelpView--09VEVQt.js +1 -0
  23. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/InputsView-C5SMvXaD.js +1 -0
  24. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/LogViewer-Ejk-hBZk.js +2 -0
  25. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/LongPressWrapper-B-jkbdNk.js +1 -0
  26. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/ModbusView-DkjmrV7V.js +1 -0
  27. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/NodeRedView-BCnN6hPl.js +1 -0
  28. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/OutputsView-DqoaDXdb.js +1 -0
  29. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/SearchableEntityPicker-AqpMXiW9.js +11 -0
  30. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/SensorView-DrMXFCl_.js +1 -0
  31. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/Sparkline-P3-zEZpz.js +10 -0
  32. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/SudoPasswordDialog-D5dvXKgf.js +1 -0
  33. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/SystemState-CvUUFRfw.js +1 -0
  34. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/TemplatesView-CEJWenj2.js +1 -0
  35. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/Tools-DMbCkTx_.js +14 -0
  36. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/UISettings-KeMgW0rB.js +38 -0
  37. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/aiConfig-IRYCBmLm.js +2 -0
  38. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/aiWizardPrompt-D9OJ-cE7.js +2 -0
  39. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/basePath-CxHj-SSK.js +1 -0
  40. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/clipboard-CCtx29e-.js +1 -0
  41. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/dialog-BTaKr79l.js +1 -0
  42. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/formatters-b1QAvEOT.js +1 -0
  43. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/gi-BamvZSOL.js +1 -0
  44. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/index-4kW8M4Zc.css +2 -0
  45. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/index-CQtJKcCO.js +2 -0
  46. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/modbusDeviceCatalog-By-WNoAq.js +1 -0
  47. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/select-2z0PCnkc.js +1 -0
  48. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/tabs-box-DFRSG6Sv.js +1 -0
  49. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/useTranslation-CMe3OXqd.js +13 -0
  50. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/utils-CqpCEpSN.js +1 -0
  51. boneio-1.5.0.dev9/boneio/webui/frontend-dist/assets/vendor-DjFmndpd.js +11 -0
  52. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/index.html +5 -3
  53. {boneio-1.5.0.dev7/boneio/webui → boneio-1.5.0.dev9/boneio/webui/frontend-dist}/schema/boneio.schema.json +8 -0
  54. {boneio-1.5.0.dev7/boneio/webui → boneio-1.5.0.dev9/boneio/webui/frontend-dist}/schema/config.schema.json +8 -0
  55. boneio-1.5.0.dev9/boneio/webui/frontend-dist/sw.js +1 -0
  56. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/middleware/auth.py +1 -0
  57. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/config.py +342 -7
  58. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/dev_fake_device.py +2 -2
  59. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/modbus.py +2 -2
  60. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/sensors.py +41 -0
  61. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/system.py +60 -3
  62. {boneio-1.5.0.dev7/boneio/webui/frontend-dist → boneio-1.5.0.dev9/boneio/webui}/schema/boneio.schema.json +8 -0
  63. {boneio-1.5.0.dev7/boneio/webui/frontend-dist → boneio-1.5.0.dev9/boneio/webui}/schema/config.schema.json +8 -0
  64. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9/boneio.egg-info}/PKG-INFO +1 -1
  65. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio.egg-info/SOURCES.txt +35 -5
  66. boneio-1.5.0.dev7/boneio/version.py +0 -2
  67. boneio-1.5.0.dev7/boneio/webui/frontend-dist/assets/ConfigEditor-DbZgmkmq.js +0 -1
  68. boneio-1.5.0.dev7/boneio/webui/frontend-dist/assets/aiWizardPrompt-BubjUKaK.js +0 -2
  69. boneio-1.5.0.dev7/boneio/webui/frontend-dist/assets/index-D6g-vdBv.css +0 -2
  70. boneio-1.5.0.dev7/boneio/webui/frontend-dist/assets/index-qx3gjAAI.js +0 -130
  71. boneio-1.5.0.dev7/boneio/webui/frontend-dist/assets/vendor-pmGLHP0_.js +0 -55
  72. boneio-1.5.0.dev7/boneio/webui/frontend-dist/sw.js +0 -1
  73. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/LICENSE +0 -0
  74. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/MANIFEST.in +0 -0
  75. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/README.md +0 -0
  76. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/__init__.py +0 -0
  77. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.2/input.yaml +0 -0
  78. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.2/output_24_16.yaml +0 -0
  79. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.2/output_32_10.yaml +0 -0
  80. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.2/output_32_5.yaml +0 -0
  81. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.2/output_cover.yaml +0 -0
  82. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  83. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.3/input.yaml +0 -0
  84. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.3/output_24_16.yaml +0 -0
  85. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.3/output_32_10.yaml +0 -0
  86. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.3/output_32_5.yaml +0 -0
  87. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.3/output_cover.yaml +0 -0
  88. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  89. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.4/input.yaml +0 -0
  90. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.4/output_24_16.yaml +0 -0
  91. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.4/output_32_10.yaml +0 -0
  92. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.4/output_32_5.yaml +0 -0
  93. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.4/output_cover.yaml +0 -0
  94. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  95. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.5/input.yaml +0 -0
  96. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.5/output_24_16.yaml +0 -0
  97. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.5/output_32_10.yaml +0 -0
  98. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.5/output_cover.yaml +0 -0
  99. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  100. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.6/input.yaml +0 -0
  101. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.6/output_24_16.yaml +0 -0
  102. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.6/output_32_10.yaml +0 -0
  103. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.6/output_cover.yaml +0 -0
  104. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  105. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.7/input.yaml +0 -0
  106. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.7/output_24_16.yaml +0 -0
  107. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.7/output_32_10.yaml +0 -0
  108. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.7/output_48_4.yaml +0 -0
  109. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.7/output_cover.yaml +0 -0
  110. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  111. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.8/input.yaml +0 -0
  112. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.8/output_24_16.yaml +0 -0
  113. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.8/output_32_10.yaml +0 -0
  114. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.8/output_48_4.yaml +0 -0
  115. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.8/output_cover.yaml +0 -0
  116. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  117. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/1.0/input.yaml +0 -0
  118. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/1.0/output_24_16.yaml +0 -0
  119. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/1.0/output_32_10.yaml +0 -0
  120. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/1.0/output_48_4.yaml +0 -0
  121. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/1.0/output_cover.yaml +0 -0
  122. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/boards/1.0/output_cover_mix.yaml +0 -0
  123. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/bonecli.py +0 -0
  124. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/__init__.py +0 -0
  125. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/cover/__init__.py +0 -0
  126. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/cover/cover.py +0 -0
  127. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/cover/time_based.py +0 -0
  128. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/cover/venetian.py +0 -0
  129. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/group/__init__.py +0 -0
  130. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/group/output_group.py +0 -0
  131. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/input/__init__.py +0 -0
  132. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/input/binary_sensor.py +0 -0
  133. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/input/detectors.py +0 -0
  134. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/input/event.py +0 -0
  135. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/input/remote/__init__.py +0 -0
  136. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/input/remote/base.py +0 -0
  137. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/input/remote/esphome.py +0 -0
  138. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/irrigation/__init__.py +0 -0
  139. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/irrigation/controller.py +0 -0
  140. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/irrigation/water_source.py +0 -0
  141. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/output/__init__.py +0 -0
  142. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/output/basic.py +0 -0
  143. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/output/buzzer.py +0 -0
  144. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/output/mcp.py +0 -0
  145. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/output/pca.py +0 -0
  146. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/output/pcf.py +0 -0
  147. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/output/remote.py +0 -0
  148. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/sensor/__init__.py +0 -0
  149. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/sensor/virtual_energy.py +0 -0
  150. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/template/__init__.py +0 -0
  151. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/template/alarm_panel.py +0 -0
  152. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/template/gate_cover.py +0 -0
  153. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/components/template/thermostat.py +0 -0
  154. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/const.py +0 -0
  155. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/__init__.py +0 -0
  156. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/cloud/__init__.py +0 -0
  157. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/cloud/data/__init__.py +0 -0
  158. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
  159. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/cloud/data/docker-compose.yaml +0 -0
  160. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
  161. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/cloud/registration.py +0 -0
  162. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/cloud/secrets.py +0 -0
  163. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/__init__.py +0 -0
  164. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/migrations/__init__.py +0 -0
  165. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
  166. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/migrations/v2_transition.py +0 -0
  167. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/package-lock.json +0 -0
  168. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/package.json +0 -0
  169. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/schema_converter.py +0 -0
  170. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/config/yaml_util.py +0 -0
  171. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/events/__init__.py +0 -0
  172. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/events/bus.py +0 -0
  173. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/__init__.py +0 -0
  174. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/action_conditions.py +0 -0
  175. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/canopen.py +0 -0
  176. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/covers.py +0 -0
  177. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/display.py +0 -0
  178. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/modbus.py +0 -0
  179. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/outputs.py +0 -0
  180. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/remote.py +0 -0
  181. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/remote_input_registrar.py +0 -0
  182. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/sensors.py +0 -0
  183. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/templates/__init__.py +0 -0
  184. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/templates/alarm.py +0 -0
  185. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/templates/gate_cover.py +0 -0
  186. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/templates/thermostat.py +0 -0
  187. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/manager/templates.py +0 -0
  188. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/__init__.py +0 -0
  189. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/basic.py +0 -0
  190. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/basic_mqtt.py +0 -0
  191. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/composite.py +0 -0
  192. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/local.py +0 -0
  193. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/lox.py +0 -0
  194. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/messaging/queue.py +0 -0
  195. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/remote/__init__.py +0 -0
  196. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/remote/base.py +0 -0
  197. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/remote/can.py +0 -0
  198. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/remote/esphome.py +0 -0
  199. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/remote/mqtt.py +0 -0
  200. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/sensor/__init__.py +0 -0
  201. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/sensor/base.py +0 -0
  202. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/sensor/system.py +0 -0
  203. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/state/__init__.py +0 -0
  204. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/state/manager.py +0 -0
  205. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/system/__init__.py +0 -0
  206. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/system/host_data.py +0 -0
  207. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/system/monitor.py +0 -0
  208. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/__init__.py +0 -0
  209. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/async_updater.py +0 -0
  210. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/conditions.py +0 -0
  211. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/filter.py +0 -0
  212. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/font_util.py +0 -0
  213. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/logger.py +0 -0
  214. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/timeperiod.py +0 -0
  215. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/core/utils/util.py +0 -0
  216. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/24x16/adc.yaml +0 -0
  217. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  218. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/24x16/config.yaml +0 -0
  219. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/24x16/event.yaml +0 -0
  220. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/24x16/mqtt.yaml +0 -0
  221. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  222. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/32x10/adc.yaml +0 -0
  223. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  224. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/32x10/config.yaml +0 -0
  225. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/32x10/event.yaml +0 -0
  226. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/32x10/mqtt.yaml +0 -0
  227. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  228. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/48x4/adc.yaml +0 -0
  229. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
  230. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/48x4/config.yaml +0 -0
  231. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/48x4/event.yaml +0 -0
  232. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/48x4/mqtt.yaml +0 -0
  233. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/48x4/output48x4A.yaml +0 -0
  234. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/__init__.py +0 -0
  235. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/can_master.yaml +0 -0
  236. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/can_slave.yaml +0 -0
  237. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover/adc.yaml +0 -0
  238. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  239. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover/config.yaml +0 -0
  240. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover/cover.yaml +0 -0
  241. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover/event.yaml +0 -0
  242. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover/mqtt.yaml +0 -0
  243. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover/outputCover.yaml +0 -0
  244. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover_mix/adc.yaml +0 -0
  245. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  246. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover_mix/config.yaml +0 -0
  247. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover_mix/cover.yaml +0 -0
  248. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover_mix/event.yaml +0 -0
  249. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  250. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  251. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/adc.yaml +0 -0
  252. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  253. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  254. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  255. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  256. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/event_all.yaml +0 -0
  257. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  258. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  259. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  260. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  261. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  262. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  263. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/exceptions.py +0 -0
  264. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/__init__.py +0 -0
  265. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/analog/__init__.py +0 -0
  266. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/analog/adc.py +0 -0
  267. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/can/__init__.py +0 -0
  268. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/can/bridge.py +0 -0
  269. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/can/client.py +0 -0
  270. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/can/interface.py +0 -0
  271. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/can/node.py +0 -0
  272. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/can/node_id.py +0 -0
  273. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/can/test_od.py +0 -0
  274. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/display/__init__.py +0 -0
  275. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/display/early_oled.py +0 -0
  276. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  277. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/display/oled.py +0 -0
  278. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/__init__.py +0 -0
  279. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  280. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  281. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  282. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  283. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/input/__init__.py +0 -0
  284. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/input/base.py +0 -0
  285. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/gpio/input/manager.py +0 -0
  286. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/i2c/__init__.py +0 -0
  287. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/i2c/bus.py +0 -0
  288. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/i2c/ina219.py +0 -0
  289. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/i2c/ina219_driver.py +0 -0
  290. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/i2c/mcp9808.py +0 -0
  291. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/i2c/pct2075.py +0 -0
  292. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/onewire/__init__.py +0 -0
  293. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/onewire/bus.py +0 -0
  294. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/onewire/dallas.py +0 -0
  295. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/onewire/ds2482.py +0 -0
  296. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/sensor/__init__.py +0 -0
  297. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  298. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/sensor/temperature/base.py +0 -0
  299. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  300. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  301. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/integration/__init__.py +0 -0
  302. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/integration/interlock.py +0 -0
  303. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/__init__.py +0 -0
  304. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/actions.py +0 -0
  305. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/MANIFEST.sha256 +0 -0
  306. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/docker/daemon.json +0 -0
  307. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
  308. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
  309. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
  310. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
  311. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
  312. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/journald/journald.conf +0 -0
  313. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
  314. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/sudoers/boneio +0 -0
  315. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
  316. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
  317. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/systemd/boneio.service +0 -0
  318. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
  319. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
  320. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
  321. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
  322. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
  323. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
  324. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/bootstrap/boneio-migrate +0 -0
  325. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/bootstrap/install-helper.sh +0 -0
  326. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
  327. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/runner.py +0 -0
  328. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/__init__.py +0 -0
  329. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
  330. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
  331. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
  332. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
  333. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
  334. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
  335. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
  336. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/migrations/versions/v1_5_1_ufw_lox_udp.py +0 -0
  337. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/__init__.py +0 -0
  338. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/cli.py +0 -0
  339. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/client.py +0 -0
  340. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/coordinator.py +0 -0
  341. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/__init__.py +0 -0
  342. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/dts1964_3f.json +0 -0
  343. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
  344. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
  345. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  346. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  347. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  348. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  349. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  350. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
  351. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  352. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/hvac/thessla.json +0 -0
  353. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  354. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/hvac/wanas415.json +0 -0
  355. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/inverters/sofar.json +0 -0
  356. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
  357. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/other/n4dsc08.json +0 -0
  358. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  359. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/cwt.json +0 -0
  360. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
  361. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/gdfs.json +0 -0
  362. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/gdfx.json +0 -0
  363. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  364. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/pt100.json +0 -0
  365. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/sht20.json +0 -0
  366. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/devices/sensors/sht30.json +0 -0
  367. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/__init__.py +0 -0
  368. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/derived/__init__.py +0 -0
  369. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/derived/numeric.py +0 -0
  370. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/derived/select.py +0 -0
  371. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/derived/switch.py +0 -0
  372. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/derived/text.py +0 -0
  373. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/sensor/__init__.py +0 -0
  374. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/sensor/binary.py +0 -0
  375. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/sensor/numeric.py +0 -0
  376. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/sensor/text.py +0 -0
  377. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/writeable/__init__.py +0 -0
  378. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/writeable/binary.py +0 -0
  379. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/entities/writeable/numeric.py +0 -0
  380. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/mock_coordinator.py +0 -0
  381. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/modbus/utils.py +0 -0
  382. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/models/__init__.py +0 -0
  383. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/models/actions.py +0 -0
  384. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/models/events.py +0 -0
  385. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/models/files.py +0 -0
  386. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/models/logs.py +0 -0
  387. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/models/mqtt.py +0 -0
  388. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/models/state.py +0 -0
  389. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/actions.yaml +0 -0
  390. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/actions_sensor.yaml +0 -0
  391. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/actions_switch.yaml +0 -0
  392. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/condition.yaml +0 -0
  393. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/filters.yaml +0 -0
  394. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/filters_adc.yaml +0 -0
  395. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/id.yaml +0 -0
  396. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/remote_devices.yaml +0 -0
  397. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/remote_inputs.yaml +0 -0
  398. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/remote_outputs.yaml +0 -0
  399. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/temp_unit.yaml +0 -0
  400. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/schema/update_interval.yaml +0 -0
  401. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/action_validation.py +0 -0
  402. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/app.py +0 -0
  403. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/dashboard_cards.py +0 -0
  404. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  405. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/css.worker-CvXBzhp8.js +0 -0
  406. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/editor.worker-Cn2oRESe.js +0 -0
  407. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/html.worker-BO6WuOEO.js +0 -0
  408. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/json.worker-BkJRGcCJ.js +0 -0
  409. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/monaco-61yH0vfd.js +0 -0
  410. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
  411. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/rolldown-runtime-QTnfLwEv.js +0 -0
  412. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/ts.worker-B0J26iPs.js +0 -0
  413. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
  414. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/assets/yaml.worker-BKRoXlmz.js +0 -0
  415. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  416. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  417. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/boneio.svg +0 -0
  418. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  419. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
  420. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
  421. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
  422. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
  423. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
  424. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
  425. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
  426. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
  427. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
  428. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
  429. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
  430. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
  431. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
  432. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
  433. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
  434. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
  435. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
  436. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
  437. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
  438. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
  439. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
  440. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
  441. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
  442. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
  443. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
  444. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
  445. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
  446. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
  447. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
  448. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
  449. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/frontend-dist/workbox-4918f2f6.js +0 -0
  450. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/hvac_svg_templates.py +0 -0
  451. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/middleware/__init__.py +0 -0
  452. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/modbus_card_templates.py +0 -0
  453. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/__init__.py +0 -0
  454. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/auth.py +0 -0
  455. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/caddy.py +0 -0
  456. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/can.py +0 -0
  457. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/covers.py +0 -0
  458. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/dashboard.py +0 -0
  459. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/irrigation.py +0 -0
  460. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/migrations.py +0 -0
  461. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/outputs.py +0 -0
  462. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/remote_devices.py +0 -0
  463. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/templates.py +0 -0
  464. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/timezone_sudoers.py +0 -0
  465. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/tools.py +0 -0
  466. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/routes/update.py +0 -0
  467. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/adc.schema.json +0 -0
  468. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/areas.schema.json +0 -0
  469. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/binary_sensor.schema.json +0 -0
  470. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/can.schema.json +0 -0
  471. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/cover.schema.json +0 -0
  472. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/dallas.schema.json +0 -0
  473. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/ds2482.schema.json +0 -0
  474. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/event.schema.json +0 -0
  475. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/ina219.schema.json +0 -0
  476. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/irrigation.schema.json +0 -0
  477. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/lm75.schema.json +0 -0
  478. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/logger.schema.json +0 -0
  479. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/lox_udp.schema.json +0 -0
  480. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/mcp23017.schema.json +0 -0
  481. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/mcp9808.schema.json +0 -0
  482. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/modbus.schema.json +0 -0
  483. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/modbus_devices.schema.json +0 -0
  484. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/mqtt.schema.json +0 -0
  485. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/oled.schema.json +0 -0
  486. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/output.schema.json +0 -0
  487. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/output_group.schema.json +0 -0
  488. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/pca9685.schema.json +0 -0
  489. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/pcf8575.schema.json +0 -0
  490. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/remote_devices.schema.json +0 -0
  491. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/remote_inputs.schema.json +0 -0
  492. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/remote_outputs.schema.json +0 -0
  493. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/sensor.schema.json +0 -0
  494. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/template.schema.json +0 -0
  495. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
  496. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/schema/web.schema.json +0 -0
  497. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/services/__init__.py +0 -0
  498. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/services/logs.py +0 -0
  499. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/web_server.py +0 -0
  500. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio/webui/websocket_manager.py +0 -0
  501. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio.egg-info/dependency_links.txt +0 -0
  502. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio.egg-info/entry_points.txt +0 -0
  503. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio.egg-info/requires.txt +0 -0
  504. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/boneio.egg-info/top_level.txt +0 -0
  505. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/pyproject.toml +0 -0
  506. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/setup.cfg +0 -0
  507. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/setup.py +0 -0
  508. {boneio-1.5.0.dev7 → boneio-1.5.0.dev9}/tests/test_py313_compatibility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.5.0.dev7
3
+ Version: 1.5.0.dev9
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
@@ -6,6 +6,7 @@ from __future__ import annotations
6
6
  import logging
7
7
  from _collections_abc import dict_values
8
8
  from typing import TYPE_CHECKING, Any
9
+ import time as _time
9
10
 
10
11
  if TYPE_CHECKING:
11
12
  from boneio.integration.homeassistant import HomeAssistantDiscoveryMessage
@@ -28,7 +29,6 @@ from boneio.const import (
28
29
  VALVE,
29
30
  )
30
31
  from boneio.core.system import get_serial_from_mac
31
- from boneio.core.utils.util import sanitize_mqtt_topic
32
32
 
33
33
  _LOGGER = logging.getLogger(__name__)
34
34
 
@@ -53,21 +53,29 @@ class ConfigHelper:
53
53
  pwa_name: str | None = None,
54
54
  ha_child_devices: bool = False,
55
55
  ha_child_devices_naming: str = "default",
56
+ serial_override: str | None = None,
56
57
  ):
57
58
  self._name = name
58
59
  self._version = version
59
60
 
60
- # Generate serial number from MAC - always required for topic prefix
61
- self._serial_no = get_serial_from_mac(network_info or {})
61
+ # Generate real serial number from MAC - always required for physical identification
62
+ self._real_serial = get_serial_from_mac(network_info or {})
62
63
 
63
- # Build fixed topic prefix: boneio/blk_{serial}
64
+ # If override is provided, use it as effective serial, otherwise use real MAC-based serial
65
+ if serial_override:
66
+ self._serial_no = serial_override
67
+ _LOGGER.warning("Serial override active: effective=%s, real=%s", serial_override, self._real_serial)
68
+ else:
69
+ self._serial_no = self._real_serial
70
+
71
+ # Build fixed topic prefix: boneio/blk_{serial} using effective serial
64
72
  # This is no longer configurable - always uses this format
65
73
  if self._serial_no:
66
74
  self._topic_prefix = f"boneio/{self._serial_no}"
67
75
  else:
68
76
  # Fallback if MAC not available (should rarely happen)
69
77
  self._topic_prefix = "boneio/blk_unknown"
70
- _LOGGER.warning("Could not determine serial number from MAC, using fallback topic prefix")
78
+ _LOGGER.warning("Could not determine serial number, using fallback topic prefix")
71
79
 
72
80
  # PWA short name for Android home screen (max 12 chars)
73
81
  if pwa_name:
@@ -165,7 +173,8 @@ class ConfigHelper:
165
173
 
166
174
  @property
167
175
  def serial_number(self) -> str:
168
- return self._serial_no
176
+ """Get effective device serial number (e.g., 'blk_abc123')."""
177
+ return self._serial_no or "blk_unknown"
169
178
 
170
179
  @property
171
180
  def proxy_port(self) -> int | None:
@@ -186,9 +195,16 @@ class ConfigHelper:
186
195
  return self._topic_prefix
187
196
 
188
197
  @property
189
- def serial_no(self) -> str:
190
- """Get device serial number (e.g., 'blk_abc123')."""
191
- return self._serial_no or "blk_unknown"
198
+ def real_serial(self) -> str:
199
+ """Real serial from MAC — for HA device_info and UI display."""
200
+ return self._real_serial or "blk_unknown"
201
+
202
+ @property
203
+ def serial_override(self) -> str | None:
204
+ """Return override value if active, None otherwise."""
205
+ if self._serial_no != self._real_serial:
206
+ return self._serial_no
207
+ return None
192
208
 
193
209
  @property
194
210
  def pwa_name(self) -> str:
@@ -390,16 +406,20 @@ class ConfigHelper:
390
406
  return self._config_cache
391
407
 
392
408
  def reload_config(self) -> dict[str, Any]:
393
- """Reload configuration from file and update cache.
409
+ """Reload configuration from YAML file (fast path for hot-reload).
394
410
 
395
- Loads config from file using load_config_from_file() which tries the
396
- disk cache first (~0.5s) and falls back to full Cerberus validation
397
- (~20s) on cache miss. This method does NOT wait for any background
398
- cache rebuild — it's independent.
411
+ Uses load_yaml_file() + merge_board_config() to read the config
412
+ directly from YAML without running Cerberus validation. This is
413
+ much faster (~0.5-1s) than the full validation path (~20s on BB).
399
414
 
400
- NOTE: This method may take up to ~20s on BeagleBone if disk cache
401
- is not available. Callers should run it via asyncio.to_thread() to
402
- avoid blocking the event loop.
415
+ Full Cerberus validation is only needed at:
416
+ - Application startup (via load_config_from_file)
417
+ - Background disk cache rebuild (debounced after config changes)
418
+ - Monaco YAML editor validation (load_config_from_string)
419
+
420
+ NOTE: Migrations are not applied here — they run at startup and
421
+ are idempotent (version-gated). Config saved via the UI always
422
+ has current schema version.
403
423
 
404
424
  Returns:
405
425
  dict: Reloaded configuration dictionary
@@ -407,8 +427,26 @@ class ConfigHelper:
407
427
  Raises:
408
428
  ValueError: If config_file_path is not set
409
429
  """
410
- _LOGGER.info("Reloading config from file: %s", self._config_file_path)
411
- return self.get_config(force_reload=True)
430
+
431
+ if self._config_file_path is None:
432
+ raise ValueError("config_file_path not set in ConfigHelper")
433
+
434
+ _t0 = _time.monotonic()
435
+ _LOGGER.info("Fast-reloading config from: %s", self._config_file_path)
436
+
437
+ from boneio.core.config.yaml_util import load_yaml_file, merge_board_config
438
+
439
+ config_yaml = load_yaml_file(self._config_file_path)
440
+ if config_yaml is None:
441
+ raise ValueError(f"Failed to load config from: {self._config_file_path}")
442
+
443
+ merged = merge_board_config(config_yaml)
444
+ self._config_cache = merged
445
+
446
+ elapsed = _time.monotonic() - _t0
447
+ _LOGGER.info("Fast config reload completed in %.2fs", elapsed)
448
+
449
+ return merged
412
450
 
413
451
  def get_section(self, section_name: str, force_reload: bool = False) -> Any:
414
452
  """Get a specific configuration section.
@@ -62,9 +62,9 @@ class BlackDiscoveryPublisher:
62
62
 
63
63
  config_helper = self._manager._config_helper
64
64
  device_info = {
65
- "id": config_helper._serial_no or "unknown",
65
+ "id": config_helper.serial_number,
66
66
  "name": config_helper.name,
67
- "serial_number": config_helper._serial_no or "unknown",
67
+ "serial_number": config_helper.serial_number,
68
68
  "type": "black",
69
69
  "firmware": __version__,
70
70
  "topic_prefix": config_helper.topic_prefix,
@@ -255,13 +255,17 @@ class InputManager:
255
255
 
256
256
  # Reload: update existing input's actions and name
257
257
  if existing_input:
258
- # Check if HA-relevant fields changed (name, area, mqtt_sequences)
258
+ # Check if HA-relevant fields changed (name, area, device_class, mqtt_sequences)
259
259
  old_name = existing_input._name if hasattr(existing_input, "_name") else None
260
260
  old_area = getattr(existing_input, "area", None)
261
+ old_device_class = getattr(existing_input, "_device_class", None)
262
+ new_device_class = gpio.get(DEVICE_CLASS)
261
263
  old_mqtt_sequences = existing_input.mqtt_sequences if hasattr(existing_input, "mqtt_sequences") else {}
262
264
  new_mqtt_sequences = gpio.get("mqtt_sequences", {})
263
265
  ha_fields_changed = (
264
- (old_name != name) or (old_area != area) or (old_mqtt_sequences != new_mqtt_sequences)
266
+ (old_name != name) or (old_area != area)
267
+ or (old_device_class != new_device_class)
268
+ or (old_mqtt_sequences != new_mqtt_sequences)
265
269
  )
266
270
 
267
271
  # Update actions (always - this is internal to the controller)
@@ -383,10 +387,15 @@ class InputManager:
383
387
 
384
388
  # Reload: update existing input's actions and name
385
389
  if existing_input:
386
- # Check if HA-relevant fields changed (name, area)
390
+ # Check if HA-relevant fields changed (name, area, device_class)
387
391
  old_name = existing_input._name if hasattr(existing_input, "_name") else None
388
392
  old_area = getattr(existing_input, "area", None)
389
- ha_fields_changed = (old_name != name) or (old_area != area)
393
+ old_device_class = getattr(existing_input, "_device_class", None)
394
+ new_device_class = gpio.get(DEVICE_CLASS)
395
+ ha_fields_changed = (
396
+ (old_name != name) or (old_area != area)
397
+ or (old_device_class != new_device_class)
398
+ )
390
399
 
391
400
  # Update actions (always - this is internal to the controller)
392
401
  existing_input.set_actions(actions=actions)
@@ -309,7 +309,7 @@ class IrrigationManager:
309
309
  Sends empty payload to discovery topics to remove entities from HA.
310
310
  """
311
311
  cfg = self._manager.config_helper
312
- serial = cfg.serial_no
312
+ serial = cfg.serial_number
313
313
 
314
314
  # Build list of discovery IDs to remove
315
315
  discovery_ids: list[tuple[str, str]] = [
@@ -243,7 +243,7 @@ class Manager:
243
243
  self.remote_devices = RemoteDeviceManager(
244
244
  message_bus=message_bus,
245
245
  remote_devices_config=remote_devices,
246
- own_serial=config_helper.serial_no,
246
+ own_serial=config_helper.serial_number,
247
247
  name=self.config_helper.name,
248
248
  )
249
249
 
@@ -625,7 +625,7 @@ class Manager:
625
625
  ha_type: Home Assistant entity type (sensor, light, cover …).
626
626
  payload: Ready-to-publish discovery payload dict.
627
627
  """
628
- topic = f"{self._config_helper.ha_discovery_prefix}/{ha_type}/{self._config_helper.serial_no}/{id}/config"
628
+ topic = f"{self._config_helper.ha_discovery_prefix}/{ha_type}/{self._config_helper.serial_number}/{id}/config"
629
629
  _LOGGER.debug("Sending HA discovery for %s entity %s.", ha_type, id)
630
630
  self._config_helper.add_autodiscovery_msg(topic=topic, ha_type=ha_type, payload=payload)
631
631
  self.send_message(topic=topic, payload=payload, retain=True)
@@ -1590,9 +1590,9 @@ class Manager:
1590
1590
  _LOGGER.info("Starting config reload")
1591
1591
 
1592
1592
  # Reload config cache in ConfigHelper
1593
- # NOTE: reload_config() calls load_config_from_file() which may run
1594
- # full Cerberus validation (~20s) on disk cache miss. Run in a thread
1595
- # executor to keep the event loop responsive (MQTT, WS, modbus).
1593
+ # Uses fast path: load_yaml_file() + merge_board_config() (~0.5-1s)
1594
+ # instead of full Cerberus validation (~20s). Run in thread executor
1595
+ # because it still does file I/O (reading YAML files from disk).
1596
1596
  try:
1597
1597
  config = await asyncio.to_thread(self._config_helper.reload_config)
1598
1598
  # Update areas mapping from reloaded config
@@ -737,7 +737,7 @@ class UpdateManager(AsyncUpdater):
737
737
  # --- Remove legacy event entity discovery (if any) ---
738
738
  old_event_topic = (
739
739
  f"{config.ha_discovery_prefix}/event/"
740
- f"{config.serial_no}/migration_alert/config"
740
+ f"{config.serial_number}/migration_alert/config"
741
741
  )
742
742
  self._manager.send_message(topic=old_event_topic, payload="", retain=True)
743
743
  _LOGGER.debug("Removed legacy migration_alert event entity discovery")
@@ -59,7 +59,7 @@ class MQTTClient(MessageBus):
59
59
  self._mqtt_energy_listeners: dict[str, Callable[[str, str], Awaitable[None]]] = {}
60
60
  self._discovery_topics = (
61
61
  [
62
- f"{self._config_helper.ha_discovery_prefix}/{ha_type}/{self._config_helper.serial_no}/#"
62
+ f"{self._config_helper.ha_discovery_prefix}/{ha_type}/{self._config_helper.serial_number}/#"
63
63
  for ha_type in self._config_helper.ha_types
64
64
  ]
65
65
  if self._config_helper.ha_discovery
@@ -288,10 +288,18 @@ class WLEDRemoteDevice(RemoteDevice):
288
288
 
289
289
  if action == "ON":
290
290
  seg_state["on"] = True
291
+ # Ensure device is globally on so the segment is visible
292
+ state["on"] = True
291
293
  elif action == "OFF":
292
294
  seg_state["on"] = False
293
295
  elif action == "TOGGLE":
294
- seg_state["on"] = "t" # WLED toggle syntax
296
+ # WLED ignores "on": "t" at segment level (tested on
297
+ # v0.15.0-b4) — resolve toggle using cached state.
298
+ current_on = self.segment_is_on(segment_id)
299
+ seg_state["on"] = not current_on
300
+ if not current_on:
301
+ # Turning on — ensure device is globally on
302
+ state["on"] = True
295
303
 
296
304
  if brightness is not None:
297
305
  seg_state["bri"] = max(0, min(255, brightness))
@@ -123,9 +123,9 @@ def ha_availabilty_message(
123
123
  "identifiers": [child_identifier],
124
124
  "manufacturer": manufacturer,
125
125
  "model": model,
126
- "model_id": config_helper.serial_number,
126
+ "model_id": config_helper.real_serial,
127
127
  "name": child_device_name,
128
- "serial_number": config_helper.serial_number,
128
+ "serial_number": config_helper.real_serial,
129
129
  "sw_version": __version__,
130
130
  "via_device": topic, # Link to main BoneIO device
131
131
  **web_url_dict,
@@ -144,9 +144,9 @@ def ha_availabilty_message(
144
144
  "identifiers": [f"{topic}_{area}"], # Use area ID for consistent grouping
145
145
  "manufacturer": manufacturer,
146
146
  "model": model,
147
- "model_id": config_helper.serial_number,
147
+ "model_id": config_helper.real_serial,
148
148
  "name": sub_device_name,
149
- "serial_number": config_helper.serial_number,
149
+ "serial_number": config_helper.real_serial,
150
150
  "sw_version": __version__,
151
151
  "via_device": topic, # Link to main BoneIO device
152
152
  "suggested_area": area_name, # Use area ID (lowercase) - HA converts area names to lowercase
@@ -158,9 +158,9 @@ def ha_availabilty_message(
158
158
  "identifiers": [topic],
159
159
  "manufacturer": manufacturer,
160
160
  "model": model,
161
- "model_id": config_helper.serial_number,
161
+ "model_id": config_helper.real_serial,
162
162
  "name": device_name,
163
- "serial_number": config_helper.serial_number,
163
+ "serial_number": config_helper.real_serial,
164
164
  "sw_version": __version__,
165
165
  **web_url_dict
166
166
  }
@@ -297,9 +297,9 @@ def _ha_irrigation_device(
297
297
  "identifiers": [f"{topic}_{IRRIGATION}_{ctrl_id}"],
298
298
  "manufacturer": "boneIO",
299
299
  "model": model,
300
- "model_id": config_helper.serial_number,
300
+ "model_id": config_helper.real_serial,
301
301
  "name": ctrl_name,
302
- "serial_number": config_helper.serial_number,
302
+ "serial_number": config_helper.real_serial,
303
303
  "sw_version": __version__,
304
304
  "via_device": topic,
305
305
  }
@@ -880,7 +880,7 @@ def modbus_polling_switch_message(
880
880
 
881
881
  discovery_topic = (
882
882
  f"{config_helper.ha_discovery_prefix}/switch/"
883
- f"{config_helper.serial_no}/{entity_id}/config"
883
+ f"{config_helper.serial_number}/{entity_id}/config"
884
884
  )
885
885
 
886
886
  area_name = config_helper.get_area_name(area) if area else None
@@ -52,7 +52,7 @@ def generate_lox_template(manager: Manager) -> str:
52
52
  Returns:
53
53
  XML string ready to be saved as a .xml template file.
54
54
  """
55
- serial = manager.config_helper.serial_no or "boneio"
55
+ serial = manager.config_helper.serial_number or "boneio"
56
56
  device_name = manager.config_helper.name or serial
57
57
 
58
58
  # Get Lox UDP config (host/ports) from running config
@@ -275,7 +275,7 @@ def generate_lox_summary(manager: Manager) -> dict[str, Any]:
275
275
  Returns:
276
276
  Dictionary with 'commands' and 'status' sections.
277
277
  """
278
- serial = manager.config_helper.serial_no or "boneio"
278
+ serial = manager.config_helper.serial_number or "boneio"
279
279
  device_name = manager.config_helper.name or serial
280
280
 
281
281
  commands: list[dict[str, str]] = []
@@ -4,7 +4,7 @@
4
4
  "description": "boneIO temperature sensor extension board",
5
5
  "category": "sensors",
6
6
  "default_address": 1,
7
- "default_update_interval": "10s",
7
+ "default_update_interval": "30s",
8
8
  "set_base": {
9
9
  "set_address_address": 100,
10
10
  "set_baudrate": {
@@ -60,7 +60,7 @@ class BaseEntity(Filter):
60
60
  self._timestamp = time.time()
61
61
  self._id = f"{self._parent[ID]}_{self._decoded_name_low.replace('_', '')}"
62
62
  self._topic = (
63
- f"{self._config_helper.ha_discovery_prefix}/{self._entity_type}/{self._config_helper.serial_no}"
63
+ f"{self._config_helper.ha_discovery_prefix}/{self._entity_type}/{self._config_helper.serial_number}"
64
64
  f"/{self._id}/config"
65
65
  )
66
66
 
@@ -170,6 +170,7 @@ async def async_run(
170
170
  pwa_name=web_config.get("cloud", {}).get("pwa_name"),
171
171
  ha_child_devices=main_config.get("ha_child_devices", False),
172
172
  ha_child_devices_naming=main_config.get("ha_child_devices_naming", "default"),
173
+ serial_override=main_config.get("serial_override"),
173
174
  )
174
175
 
175
176
  # Load areas configuration
@@ -358,7 +359,7 @@ async def async_run(
358
359
  cloud_reg = None
359
360
  if _config_helper.cloud_registration:
360
361
  local_ip = network_state.get("ip", "")
361
- serial = _config_helper.serial_no
362
+ serial = _config_helper.serial_number
362
363
  if local_ip and serial:
363
364
  cloud_reg = CloudRegistration(
364
365
  serial_number=serial,
@@ -2255,3 +2255,16 @@ boneio:
2255
2255
  - default: Entity name only (e.g., "OUT 17"). May cause duplicates if multiple boneIO devices share output names.
2256
2256
  - device_name: Adds boneIO device name prefix (e.g., "boneIO Black - OUT 17").
2257
2257
  - device_name_area: Adds device name and area (e.g., "boneIO Black - Living Room - OUT 17"). Falls back to device_name if no area is assigned.
2258
+ serial_override:
2259
+ required: False
2260
+ type: string
2261
+ nullable: True
2262
+ regex: '^blk[a-f0-9]{6}$'
2263
+ meta:
2264
+ label: Serial number override
2265
+ description: |
2266
+ Override the auto-detected serial number (based on MAC address).
2267
+ Use this when restoring config from a different device (e.g., RMA replacement).
2268
+ Format: blk followed by 6 hex characters (e.g., blk8c7df0).
2269
+ WARNING: Two devices with the same serial on the same MQTT broker will conflict!
2270
+
@@ -0,0 +1,2 @@
1
+ # flake8: noqa
2
+ __version__ = "1.5.0dev9"
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{c as t}from"./monaco-61yH0vfd.js";import{y as n}from"./vendor-DjFmndpd.js";import{t as r}from"./useTranslation-CMe3OXqd.js";import{$ as i,B as a,C as o,I as s,It as c,N as l,Pt as u,U as d,Ut as f,Wt as p,b as m,s as h,ut as g,y as _,z as v}from"./index-CQtJKcCO.js";import{t as y}from"./EditItemDialog-KRY9Nr7Q.js";var b=e(t(),1);function x(e){return p({tag:`svg`,attr:{viewBox:`0 0 512 512`},child:[{tag:`path`,attr:{d:`M224 0c17.7 0 32 14.3 32 32l0 12 96-12c17.7 0 32 14.3 32 32s-14.3 32-32 32L256 84l-31-3.9-1-.1-1 .1L192 84 96 96C78.3 96 64 81.7 64 64s14.3-32 32-32l96 12 0-12c0-17.7 14.3-32 32-32zM0 224c0-17.7 14.3-32 32-32l96 0 22.6-22.6c6-6 14.1-9.4 22.6-9.4l18.7 0 0-43.8 32-4 32 4 0 43.8 18.7 0c8.5 0 16.6 3.4 22.6 9.4L320 192l32 0c88.4 0 160 71.6 160 160c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32-14.3-32-32s-14.3-32-32-32l-36.1 0c-20.2 29-53.9 48-91.9 48s-71.7-19-91.9-48L32 320c-17.7 0-32-14.3-32-32l0-64zM436.8 423.4c1.9-4.5 6.3-7.4 11.2-7.4s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1l0 1.2c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-1.2c0-4.5 .9-8.9 2.7-13.1l18.2-42.4z`},child:[]}]})(e)}var S=n();function C({outputType:e,className:t}){switch(e){case`light`:return(0,S.jsx)(i,{className:h(`text-warning`,t)});case`switch`:return(0,S.jsx)(c,{className:h(`text-info`,t)});case`valve`:return(0,S.jsx)(x,{className:h(`text-accent`,t)});case`cover`:return(0,S.jsx)(l,{className:h(`text-secondary`,t)});case`shutter`:case`blind`:case`curtain`:return(0,S.jsx)(f,{className:h(`text-secondary`,t)});default:return null}}var w={single:`1×`,double:`2×`,triple:`3×`,long:`L`,pressed:`P`,released:`R`,double_then_long:`2×L`,single_then_long:`1×L`,double_then_single:`2×1`},T={TOGGLE:`short_toggle`,ON:`short_on`,OFF:`short_off`,OPEN:`short_open`,CLOSE:`short_close`,STOP:`short_stop`},E=[{key:`single`,labelKey:`binding_matrix.legend_single`,icon:`1×`},{key:`double`,labelKey:`binding_matrix.legend_double`,icon:`2×`},{key:`triple`,labelKey:`binding_matrix.legend_triple`,icon:`3×`},{key:`long`,labelKey:`binding_matrix.legend_long`,icon:`L`},{key:`pressed`,labelKey:`binding_matrix.legend_pressed`,icon:`P`},{key:`released`,labelKey:`binding_matrix.legend_released`,icon:`R`}],D=[{labelKey:`actions.toggle`,shortKey:`actions.short_toggle`},{labelKey:`actions.on`,shortKey:`actions.short_on`},{labelKey:`actions.off`,shortKey:`actions.short_off`},{labelKey:`actions.open`,shortKey:`actions.short_open`},{labelKey:`actions.close`,shortKey:`actions.short_close`},{labelKey:`actions.stop`,shortKey:`actions.short_stop`}],O={single:`single`,double:`double`,triple:`triple`,long:`long`,pressed:`basic`,released:`basic`,double_then_long:`sequences`,single_then_long:`sequences`,double_then_single:`sequences`};function k(e,t){let n=w[e.clickType]||e.clickType,r=T[e.actionValue];return`${n} ${r?t(`actions.${r}`):e.actionValue}`}function A(e,t){let n=`actions.${e.actionValue.toLowerCase()}`,r=t(n),i=r===n?e.actionValue:r;return`${e.clickType} → ${i}`}function j(e){let t=e.action||`output`,n=``,r=``,i;switch(t){case`output`:n=e.boneio_output||``,r=e.action_output||`TOGGLE`;break;case`cover`:n=e.boneio_cover||``,r=e.action_cover||`TOGGLE`;break;case`remote_output`:i=e.boneio_id||``,n=i?`${i}/${e.output_id||``}`:e.output_id||``,r=e.action_output||`TOGGLE`;break;case`remote_cover`:i=e.boneio_id||``,n=i?`${i}/${e.cover_id||``}`:e.cover_id||``,r=e.action_cover||`TOGGLE`;break;default:n=``,r=e.action_output||e.action_cover||``;break}return{targetId:n,actionType:t,actionValue:r,remoteDevice:i}}function M(e){let t=[],n=[`single`,`double`,`triple`,`long`,`pressed`,`released`,`double_then_long`,`single_then_long`,`double_then_single`],r=e.local_inputs||[];for(let e=0;e<r.length;e++){let i=r[e],a=i.id||i.pin||`local_${e}`,o=[];for(let e of n){let t=i.actions?.[e]||[];for(let n of t){let{targetId:t,actionType:r,actionValue:i,remoteDevice:a}=j(n);t&&o.push({clickType:e,actionType:r,targetId:t,actionValue:i,remoteDevice:a})}}t.push({id:a,name:i.name||i.id||i.pin||a,area:i.area||void 0,type:`local`,bindings:o})}let i=e.remote_inputs||[];for(let e=0;e<i.length;e++){let r=i[e],a=r.boneio_id||r.remote_device||``,o=r.id||r.entity_id||``,s=a?`${a}/${o}`:o||`remote_${e}`,c=[];for(let e of n){let t=r.actions?.[e]||[];for(let n of t){let{targetId:t,actionType:r,actionValue:i,remoteDevice:a}=j(n);t&&c.push({clickType:e,actionType:r,targetId:t,actionValue:i,remoteDevice:a})}}t.push({id:s,name:r.name||r.id||o,area:r.area||void 0,type:`remote`,remoteDevice:a,bindings:c})}return t}function N(e){let t=[],n=e.output||[];for(let e=0;e<n.length;e++){let r=n[e];if(r.output_type===`cover`||r.output_type===`none`)continue;let i=r.id||`output_${e}`;t.push({id:i,name:r.name||r.id||i,area:r.area||void 0,type:`output`,outputType:r.output_type})}let r=e.cover||[];for(let e=0;e<r.length;e++){let n=r[e],i=n.id||`cover_${e}`;t.push({id:i,name:n.name||n.id||i,area:n.area||void 0,type:`cover`,outputType:n.device_class||`cover`})}let i=e.remote_outputs||[];for(let e=0;e<i.length;e++){let n=i[e],r=n.boneio_id||n.remote_device||``,a=n.id||n.output_id||``,o=r?`${r}/${a}`:a||`remote_out_${e}`;t.push({id:o,name:n.name||n.id||a,area:n.area||void 0,type:`remote_output`,remoteDevice:r,outputType:n.output_type})}return t}function P({inputs:e,outputs:t,t:n}){let r=e.filter(e=>e.type===`local`),i=e.filter(e=>e.type===`remote`),a=t.filter(e=>e.type===`output`),o=t.filter(e=>e.type===`cover`),s=t.filter(e=>e.type===`remote_output`||e.type===`remote_cover`),c=r.filter(e=>e.bindings.length>0),l=i.filter(e=>e.bindings.length>0),u=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),d=a.filter(e=>u.has(e.id)),f=o.filter(e=>u.has(e.id)),p=s.filter(e=>u.has(e.id)),m=e.reduce((e,t)=>e+t.bindings.length,0);return(0,S.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-4 gap-3 mb-4`,children:[(0,S.jsxs)(`div`,{className:`bg-base-200/50 rounded-xl p-3 border border-base-300 space-y-1`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-base-content/50`,children:n(`binding_matrix.local`)}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📥 `,n(`binding_matrix.inputs`),`: `,r.length,(0,S.jsxs)(`span`,{className:`text-success ml-1`,children:[`(`,c.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,r.length-c.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`💡 `,n(`binding_matrix.outputs`),`: `,a.length,(0,S.jsxs)(`span`,{className:`text-success ml-1`,children:[`(`,d.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,a.length-d.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`🚪 `,n(`binding_matrix.covers`),`: `,o.length,(0,S.jsxs)(`span`,{className:`text-success ml-1`,children:[`(`,f.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,o.length-f.length,` ○)`]})]})]}),(i.length>0||s.length>0)&&(0,S.jsxs)(`div`,{className:`bg-info/5 rounded-xl p-3 border border-info/20 space-y-1`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-info/70`,children:n(`binding_matrix.remote`)}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📥 `,n(`binding_matrix.inputs`),`: `,i.length,(0,S.jsxs)(`span`,{className:`text-success ml-1`,children:[`(`,l.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,i.length-l.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📡 `,n(`binding_matrix.outputs`),`: `,s.length,(0,S.jsxs)(`span`,{className:`text-success ml-1`,children:[`(`,p.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,s.length-p.length,` ○)`]})]})]}),(0,S.jsxs)(`div`,{className:`bg-primary/5 rounded-xl p-3 border border-primary/20 flex flex-col justify-center`,children:[(0,S.jsx)(`p`,{className:`text-2xl font-extrabold text-primary`,children:m}),(0,S.jsx)(`p`,{className:`text-xs font-medium text-primary/70`,children:n(`binding_matrix.total_bindings`)})]}),(0,S.jsxs)(`div`,{className:`bg-base-200/50 rounded-xl p-3 border border-base-300`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-base-content/50 mb-1.5`,children:n(`binding_matrix.legend`)}),(0,S.jsx)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-0.5`,children:E.map(e=>(0,S.jsxs)(`span`,{className:`text-xxs text-base-content/60`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/80`,children:e.icon}),` `,n(e.labelKey)]},e.key))}),(0,S.jsx)(`div`,{className:`border-t border-base-300 mt-1.5 pt-1.5 grid grid-cols-3 gap-x-2 gap-y-0.5`,children:D.map(e=>(0,S.jsxs)(`span`,{className:`text-xxs text-base-content/60`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/80`,children:n(e.shortKey)}),` `,n(e.labelKey)]},e.shortKey))})]})]})}function F({inputs:e,outputs:t,t:n}){let[r,i]=(0,b.useState)(!0),[a,c]=(0,b.useState)(!0),l=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),u=e.filter(e=>e.type===`local`&&e.bindings.length===0),d=t.filter(e=>e.type===`output`&&!l.has(e.id)),f=t.filter(e=>e.type===`cover`&&!l.has(e.id)),p=e.filter(e=>e.type===`remote`&&e.bindings.length===0),h=t.filter(e=>(e.type===`remote_output`||e.type===`remote_cover`)&&!l.has(e.id)),g=u.length>0||d.length>0||f.length>0,_=p.length>0||h.length>0;return!g&&!_?null:(0,S.jsxs)(`div`,{className:`mt-4 space-y-3`,children:[g&&(0,S.jsxs)(`div`,{className:`border border-warning/20 rounded-xl bg-warning/5 overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm font-semibold text-warning hover:bg-warning/10 transition-colors`,onClick:()=>i(!r),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(s,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_local`)]}),r?(0,S.jsx)(o,{className:`w-3 h-3`}):(0,S.jsx)(m,{className:`w-3 h-3`})]}),r&&(0,S.jsxs)(`div`,{className:`p-3 pt-0 space-y-2`,children:[u.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_inputs`)} (${u.length})`,items:u.map(e=>({id:e.id,name:e.name,area:e.area}))}),d.length>0&&(0,S.jsx)(I,{title:`💡 ${n(`binding_matrix.free_outputs`)} (${d.length})`,items:d.map(e=>({id:e.id,name:e.name,area:e.area}))}),f.length>0&&(0,S.jsx)(I,{title:`🚪 ${n(`binding_matrix.free_covers`)} (${f.length})`,items:f.map(e=>({id:e.id,name:e.name,area:e.area}))})]})]}),_&&(0,S.jsxs)(`div`,{className:`border border-info/20 rounded-xl bg-info/5 overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm font-semibold text-info hover:bg-info/10 transition-colors`,onClick:()=>c(!a),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(s,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_remote`)]}),a?(0,S.jsx)(o,{className:`w-3 h-3`}):(0,S.jsx)(m,{className:`w-3 h-3`})]}),a&&(0,S.jsxs)(`div`,{className:`p-3 pt-0 space-y-2`,children:[p.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_remote_inputs`)} (${p.length})`,items:p.map(e=>({id:e.id,name:e.name,area:e.area,badge:e.remoteDevice}))}),h.length>0&&(0,S.jsx)(I,{title:`📡 ${n(`binding_matrix.free_remote_outputs`)} (${h.length})`,items:h.map(e=>({id:e.id,name:e.name,area:e.area,badge:e.remoteDevice}))})]})]})]})}function I({title:e,items:t}){return(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`p`,{className:`text-xs font-semibold text-base-content/60 mb-1`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:t.map(e=>(0,S.jsxs)(`span`,{className:`badge badge-sm badge-ghost text-xxs font-mono gap-1`,title:e.id,children:[e.name,e.area&&(0,S.jsxs)(`span`,{className:`text-base-content/40`,children:[`(`,e.area,`)`]}),e.badge&&(0,S.jsxs)(`span`,{className:`text-info/60`,children:[`[`,e.badge,`]`]})]},e.id))})]})}function ee({inputs:e,outputs:t,areaFilter:n,hideEmpty:r,t:i,onEditInput:a,onEditOutput:o}){let[s,c]=(0,b.useState)(null),[l,u]=(0,b.useState)(null),d=(0,b.useRef)(null),f=(0,b.useRef)(!1),p=(0,b.useRef)(!1),m=(0,b.useRef)(0),_=(0,b.useRef)(0),[v,y]=(0,b.useState)(null),x=(0,b.useRef)(null),w=(0,b.useCallback)((e,t,n)=>{n||(e.preventDefault(),y({x:e.clientX,y:e.clientY,row:t}))},[]),T=(0,b.useCallback)((e,t,n)=>{if(n)return;let r=`touches`in e?{x:e.touches[0].clientX,y:e.touches[0].clientY}:{x:e.clientX,y:e.clientY};x.current=setTimeout(()=>{y({...r,row:t}),x.current=null},500)},[]),D=(0,b.useCallback)(()=>{x.current&&=(clearTimeout(x.current),null)},[]);(0,b.useEffect)(()=>{if(!v)return;let e=null,t=requestAnimationFrame(()=>{let t=()=>y(null);window.addEventListener(`click`,t,{capture:!0}),window.addEventListener(`contextmenu`,t,{capture:!0}),window.addEventListener(`scroll`,t,!0),e=()=>{window.removeEventListener(`click`,t,{capture:!0}),window.removeEventListener(`contextmenu`,t,{capture:!0}),window.removeEventListener(`scroll`,t,!0)}});return()=>{cancelAnimationFrame(t),e?.()}},[v]);let O=(0,b.useMemo)(()=>{let e=new Map;for(let n of t)e.set(n.id,n.area);return e},[t]),j=(0,b.useMemo)(()=>{let t=e;return n.size>0&&(t=t.filter(e=>{let t=e.area||`__none__`;return n.has(t)?!0:e.bindings.some(e=>{let t=O.get(e.targetId)||`__none__`;return n.has(t)})})),r&&(t=t.filter(e=>e.bindings.length>0)),t},[e,n,r,O]),M=(0,b.useMemo)(()=>new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),[e]),N=(0,b.useMemo)(()=>{let t=new Map;for(let n of e){let e=n.area||`__none__`;for(let r of n.bindings)t.has(r.targetId)||t.set(r.targetId,new Set),t.get(r.targetId).add(e)}return t},[e]),P=(0,b.useMemo)(()=>{let e=t;return n.size>0&&(e=e.filter(e=>{let t=e.area||`__none__`;if(n.has(t))return!0;let r=N.get(e.id);if(r){for(let e of r)if(n.has(e))return!0}return!1})),r&&(e=e.filter(e=>M.has(e.id))),e},[t,n,r,M,N]),F=(0,b.useMemo)(()=>{let e=new Map;for(let t of j){let n=new Map;for(let e of t.bindings){let t=n.get(e.targetId)||[];t.push(e),n.set(e.targetId,t)}e.set(t.id,n)}return e},[j]);return j.length===0||P.length===0?(0,S.jsx)(`div`,{className:`text-center py-12 text-base-content/40`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:i(`binding_matrix.no_data`)})}):(0,S.jsxs)(`div`,{ref:d,className:`overflow-x-auto rounded-xl border border-base-300 cursor-grab active:cursor-grabbing select-none`,onMouseDown:e=>{f.current=!0,p.current=!1,m.current=e.clientX,_.current=d.current?.scrollLeft||0},onMouseMove:e=>{if(!f.current||!d.current)return;let t=e.clientX-m.current;!p.current&&Math.abs(t)>5&&(p.current=!0),p.current&&(d.current.scrollLeft=_.current-t)},onMouseUp:()=>{f.current=!1,p.current=!1},onMouseLeave:()=>{f.current=!1,p.current=!1},onClickCapture:e=>{p.current&&(e.stopPropagation(),e.preventDefault())},children:[(0,S.jsxs)(`table`,{className:`table table-xs w-auto`,children:[(0,S.jsx)(`thead`,{children:(0,S.jsxs)(`tr`,{children:[(0,S.jsx)(`th`,{className:`sticky left-0 z-20 bg-base-200 border-r border-base-300 min-w-[120px]`}),P.map(e=>(0,S.jsxs)(`th`,{className:h(`text-center text-xxs font-bold px-2 py-2 min-w-[80px] border-r border-base-300 bg-base-200 cursor-pointer group/col whitespace-nowrap`,l===e.id&&`bg-primary/10`),onMouseEnter:()=>u(e.id),onMouseLeave:()=>u(null),onClick:()=>o(e),title:i(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-center gap-1`,children:[(0,S.jsx)(C,{outputType:e.outputType,className:`w-3 h-3 shrink-0`}),(0,S.jsx)(`span`,{className:`whitespace-nowrap`,children:e.name}),(0,S.jsx)(g,{className:`w-2 h-2 opacity-0 group-hover/col:opacity-40 transition-opacity shrink-0`})]}),e.area?(0,S.jsx)(`div`,{className:`text-xxs font-normal text-base-content/40 truncate`,children:e.area}):(0,S.jsx)(`div`,{className:`text-xxs font-normal text-base-content/20`,children:`—`}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`text-xxs font-normal text-info/50 truncate`,children:e.remoteDevice})]},e.id))]})}),(0,S.jsx)(`tbody`,{children:j.map(e=>{let t=F.get(e.id);return(0,S.jsxs)(`tr`,{className:h(`hover:bg-base-200/50`,s===e.id&&`bg-base-200/40`),onMouseEnter:()=>c(e.id),onMouseLeave:()=>c(null),children:[(0,S.jsxs)(`td`,{className:h(`sticky left-0 z-10 bg-base-100 border-r border-base-300 font-medium text-xs cursor-pointer group/row`,s===e.id&&`bg-base-200/60`,e.bindings.length===0&&`text-base-content/30`),onClick:()=>a(e),title:i(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`font-bold truncate max-w-[120px] flex items-center gap-1`,title:e.id,children:[e.name,(0,S.jsx)(g,{className:`w-2.5 h-2.5 opacity-0 group-hover/row:opacity-40 transition-opacity shrink-0`})]}),e.area&&(0,S.jsx)(`div`,{className:`text-xxs text-base-content/40`,children:e.area}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`text-xxs text-info/50`,children:e.remoteDevice})]}),P.map(n=>{let r=t?.get(n.id)||[],o=s===e.id||l===n.id;return(0,S.jsx)(`td`,{className:h(`text-center text-xs border-r border-base-300 px-1 py-1`,r.length>0?`bg-success/15 text-success font-medium`:`text-base-content/30`,o&&r.length>0&&`bg-success/25`,o&&r.length===0&&`bg-base-200/40`),onMouseEnter:()=>u(n.id),onMouseLeave:()=>{u(null),D()},onContextMenu:t=>w(t,e,r.length>0),onMouseDown:t=>{t.button===0&&T(t,e,r.length>0)},onMouseUp:D,onTouchStart:t=>T(t,e,r.length>0),onTouchEnd:D,onTouchMove:D,children:r.length>0&&(0,S.jsx)(`div`,{className:`flex flex-col gap-0.5`,children:r.map((t,n)=>(0,S.jsx)(`button`,{className:`whitespace-nowrap cursor-pointer hover:bg-success/30 rounded px-0.5 transition-colors text-left`,onClick:()=>a(e,t.clickType),title:`${A(t,i)}\n${i(`binding_matrix.click_to_edit`)}`,children:k(t,i)},n))})},n.id)})]},e.id)})})]}),v&&(0,S.jsxs)(`div`,{className:`fixed z-50 bg-base-100 border border-base-300 rounded-lg shadow-xl py-1 min-w-[180px] animate-in fade-in zoom-in-95 duration-100`,style:{left:v.x,top:v.y},onClick:e=>e.stopPropagation(),children:[(0,S.jsx)(`div`,{className:`px-3 py-1.5 text-xxs font-semibold text-base-content/40 uppercase tracking-wider`,children:i(`binding_matrix.add_action`)}),E.map(e=>(0,S.jsxs)(`button`,{className:`w-full text-left px-3 py-1.5 text-sm hover:bg-primary/10 transition-colors flex items-center gap-2`,onClick:()=>{a(v.row,e.key),y(null)},children:[(0,S.jsx)(`span`,{className:`font-mono text-base-content/70`,children:e.icon}),i(`binding_matrix.legend_${e.key}`)]},e.key))]})]})}function te({inputs:e,areaFilter:t,hideEmpty:n,t:r,onEditInput:i}){let[a,s]=(0,b.useState)(null),c=(0,b.useMemo)(()=>{let r=e;return t.size>0&&(r=r.filter(e=>{let n=e.area||`__none__`;return t.has(n)})),n&&(r=r.filter(e=>e.bindings.length>0)),r},[e,t,n]),l=(0,b.useCallback)(e=>{s(t=>t===e?null:e)},[]);return c.length===0?(0,S.jsx)(`div`,{className:`text-center py-12 text-base-content/40`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:r(`binding_matrix.no_data`)})}):(0,S.jsx)(`div`,{className:`space-y-1.5`,children:c.map(e=>{let t=a===e.id,n=e.bindings.length>0,s=new Map;for(let t of e.bindings){let e=s.get(t.targetId)||[];e.push(t),s.set(t.targetId,e)}return(0,S.jsxs)(`div`,{className:h(`rounded-xl border overflow-hidden transition-colors`,n?`border-success/20 bg-success/5`:`border-base-300 bg-base-200/30`),children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm hover:bg-base-200/30 transition-colors`,onClick:()=>n&&l(e.id),disabled:!n,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[n?(0,S.jsx)(_,{className:`w-3.5 h-3.5 text-success shrink-0`}):(0,S.jsx)(u,{className:`w-3.5 h-3.5 text-base-content/20 shrink-0`}),(0,S.jsxs)(`div`,{className:`min-w-0 text-left`,children:[(0,S.jsx)(`span`,{className:h(`font-semibold truncate block`,!n&&`text-base-content/30`),children:e.name}),e.area&&(0,S.jsx)(`span`,{className:`text-xxs text-base-content/40`,children:e.area})]})]}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[n&&(0,S.jsx)(`span`,{className:`badge badge-sm badge-success font-bold`,children:e.bindings.length}),e.type===`remote`&&(0,S.jsx)(`span`,{className:`badge badge-xs badge-info font-mono`,children:e.remoteDevice}),n&&(t?(0,S.jsx)(o,{className:`w-3 h-3 text-base-content/30`}):(0,S.jsx)(m,{className:`w-3 h-3 text-base-content/30`}))]})]}),t&&n&&(0,S.jsxs)(`div`,{className:`border-t border-base-300 p-3 space-y-2 bg-base-100/50`,children:[[...s.entries()].map(([e,t])=>(0,S.jsxs)(`div`,{className:`flex items-start gap-2 text-xs`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/70 shrink-0 mt-0.5`,children:`→`}),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`span`,{className:`font-semibold`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1 mt-0.5`,children:t.map((e,t)=>(0,S.jsx)(`span`,{className:`badge badge-xs badge-success font-mono gap-0.5`,children:k(e,r)},t))})]})]},e)),(0,S.jsxs)(`button`,{className:`btn btn-xs btn-primary btn-outline gap-1 mt-1`,onClick:t=>{t.stopPropagation(),i(e)},children:[(0,S.jsx)(g,{className:`w-2.5 h-2.5`}),r(`binding_matrix.edit_input`)]})]})]},e.id)})})}var L=({formData:e,sections:t,onSaveSection:n,onUpdateFormData:i})=>{let{t:o}=r(),[s,c]=(0,b.useState)(new Set),[l,u]=(0,b.useState)(!1),[f,p]=(0,b.useState)(!1),[h,g]=(0,b.useState)(!1),[_,x]=(0,b.useState)(null),[C,w]=(0,b.useState)(``),[T,E]=(0,b.useState)(-1),[D,k]=(0,b.useState)(`basic`),[A,j]=(0,b.useState)(!1),[I,L]=(0,b.useState)(!1),R=(0,b.useRef)(null),[ne,z]=(0,b.useState)(!1),[B,V]=(0,b.useState)(null),[H,re]=(0,b.useState)(``),[U,ie]=(0,b.useState)(-1),[ae,W]=(0,b.useState)(!1),G=(0,b.useRef)(null),K=(0,b.useCallback)((t,n)=>{let r=t.type===`remote`?`remote_inputs`:`local_inputs`,i=e[r]||[],a=i.findIndex((e,n)=>{if(t.type===`remote`){let r=e.boneio_id||e.remote_device||``,i=e.id||e.entity_id||``;return(r?`${r}/${i}`:i||`remote_${n}`)===t.id}return(e.id||e.pin||`local_${n}`)===t.id});a<0||(w(r),E(a),x(JSON.parse(JSON.stringify(i[a]))),R.current=JSON.stringify(i[a]),k(n&&O[n]||`basic`),j(!1),g(!0))},[e]),oe=(0,b.useCallback)(async()=>{if(A||T<0||!_)return;let t=[...e[C]||[]];t[T]=_,L(!0);try{i(C,t),await n(C,t),g(!1),x(null)}catch(e){console.error(`Failed to save input:`,e)}finally{L(!1)}},[_,T,C,e,A,n,i]),se=(0,b.useCallback)(()=>{g(!1),x(null)},[]),q=(0,b.useMemo)(()=>M(e),[e]),J=(0,b.useMemo)(()=>N(e),[e]),ce=(0,b.useMemo)(()=>{let e=new Set;return q.forEach(t=>{t.area&&e.add(t.area)}),J.forEach(t=>{t.area&&e.add(t.area)}),[...e].sort()},[q,J]),le=(0,b.useMemo)(()=>q.some(e=>!e.area)||J.some(e=>!e.area),[q,J]),Y=(0,b.useMemo)(()=>e.output||[],[e.output]),X=(0,b.useMemo)(()=>e.cover||[],[e.cover]),Z=(0,b.useMemo)(()=>e.output_group||[],[e.output_group]),ue=(0,b.useMemo)(()=>e.remote_devices||[],[e.remote_devices]),de=(0,b.useMemo)(()=>(e.local_inputs||[]).filter(e=>e._inputType===`binary_sensor`),[e.local_inputs]),Q=(0,b.useMemo)(()=>(e.local_inputs||[]).filter(e=>e._inputType!==`binary_sensor`),[e.local_inputs]),$=(0,b.useMemo)(()=>e.areas||[],[e.areas]),fe=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`local_inputs`);return e?.schema||e?.normalizedSchema||{}},[t]),pe=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`output`);return e?.schema||e?.normalizedSchema||{}},[t]),me=(0,b.useMemo)(()=>t.find(e=>e.name===`output`)?.uiSchema||{},[t]),he=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`cover`);return e?.schema||e?.normalizedSchema||{}},[t]),ge=(0,b.useCallback)(t=>{let n={output:`output`,cover:`cover`,remote_output:`remote_outputs`,remote_cover:`remote_covers`}[t.type]||`output`,r=e[n]||[],i=r.findIndex((e,n)=>{if(t.type===`remote_output`||t.type===`remote_cover`){let r=e.boneio_id||e.remote_device||``,i=e.id||e.output_id||``;return(r?`${r}/${i}`:i||`remote_out_${n}`)===t.id}return(e.id||``)===t.id});i<0||(re(n),ie(i),V(JSON.parse(JSON.stringify(r[i]))),G.current=JSON.stringify(r[i]),z(!0))},[e]),_e=(0,b.useCallback)(async()=>{if(U<0||!B)return;let t=[...e[H]||[]];t[U]=B,W(!0);try{i(H,t),await n(H,t),z(!1),V(null)}catch(e){console.error(`Failed to save output:`,e)}finally{W(!1)}},[B,U,H,e,n,i]),ve=(0,b.useCallback)(()=>{z(!1),V(null)},[]),ye=_&&R.current&&JSON.stringify(_)!==R.current,be=B&&G.current&&JSON.stringify(B)!==G.current;return(0,S.jsxs)(`div`,{className:`p-4 md:p-6 max-w-full`,children:[(0,S.jsxs)(`div`,{className:`mb-4`,children:[(0,S.jsx)(`h2`,{className:`text-xl font-extrabold tracking-tight`,children:o(`binding_matrix.title`)}),(0,S.jsx)(`p`,{className:`text-sm text-base-content/50`,children:o(`binding_matrix.subtitle`)})]}),(0,S.jsx)(P,{inputs:q,outputs:J,t:o}),(0,S.jsxs)(`div`,{className:`flex flex-wrap gap-3 mb-4 items-center`,children:[(0,S.jsxs)(`div`,{className:`relative flex items-center gap-2`,children:[(0,S.jsx)(d,{className:`w-3 h-3 text-base-content/40`}),(0,S.jsxs)(`button`,{className:`btn btn-sm btn-outline gap-1 min-w-[160px] justify-between`,onClick:()=>u(e=>!e),children:[(0,S.jsx)(`span`,{className:`truncate text-xs`,children:s.size===0?o(`binding_matrix.all_areas`):s.size===1?s.has(`__none__`)?o(`binding_matrix.no_area`):[...s][0]:o(`binding_matrix.areas_selected`,{count:s.size})}),(0,S.jsx)(m,{className:`w-2.5 h-2.5 shrink-0`})]}),l&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>u(!1)}),(0,S.jsxs)(`div`,{className:`absolute top-full left-0 mt-1 z-50 bg-base-100 border border-base-300 rounded-lg shadow-xl py-1 min-w-[200px] max-h-[300px] overflow-y-auto`,children:[(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.size===0,onChange:()=>c(new Set)}),(0,S.jsx)(`span`,{className:`text-xs font-semibold`,children:o(`binding_matrix.all_areas`)})]}),(0,S.jsx)(`div`,{className:`border-t border-base-300 my-0.5`}),le&&(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.has(`__none__`),onChange:()=>{let e=new Set(s);e.has(`__none__`)?e.delete(`__none__`):e.add(`__none__`),c(e)}}),(0,S.jsx)(`span`,{className:`text-xs italic text-base-content/50`,children:o(`binding_matrix.no_area`)})]}),ce.map(e=>(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.has(e),onChange:()=>{let t=new Set(s);t.has(e)?t.delete(e):t.add(e),c(t)}}),(0,S.jsx)(`span`,{className:`text-xs`,children:e})]},e))]})]})]}),(0,S.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-sm checkbox-primary`,checked:f,onChange:e=>p(e.target.checked)}),(0,S.jsxs)(`span`,{className:`text-xs font-medium text-base-content/60 flex items-center gap-1`,children:[f?(0,S.jsx)(a,{className:`w-3 h-3`}):(0,S.jsx)(v,{className:`w-3 h-3`}),o(`binding_matrix.hide_empty`)]})]})]}),(0,S.jsx)(`div`,{className:`hidden md:block`,children:(0,S.jsx)(ee,{inputs:q,outputs:J,areaFilter:s,hideEmpty:f,t:o,onEditInput:K,onEditOutput:ge})}),(0,S.jsx)(`div`,{className:`md:hidden`,children:(0,S.jsx)(te,{inputs:q,areaFilter:s,hideEmpty:f,t:o,onEditInput:K})}),(0,S.jsx)(F,{inputs:q,outputs:J,t:o}),(0,S.jsx)(y,{open:h,onOpenChange:g,editingItem:_,editingIndex:T,sectionType:C,schema:C===`remote_inputs`?t.find(e=>e.name===`remote_inputs`)?.schema||t.find(e=>e.name===`remote_inputs`)?.normalizedSchema||{}:fe,allBinarySensors:de,allEvents:Q,allOutputs:Y,allOutputGroups:Z,allCovers:X,allAreas:$,allRemoteDevices:ue,savedOutputs:Y,savedOutputGroups:Z,savedCovers:X,onChange:x,onSave:oe,onCancel:se,onValidationChange:j,saveDisabled:A||!ye,isSaving:I,initialTab:D}),(0,S.jsx)(y,{open:ne,onOpenChange:z,editingItem:B,editingIndex:U,sectionType:H,schema:H===`cover`?he:pe,uiSchema:H===`cover`?void 0:me,allOutputs:Y,allCovers:X,allAreas:$,onChange:V,onSave:_e,onCancel:ve,saveDisabled:!be,isSaving:ae})]})};export{L as default};
@@ -0,0 +1 @@
1
+ import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{a as t,c as n,i as r,n as i,o as a,r as o,t as s}from"./monaco-61yH0vfd.js";import{y as c}from"./vendor-DjFmndpd.js";import{r as l,t as u}from"./useTranslation-CMe3OXqd.js";import{S as d,Wt as f,_t as p,b as m,gt as h,vt as g}from"./index-CQtJKcCO.js";var _=e(n(),1);function v(){let[e,t]=(0,_.useState)(`dark`);return(0,_.useEffect)(()=>{t(localStorage.getItem(`theme`)||`dark`);let e=new MutationObserver(e=>{e.forEach(e=>{e.attributeName===`data-theme`&&t(document.documentElement.getAttribute(`data-theme`)||`dark`)})});return e.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-theme`]}),()=>e.disconnect()},[]),e}function y(e){return f({tag:`svg`,attr:{viewBox:`0 0 24 24`},child:[{tag:`path`,attr:{d:`M11.28 9.53 8.81 12l2.47 2.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-3-3a.75.75 0 0 1 0-1.06l3-3a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734Z`},child:[]},{tag:`path`,attr:{d:`M3.75 2h16.5c.966 0 1.75.784 1.75 1.75v16.5A1.75 1.75 0 0 1 20.25 22H3.75A1.75 1.75 0 0 1 2 20.25V3.75C2 2.784 2.784 2 3.75 2ZM3.5 3.75v16.5c0 .138.112.25.25.25H15v-17H3.75a.25.25 0 0 0-.25.25Zm13 16.75h3.75a.25.25 0 0 0 .25-.25V3.75a.25.25 0 0 0-.25-.25H16.5Z`},child:[]}]})(e)}var b=c();function x({isOpen:e,onClose:t}){let{t:n}=u(),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(null),s=async()=>{i(!0);try{let e=await l.get(`/api/check_configuration`);o({status:e.data.status,message:e.data.message})}catch{o({status:`error`,message:n(`config_check.failed`)})}finally{i(!1)}};return e?(0,b.jsx)(`div`,{className:`fixed inset-0 bg-base-300/80 flex items-center justify-center z-50`,children:(0,b.jsxs)(`div`,{className:`bg-base-200 p-8 rounded-lg shadow-lg max-w-2xl w-full mx-4`,children:[(0,b.jsx)(`h2`,{className:`text-2xl font-bold mb-6`,children:n(`config_check.title`)}),r?(0,b.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-8`,children:[(0,b.jsx)(`div`,{className:`loading loading-spinner loading-lg`}),(0,b.jsx)(`p`,{className:`text-lg`,children:n(`config_check.checking`)})]}):a?(0,b.jsxs)(`div`,{className:`space-y-4`,children:[(0,b.jsx)(`div`,{className:`text-lg font-semibold ${a.status===`success`?`text-success`:`text-error`}`,children:a.status===`success`?n(`config_check.valid`):n(`config_check.error`)}),a.message&&(0,b.jsx)(`pre`,{className:`bg-base-300 p-4 rounded-lg whitespace-pre-wrap`,children:a.message}),(0,b.jsxs)(`div`,{className:`flex justify-end gap-4 mt-6`,children:[(0,b.jsx)(`button`,{className:`btn btn-ghost`,onClick:()=>{o(null),t()},children:n(`common.close`)}),(0,b.jsx)(`button`,{className:`btn btn-primary`,onClick:()=>{o(null),s()},children:n(`config_check.check_again`)})]})]}):(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(`p`,{className:`text-base-content/70`,children:n(`config_check.description`)}),(0,b.jsxs)(`div`,{className:`flex justify-end gap-4`,children:[(0,b.jsx)(`button`,{className:`btn btn-ghost`,onClick:t,children:n(`common.cancel`)}),(0,b.jsx)(`button`,{className:`btn btn-primary`,onClick:s,children:n(`config_check.check_button`)})]})]})]})}):null}function S(e){return new Worker(`/assets/yaml.worker-BKRoXlmz.js`,{name:e?.name})}self.MonacoEnvironment={getWorker(e,t){return t===`yaml`?new S:t===`json`?new s:new i}},a.config({monaco:r});var C;function w(){let[e,n]=(0,_.useState)([]),[r,i]=(0,_.useState)(null),[a,s]=(0,_.useState)(``),[c,u]=(0,_.useState)(!1),[f,S]=(0,_.useState)(`waiting`),[w,T]=(0,_.useState)(!0),[E,D]=(0,_.useState)(!1),O=v(),k=async()=>{try{n((await l.get(`/api/files`)).data.items)}catch(e){console.error(`Error loading directory:`,e)}},A=async e=>{try{let t=`/api/files/${encodeURIComponent(e)}`,n=await l.get(t);i(e),s(n.data.content),localStorage.setItem(`lastOpenedFile`,e)}catch(e){console.error(`Error loading file:`,e)}},j=async()=>{if(r)try{await l.put(`/api/files/${encodeURIComponent(r)}`,{content:a}),console.log(`File saved successfully`)}catch(e){console.error(`Error saving file:`,e)}},M=async e=>{if(!C){let t=(await l.get(`/schema/config.schema.json`)).data;C=await o(e,{enableSchemaRequest:!0,schemas:[{uri:window.location.origin+`/schema/config.schema.json`,fileMatch:[`config.yaml`,`config.yml`],schema:t},...Object.keys(t.properties).map(e=>({uri:window.location.origin+`/schema/${e}.schema.json`,fileMatch:[`${e}.yaml`,`${e}.yml`],schema:t.properties[e]}))],validate:!0})}},N=async(e,t)=>{e.addCommand(t.KeyMod.CtrlCmd|t.KeyCode.KeyS,()=>{j()})},P=e=>{n(t=>{let n=t=>t.map(t=>t.path===e?{...t,isOpen:!t.isOpen}:t.children?{...t,children:n(t.children)}:t);return n(t)})},F=(e,t=0)=>e.map(e=>{let n=t==0||e.isOpen;return(0,b.jsxs)(`div`,{children:[(0,b.jsxs)(`button`,{className:`flex items-center gap-2 w-full px-2 py-1 hover:bg-base-300 ${r===e.path?`bg-primary/10`:``}`,style:{paddingLeft:`${t*16+8}px`},onClick:()=>e.type===`file`?A(e.path):P(e.path),children:[e.type===`directory`&&(0,b.jsx)(`span`,{className:`text-xs`,children:n?(0,b.jsx)(m,{}):(0,b.jsx)(d,{})}),(0,b.jsx)(`span`,{className:`text-base-content/70`,children:e.type===`directory`?n?(0,b.jsx)(g,{}):(0,b.jsx)(p,{}):(0,b.jsx)(h,{})}),(0,b.jsx)(`span`,{className:`text-sm truncate`,children:e.name})]}),e.type===`directory`&&n&&e.children&&F(e.children,t+1)]},e.path)}),I=async()=>{try{return await l.get(`/api/files`),!0}catch{return!1}},L=async()=>{for(u(!0),S(`waiting`),await new Promise(e=>setTimeout(e,2e3)),S(`checking`);;){if(await I()){S(`ready`),await new Promise(e=>setTimeout(e,1e3)),u(!1),k();break}await new Promise(e=>setTimeout(e,1e3))}};return(0,_.useEffect)(()=>{(async()=>{await k();let e=localStorage.getItem(`lastOpenedFile`);e&&A(e)})()},[]),(0,b.jsxs)(`div`,{className:`flex h-full bg-base-300`,children:[c?(0,b.jsx)(`div`,{className:`fixed inset-0 bg-base-300/80 flex items-center justify-center z-50`,children:(0,b.jsxs)(`div`,{className:`bg-base-200 p-8 rounded-lg shadow-lg text-center`,children:[(0,b.jsx)(`div`,{className:`loading loading-spinner loading-lg mb-4`}),(0,b.jsxs)(`h2`,{className:`text-xl font-bold mb-4`,children:[f===`waiting`&&`Restarting Service...`,f===`checking`&&`Waiting for Service...`,f===`ready`&&`Service Restarted!`]}),(0,b.jsxs)(`p`,{className:`text-base-content/70`,children:[f===`waiting`&&`Initiating service restart`,f===`checking`&&`Checking if service is back online`,f===`ready`&&`Redirecting...`]})]})}):null,(0,b.jsxs)(`div`,{className:`${w?`w-64`:`w-0`} transition-all duration-300 bg-base-200 border-r border-base-content/10 overflow-hidden`,children:[(0,b.jsx)(`div`,{className:`p-2 text-sm font-semibold text-base-content/70 uppercase`,children:`Explorer`}),(0,b.jsx)(`div`,{className:`overflow-y-auto`,children:F(e)})]}),(0,b.jsxs)(`div`,{className:`flex-1 overflow-hidden flex flex-col h-full max-h-screen`,children:[(0,b.jsxs)(`div`,{className:`flex items-center p-2 border-b border-base-content/10`,children:[(0,b.jsx)(`button`,{onClick:()=>T(!w),className:`btn btn-ghost btn-sm p-1`,title:w?`Hide file tree`:`Show file tree`,children:(0,b.jsx)(y,{className:`h-5 w-5 opacity-70 transition-transform duration-200 ${w?``:`rotate-180`}`})}),r&&(0,b.jsx)(`span`,{className:`ml-2 text-sm opacity-70`,children:r})]}),(0,b.jsx)(`div`,{className:`flex-1 overflow-hidden`,children:(0,b.jsx)(t,{height:`100%`,width:`100%`,defaultLanguage:`yaml`,path:r||`config.yaml`,theme:O===`light`?`vs-light`:`vs-dark`,value:a,onChange:e=>s(e||``),onMount:N,beforeMount:M,options:{minimap:{enabled:!0},scrollBeyondLastLine:!1,fontSize:14,automaticLayout:!0,readOnly:!1,formatOnType:!0,formatOnPaste:!0,quickSuggestions:{other:!0,comments:!1,strings:!0}}})}),(0,b.jsxs)(`div`,{className:`h-12 bg-base-200 border-t border-base-content/10 flex items-center justify-end px-4 gap-4`,children:[(0,b.jsx)(`button`,{onClick:j,disabled:!r,className:`btn btn-primary btn-sm`,children:`Save`}),(0,b.jsx)(`button`,{onClick:()=>D(!0),className:`btn btn-primary btn-sm`,children:`Check Config`}),(0,b.jsx)(`button`,{onClick:async()=>{await j();try{if((await l.post(`/api/restart`)).data.status===`not available`){let e=document.getElementById(`toast`);e&&(e.classList.remove(`hidden`),setTimeout(()=>{e.classList.add(`hidden`)},5e3))}else console.log(`Service restarted successfully`),L()}catch(e){console.error(`Error restarting service:`,e)}},disabled:!r,className:`btn btn-secondary btn-sm`,children:`Save and Restart`})]})]}),(0,b.jsx)(`div`,{id:`toast`,className:`toast toast-end hidden`,children:(0,b.jsx)(`div`,{className:`alert alert-warning`,children:(0,b.jsx)(`span`,{children:`Restart not possible. Application is not running as systemd service. Restart manually.`})})}),(0,b.jsx)(x,{isOpen:E,onClose:()=>D(!1)})]})}export{w as default};