boneio 1.6.0.dev14__tar.gz → 1.6.0.dev15__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 (798) hide show
  1. {boneio-1.6.0.dev14/boneio.egg-info → boneio-1.6.0.dev15}/PKG-INFO +1 -1
  2. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/template/alarm_panel.py +142 -18
  3. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/const.py +1 -0
  4. boneio-1.6.0.dev15/boneio/core/atomic_file.py +113 -0
  5. {boneio-1.6.0.dev14/boneio/migrations/assets/docker/nodered → boneio-1.6.0.dev15/boneio/core/cloud/data}/docker-compose.yaml +1 -1
  6. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/migrations/__init__.py +3 -2
  7. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/migrations/v1_proxy_port.py +2 -2
  8. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/migrations/v2_transition.py +2 -2
  9. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/migrations/v4_wled_cache.py +2 -2
  10. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/migrations/v5_ina_screen.py +2 -2
  11. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/migrations/v6_input_keys.py +3 -2
  12. boneio-1.6.0.dev15/boneio/core/config/write_lock.py +16 -0
  13. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/yaml_patch.py +31 -5
  14. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/yaml_util.py +20 -7
  15. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/containers.py +30 -0
  16. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/canopen.py +87 -15
  17. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/manager.py +14 -2
  18. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/templates.py +18 -2
  19. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/lox.py +84 -1
  20. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/mqtt.py +26 -3
  21. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/security/posture.py +73 -0
  22. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/system_ops.py +54 -0
  23. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/can/node_id.py +3 -2
  24. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/integration/homeassistant.py +43 -0
  25. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/integration/lox_template.py +131 -2
  26. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/actions.py +20 -0
  27. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/MANIFEST.sha256 +9 -5
  28. boneio-1.6.0.dev15/boneio/migrations/assets/apt/52boneio-periodic +4 -0
  29. boneio-1.6.0.dev15/boneio/migrations/assets/apt/52boneio-unattended +33 -0
  30. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/docker/nodered/docker-compose-cloud.yaml +1 -1
  31. {boneio-1.6.0.dev14/boneio/core/cloud/data → boneio-1.6.0.dev15/boneio/migrations/assets/docker/nodered}/docker-compose.yaml +11 -4
  32. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/helpers/boneio-containers +113 -1
  33. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/helpers/boneio-migrate-v2 +61 -0
  34. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/helpers/boneio-system +639 -0
  35. boneio-1.6.0.dev15/boneio/migrations/assets/systemd/boneio-dpkg-recover.service +24 -0
  36. boneio-1.6.0.dev15/boneio/migrations/assets/systemd/dropins/apt-daily-priority.conf +10 -0
  37. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.3.0.json +1 -1
  38. boneio-1.6.0.dev15/boneio/migrations/plans/1.3.0.sig +1 -0
  39. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.4.4.json +1 -1
  40. boneio-1.6.0.dev15/boneio/migrations/plans/1.4.4.sig +0 -0
  41. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.15.json +1 -1
  42. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.15.sig +1 -0
  43. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.16.json +1 -0
  44. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.16.sig +0 -0
  45. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.17.json +1 -0
  46. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.17.sig +0 -0
  47. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.18.json +1 -0
  48. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.18.sig +0 -0
  49. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.19.json +1 -0
  50. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.19.sig +0 -0
  51. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.20.json +1 -0
  52. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.20.sig +0 -0
  53. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.21.json +1 -0
  54. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.21.sig +1 -0
  55. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.22.json +1 -0
  56. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.22.sig +1 -0
  57. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.5.json +1 -1
  58. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.5.sig +0 -0
  59. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.8.json +1 -1
  60. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.8.sig +1 -0
  61. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.9.json +1 -0
  62. boneio-1.6.0.dev15/boneio/migrations/plans/1.6.9.sig +1 -0
  63. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/manifest.json +1 -1
  64. boneio-1.6.0.dev15/boneio/migrations/plans/manifest.sig +1 -0
  65. boneio-1.6.0.dev15/boneio/migrations/versions/v1_6_18_os_updates.py +75 -0
  66. boneio-1.6.0.dev15/boneio/migrations/versions/v1_6_19_helper_apt_purge.py +58 -0
  67. boneio-1.6.0.dev15/boneio/migrations/versions/v1_6_20_drop_packagekit.py +54 -0
  68. boneio-1.6.0.dev15/boneio/migrations/versions/v1_6_21_caddy_pinned.py +68 -0
  69. boneio-1.6.0.dev15/boneio/migrations/versions/v1_6_22_security_autoupdates.py +104 -0
  70. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/qdw90a.json +2 -2
  71. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/actions.yaml +5 -3
  72. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/schema.yaml +5 -1
  73. boneio-1.6.0.dev15/boneio/version.py +2 -0
  74. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/action_validation.py +4 -0
  75. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/app.py +2 -0
  76. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/AccountsView-B5UZiRGW.js +1 -0
  77. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/AppInitContext-BFVuHdYV.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/AppInitContext-BeNfj23N.js +1 -1
  78. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/BackupSection-BMRPho1e.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/BackupSection-8GT7vpuH.js +1 -1
  79. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/BindingMatrix-CxQl1VOm.js +1 -0
  80. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/DeviceControlSection-akl63I0o.js +1 -0
  81. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/DiagnosticsView-CG4ax2y-.js +5 -0
  82. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/EntityGrid-Cv1Uo0zY.js +1 -0
  83. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/FactoryResetSection-BR2jvi92.js +1 -0
  84. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/FormInputToggle-aLYpUS-x.js +11 -0
  85. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/HaDashboardWizard-D_UVKWpT.js +1 -0
  86. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/HostnameSection-DW9-2qpm.js +1 -0
  87. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/InputsView-CGcgJgga.js +1 -0
  88. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/LocationSection-MPR1TTp9.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/LocationSection-w1b0toMH.js +2 -2
  89. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/LoggerForm-Cpld2Dm1.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/LoggerForm-CUYH8NgD.js +1 -1
  90. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/LongPressWrapper-CzUUPJt9.js +1 -0
  91. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/MigrationsSection-BzIAgtBk.js +1 -0
  92. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/ModbusView-BajWrYrq.js +1 -0
  93. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/MqttPasswordsSection-x25bWMgI.js +1 -0
  94. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/NodeRedManagement-35JRm9JH.js +1 -0
  95. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/NodeRedView-C_0IlqZ6.js +1 -0
  96. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/NumericInput-DGzxoNxg.js +1 -0
  97. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/OutputsView-BU85e0Ar.js +1 -0
  98. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/SecurityView-CeQj1X27.js +1 -0
  99. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/SensorView-Bs7Vou_q.js +1 -0
  100. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/Sparkline-BEqfa9XQ.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/Sparkline-IwpgUXqb.js +1 -1
  101. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/SystemState-RNXVYdNx.js +2 -0
  102. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/TemplatesView-DR9E5__-.js +1 -0
  103. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/TilePicker-BF276mfl.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/TilePicker-C413YRFn.js +1 -1
  104. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/TimezoneSection-CbzWiCHs.js +1 -0
  105. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/UISettings-r739sHGY.js +100 -0
  106. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/UpdateSafetyNotice-DBFx_ZD1.js +1 -0
  107. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/ViewToggle-NR-6vDt_.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/ViewToggle-CTm9ZUC_.js +1 -1
  108. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/aiConfig-C_B1zOY8.js +2 -0
  109. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/aiWizardPrompt-X9_lrmYw.js +2 -0
  110. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/bodies-LCcudJje.js +1 -0
  111. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/dialog-BoiNz97x.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/dialog-DUHsilMe.js +1 -1
  112. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/fa-Bo0hGcDa.js +1 -0
  113. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/gi-BnKGxudz.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/gi-BEb-YkSt.js +1 -1
  114. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/index-UQJ1vWT5.js +42 -0
  115. boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/index-bS3WyOSw.css +2 -0
  116. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/monaco-B-R6zL6B.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/monaco-BLbWyoLh.js +3 -3
  117. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/monaco-6YvBi37C.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/monaco-CSUyZZpP.js +1 -1
  118. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/select-DPcHU94h.js → boneio-1.6.0.dev15/boneio/webui/frontend-dist/assets/select-DCMFLjZt.js +1 -1
  119. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/index.html +5 -5
  120. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +6 -4
  121. {boneio-1.6.0.dev14/boneio/webui → boneio-1.6.0.dev15/boneio/webui/frontend-dist}/schema/config.schema.json +37 -25
  122. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/event.schema.json +21 -14
  123. {boneio-1.6.0.dev14/boneio/webui → boneio-1.6.0.dev15/boneio/webui/frontend-dist}/schema/schedule.schema.json +3 -2
  124. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/template.schema.json +1 -1
  125. {boneio-1.6.0.dev14/boneio/webui → boneio-1.6.0.dev15/boneio/webui/frontend-dist}/schema/virtual_switch.schema.json +6 -4
  126. boneio-1.6.0.dev15/boneio/webui/frontend-dist/sw.js +1 -0
  127. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/recovery/app.py +1 -21
  128. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/__init__.py +2 -0
  129. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/config_actions.py +296 -95
  130. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/config_core.py +10 -0
  131. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/config_files.py +3 -2
  132. boneio-1.6.0.dev15/boneio/webui/routes/os_update.py +181 -0
  133. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/security.py +80 -31
  134. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/system.py +9 -1
  135. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/templates.py +14 -1
  136. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/update.py +16 -12
  137. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/binary_sensor.schema.json +6 -4
  138. {boneio-1.6.0.dev14/boneio/webui/frontend-dist → boneio-1.6.0.dev15/boneio/webui}/schema/config.schema.json +37 -25
  139. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/event.schema.json +21 -14
  140. {boneio-1.6.0.dev14/boneio/webui/frontend-dist → boneio-1.6.0.dev15/boneio/webui}/schema/schedule.schema.json +3 -2
  141. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/template.schema.json +1 -1
  142. {boneio-1.6.0.dev14/boneio/webui/frontend-dist → boneio-1.6.0.dev15/boneio/webui}/schema/virtual_switch.schema.json +6 -4
  143. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15/boneio.egg-info}/PKG-INFO +1 -1
  144. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio.egg-info/SOURCES.txt +65 -42
  145. boneio-1.6.0.dev14/boneio/migrations/plans/1.3.0.sig +0 -0
  146. boneio-1.6.0.dev14/boneio/migrations/plans/1.4.4.sig +0 -1
  147. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.15.sig +0 -0
  148. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.16.json +0 -1
  149. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.16.sig +0 -1
  150. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.17.json +0 -1
  151. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.17.sig +0 -1
  152. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.5.sig +0 -1
  153. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.8.sig +0 -1
  154. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.9.json +0 -1
  155. boneio-1.6.0.dev14/boneio/migrations/plans/1.6.9.sig +0 -1
  156. boneio-1.6.0.dev14/boneio/migrations/plans/manifest.sig +0 -1
  157. boneio-1.6.0.dev14/boneio/version.py +0 -2
  158. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/AccountsView-b9cHQ2Ja.js +0 -1
  159. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/BindingMatrix-DNNr0bY-.js +0 -1
  160. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/DeviceControlSection-CZ8B2tdJ.js +0 -1
  161. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/DiagnosticsView-0TNIliLz.js +0 -5
  162. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/EntityCard-BjdIs2gm.js +0 -1
  163. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/EntityGrid-BLlo9M8D.js +0 -1
  164. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/FactoryResetSection-BCy9YTcG.js +0 -1
  165. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/FormInputToggle-CRZQ_P36.js +0 -11
  166. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/HaDashboardWizard-d9XVXE0y.js +0 -1
  167. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/HostnameSection-XOwK_W3H.js +0 -1
  168. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/InputsView-s9FgPsOr.js +0 -1
  169. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/LongPressWrapper-AJLU_XHN.js +0 -1
  170. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/MigrationsSection-CCWHkMXl.js +0 -1
  171. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/ModbusView-CYqwCIJI.js +0 -1
  172. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/MqttPasswordsSection-BB7rJgN6.js +0 -1
  173. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/NodeRedManagement-BPA0iU9M.js +0 -1
  174. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/NodeRedView-DyV1sQAw.js +0 -1
  175. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/OutputsView-BE4ErvD9.js +0 -1
  176. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/SecurityView-BLfGOLNh.js +0 -1
  177. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/SensorView-DAVxLLe8.js +0 -1
  178. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/SystemState-ByJOlcGy.js +0 -2
  179. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/TemplatesView-BLUQcVgO.js +0 -1
  180. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/TimezoneSection-DnpMCu6V.js +0 -1
  181. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/UISettings-D7YnpB9C.js +0 -100
  182. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/aiConfig-cP4JCqzO.js +0 -2
  183. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/aiWizardPrompt-uHuqfc9m.js +0 -2
  184. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/fa-DbkExr12.js +0 -1
  185. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/index-D_pSOr4m.css +0 -2
  186. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/index-u9hhGcIi.js +0 -48
  187. boneio-1.6.0.dev14/boneio/webui/frontend-dist/assets/longPress-Dx7OCSyP.js +0 -1
  188. boneio-1.6.0.dev14/boneio/webui/frontend-dist/sw.js +0 -1
  189. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/LICENSE +0 -0
  190. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/MANIFEST.in +0 -0
  191. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/README.md +0 -0
  192. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/__init__.py +0 -0
  193. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.2/input.yaml +0 -0
  194. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.2/output_24_16.yaml +0 -0
  195. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.2/output_32_10.yaml +0 -0
  196. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.2/output_32_5.yaml +0 -0
  197. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.2/output_cover.yaml +0 -0
  198. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  199. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.3/input.yaml +0 -0
  200. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.3/output_24_16.yaml +0 -0
  201. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.3/output_32_10.yaml +0 -0
  202. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.3/output_32_5.yaml +0 -0
  203. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.3/output_cover.yaml +0 -0
  204. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  205. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.4/input.yaml +0 -0
  206. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.4/output_24_16.yaml +0 -0
  207. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.4/output_32_10.yaml +0 -0
  208. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.4/output_32_5.yaml +0 -0
  209. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.4/output_cover.yaml +0 -0
  210. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  211. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.5/input.yaml +0 -0
  212. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.5/output_24_16.yaml +0 -0
  213. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.5/output_32_10.yaml +0 -0
  214. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.5/output_cover.yaml +0 -0
  215. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  216. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.6/input.yaml +0 -0
  217. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.6/output_24_16.yaml +0 -0
  218. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.6/output_32_10.yaml +0 -0
  219. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.6/output_cover.yaml +0 -0
  220. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  221. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.7/input.yaml +0 -0
  222. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.7/output_24_16.yaml +0 -0
  223. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.7/output_32_10.yaml +0 -0
  224. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.7/output_48_4.yaml +0 -0
  225. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.7/output_cover.yaml +0 -0
  226. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  227. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.8/input.yaml +0 -0
  228. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.8/output_24_16.yaml +0 -0
  229. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.8/output_32_10.yaml +0 -0
  230. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.8/output_48_4.yaml +0 -0
  231. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.8/output_cover.yaml +0 -0
  232. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  233. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.0/input.yaml +0 -0
  234. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.0/output_24_16.yaml +0 -0
  235. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.0/output_32_10.yaml +0 -0
  236. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.0/output_48_4.yaml +0 -0
  237. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.0/output_cover.yaml +0 -0
  238. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.0/output_cover_mix.yaml +0 -0
  239. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.1/input.yaml +0 -0
  240. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.1/output_24_16.yaml +0 -0
  241. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.1/output_32_10.yaml +0 -0
  242. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.1/output_48_4.yaml +0 -0
  243. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.1/output_cover.yaml +0 -0
  244. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/boards/1.1/output_cover_mix.yaml +0 -0
  245. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/bonecli.py +0 -0
  246. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/__init__.py +0 -0
  247. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/cover/__init__.py +0 -0
  248. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/cover/cover.py +0 -0
  249. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/cover/remote.py +0 -0
  250. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/cover/time_based.py +0 -0
  251. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/cover/venetian.py +0 -0
  252. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/group/__init__.py +0 -0
  253. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/group/output_group.py +0 -0
  254. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/__init__.py +0 -0
  255. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/binary_sensor.py +0 -0
  256. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/detectors.py +0 -0
  257. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/event.py +0 -0
  258. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/remote/__init__.py +0 -0
  259. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/remote/base.py +0 -0
  260. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/remote/esphome.py +0 -0
  261. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/input/remote/mqtt.py +0 -0
  262. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/irrigation/__init__.py +0 -0
  263. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/irrigation/controller.py +0 -0
  264. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/irrigation/water_source.py +0 -0
  265. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/output/__init__.py +0 -0
  266. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/output/basic.py +0 -0
  267. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/output/buzzer.py +0 -0
  268. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/output/mcp.py +0 -0
  269. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/output/pca.py +0 -0
  270. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/output/pcf.py +0 -0
  271. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/output/remote.py +0 -0
  272. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/sensor/__init__.py +0 -0
  273. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/sensor/virtual_energy.py +0 -0
  274. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/template/__init__.py +0 -0
  275. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/template/gate_cover.py +0 -0
  276. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/template/thermostat.py +0 -0
  277. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/components/virtual_switch.py +0 -0
  278. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/__init__.py +0 -0
  279. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/auth/__init__.py +0 -0
  280. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/auth/cli.py +0 -0
  281. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/auth/hashing.py +0 -0
  282. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/auth/jwt_secret.py +0 -0
  283. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/auth/migration.py +0 -0
  284. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/auth/models.py +0 -0
  285. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/auth/store.py +0 -0
  286. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/cloud/__init__.py +0 -0
  287. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/cloud/data/__init__.py +0 -0
  288. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
  289. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/cloud/registration.py +0 -0
  290. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/cloud/secrets.py +0 -0
  291. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/__init__.py +0 -0
  292. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/config_helper.py +0 -0
  293. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/input_bindings.py +0 -0
  294. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/package-lock.json +0 -0
  295. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/package.json +0 -0
  296. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/provenance.py +0 -0
  297. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/schema_converter.py +0 -0
  298. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/secret_masking.py +0 -0
  299. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/config/yaml_compat.py +0 -0
  300. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/diagnostics/__init__.py +0 -0
  301. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/diagnostics/collect.py +0 -0
  302. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/discovery.py +0 -0
  303. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/events/__init__.py +0 -0
  304. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/events/bus.py +0 -0
  305. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/__init__.py +0 -0
  306. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/action_conditions.py +0 -0
  307. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/covers.py +0 -0
  308. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/display.py +0 -0
  309. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/inputs.py +0 -0
  310. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/irrigation.py +0 -0
  311. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/modbus.py +0 -0
  312. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/outputs.py +0 -0
  313. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/remote.py +0 -0
  314. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/remote_input_registrar.py +0 -0
  315. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/scheduler.py +0 -0
  316. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/security_alert.py +0 -0
  317. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/sensors.py +0 -0
  318. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/sun.py +0 -0
  319. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/templates/__init__.py +0 -0
  320. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/templates/alarm.py +0 -0
  321. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/templates/gate_cover.py +0 -0
  322. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/templates/thermostat.py +0 -0
  323. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/update.py +0 -0
  324. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/manager/virtual_switches.py +0 -0
  325. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/__init__.py +0 -0
  326. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/basic.py +0 -0
  327. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/basic_mqtt.py +0 -0
  328. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/composite.py +0 -0
  329. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/local.py +0 -0
  330. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/messaging/queue.py +0 -0
  331. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/net/__init__.py +0 -0
  332. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/net/discovery_guard.py +0 -0
  333. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/recovery.py +0 -0
  334. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/remote/__init__.py +0 -0
  335. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/remote/base.py +0 -0
  336. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/remote/can.py +0 -0
  337. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/remote/esphome.py +0 -0
  338. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/remote/mqtt.py +0 -0
  339. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/remote/wled.py +0 -0
  340. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/remote/wled_cache.py +0 -0
  341. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/security/__init__.py +0 -0
  342. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/security/certificate.py +0 -0
  343. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/security/framing.py +0 -0
  344. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/sensor/__init__.py +0 -0
  345. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/sensor/base.py +0 -0
  346. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/sensor/sun.py +0 -0
  347. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/sensor/system.py +0 -0
  348. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/state/__init__.py +0 -0
  349. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/state/manager.py +0 -0
  350. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/system/__init__.py +0 -0
  351. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/system/host_data.py +0 -0
  352. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/system/monitor.py +0 -0
  353. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/__init__.py +0 -0
  354. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/async_updater.py +0 -0
  355. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/conditions.py +0 -0
  356. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/filter.py +0 -0
  357. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/font_util.py +0 -0
  358. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/logger.py +0 -0
  359. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/naming.py +0 -0
  360. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/overlay.py +0 -0
  361. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/sun.py +0 -0
  362. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/timeperiod.py +0 -0
  363. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/core/utils/util.py +0 -0
  364. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/24x16/adc.yaml +0 -0
  365. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  366. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/24x16/config.yaml +0 -0
  367. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/24x16/event.yaml +0 -0
  368. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/24x16/mqtt.yaml +0 -0
  369. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  370. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/32x10/adc.yaml +0 -0
  371. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  372. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/32x10/config.yaml +0 -0
  373. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/32x10/event.yaml +0 -0
  374. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/32x10/mqtt.yaml +0 -0
  375. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  376. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/48x4/adc.yaml +0 -0
  377. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
  378. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/48x4/config.yaml +0 -0
  379. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/48x4/event.yaml +0 -0
  380. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/48x4/mqtt.yaml +0 -0
  381. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/48x4/output48x4A.yaml +0 -0
  382. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/__init__.py +0 -0
  383. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/can_master.yaml +0 -0
  384. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/can_slave.yaml +0 -0
  385. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover/adc.yaml +0 -0
  386. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  387. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover/config.yaml +0 -0
  388. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover/cover.yaml +0 -0
  389. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover/event.yaml +0 -0
  390. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover/mqtt.yaml +0 -0
  391. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover/outputCover.yaml +0 -0
  392. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover_mix/adc.yaml +0 -0
  393. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  394. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover_mix/config.yaml +0 -0
  395. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover_mix/cover.yaml +0 -0
  396. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover_mix/event.yaml +0 -0
  397. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  398. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  399. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/adc.yaml +0 -0
  400. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  401. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  402. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  403. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  404. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/event_all.yaml +0 -0
  405. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  406. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  407. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  408. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  409. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  410. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  411. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/exceptions.py +0 -0
  412. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/__init__.py +0 -0
  413. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/analog/__init__.py +0 -0
  414. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/analog/adc.py +0 -0
  415. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/can/__init__.py +0 -0
  416. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/can/bridge.py +0 -0
  417. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/can/client.py +0 -0
  418. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/can/interface.py +0 -0
  419. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/can/node.py +0 -0
  420. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/can/test_od.py +0 -0
  421. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/display/__init__.py +0 -0
  422. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/display/early_oled.py +0 -0
  423. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  424. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/display/oled.py +0 -0
  425. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/__init__.py +0 -0
  426. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  427. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  428. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  429. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  430. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/input/__init__.py +0 -0
  431. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/input/base.py +0 -0
  432. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/gpio/input/manager.py +0 -0
  433. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/__init__.py +0 -0
  434. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/bus.py +0 -0
  435. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/ina219.py +0 -0
  436. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/ina219_driver.py +0 -0
  437. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/ina226.py +0 -0
  438. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/ina226_driver.py +0 -0
  439. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/mcp9808.py +0 -0
  440. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/i2c/pct2075.py +0 -0
  441. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/onewire/__init__.py +0 -0
  442. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/onewire/dallas.py +0 -0
  443. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/sensor/__init__.py +0 -0
  444. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  445. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/sensor/temperature/base.py +0 -0
  446. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  447. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  448. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/integration/__init__.py +0 -0
  449. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/integration/interlock.py +0 -0
  450. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/__init__.py +0 -0
  451. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/docker/daemon.json +0 -0
  452. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
  453. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
  454. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
  455. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/helpers/boneio-helpers-heal +0 -0
  456. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/issue.d/10-boneio.issue +0 -0
  457. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/journald/journald.conf +0 -0
  458. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/kernel/postinst-boneio-overlay +0 -0
  459. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/migrations-recovery.pem +0 -0
  460. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/migrations.pem +0 -0
  461. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/modules-load.d/onewire.conf +0 -0
  462. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
  463. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/sshd/10-boneio-hardening.conf +0 -0
  464. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/sudoers/boneio +0 -0
  465. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/sudoers/boneio-helpers +0 -0
  466. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/sudoers/boneio-timedatectl +0 -0
  467. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/boneio-helpers-heal.service +0 -0
  468. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
  469. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
  470. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/boneio.service +0 -0
  471. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/dropins/avahi-daemon-defer.conf +0 -0
  472. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/dropins/bb-usb-gadgets-defer.conf +0 -0
  473. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/dropins/mosquitto-priority.conf +0 -0
  474. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/dropins/timer-no-persistent.conf +0 -0
  475. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/dropins/user-manager-defer.conf +0 -0
  476. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/linger-marker +0 -0
  477. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
  478. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
  479. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
  480. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
  481. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
  482. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
  483. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/assets/wheels/pyyaml-6.0.3-cp313-cp313-linux_armv7l.whl +0 -0
  484. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/bootstrap/boneio-migrate +0 -0
  485. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/bootstrap/install-helper.sh +0 -0
  486. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
  487. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.3.1.json +0 -0
  488. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.3.1.sig +0 -0
  489. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.3.2.json +0 -0
  490. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.3.2.sig +0 -0
  491. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.4.0.json +0 -0
  492. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.4.0.sig +0 -0
  493. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.4.3.json +0 -0
  494. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.4.3.sig +0 -0
  495. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.0.json +0 -0
  496. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.0.sig +0 -0
  497. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.1.json +0 -0
  498. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.1.sig +0 -0
  499. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.10.json +0 -0
  500. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.10.sig +0 -0
  501. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.11.json +0 -0
  502. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.11.sig +0 -0
  503. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.12.json +0 -0
  504. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.12.sig +0 -0
  505. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.13.json +0 -0
  506. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.13.sig +0 -0
  507. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.14.json +0 -0
  508. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.14.sig +0 -0
  509. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.15.json +0 -0
  510. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.15.sig +0 -0
  511. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.16.json +0 -0
  512. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.16.sig +0 -0
  513. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.17.json +0 -0
  514. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.17.sig +0 -0
  515. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.18.json +0 -0
  516. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.18.sig +0 -0
  517. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.2.json +0 -0
  518. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.2.sig +0 -0
  519. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.3.json +0 -0
  520. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.3.sig +0 -0
  521. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.4.json +0 -0
  522. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.4.sig +0 -0
  523. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.5.json +0 -0
  524. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.5.sig +0 -0
  525. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.6.json +0 -0
  526. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.6.sig +0 -0
  527. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.7.json +0 -0
  528. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.7.sig +0 -0
  529. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.8.json +0 -0
  530. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.8.sig +0 -0
  531. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.9.json +0 -0
  532. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.5.9.sig +0 -0
  533. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.0.json +0 -0
  534. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.0.sig +0 -0
  535. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.1.json +0 -0
  536. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.1.sig +0 -0
  537. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.10.json +0 -0
  538. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.10.sig +0 -0
  539. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.11.json +0 -0
  540. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.11.sig +0 -0
  541. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.12.json +0 -0
  542. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.12.sig +0 -0
  543. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.13.json +0 -0
  544. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.13.sig +0 -0
  545. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.14.json +0 -0
  546. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.14.sig +0 -0
  547. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.2.json +0 -0
  548. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.2.sig +0 -0
  549. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.3.json +0 -0
  550. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.3.sig +0 -0
  551. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.4.json +0 -0
  552. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.4.sig +0 -0
  553. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.6.json +0 -0
  554. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.6.sig +0 -0
  555. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.7.json +0 -0
  556. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/plans/1.6.7.sig +0 -0
  557. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/runner.py +0 -0
  558. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/__init__.py +0 -0
  559. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
  560. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
  561. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
  562. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
  563. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
  564. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
  565. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
  566. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_10_disable_console_setup.py +0 -0
  567. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_11_timer_catchup.py +0 -0
  568. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_12_oled_splash_off_critical_path.py +0 -0
  569. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_13_mosquitto_priority.py +0 -0
  570. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_14_journal_apparent_size.py +0 -0
  571. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_15_prune_orphan_journals.py +0 -0
  572. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_16_login_linger.py +0 -0
  573. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_17_defer_user_manager.py +0 -0
  574. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_18_fix_hostname_once.py +0 -0
  575. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_1_ufw_lox_udp.py +0 -0
  576. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_2_libyaml.py +0 -0
  577. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_3_libyaml_retry.py +0 -0
  578. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_4_onewire_modules.py +0 -0
  579. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_5_overlay_kernel_hook.py +0 -0
  580. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_6_boot_service_order.py +0 -0
  581. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_7_journald_limits.py +0 -0
  582. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_8_apparmor_prune.py +0 -0
  583. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_5_9_defer_nonessential.py +0 -0
  584. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_0_nodered_admin_auth.py +0 -0
  585. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_10_narrow_sudo_rules.py +0 -0
  586. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_11_drop_docker_group.py +0 -0
  587. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_12_console_shows_ip.py +0 -0
  588. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_13_custom_certificate.py +0 -0
  589. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_14_certificate_lifetime.py +0 -0
  590. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_15_web_port_reaches_caddy.py +0 -0
  591. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_16_release_floor_ordering.py +0 -0
  592. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_17_service_password.py +0 -0
  593. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_1_mosquitto_passwd_perms.py +0 -0
  594. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_2_drop_build_sudo_rule.py +0 -0
  595. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_3_firewall_rule_gaps.py +0 -0
  596. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_4_ssh_login_hardening.py +0 -0
  597. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_5_trust_transition.py +0 -0
  598. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_6_retire_legacy_helper.py +0 -0
  599. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_7_timedatectl_sudoers.py +0 -0
  600. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_8_system_helper.py +0 -0
  601. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/migrations/versions/v1_6_9_ntp_servers.py +0 -0
  602. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/__init__.py +0 -0
  603. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/cli.py +0 -0
  604. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/client.py +0 -0
  605. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/coordinator.py +0 -0
  606. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/__init__.py +0 -0
  607. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/dts1964_3f.json +0 -0
  608. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
  609. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
  610. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  611. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  612. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  613. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  614. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  615. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/hvac/defro-drx.json +0 -0
  616. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
  617. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  618. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/hvac/thessla.json +0 -0
  619. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  620. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/hvac/wanas415.json +0 -0
  621. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/inverters/sofar.json +0 -0
  622. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
  623. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/other/n4dsc08.json +0 -0
  624. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  625. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
  626. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/cwt.json +0 -0
  627. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
  628. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/gdfs.json +0 -0
  629. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/gdfx.json +0 -0
  630. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  631. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/pt100.json +0 -0
  632. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/sht20.json +0 -0
  633. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/devices/sensors/sht30.json +0 -0
  634. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/__init__.py +0 -0
  635. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/base.py +0 -0
  636. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/derived/__init__.py +0 -0
  637. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/derived/numeric.py +0 -0
  638. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/derived/select.py +0 -0
  639. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/derived/switch.py +0 -0
  640. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/derived/text.py +0 -0
  641. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/sensor/__init__.py +0 -0
  642. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/sensor/binary.py +0 -0
  643. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/sensor/numeric.py +0 -0
  644. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/sensor/text.py +0 -0
  645. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/writeable/__init__.py +0 -0
  646. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/writeable/binary.py +0 -0
  647. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/entities/writeable/numeric.py +0 -0
  648. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/mock_coordinator.py +0 -0
  649. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/modbus/utils.py +0 -0
  650. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/models/__init__.py +0 -0
  651. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/models/actions.py +0 -0
  652. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/models/events.py +0 -0
  653. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/models/files.py +0 -0
  654. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/models/logs.py +0 -0
  655. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/models/mqtt.py +0 -0
  656. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/models/state.py +0 -0
  657. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/runner.py +0 -0
  658. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/actions_sensor.yaml +0 -0
  659. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/actions_switch.yaml +0 -0
  660. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/condition.yaml +0 -0
  661. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/filters.yaml +0 -0
  662. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/filters_adc.yaml +0 -0
  663. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/id.yaml +0 -0
  664. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/remote_devices.yaml +0 -0
  665. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/remote_inputs.yaml +0 -0
  666. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/remote_outputs.yaml +0 -0
  667. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/temp_unit.yaml +0 -0
  668. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/schema/update_interval.yaml +0 -0
  669. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/bind.py +0 -0
  670. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/dashboard_cards.py +0 -0
  671. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/axios-DJBeJS4R.js +0 -0
  672. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/basePath-CxHj-SSK.js +0 -0
  673. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/clipboard-CCtx29e-.js +0 -0
  674. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  675. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/configCache-BS98BpF9.js +0 -0
  676. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/editor.worker-O-CH8JUO.js +0 -0
  677. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/formatters-Cc0QIRxb.js +0 -0
  678. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
  679. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/rolldown-runtime-hePW80VL.js +0 -0
  680. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/utils-DOQQTBMN.js +0 -0
  681. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
  682. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/assets/yaml.worker-CeS-z5zL.js +0 -0
  683. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  684. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  685. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/boneio.svg +0 -0
  686. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  687. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
  688. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
  689. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
  690. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
  691. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
  692. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
  693. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
  694. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
  695. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/ina226.schema.json +0 -0
  696. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
  697. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
  698. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/location.schema.json +0 -0
  699. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
  700. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
  701. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
  702. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
  703. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
  704. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
  705. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
  706. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
  707. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/osdp.schema.json +0 -0
  708. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
  709. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
  710. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
  711. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
  712. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
  713. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
  714. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
  715. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
  716. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
  717. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
  718. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/frontend-dist/workbox-7e79c025.js +0 -0
  719. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/hvac_svg_templates.py +0 -0
  720. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/middleware/__init__.py +0 -0
  721. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/middleware/auth.py +0 -0
  722. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/middleware/csrf.py +0 -0
  723. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/middleware/policy.py +0 -0
  724. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/modbus_card_templates.py +0 -0
  725. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/rate_limit.py +0 -0
  726. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/recovery/__init__.py +0 -0
  727. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/recovery/server.py +0 -0
  728. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/recovery/static/index.html +0 -0
  729. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/recovery/static/recovery.css +0 -0
  730. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/recovery/static/recovery.js +0 -0
  731. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/accounts.py +0 -0
  732. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/auth.py +0 -0
  733. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/can.py +0 -0
  734. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/config.py +0 -0
  735. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/config_backups.py +0 -0
  736. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/config_discovery.py +0 -0
  737. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/covers.py +0 -0
  738. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/dashboard.py +0 -0
  739. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/dev_fake_device.py +0 -0
  740. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/diagnostics.py +0 -0
  741. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/irrigation.py +0 -0
  742. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/migrations.py +0 -0
  743. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/modbus.py +0 -0
  744. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/mqtt_reference.py +0 -0
  745. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/nodered.py +0 -0
  746. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/onboarding.py +0 -0
  747. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/outputs.py +0 -0
  748. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/remote_devices.py +0 -0
  749. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/schedule.py +0 -0
  750. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/sensors.py +0 -0
  751. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/sun.py +0 -0
  752. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/timezone_sudoers.py +0 -0
  753. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/routes/tools.py +0 -0
  754. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/adc.schema.json +0 -0
  755. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/areas.schema.json +0 -0
  756. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/boneio.schema.json +0 -0
  757. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/can.schema.json +0 -0
  758. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/cover.schema.json +0 -0
  759. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/dallas.schema.json +0 -0
  760. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/ds2482.schema.json +0 -0
  761. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/ina219.schema.json +0 -0
  762. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/ina226.schema.json +0 -0
  763. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/irrigation.schema.json +0 -0
  764. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/lm75.schema.json +0 -0
  765. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/location.schema.json +0 -0
  766. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/logger.schema.json +0 -0
  767. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/lox_udp.schema.json +0 -0
  768. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/mcp23017.schema.json +0 -0
  769. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/mcp9808.schema.json +0 -0
  770. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/modbus.schema.json +0 -0
  771. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/modbus_devices.schema.json +0 -0
  772. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/mqtt.schema.json +0 -0
  773. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/oled.schema.json +0 -0
  774. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/osdp.schema.json +0 -0
  775. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/output.schema.json +0 -0
  776. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/output_group.schema.json +0 -0
  777. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/pca9685.schema.json +0 -0
  778. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/pcf8575.schema.json +0 -0
  779. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/remote_devices.schema.json +0 -0
  780. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/remote_inputs.schema.json +0 -0
  781. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/remote_outputs.schema.json +0 -0
  782. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/sensor.schema.json +0 -0
  783. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
  784. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/schema/web.schema.json +0 -0
  785. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/security_headers.py +0 -0
  786. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/services/__init__.py +0 -0
  787. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/services/logs.py +0 -0
  788. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/sudo_rate_limiter.py +0 -0
  789. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/web_server.py +0 -0
  790. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio/webui/websocket_manager.py +0 -0
  791. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio.egg-info/dependency_links.txt +0 -0
  792. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio.egg-info/entry_points.txt +0 -0
  793. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio.egg-info/requires.txt +0 -0
  794. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/boneio.egg-info/top_level.txt +0 -0
  795. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/pyproject.toml +0 -0
  796. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/setup.cfg +0 -0
  797. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/setup.py +0 -0
  798. {boneio-1.6.0.dev14 → boneio-1.6.0.dev15}/tests/test_py313_compatibility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boneio
3
- Version: 1.6.0.dev14
3
+ Version: 1.6.0.dev15
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
@@ -11,6 +11,7 @@ from __future__ import annotations
11
11
  import asyncio
12
12
  import contextlib
13
13
  import hashlib
14
+ import hmac
14
15
  import json
15
16
  import logging
16
17
  import time
@@ -49,6 +50,22 @@ OUTPUT_NOTIFICATION = "notification"
49
50
  OUTPUT_LIGHT = "light"
50
51
  OUTPUT_CUSTOM = "custom"
51
52
 
53
+ # Outcome of a command that needed a code; the web API maps these to HTTP.
54
+ CODE_OK = "ok"
55
+ CODE_INVALID = "invalid_code"
56
+ CODE_MISSING = "code_required"
57
+ CODE_LOCKED = "locked"
58
+
59
+ # Wrong-code throttling (PLAN_OSDP §7.2 pt 1). A four-digit PIN is 10 000
60
+ # guesses; unthrottled, a script over the API or MQTT runs through them in
61
+ # minutes. After this many wrong codes in a row every code is refused, the
62
+ # right one included, for a pause that doubles with each further run of
63
+ # failures. It throttles and never locks for good — the same rule as
64
+ # webui/rate_limit.py: the worst a guesser can do is make the owner wait.
65
+ CODE_MAX_FAILURES = 5
66
+ CODE_LOCKOUT_BASE_S = 30.0
67
+ CODE_LOCKOUT_MAX_S = 900.0
68
+
52
69
  # Input wiring types
53
70
  NORMALLY_CLOSED = "normally_closed"
54
71
  NORMALLY_OPEN = "normally_open"
@@ -199,7 +216,9 @@ class AlarmPinCode:
199
216
  Returns:
200
217
  True if the PIN matches.
201
218
  """
202
- return self._hash == self.hash_code(plain_code)
219
+ # Constant-time: `==` on the digests leaks, through timing, how much of
220
+ # a guess matched (PLAN_OSDP §7.2 pt 3).
221
+ return hmac.compare_digest(self._hash, self.hash_code(plain_code))
203
222
 
204
223
  @staticmethod
205
224
  def hash_code(plain: str) -> str:
@@ -291,11 +310,21 @@ class BoneIOAlarmPanel:
291
310
  self._state_topic = f"{topic_prefix}/alarm/{id}/{STATE}"
292
311
  self._cmd_topic = f"{topic_prefix}/cmd/alarm/{id}/set"
293
312
  self._attributes_topic = f"{topic_prefix}/alarm/{id}/attributes"
313
+ # The "codes locked" binary_sensor in HA, for automations.
314
+ self._code_lock_topic = f"{topic_prefix}/alarm/{id}/code_lock"
294
315
 
295
316
  # Track triggered inputs for logging
296
317
  self._triggered_zone: str | None = None
297
318
  self._triggered_input: str | None = None
298
319
 
320
+ # Wrong-code throttling. One counter for the panel, whatever the code
321
+ # came through — HA, the web UI, a keypad — so switching paths does
322
+ # not buy a guesser a fresh allowance.
323
+ self._code_failures = 0
324
+ self._code_lockouts = 0
325
+ self._code_locked_until: float | None = None
326
+ self._code_unlock_timer: asyncio.TimerHandle | None = None
327
+
299
328
  _LOGGER.info(
300
329
  "Initialized BoneIOAlarmPanel: id=%s, zones=%d, outputs=%d, "
301
330
  "codes=%d, arming=%.0fs, delay=%.0fs, trigger=%.0fs",
@@ -359,6 +388,21 @@ class BoneIOAlarmPanel:
359
388
  remaining = self._arming_time_s - elapsed
360
389
  return max(0.0, round(remaining, 1))
361
390
 
391
+ @property
392
+ def code_failed_attempts(self) -> int:
393
+ """Wrong codes entered in a row since the last right one."""
394
+ return self._code_failures
395
+
396
+ @property
397
+ def code_locked_remaining_s(self) -> float | None:
398
+ """Seconds until codes are checked again, or None when not locked."""
399
+ if self._code_locked_until is None:
400
+ return None
401
+ remaining = self._code_locked_until - time.monotonic()
402
+ if remaining <= 0:
403
+ return None
404
+ return round(remaining, 1)
405
+
362
406
  # -- State persistence ----------------------------------------------------
363
407
 
364
408
  _PERSIST_ATTR_TYPE = ALARM_CONTROL_PANEL
@@ -396,34 +440,98 @@ class BoneIOAlarmPanel:
396
440
 
397
441
  # -- PIN code validation -------------------------------------------------
398
442
 
399
- def _validate_code(self, code: str | None, action: str) -> tuple[bool, str | None]:
400
- """Validate a PIN code against configured codes.
443
+ def _validate_code(self, code: str | None, action: str) -> tuple[str, str | None]:
444
+ """Validate a PIN code against configured codes, with throttling.
401
445
 
402
446
  Args:
403
447
  code: The PIN code to validate (None if not provided).
404
448
  action: The action being performed (for logging).
405
449
 
406
450
  Returns:
407
- Tuple of (is_valid, user_name). If no codes are configured,
408
- always returns (True, None).
451
+ Tuple of (outcome, user_name): outcome is CODE_OK, CODE_MISSING,
452
+ CODE_INVALID or CODE_LOCKED. If no codes are configured, always
453
+ (CODE_OK, None).
409
454
  """
410
455
  if not self._codes:
411
- return True, None
456
+ return CODE_OK, None
457
+
458
+ # Refused unchecked while locked — checking would let a guesser keep
459
+ # going and only hide which guess was right.
460
+ locked_s = self.code_locked_remaining_s
461
+ if locked_s is not None:
462
+ _LOGGER.warning(
463
+ "Alarm %s: %s rejected — codes locked for %.0fs after %d wrong codes",
464
+ self._id, action, locked_s, self._code_failures,
465
+ )
466
+ return CODE_LOCKED, None
412
467
 
413
468
  if not code:
469
+ # Not a guess, so not counted: HA sends a bare command when the
470
+ # user taps a button before typing anything.
414
471
  _LOGGER.warning("Alarm %s: %s rejected — no code provided", self._id, action)
415
- return False, None
472
+ return CODE_MISSING, None
416
473
 
417
474
  for pin in self._codes:
418
- if pin.verify(code):
419
- return True, pin.name
475
+ if pin.verify(str(code)):
476
+ if self._code_failures:
477
+ self._code_failures = 0
478
+ self._code_lockouts = 0
479
+ self._code_locked_until = None
480
+ self._publish_attributes()
481
+ return CODE_OK, pin.name
482
+
483
+ self._code_failures += 1
484
+ _LOGGER.warning(
485
+ "Alarm %s: %s rejected — invalid code (%d in a row)",
486
+ self._id, action, self._code_failures,
487
+ )
488
+ if self._code_failures % CODE_MAX_FAILURES == 0:
489
+ lock_s = min(CODE_LOCKOUT_MAX_S, CODE_LOCKOUT_BASE_S * (2 ** self._code_lockouts))
490
+ self._code_lockouts += 1
491
+ self._code_locked_until = time.monotonic() + lock_s
492
+ _LOGGER.warning(
493
+ "Alarm %s: %d wrong codes in a row — codes locked for %.0fs",
494
+ self._id, self._code_failures, lock_s,
495
+ )
496
+ self._publish_code_lock(True)
497
+ self._schedule_code_unlock(lock_s)
498
+ self._publish_attributes()
499
+ return CODE_LOCKED, None
500
+ self._publish_attributes()
501
+ return CODE_INVALID, None
502
+
503
+ def _publish_code_lock(self, locked: bool) -> None:
504
+ """Publish the "codes locked" binary_sensor state (retained)."""
505
+ self._message_bus.send_message(
506
+ topic=self._code_lock_topic,
507
+ payload="ON" if locked else "OFF",
508
+ retain=True,
509
+ )
510
+
511
+ def _schedule_code_unlock(self, delay_s: float) -> None:
512
+ """Turn the binary_sensor off again when the lockout runs out.
513
+
514
+ The lockout itself needs no timer — it is a deadline checked on the
515
+ next code — but HA only learns it ended if something says so.
516
+ """
517
+ if self._code_unlock_timer is not None:
518
+ self._code_unlock_timer.cancel()
519
+ try:
520
+ loop = asyncio.get_running_loop()
521
+ except RuntimeError:
522
+ return
523
+ self._code_unlock_timer = loop.call_later(delay_s, self._on_code_unlock)
420
524
 
421
- _LOGGER.warning("Alarm %s: %s rejected — invalid code", self._id, action)
422
- return False, None
525
+ def _on_code_unlock(self) -> None:
526
+ """Lockout over: tell HA, and refresh the attributes it reads."""
527
+ self._code_unlock_timer = None
528
+ _LOGGER.info("Alarm %s: code lockout ended", self._id)
529
+ self._publish_code_lock(False)
530
+ self._publish_attributes()
423
531
 
424
532
  # -- MQTT command handler ------------------------------------------------
425
533
 
426
- async def handle_command(self, _topic: str, payload: str) -> None:
534
+ async def handle_command(self, _topic: str, payload: str) -> str:
427
535
  """Handle alarm command from HA.
428
536
 
429
537
  Payload can be a plain command string (ARM_HOME, DISARM, etc.)
@@ -433,6 +541,11 @@ class BoneIOAlarmPanel:
433
541
  Args:
434
542
  _topic: MQTT topic (unused).
435
543
  payload: Command string or JSON payload.
544
+
545
+ Returns:
546
+ CODE_OK when the command was accepted, otherwise why the code was
547
+ refused (CODE_MISSING, CODE_INVALID, CODE_LOCKED). MQTT ignores
548
+ it; the web API turns it into a status code.
436
549
  """
437
550
  code: str | None = None
438
551
  command: str
@@ -452,17 +565,17 @@ class BoneIOAlarmPanel:
452
565
  self._id, command, self._state)
453
566
 
454
567
  if command == CMD_DISARM:
455
- valid, user_name = self._validate_code(code, "DISARM")
456
- if not valid:
457
- return
568
+ outcome, user_name = self._validate_code(code, "DISARM")
569
+ if outcome != CODE_OK:
570
+ return outcome
458
571
  if user_name:
459
572
  _LOGGER.info("Alarm %s disarmed by %s", self._id, user_name)
460
573
  await self._disarm()
461
574
  elif command in (CMD_ARM_HOME, CMD_ARM_AWAY, CMD_ARM_NIGHT):
462
575
  if self._code_arm_required:
463
- valid, user_name = self._validate_code(code, command)
464
- if not valid:
465
- return
576
+ outcome, user_name = self._validate_code(code, command)
577
+ if outcome != CODE_OK:
578
+ return outcome
466
579
  if user_name:
467
580
  _LOGGER.info("Alarm %s armed (%s) by %s", self._id, command, user_name)
468
581
  target = {
@@ -475,6 +588,7 @@ class BoneIOAlarmPanel:
475
588
  await self._trigger("manual", "manual")
476
589
  else:
477
590
  _LOGGER.warning("Unknown alarm command: %s", command)
591
+ return CODE_OK
478
592
 
479
593
  # -- Input event handler -------------------------------------------------
480
594
 
@@ -776,6 +890,9 @@ class BoneIOAlarmPanel:
776
890
  attrs: dict[str, Any] = {
777
891
  "triggered_zone": self._triggered_zone,
778
892
  "triggered_input": self._triggered_input,
893
+ # For an HA automation that tells someone their PIN is being guessed.
894
+ "code_failed_attempts": self._code_failures,
895
+ "code_locked_s": self.code_locked_remaining_s,
779
896
  }
780
897
  if blocking_inputs is not None:
781
898
  attrs["blocking_inputs"] = blocking_inputs
@@ -793,11 +910,18 @@ class BoneIOAlarmPanel:
793
910
  self._cmd_topic, self.handle_command
794
911
  )
795
912
  self._publish_state()
913
+ # A lockout lives in memory only, so after a restart codes are open —
914
+ # say so, rather than leave a retained ON from before the restart.
915
+ if self._codes:
916
+ self._publish_code_lock(False)
796
917
  _LOGGER.info("Alarm panel %s started", self._id)
797
918
 
798
919
  async def stop(self) -> None:
799
920
  """Stop alarm panel — cancel timers and unsubscribe."""
800
921
  self._cancel_all_timers()
922
+ if self._code_unlock_timer is not None:
923
+ self._code_unlock_timer.cancel()
924
+ self._code_unlock_timer = None
801
925
  await self._deactivate_outputs()
802
926
  with contextlib.suppress(Exception):
803
927
  await self._message_bus.unsubscribe_and_stop_listen(self._cmd_topic)
@@ -194,6 +194,7 @@ cover_actions = {
194
194
  "TOGGLE_OPEN": "toggle_open",
195
195
  "TOGGLE_CLOSE": "toggle_close",
196
196
  "SMART_TOGGLE": "smart_toggle",
197
+ "SET_POSITION": "set_cover_position",
197
198
  "TILT": "set_tilt",
198
199
  "TILT_OPEN": "tilt_open",
199
200
  "TILT_CLOSE": "tilt_close",
@@ -0,0 +1,113 @@
1
+ """Replace a file's content without ever leaving half of it on disk.
2
+
3
+ The controller has no UPS and runs from an SD card or eMMC. A plain
4
+ ``open(path, "w")`` truncates the file first, so power lost during the write
5
+ leaves ``config.yaml`` cut short — and a controller that no longer boots.
6
+ Writing next to the target and renaming over it means a reader, or the next
7
+ boot, sees either the old file or the new one, never a mix.
8
+
9
+ Kept free of heavy imports: the recovery app uses it too.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import glob
15
+ import os
16
+ import tempfile
17
+ import time
18
+ from pathlib import Path
19
+
20
+
21
+ #: A temp file this old was left by a writer that died: a save takes well
22
+ #: under a second, and one still running must not lose its file.
23
+ _STALE_TEMP_SECONDS = 60
24
+ #: What tempfile.mkstemp appends to the prefix.
25
+ _TEMP_SUFFIX_LEN = 8
26
+
27
+
28
+ def _remove_stale_temps(target: Path) -> None:
29
+ """Delete temp files left by writes that never reached the rename.
30
+
31
+ Nothing can clean up after a power cut or SIGKILL mid-write, so without
32
+ this they pile up in the config directory, one per interrupted save.
33
+ """
34
+ prefix = f".{target.name}."
35
+ cutoff = time.time() - _STALE_TEMP_SECONDS
36
+ try:
37
+ candidates = list(target.parent.glob(f"{glob.escape(prefix)}*"))
38
+ except OSError:
39
+ return
40
+ for candidate in candidates:
41
+ if len(candidate.name) != len(prefix) + _TEMP_SUFFIX_LEN:
42
+ continue
43
+ try:
44
+ if candidate.lstat().st_mtime < cutoff:
45
+ candidate.unlink()
46
+ except OSError:
47
+ continue
48
+
49
+
50
+ def _new_file_mode() -> int:
51
+ """What ``open(path, "w")`` would have given a new file under our umask.
52
+
53
+ Read from /proc rather than with os.umask(), which can only be read by
54
+ setting it, and would briefly change it for every other thread.
55
+ """
56
+ try:
57
+ with open("/proc/self/status", encoding="ascii") as f:
58
+ for line in f:
59
+ if line.startswith("Umask:"):
60
+ return 0o666 & ~int(line.split()[1], 8)
61
+ except (OSError, ValueError, IndexError):
62
+ pass
63
+ return 0o644
64
+
65
+
66
+ def write_atomically(
67
+ path: str | os.PathLike[str], content: str | bytes, mode: int | None = None
68
+ ) -> None:
69
+ """Write ``content`` to ``path`` atomically.
70
+
71
+ Keeps the original's permission bits: an included file that holds a broker
72
+ password is often 0600, and a rewrite must not widen that. A symlink is
73
+ followed, so the file it points to is replaced rather than the link.
74
+
75
+ Args:
76
+ path: File to write. Its directory must exist.
77
+ content: New content; ``str`` is written as UTF-8.
78
+ mode: Permission bits to set. Defaults to the existing file's, or what
79
+ the process umask gives a new one.
80
+ """
81
+ target = Path(os.path.realpath(path))
82
+ if mode is None:
83
+ try:
84
+ mode = target.stat().st_mode & 0o777
85
+ except FileNotFoundError:
86
+ mode = _new_file_mode()
87
+
88
+ fd, tmp = tempfile.mkstemp(dir=target.parent, prefix=f".{target.name}.")
89
+ try:
90
+ with os.fdopen(fd, "wb") as f:
91
+ f.write(content.encode("utf-8") if isinstance(content, str) else content)
92
+ f.flush()
93
+ os.fsync(f.fileno())
94
+ os.chmod(tmp, mode)
95
+ os.replace(tmp, target)
96
+ except BaseException:
97
+ Path(tmp).unlink(missing_ok=True)
98
+ raise
99
+
100
+ _remove_stale_temps(target)
101
+
102
+ # The rename lives in the directory entry; without this a power cut right
103
+ # after it can still bring back the old file.
104
+ try:
105
+ dir_fd = os.open(target.parent, os.O_RDONLY)
106
+ except OSError:
107
+ return
108
+ try:
109
+ os.fsync(dir_fd)
110
+ except OSError:
111
+ pass
112
+ finally:
113
+ os.close(dir_fd)
@@ -17,7 +17,7 @@ services:
17
17
  networks:
18
18
  - edge
19
19
  caddy:
20
- image: caddy:2-alpine
20
+ image: caddy:2.11.4-alpine@sha256:6aeddd44c3078b0f9a35206472a11420648a79c184603ef95957d0a20044cb2b
21
21
  restart: unless-stopped
22
22
  hostname: ${HOSTNAME:-boneio}
23
23
  ports:
@@ -14,6 +14,8 @@ import re
14
14
  from collections.abc import Callable
15
15
  from dataclasses import dataclass, field
16
16
 
17
+ from boneio.core.atomic_file import write_atomically
18
+
17
19
  _LOGGER = logging.getLogger(__name__)
18
20
 
19
21
  # Current schema version — bump this when adding new migrations
@@ -308,8 +310,7 @@ def _persist_config_version(config_file: str, version: int) -> None:
308
310
  indent = " " * (boneio_indent + 2)
309
311
  updated_lines.append(f"{indent}config_version: {version}\n")
310
312
 
311
- with open(config_file, "w", encoding="utf-8") as f:
312
- f.writelines(updated_lines)
313
+ write_atomically(config_file, "".join(updated_lines))
313
314
 
314
315
  _LOGGER.info("Persisted config_version: %d to %s", version, config_file)
315
316
 
@@ -9,6 +9,7 @@ from __future__ import annotations
9
9
  import logging
10
10
  import re
11
11
 
12
+ from boneio.core.atomic_file import write_atomically
12
13
  from boneio.core.config.migrations import register_migration
13
14
 
14
15
  _LOGGER = logging.getLogger(__name__)
@@ -41,8 +42,7 @@ def _persist_proxy_port(config_file: str) -> None:
41
42
  updated_lines.append(line)
42
43
 
43
44
  if updated:
44
- with open(config_file, "w", encoding="utf-8") as f:
45
- f.writelines(updated_lines)
45
+ write_atomically(config_file, "".join(updated_lines))
46
46
 
47
47
 
48
48
  @register_migration(
@@ -9,6 +9,7 @@ from __future__ import annotations
9
9
  import logging
10
10
  import re
11
11
 
12
+ from boneio.core.atomic_file import write_atomically
12
13
  from boneio.core.config.migrations import register_migration
13
14
 
14
15
  _LOGGER = logging.getLogger(__name__)
@@ -52,8 +53,7 @@ def _persist_transition(config_file: str) -> None:
52
53
  updated_lines.append(line)
53
54
 
54
55
  if updated:
55
- with open(config_file, "w", encoding="utf-8") as f:
56
- f.writelines(updated_lines)
56
+ write_atomically(config_file, "".join(updated_lines))
57
57
 
58
58
 
59
59
  @register_migration(
@@ -16,6 +16,7 @@ import logging
16
16
  import re
17
17
  from pathlib import Path
18
18
 
19
+ from boneio.core.atomic_file import write_atomically
19
20
  from boneio.core.config.migrations import register_migration
20
21
 
21
22
  _LOGGER = logging.getLogger(__name__)
@@ -200,8 +201,7 @@ def _strip_wled_fields_from_file(
200
201
  content = pattern.sub("", content)
201
202
 
202
203
  if content != original_content:
203
- with open(yaml_path, "w", encoding="utf-8") as f:
204
- f.write(content)
204
+ write_atomically(yaml_path, content)
205
205
  _LOGGER.info(
206
206
  "Stripped WLED cache fields from %s (saved %d bytes)",
207
207
  yaml_path.name,
@@ -9,6 +9,7 @@ from __future__ import annotations
9
9
  import logging
10
10
  import re
11
11
 
12
+ from boneio.core.atomic_file import write_atomically
12
13
  from boneio.core.config.migrations import register_migration
13
14
 
14
15
  _LOGGER = logging.getLogger(__name__)
@@ -42,8 +43,7 @@ def _persist_ina_screen(config_file: str) -> None:
42
43
  updated_lines.append(line)
43
44
 
44
45
  if updated:
45
- with open(config_file, "w", encoding="utf-8") as f:
46
- f.writelines(updated_lines)
46
+ write_atomically(config_file, "".join(updated_lines))
47
47
 
48
48
 
49
49
  @register_migration(
@@ -27,6 +27,7 @@ import logging
27
27
  import re
28
28
  from pathlib import Path
29
29
 
30
+ from boneio.core.atomic_file import write_atomically
30
31
  from boneio.core.config.migrations import register_migration
31
32
 
32
33
  _LOGGER = logging.getLogger(__name__)
@@ -116,7 +117,7 @@ def strip_item_keys(config_file: str, sections: tuple[str, ...], keys: tuple[str
116
117
  flush()
117
118
 
118
119
  if main_removed:
119
- main.write_text("".join(out), encoding="utf-8")
120
+ write_atomically(main, "".join(out))
120
121
  _LOGGER.info("Removed %d deprecated line(s) from %s", main_removed, main)
121
122
 
122
123
 
@@ -128,7 +129,7 @@ def _strip_file(path: Path, keys: tuple[str, ...]) -> None:
128
129
  lines = path.read_text(encoding="utf-8").splitlines(keepends=True)
129
130
  cleaned, removed = _strip_key_lines(lines, keys)
130
131
  if removed:
131
- path.write_text("".join(cleaned), encoding="utf-8")
132
+ write_atomically(path, "".join(cleaned))
132
133
  _LOGGER.info("Removed %d deprecated line(s) from %s", removed, path)
133
134
 
134
135
 
@@ -0,0 +1,16 @@
1
+ """One lock for every read-modify-write of the configuration files.
2
+
3
+ Each save reads a whole file, edits it in memory and writes it back. Two of
4
+ them running side by side — a section save from the panel in an executor
5
+ thread and a password change in another — each write back the file as they
6
+ read it, and the later one silently undoes the earlier.
7
+
8
+ Reentrant, so a route can hold it across a read, a backup and a write while
9
+ the functions it calls take it again.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import threading
15
+
16
+ CONFIG_WRITE_LOCK = threading.RLock()
@@ -12,9 +12,15 @@ survives the trip back through the parser.
12
12
 
13
13
  from __future__ import annotations
14
14
 
15
+ import functools
15
16
  import logging
16
17
  import re
18
+ from collections.abc import Callable
17
19
  from pathlib import Path
20
+ from typing import ParamSpec, TypeVar
21
+
22
+ from boneio.core.atomic_file import write_atomically
23
+ from boneio.core.config.write_lock import CONFIG_WRITE_LOCK
18
24
 
19
25
  _LOGGER = logging.getLogger(__name__)
20
26
 
@@ -26,6 +32,21 @@ class YamlPatchError(Exception):
26
32
  """Raised when the file cannot be edited safely."""
27
33
 
28
34
 
35
+ _P = ParamSpec("_P")
36
+ _R = TypeVar("_R")
37
+
38
+
39
+ def _locked(func: Callable[_P, _R]) -> Callable[_P, _R]:
40
+ """Run a read-modify-write under the lock every config save takes."""
41
+
42
+ @functools.wraps(func)
43
+ def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
44
+ with CONFIG_WRITE_LOCK:
45
+ return func(*args, **kwargs)
46
+
47
+ return wrapper
48
+
49
+
29
50
  def quote_scalar(value: str) -> str:
30
51
  """Render a string so YAML reads it back unchanged.
31
52
 
@@ -94,6 +115,7 @@ def _line_key(line: str) -> tuple[str, int, str] | None:
94
115
  return key.strip(), len(line) - len(line.lstrip()), rest.strip()
95
116
 
96
117
 
118
+ @_locked
97
119
  def set_block_list(
98
120
  config_file: str | Path, path: tuple[str, ...], field: str, items: list[str]
99
121
  ) -> None:
@@ -172,7 +194,7 @@ def set_block_list(
172
194
  else:
173
195
  lines[start : (end if end is not None else len(lines))] = [block]
174
196
 
175
- file_path.write_text("".join(lines), encoding="utf-8")
197
+ write_atomically(file_path, "".join(lines))
176
198
  _LOGGER.info("Wrote %s.%s (%d entries)", ".".join(path), field, len(items))
177
199
 
178
200
 
@@ -199,6 +221,7 @@ def _section_body_start(lines: list[str], path: tuple[str, ...]) -> int:
199
221
  return len(lines)
200
222
 
201
223
 
224
+ @_locked
202
225
  def ensure_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
203
226
  """Make sure a nested mapping exists, creating the missing levels.
204
227
 
@@ -257,7 +280,7 @@ def ensure_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
257
280
  f"{INDENT * (depth + offset)}{key}:\n" for offset, key in enumerate(missing)
258
281
  )
259
282
  lines.insert(insert_at, block)
260
- file_path.write_text("".join(lines), encoding="utf-8")
283
+ write_atomically(file_path, "".join(lines))
261
284
  _LOGGER.info("Created section '%s' in %s", ".".join(path), file_path)
262
285
  return True
263
286
 
@@ -310,6 +333,7 @@ def has_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
310
333
  return _find_section_line(lines, path) is not None
311
334
 
312
335
 
336
+ @_locked
313
337
  def remove_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
314
338
  """Delete a nested mapping key and everything under it.
315
339
 
@@ -379,7 +403,7 @@ def remove_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
379
403
  break
380
404
 
381
405
  del lines[start:end]
382
- file_path.write_text("".join(lines), encoding="utf-8")
406
+ write_atomically(file_path, "".join(lines))
383
407
  return True
384
408
 
385
409
 
@@ -479,6 +503,7 @@ def secret_reference(config_file: str | Path, path: tuple[str, ...]) -> str | No
479
503
  return match.group(1) if match else None
480
504
 
481
505
 
506
+ @_locked
482
507
  def set_scalar(config_file: str | Path, path: tuple[str, ...], value: str) -> None:
483
508
  """Write a single value, creating the field if it is not there.
484
509
 
@@ -525,11 +550,12 @@ def set_scalar(config_file: str | Path, path: tuple[str, ...], value: str) -> No
525
550
  lines[-1] += "\n"
526
551
  lines.append(line)
527
552
 
528
- file_path.write_text("".join(lines), encoding="utf-8")
553
+ write_atomically(file_path, "".join(lines))
529
554
  # The value is the point of this function and stays out of the log.
530
555
  _LOGGER.info("Wrote %s in %s", ".".join(path), file_path.name)
531
556
 
532
557
 
558
+ @_locked
533
559
  def set_secret(secrets_file: str | Path, name: str, value: str) -> None:
534
560
  """Store a value in secrets.yaml, leaving every other secret alone.
535
561
 
@@ -559,5 +585,5 @@ def set_secret(secrets_file: str | Path, name: str, value: str) -> None:
559
585
  lines[-1] += "\n"
560
586
  lines.append(line)
561
587
 
562
- file_path.write_text("".join(lines), encoding="utf-8")
588
+ write_atomically(file_path, "".join(lines))
563
589
  _LOGGER.info("Wrote the secret %s", name)