boneio 1.6.0.dev4__tar.gz → 1.6.0.dev5__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 (716) hide show
  1. {boneio-1.6.0.dev4/boneio.egg-info → boneio-1.6.0.dev5}/PKG-INFO +1 -1
  2. boneio-1.6.0.dev5/boneio/core/cloud/__init__.py +5 -0
  3. {boneio-1.6.0.dev4/boneio/migrations/assets/docker/nodered → boneio-1.6.0.dev5/boneio/core/cloud/data}/docker-compose-cloud.yaml +4 -0
  4. {boneio-1.6.0.dev4/boneio/migrations/assets/docker/nodered → boneio-1.6.0.dev5/boneio/core/cloud/data}/docker-compose.yaml +4 -0
  5. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/cloud/data/init-certs-cloud.sh +6 -28
  6. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/cloud/registration.py +78 -3
  7. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/yaml_patch.py +121 -0
  8. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/containers.py +6 -1
  9. boneio-1.6.0.dev5/boneio/core/security/certificate.py +297 -0
  10. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/security/posture.py +89 -0
  11. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/MANIFEST.sha256 +3 -3
  12. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +31 -32
  13. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/helpers/boneio-containers +4 -1
  14. boneio-1.6.0.dev5/boneio/migrations/assets/issue.d/10-boneio.issue +1 -0
  15. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.3.0.json +1 -1
  16. boneio-1.6.0.dev5/boneio/migrations/plans/1.3.0.sig +1 -0
  17. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.4.4.json +1 -1
  18. boneio-1.6.0.dev5/boneio/migrations/plans/1.4.4.sig +1 -0
  19. boneio-1.6.0.dev4/boneio/migrations/plans/1.4.0.json → boneio-1.6.0.dev5/boneio/migrations/plans/1.6.10.json +1 -1
  20. boneio-1.6.0.dev5/boneio/migrations/plans/1.6.10.sig +2 -0
  21. boneio-1.6.0.dev5/boneio/migrations/plans/1.6.12.json +1 -0
  22. boneio-1.6.0.dev5/boneio/migrations/plans/1.6.12.sig +1 -0
  23. boneio-1.6.0.dev5/boneio/migrations/plans/1.6.13.json +1 -0
  24. boneio-1.6.0.dev5/boneio/migrations/plans/1.6.13.sig +1 -0
  25. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.4.json +1 -1
  26. boneio-1.6.0.dev5/boneio/migrations/plans/1.6.4.sig +0 -0
  27. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.5.json +1 -1
  28. boneio-1.6.0.dev5/boneio/migrations/plans/1.6.5.sig +2 -0
  29. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/manifest.json +1 -1
  30. boneio-1.6.0.dev5/boneio/migrations/plans/manifest.sig +1 -0
  31. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_3_0_baseline.py +3 -0
  32. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +3 -0
  33. boneio-1.6.0.dev5/boneio/migrations/versions/v1_6_13_custom_certificate.py +52 -0
  34. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_4_ssh_login_hardening.py +3 -0
  35. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/runner.py +7 -0
  36. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/schema.yaml +11 -0
  37. boneio-1.6.0.dev5/boneio/version.py +2 -0
  38. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/app.py +7 -1
  39. boneio-1.6.0.dev5/boneio/webui/bind.py +193 -0
  40. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/AccountsView-iveRbldx.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/AccountsView-Bmey_Yr2.js +1 -1
  41. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/ActionFields-DdCxR8lP.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/ActionFields-Dd53m3KH.js +1 -1
  42. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/BackupSection-C1qj4qOG.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/BackupSection-BIhcVjYm.js +1 -1
  43. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/BindingMatrix-Bj6KE0yY.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/BindingMatrix-D9Pr22Wp.js +1 -1
  44. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/DeviceControlSection-CPmqccka.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/DeviceControlSection-DKC8tOXc.js +1 -1
  45. boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/DiagnosticsView-C_oo-SRw.js +5 -0
  46. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/EditItemDialog-BH1onHq0.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/EditItemDialog-Dm4kPdmF.js +1 -1
  47. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/EntityCard-yD9_Hl71.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/EntityCard-CkJgrIUC.js +1 -1
  48. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/FactoryResetSection-E3xtkFLr.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/FactoryResetSection-sz3F--K9.js +1 -1
  49. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/FormInputToggle-Spiz-w7l.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/FormInputToggle-C7Nq2Hp8.js +1 -1
  50. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/HaDashboardWizard-f8fMg8FC.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/HaDashboardWizard-DEf4Sy_8.js +1 -1
  51. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/HostnameSection-DrpKbp6I.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/HostnameSection-D0zvj1uy.js +1 -1
  52. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/InputsView-W99g8hSl.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/InputsView-DkpdOPNR.js +1 -1
  53. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/LocationSection-ZILUsfeR.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/LocationSection-D5EoVv-i.js +2 -2
  54. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/LoggerForm-Chw9zm0N.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/LoggerForm-DHJUPaaV.js +1 -1
  55. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/MigrationsSection-DSbw5UVz.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/MigrationsSection-BPvuefg6.js +1 -1
  56. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/ModbusView-CdP0fXYx.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/ModbusView-Cch7ykif.js +1 -1
  57. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/MqttPasswordsSection-BYwPAyFi.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/MqttPasswordsSection-dncPiufr.js +1 -1
  58. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/NodeRedManagement-DRMiFlH2.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/NodeRedManagement-Cowu2_4i.js +1 -1
  59. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/OutputsView-C9sDLF1P.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/OutputsView-C_PNR9px.js +1 -1
  60. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/ScheduleSection-C2qLKNWR.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/ScheduleSection-ByEXYj3H.js +1 -1
  61. boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/SecurityView-BGcKCB34.js +1 -0
  62. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/SensorView-DNtKJE4b.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/SensorView-DxwEx546.js +1 -1
  63. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/SystemState-DbY5T6BB.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/SystemState-CvlqTKsV.js +1 -1
  64. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/TemplatesView-6kNzVE3p.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/TemplatesView-D0PTisZV.js +1 -1
  65. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/TilePicker-jd3hKaoZ.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/TilePicker-I46eKfzF.js +1 -1
  66. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/TimezoneSection-BEuXBmWp.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/TimezoneSection-DRA9cBch.js +1 -1
  67. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/UISettings-DIcCTtXU.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/UISettings-qOAoRlwa.js +3 -3
  68. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/index-1pLHiRke.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/index-BDR1Gl2A.js +24 -4
  69. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/monaco-C9XC2D1j.js → boneio-1.6.0.dev5/boneio/webui/frontend-dist/assets/monaco-CQ8fwGzT.js +1 -1
  70. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/index.html +1 -1
  71. {boneio-1.6.0.dev4/boneio/webui → boneio-1.6.0.dev5/boneio/webui/frontend-dist}/schema/config.schema.json +13 -0
  72. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/web.schema.json +13 -0
  73. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/sw.js +1 -1
  74. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/config_core.py +131 -1
  75. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/onboarding.py +9 -0
  76. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/security.py +297 -2
  77. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/system.py +8 -0
  78. {boneio-1.6.0.dev4/boneio/webui/frontend-dist → boneio-1.6.0.dev5/boneio/webui}/schema/config.schema.json +13 -0
  79. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/web.schema.json +13 -0
  80. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/web_server.py +5 -1
  81. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/websocket_manager.py +42 -2
  82. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5/boneio.egg-info}/PKG-INFO +1 -1
  83. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio.egg-info/SOURCES.txt +35 -30
  84. boneio-1.6.0.dev4/boneio/core/cloud/__init__.py +0 -5
  85. boneio-1.6.0.dev4/boneio/migrations/assets/issue.d/10-boneio.issue +0 -1
  86. boneio-1.6.0.dev4/boneio/migrations/plans/1.3.0.sig +0 -0
  87. boneio-1.6.0.dev4/boneio/migrations/plans/1.4.0.sig +0 -1
  88. boneio-1.6.0.dev4/boneio/migrations/plans/1.4.4.sig +0 -1
  89. boneio-1.6.0.dev4/boneio/migrations/plans/1.6.12.json +0 -1
  90. boneio-1.6.0.dev4/boneio/migrations/plans/1.6.12.sig +0 -2
  91. boneio-1.6.0.dev4/boneio/migrations/plans/1.6.4.sig +0 -1
  92. boneio-1.6.0.dev4/boneio/migrations/plans/1.6.5.sig +0 -2
  93. boneio-1.6.0.dev4/boneio/migrations/plans/manifest.sig +0 -0
  94. boneio-1.6.0.dev4/boneio/version.py +0 -2
  95. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/DiagnosticsView-Bi1hrIcs.js +0 -5
  96. boneio-1.6.0.dev4/boneio/webui/frontend-dist/assets/SecurityView-DBkwBU2t.js +0 -1
  97. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/LICENSE +0 -0
  98. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/MANIFEST.in +0 -0
  99. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/README.md +0 -0
  100. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/__init__.py +0 -0
  101. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.2/input.yaml +0 -0
  102. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.2/output_24_16.yaml +0 -0
  103. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.2/output_32_10.yaml +0 -0
  104. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.2/output_32_5.yaml +0 -0
  105. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.2/output_cover.yaml +0 -0
  106. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
  107. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.3/input.yaml +0 -0
  108. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.3/output_24_16.yaml +0 -0
  109. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.3/output_32_10.yaml +0 -0
  110. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.3/output_32_5.yaml +0 -0
  111. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.3/output_cover.yaml +0 -0
  112. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
  113. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.4/input.yaml +0 -0
  114. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.4/output_24_16.yaml +0 -0
  115. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.4/output_32_10.yaml +0 -0
  116. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.4/output_32_5.yaml +0 -0
  117. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.4/output_cover.yaml +0 -0
  118. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
  119. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.5/input.yaml +0 -0
  120. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.5/output_24_16.yaml +0 -0
  121. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.5/output_32_10.yaml +0 -0
  122. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.5/output_cover.yaml +0 -0
  123. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
  124. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.6/input.yaml +0 -0
  125. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.6/output_24_16.yaml +0 -0
  126. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.6/output_32_10.yaml +0 -0
  127. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.6/output_cover.yaml +0 -0
  128. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
  129. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.7/input.yaml +0 -0
  130. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.7/output_24_16.yaml +0 -0
  131. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.7/output_32_10.yaml +0 -0
  132. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.7/output_48_4.yaml +0 -0
  133. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.7/output_cover.yaml +0 -0
  134. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
  135. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.8/input.yaml +0 -0
  136. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.8/output_24_16.yaml +0 -0
  137. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.8/output_32_10.yaml +0 -0
  138. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.8/output_48_4.yaml +0 -0
  139. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.8/output_cover.yaml +0 -0
  140. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
  141. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/1.0/input.yaml +0 -0
  142. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/1.0/output_24_16.yaml +0 -0
  143. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/1.0/output_32_10.yaml +0 -0
  144. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/1.0/output_48_4.yaml +0 -0
  145. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/1.0/output_cover.yaml +0 -0
  146. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/boards/1.0/output_cover_mix.yaml +0 -0
  147. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/bonecli.py +0 -0
  148. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/__init__.py +0 -0
  149. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/cover/__init__.py +0 -0
  150. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/cover/cover.py +0 -0
  151. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/cover/remote.py +0 -0
  152. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/cover/time_based.py +0 -0
  153. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/cover/venetian.py +0 -0
  154. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/group/__init__.py +0 -0
  155. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/group/output_group.py +0 -0
  156. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/input/__init__.py +0 -0
  157. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/input/binary_sensor.py +0 -0
  158. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/input/detectors.py +0 -0
  159. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/input/event.py +0 -0
  160. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/input/remote/__init__.py +0 -0
  161. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/input/remote/base.py +0 -0
  162. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/input/remote/esphome.py +0 -0
  163. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/irrigation/__init__.py +0 -0
  164. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/irrigation/controller.py +0 -0
  165. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/irrigation/water_source.py +0 -0
  166. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/output/__init__.py +0 -0
  167. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/output/basic.py +0 -0
  168. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/output/buzzer.py +0 -0
  169. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/output/mcp.py +0 -0
  170. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/output/pca.py +0 -0
  171. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/output/pcf.py +0 -0
  172. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/output/remote.py +0 -0
  173. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/sensor/__init__.py +0 -0
  174. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/sensor/virtual_energy.py +0 -0
  175. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/template/__init__.py +0 -0
  176. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/template/alarm_panel.py +0 -0
  177. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/template/gate_cover.py +0 -0
  178. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/components/template/thermostat.py +0 -0
  179. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/const.py +0 -0
  180. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/__init__.py +0 -0
  181. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/auth/__init__.py +0 -0
  182. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/auth/cli.py +0 -0
  183. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/auth/hashing.py +0 -0
  184. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/auth/migration.py +0 -0
  185. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/auth/models.py +0 -0
  186. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/auth/store.py +0 -0
  187. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/cloud/data/__init__.py +0 -0
  188. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/cloud/secrets.py +0 -0
  189. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/__init__.py +0 -0
  190. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/config_helper.py +0 -0
  191. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/input_bindings.py +0 -0
  192. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/migrations/__init__.py +0 -0
  193. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
  194. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/migrations/v2_transition.py +0 -0
  195. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/migrations/v4_wled_cache.py +0 -0
  196. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/migrations/v5_ina_screen.py +0 -0
  197. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/package-lock.json +0 -0
  198. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/package.json +0 -0
  199. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/provenance.py +0 -0
  200. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/schema_converter.py +0 -0
  201. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/secret_masking.py +0 -0
  202. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/yaml_compat.py +0 -0
  203. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/config/yaml_util.py +0 -0
  204. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/diagnostics/__init__.py +0 -0
  205. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/diagnostics/collect.py +0 -0
  206. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/discovery.py +0 -0
  207. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/events/__init__.py +0 -0
  208. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/events/bus.py +0 -0
  209. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/__init__.py +0 -0
  210. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/action_conditions.py +0 -0
  211. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/canopen.py +0 -0
  212. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/covers.py +0 -0
  213. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/display.py +0 -0
  214. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/inputs.py +0 -0
  215. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/irrigation.py +0 -0
  216. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/manager.py +0 -0
  217. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/modbus.py +0 -0
  218. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/outputs.py +0 -0
  219. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/remote.py +0 -0
  220. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/remote_input_registrar.py +0 -0
  221. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/scheduler.py +0 -0
  222. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/security_alert.py +0 -0
  223. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/sensors.py +0 -0
  224. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/sun.py +0 -0
  225. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/templates/__init__.py +0 -0
  226. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/templates/alarm.py +0 -0
  227. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/templates/gate_cover.py +0 -0
  228. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/templates/thermostat.py +0 -0
  229. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/templates.py +0 -0
  230. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/manager/update.py +0 -0
  231. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/__init__.py +0 -0
  232. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/basic.py +0 -0
  233. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/basic_mqtt.py +0 -0
  234. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/composite.py +0 -0
  235. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/local.py +0 -0
  236. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/lox.py +0 -0
  237. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/mqtt.py +0 -0
  238. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/messaging/queue.py +0 -0
  239. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/net/__init__.py +0 -0
  240. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/net/discovery_guard.py +0 -0
  241. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/remote/__init__.py +0 -0
  242. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/remote/base.py +0 -0
  243. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/remote/can.py +0 -0
  244. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/remote/esphome.py +0 -0
  245. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/remote/mqtt.py +0 -0
  246. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/remote/wled.py +0 -0
  247. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/remote/wled_cache.py +0 -0
  248. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/security/__init__.py +0 -0
  249. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/security/framing.py +0 -0
  250. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/sensor/__init__.py +0 -0
  251. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/sensor/base.py +0 -0
  252. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/sensor/sun.py +0 -0
  253. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/sensor/system.py +0 -0
  254. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/state/__init__.py +0 -0
  255. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/state/manager.py +0 -0
  256. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/system/__init__.py +0 -0
  257. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/system/host_data.py +0 -0
  258. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/system/monitor.py +0 -0
  259. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/system_ops.py +0 -0
  260. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/__init__.py +0 -0
  261. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/async_updater.py +0 -0
  262. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/conditions.py +0 -0
  263. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/filter.py +0 -0
  264. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/font_util.py +0 -0
  265. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/logger.py +0 -0
  266. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/overlay.py +0 -0
  267. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/sun.py +0 -0
  268. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/timeperiod.py +0 -0
  269. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/core/utils/util.py +0 -0
  270. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/24x16/adc.yaml +0 -0
  271. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
  272. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/24x16/config.yaml +0 -0
  273. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/24x16/event.yaml +0 -0
  274. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/24x16/mqtt.yaml +0 -0
  275. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/24x16/output24x16A.yaml +0 -0
  276. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/32x10/adc.yaml +0 -0
  277. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
  278. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/32x10/config.yaml +0 -0
  279. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/32x10/event.yaml +0 -0
  280. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/32x10/mqtt.yaml +0 -0
  281. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/32x10/output32x10A.yaml +0 -0
  282. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/48x4/adc.yaml +0 -0
  283. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
  284. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/48x4/config.yaml +0 -0
  285. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/48x4/event.yaml +0 -0
  286. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/48x4/mqtt.yaml +0 -0
  287. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/48x4/output48x4A.yaml +0 -0
  288. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/__init__.py +0 -0
  289. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/can_master.yaml +0 -0
  290. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/can_slave.yaml +0 -0
  291. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover/adc.yaml +0 -0
  292. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover/binary_sensor.yaml +0 -0
  293. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover/config.yaml +0 -0
  294. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover/cover.yaml +0 -0
  295. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover/event.yaml +0 -0
  296. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover/mqtt.yaml +0 -0
  297. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover/outputCover.yaml +0 -0
  298. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover_mix/adc.yaml +0 -0
  299. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
  300. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover_mix/config.yaml +0 -0
  301. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover_mix/cover.yaml +0 -0
  302. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover_mix/event.yaml +0 -0
  303. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
  304. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
  305. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/adc.yaml +0 -0
  306. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
  307. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
  308. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
  309. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
  310. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/event_all.yaml +0 -0
  311. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
  312. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
  313. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
  314. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
  315. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
  316. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
  317. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/exceptions.py +0 -0
  318. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/__init__.py +0 -0
  319. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/analog/__init__.py +0 -0
  320. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/analog/adc.py +0 -0
  321. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/can/__init__.py +0 -0
  322. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/can/bridge.py +0 -0
  323. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/can/client.py +0 -0
  324. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/can/interface.py +0 -0
  325. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/can/node.py +0 -0
  326. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/can/node_id.py +0 -0
  327. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/can/test_od.py +0 -0
  328. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/display/__init__.py +0 -0
  329. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/display/early_oled.py +0 -0
  330. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/display/fonts/danube__.ttf +0 -0
  331. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/display/oled.py +0 -0
  332. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/__init__.py +0 -0
  333. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/expanders/__init__.py +0 -0
  334. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
  335. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
  336. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
  337. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/input/__init__.py +0 -0
  338. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/input/base.py +0 -0
  339. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/gpio/input/manager.py +0 -0
  340. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/__init__.py +0 -0
  341. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/bus.py +0 -0
  342. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/ina219.py +0 -0
  343. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/ina219_driver.py +0 -0
  344. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/ina226.py +0 -0
  345. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/ina226_driver.py +0 -0
  346. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/mcp9808.py +0 -0
  347. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/i2c/pct2075.py +0 -0
  348. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/onewire/__init__.py +0 -0
  349. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/onewire/dallas.py +0 -0
  350. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/sensor/__init__.py +0 -0
  351. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/sensor/temperature/__init__.py +0 -0
  352. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/sensor/temperature/base.py +0 -0
  353. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
  354. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
  355. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/integration/__init__.py +0 -0
  356. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/integration/homeassistant.py +0 -0
  357. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/integration/interlock.py +0 -0
  358. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/integration/lox_template.py +0 -0
  359. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/__init__.py +0 -0
  360. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/actions.py +0 -0
  361. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/docker/daemon.json +0 -0
  362. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
  363. {boneio-1.6.0.dev4/boneio/core/cloud/data → boneio-1.6.0.dev5/boneio/migrations/assets/docker/nodered}/docker-compose-cloud.yaml +0 -0
  364. {boneio-1.6.0.dev4/boneio/core/cloud/data → boneio-1.6.0.dev5/boneio/migrations/assets/docker/nodered}/docker-compose.yaml +0 -0
  365. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
  366. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/helpers/boneio-helpers-heal +0 -0
  367. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/helpers/boneio-migrate-v2 +0 -0
  368. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/helpers/boneio-system +0 -0
  369. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/journald/journald.conf +0 -0
  370. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/kernel/postinst-boneio-overlay +0 -0
  371. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/migrations-recovery.pem +0 -0
  372. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/migrations.pem +0 -0
  373. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/modules-load.d/onewire.conf +0 -0
  374. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
  375. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/sshd/10-boneio-hardening.conf +0 -0
  376. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/sudoers/boneio +0 -0
  377. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/sudoers/boneio-helpers +0 -0
  378. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/sudoers/boneio-timedatectl +0 -0
  379. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/boneio-helpers-heal.service +0 -0
  380. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
  381. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
  382. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/boneio.service +0 -0
  383. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/dropins/avahi-daemon-defer.conf +0 -0
  384. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/dropins/bb-usb-gadgets-defer.conf +0 -0
  385. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/dropins/mosquitto-priority.conf +0 -0
  386. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/dropins/timer-no-persistent.conf +0 -0
  387. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/dropins/user-manager-defer.conf +0 -0
  388. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/linger-marker +0 -0
  389. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
  390. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
  391. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
  392. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
  393. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
  394. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
  395. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/assets/wheels/pyyaml-6.0.3-cp313-cp313-linux_armv7l.whl +0 -0
  396. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/bootstrap/boneio-migrate +0 -0
  397. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/bootstrap/install-helper.sh +0 -0
  398. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
  399. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.3.1.json +0 -0
  400. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.3.1.sig +0 -0
  401. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.3.2.json +0 -0
  402. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.3.2.sig +0 -0
  403. /boneio-1.6.0.dev4/boneio/migrations/plans/1.6.10.json → /boneio-1.6.0.dev5/boneio/migrations/plans/1.4.0.json +0 -0
  404. /boneio-1.6.0.dev4/boneio/migrations/plans/1.6.10.sig → /boneio-1.6.0.dev5/boneio/migrations/plans/1.4.0.sig +0 -0
  405. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.4.3.json +0 -0
  406. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.4.3.sig +0 -0
  407. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.0.json +0 -0
  408. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.0.sig +0 -0
  409. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.1.json +0 -0
  410. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.1.sig +0 -0
  411. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.10.json +0 -0
  412. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.10.sig +0 -0
  413. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.11.json +0 -0
  414. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.11.sig +0 -0
  415. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.12.json +0 -0
  416. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.12.sig +0 -0
  417. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.13.json +0 -0
  418. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.13.sig +0 -0
  419. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.14.json +0 -0
  420. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.14.sig +0 -0
  421. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.15.json +0 -0
  422. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.15.sig +0 -0
  423. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.16.json +0 -0
  424. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.16.sig +0 -0
  425. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.17.json +0 -0
  426. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.17.sig +0 -0
  427. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.18.json +0 -0
  428. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.18.sig +0 -0
  429. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.2.json +0 -0
  430. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.2.sig +0 -0
  431. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.3.json +0 -0
  432. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.3.sig +0 -0
  433. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.4.json +0 -0
  434. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.4.sig +0 -0
  435. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.5.json +0 -0
  436. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.5.sig +0 -0
  437. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.6.json +0 -0
  438. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.6.sig +0 -0
  439. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.7.json +0 -0
  440. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.7.sig +0 -0
  441. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.8.json +0 -0
  442. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.8.sig +0 -0
  443. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.9.json +0 -0
  444. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.5.9.sig +0 -0
  445. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.0.json +0 -0
  446. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.0.sig +0 -0
  447. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.1.json +0 -0
  448. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.1.sig +0 -0
  449. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.11.json +0 -0
  450. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.11.sig +0 -0
  451. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.2.json +0 -0
  452. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.2.sig +0 -0
  453. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.3.json +0 -0
  454. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.3.sig +0 -0
  455. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.6.json +0 -0
  456. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.6.sig +0 -0
  457. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.7.json +0 -0
  458. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.7.sig +0 -0
  459. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.8.json +0 -0
  460. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.8.sig +0 -0
  461. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.9.json +0 -0
  462. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/plans/1.6.9.sig +0 -0
  463. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/runner.py +0 -0
  464. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/__init__.py +0 -0
  465. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
  466. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
  467. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
  468. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
  469. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
  470. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_10_disable_console_setup.py +0 -0
  471. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_11_timer_catchup.py +0 -0
  472. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_12_oled_splash_off_critical_path.py +0 -0
  473. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_13_mosquitto_priority.py +0 -0
  474. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_14_journal_apparent_size.py +0 -0
  475. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_15_prune_orphan_journals.py +0 -0
  476. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_16_login_linger.py +0 -0
  477. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_17_defer_user_manager.py +0 -0
  478. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_18_fix_hostname_once.py +0 -0
  479. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_1_ufw_lox_udp.py +0 -0
  480. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_2_libyaml.py +0 -0
  481. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_3_libyaml_retry.py +0 -0
  482. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_4_onewire_modules.py +0 -0
  483. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_5_overlay_kernel_hook.py +0 -0
  484. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_6_boot_service_order.py +0 -0
  485. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_7_journald_limits.py +0 -0
  486. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_8_apparmor_prune.py +0 -0
  487. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_5_9_defer_nonessential.py +0 -0
  488. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_0_nodered_admin_auth.py +0 -0
  489. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_10_narrow_sudo_rules.py +0 -0
  490. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_11_drop_docker_group.py +0 -0
  491. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_12_console_shows_ip.py +0 -0
  492. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_1_mosquitto_passwd_perms.py +0 -0
  493. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_2_drop_build_sudo_rule.py +0 -0
  494. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_3_firewall_rule_gaps.py +0 -0
  495. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_5_trust_transition.py +0 -0
  496. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_6_retire_legacy_helper.py +0 -0
  497. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_7_timedatectl_sudoers.py +0 -0
  498. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_8_system_helper.py +0 -0
  499. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/migrations/versions/v1_6_9_ntp_servers.py +0 -0
  500. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/__init__.py +0 -0
  501. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/cli.py +0 -0
  502. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/client.py +0 -0
  503. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/coordinator.py +0 -0
  504. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/__init__.py +0 -0
  505. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/dts1964_3f.json +0 -0
  506. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
  507. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
  508. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
  509. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
  510. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
  511. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
  512. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
  513. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/hvac/defro-drx.json +0 -0
  514. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
  515. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
  516. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/hvac/thessla.json +0 -0
  517. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/hvac/ventclear.json +0 -0
  518. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/hvac/wanas415.json +0 -0
  519. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/inverters/sofar.json +0 -0
  520. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
  521. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/other/n4dsc08.json +0 -0
  522. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/other/r4dcb08.json +0 -0
  523. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
  524. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/cwt.json +0 -0
  525. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
  526. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/gdfs.json +0 -0
  527. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/gdfx.json +0 -0
  528. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
  529. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/pt100.json +0 -0
  530. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/qdw90a.json +0 -0
  531. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/sht20.json +0 -0
  532. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/devices/sensors/sht30.json +0 -0
  533. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/__init__.py +0 -0
  534. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/base.py +0 -0
  535. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/derived/__init__.py +0 -0
  536. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/derived/numeric.py +0 -0
  537. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/derived/select.py +0 -0
  538. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/derived/switch.py +0 -0
  539. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/derived/text.py +0 -0
  540. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/sensor/__init__.py +0 -0
  541. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/sensor/binary.py +0 -0
  542. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/sensor/numeric.py +0 -0
  543. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/sensor/text.py +0 -0
  544. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/writeable/__init__.py +0 -0
  545. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/writeable/binary.py +0 -0
  546. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/entities/writeable/numeric.py +0 -0
  547. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/mock_coordinator.py +0 -0
  548. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/modbus/utils.py +0 -0
  549. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/models/__init__.py +0 -0
  550. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/models/actions.py +0 -0
  551. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/models/events.py +0 -0
  552. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/models/files.py +0 -0
  553. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/models/logs.py +0 -0
  554. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/models/mqtt.py +0 -0
  555. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/models/state.py +0 -0
  556. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/actions.yaml +0 -0
  557. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/actions_sensor.yaml +0 -0
  558. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/actions_switch.yaml +0 -0
  559. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/condition.yaml +0 -0
  560. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/filters.yaml +0 -0
  561. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/filters_adc.yaml +0 -0
  562. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/id.yaml +0 -0
  563. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/remote_devices.yaml +0 -0
  564. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/remote_inputs.yaml +0 -0
  565. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/remote_outputs.yaml +0 -0
  566. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/temp_unit.yaml +0 -0
  567. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/schema/update_interval.yaml +0 -0
  568. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/action_validation.py +0 -0
  569. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/dashboard_cards.py +0 -0
  570. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/AppInitContext-CsffdB9c.js +0 -0
  571. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/EntityGrid-BDdmT0qN.js +0 -0
  572. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/LongPressWrapper-BKkWvoC1.js +0 -0
  573. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/NodeRedView-Ct08K8xu.js +0 -0
  574. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/Sparkline-D-2-v-7o.js +0 -0
  575. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/ViewToggle-B8OpHNHc.js +0 -0
  576. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/aiConfig-_hPXvgdY.js +0 -0
  577. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/aiWizardPrompt-Dc7dZBzw.js +0 -0
  578. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/axios-uEi8e3Ln.js +0 -0
  579. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/basePath-CxHj-SSK.js +0 -0
  580. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/chunk-QTnfLwEv.js +0 -0
  581. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/clipboard-CCtx29e-.js +0 -0
  582. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  583. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/configCache-CLN4xEny.js +0 -0
  584. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/coverUtils-Cf4Uxn2U.js +0 -0
  585. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/createLucideIcon-BEjh8B3y.js +0 -0
  586. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/editor.worker-Cn2oRESe.js +0 -0
  587. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/fa-BEzM11bH.js +0 -0
  588. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/formatters-zOiGPJLh.js +0 -0
  589. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/gi-tOlGxC0X.js +0 -0
  590. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/index-lVrZSgFS.css +0 -0
  591. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/longPress-Dx7OCSyP.js +0 -0
  592. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
  593. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/monaco-DUFfd7ef.js +0 -0
  594. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/monaco-Dpn-hvLa.js +0 -0
  595. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/select-D3PIwbEj.js +0 -0
  596. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/tabs-box-Byn-MOyS.js +0 -0
  597. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/utils-B6KiDbIe.js +0 -0
  598. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
  599. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/assets/yaml.worker-8qQfrID5.js +0 -0
  600. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/boneio-192.png +0 -0
  601. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/boneio-512.png +0 -0
  602. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/boneio.svg +0 -0
  603. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
  604. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
  605. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
  606. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
  607. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
  608. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
  609. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
  610. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
  611. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
  612. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
  613. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
  614. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/ina226.schema.json +0 -0
  615. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
  616. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
  617. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/location.schema.json +0 -0
  618. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
  619. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
  620. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
  621. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
  622. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
  623. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
  624. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
  625. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
  626. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
  627. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
  628. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
  629. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
  630. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
  631. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
  632. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
  633. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/schedule.schema.json +0 -0
  634. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
  635. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
  636. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
  637. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/frontend-dist/workbox-7e79c025.js +0 -0
  638. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/hvac_svg_templates.py +0 -0
  639. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/middleware/__init__.py +0 -0
  640. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/middleware/auth.py +0 -0
  641. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/middleware/csrf.py +0 -0
  642. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/middleware/policy.py +0 -0
  643. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/modbus_card_templates.py +0 -0
  644. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/rate_limit.py +0 -0
  645. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/__init__.py +0 -0
  646. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/accounts.py +0 -0
  647. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/auth.py +0 -0
  648. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/can.py +0 -0
  649. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/config.py +0 -0
  650. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/config_actions.py +0 -0
  651. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/config_backups.py +0 -0
  652. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/config_discovery.py +0 -0
  653. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/config_files.py +0 -0
  654. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/covers.py +0 -0
  655. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/dashboard.py +0 -0
  656. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/dev_fake_device.py +0 -0
  657. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/diagnostics.py +0 -0
  658. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/irrigation.py +0 -0
  659. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/migrations.py +0 -0
  660. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/modbus.py +0 -0
  661. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/mqtt_reference.py +0 -0
  662. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/nodered.py +0 -0
  663. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/outputs.py +0 -0
  664. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/remote_devices.py +0 -0
  665. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/schedule.py +0 -0
  666. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/sensors.py +0 -0
  667. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/sun.py +0 -0
  668. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/templates.py +0 -0
  669. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/timezone_sudoers.py +0 -0
  670. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/tools.py +0 -0
  671. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/routes/update.py +0 -0
  672. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/adc.schema.json +0 -0
  673. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/areas.schema.json +0 -0
  674. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/binary_sensor.schema.json +0 -0
  675. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/boneio.schema.json +0 -0
  676. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/can.schema.json +0 -0
  677. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/cover.schema.json +0 -0
  678. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/dallas.schema.json +0 -0
  679. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/ds2482.schema.json +0 -0
  680. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/event.schema.json +0 -0
  681. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/ina219.schema.json +0 -0
  682. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/ina226.schema.json +0 -0
  683. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/irrigation.schema.json +0 -0
  684. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/lm75.schema.json +0 -0
  685. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/location.schema.json +0 -0
  686. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/logger.schema.json +0 -0
  687. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/lox_udp.schema.json +0 -0
  688. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/mcp23017.schema.json +0 -0
  689. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/mcp9808.schema.json +0 -0
  690. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/modbus.schema.json +0 -0
  691. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/modbus_devices.schema.json +0 -0
  692. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/mqtt.schema.json +0 -0
  693. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/oled.schema.json +0 -0
  694. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/output.schema.json +0 -0
  695. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/output_group.schema.json +0 -0
  696. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/pca9685.schema.json +0 -0
  697. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/pcf8575.schema.json +0 -0
  698. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/remote_devices.schema.json +0 -0
  699. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/remote_inputs.schema.json +0 -0
  700. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/remote_outputs.schema.json +0 -0
  701. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/schedule.schema.json +0 -0
  702. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/sensor.schema.json +0 -0
  703. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/template.schema.json +0 -0
  704. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
  705. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/security_headers.py +0 -0
  706. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/services/__init__.py +0 -0
  707. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/services/logs.py +0 -0
  708. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio/webui/sudo_rate_limiter.py +0 -0
  709. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio.egg-info/dependency_links.txt +0 -0
  710. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio.egg-info/entry_points.txt +0 -0
  711. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio.egg-info/requires.txt +0 -0
  712. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/boneio.egg-info/top_level.txt +0 -0
  713. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/pyproject.toml +0 -0
  714. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/setup.cfg +0 -0
  715. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/setup.py +0 -0
  716. {boneio-1.6.0.dev4 → boneio-1.6.0.dev5}/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.dev4
3
+ Version: 1.6.0.dev5
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
@@ -0,0 +1,5 @@
1
+ """Cloud registration module for boneIO Black PWA support."""
2
+
3
+ from boneio.core.cloud.registration import CloudRegistration, set_enabled
4
+
5
+ __all__ = ["CloudRegistration", "set_enabled"]
@@ -20,6 +20,10 @@ services:
20
20
  - "${HTTPS_PORT:-8443}:443"
21
21
  environment:
22
22
  - HOST_HOSTNAME=${HOSTNAME}
23
+ # The port the host publishes 443 on. Caddy only sees 443 from
24
+ # inside the container, so a redirect built from what it sees
25
+ # would send browsers to a port nothing listens on.
26
+ - PUBLIC_HTTPS_PORT=${HTTPS_PORT:-8443}
23
27
  volumes:
24
28
  - ./caddy/502.html:/srv/502.html:ro
25
29
  - ./caddy/init-certs-cloud.sh:/init-certs-cloud.sh:ro
@@ -25,6 +25,10 @@ services:
25
25
  - "${HTTPS_PORT:-8443}:443"
26
26
  environment:
27
27
  - HOST_HOSTNAME=${HOSTNAME:-boneio}
28
+ # The port the host publishes 443 on. Caddy only sees 443 from
29
+ # inside the container, so a redirect built from what it sees
30
+ # would send browsers to a port nothing listens on.
31
+ - PUBLIC_HTTPS_PORT=${HTTPS_PORT:-8443}
28
32
  volumes:
29
33
  - ./caddy/502.html:/srv/502.html:ro
30
34
  - ./caddy/init-certs.sh:/init-certs.sh:ro
@@ -79,34 +79,12 @@ cat > /tmp/Caddyfile << EOF
79
79
 
80
80
  # HTTP - serve directly
81
81
  :80 {
82
- handle_errors {
83
- @502-504 expression {err.status_code} >= 502 && {err.status_code} <= 504
84
- handle @502-504 {
85
- root * /srv
86
- rewrite * /502.html
87
- file_server
88
- }
89
- }
90
-
91
- handle /nodered-status {
92
- header Content-Type application/json
93
- header X-NodeRed-Available "true"
94
- header Access-Control-Expose-Headers "X-NodeRed-Available"
95
- respond \`{"available": true}\` 200
96
- }
97
-
98
- handle /nodered/* {
99
- reverse_proxy node-red:1880 {
100
- header_up X-Forwarded-Proto {scheme}
101
- header_down X-NodeRed-Available "true"
102
- }
103
- }
104
-
105
- handle {
106
- reverse_proxy host.docker.internal:8090 {
107
- header_up X-Forwarded-Proto {scheme}
108
- }
109
- }
82
+ # Redirect to HTTPS. This port used to serve the panel in the clear —
83
+ # the login form, the token it hands back, and a configuration carrying
84
+ # passwords. The port is substituted by this shell as the file is
85
+ # written: Caddy only sees 443 from inside the container, while the
86
+ # host publishes it as 8443.
87
+ redir https://{host}:${PUBLIC_HTTPS_PORT:-8443}{uri}
110
88
  }
111
89
 
112
90
  ${CLOUD_BLOCK}
@@ -41,9 +41,11 @@ KEY_FILE = CERT_DIR / "privkey.pem"
41
41
 
42
42
  # Caddy configuration paths
43
43
  CADDY_CONFIG_DIR = _DOCKER_DIR / "caddy"
44
- CADDY_DEFAULT_CONFIG = CADDY_CONFIG_DIR / "Caddyfile"
45
- CADDY_CLOUD_CONFIG = CADDY_CONFIG_DIR / "Caddyfile.cloud"
46
- CADDY_ACTIVE_CONFIG = CADDY_CONFIG_DIR / "Caddyfile"
44
+ # No Caddyfile constants here on purpose. Caddy's configuration is not a file
45
+ # in this directory — init-certs.sh (or init-certs-cloud.sh) writes it to
46
+ # /tmp/Caddyfile inside the container on every start. Switching between local
47
+ # and cloud mode swaps the compose file, and with it which of those two scripts
48
+ # runs; there is no Caddyfile to copy over another.
47
49
 
48
50
  # Registration interval (1 hour)
49
51
  REGISTRATION_INTERVAL = 3600
@@ -637,3 +639,76 @@ class CloudRegistration:
637
639
  return "init-certs-cloud.sh" in content
638
640
  except Exception:
639
641
  return False
642
+
643
+
644
+ async def set_enabled(config_helper, enabled: bool, local_ip: str | None = None) -> str:
645
+ """Turn cloud registration on or off on a running device.
646
+
647
+ Registration used to begin only in :mod:`boneio.runner`, so switching it on
648
+ from the panel wrote a line to config.yaml and asked for a restart —
649
+ on a controller whose whole point is that it is running. Everything the
650
+ change needs is already here: :meth:`CloudRegistration.start` does no more
651
+ than launch the loop that registers the name, fetches the certificate,
652
+ swaps the compose template and recreates Caddy.
653
+
654
+ Idempotent in both directions, because the panel can be open twice and a
655
+ save can be repeated.
656
+
657
+ Args:
658
+ config_helper: The live :class:`ConfigHelper`.
659
+ enabled: The state asked for.
660
+ local_ip: This device's address on the LAN. Read from the system when
661
+ not given.
662
+
663
+ Returns:
664
+ A short word for what happened: ``started``, ``stopped``, ``unchanged``
665
+ or ``unavailable``.
666
+ """
667
+ existing = getattr(config_helper, "_cloud_reg", None)
668
+
669
+ if not enabled:
670
+ config_helper._cloud_registration = False
671
+ if existing is None:
672
+ return "unchanged"
673
+ try:
674
+ await existing.stop()
675
+ # Put the plain template back, or Caddy keeps trying to serve a
676
+ # certificate for a name that is no longer being renewed.
677
+ await existing._restore_local_config()
678
+ except Exception as err: # noqa: BLE001
679
+ _LOGGER.warning("Could not stop cloud registration cleanly: %s", err)
680
+ config_helper._cloud_reg = None
681
+ _LOGGER.info("Cloud registration stopped on request")
682
+ return "stopped"
683
+
684
+ if existing is not None:
685
+ config_helper._cloud_registration = True
686
+ return "unchanged"
687
+
688
+ serial = getattr(config_helper, "serial_number", None)
689
+ if not local_ip:
690
+ try:
691
+ from boneio.core.system.monitor import get_network_info
692
+
693
+ local_ip = (get_network_info() or {}).get("ip", "")
694
+ except Exception as err: # noqa: BLE001
695
+ _LOGGER.warning("Could not read this device's address: %s", err)
696
+ local_ip = ""
697
+
698
+ if not serial or not local_ip:
699
+ # The setting is saved either way; the next start picks it up. Saying
700
+ # so is better than reporting success for a service that did not begin.
701
+ _LOGGER.warning(
702
+ "Cloud registration is enabled but %s is not known yet; it will "
703
+ "start on the next boot.",
704
+ "the serial number" if not serial else "this device's address",
705
+ )
706
+ config_helper._cloud_registration = True
707
+ return "unavailable"
708
+
709
+ registration = CloudRegistration(serial_number=serial, local_ip=local_ip)
710
+ await registration.start()
711
+ config_helper._cloud_reg = registration
712
+ config_helper._cloud_registration = True
713
+ _LOGGER.info("Cloud registration started for %s (IP: %s)", serial, local_ip)
714
+ return "started"
@@ -260,3 +260,124 @@ def ensure_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
260
260
  file_path.write_text("".join(lines), encoding="utf-8")
261
261
  _LOGGER.info("Created section '%s' in %s", ".".join(path), file_path)
262
262
  return True
263
+
264
+
265
+ def _find_section_line(lines: list[str], path: tuple[str, ...]) -> int | None:
266
+ """Index of the line declaring a nested key, or None if it is not there.
267
+
268
+ Args:
269
+ lines: File lines.
270
+ path: Section path, outermost first.
271
+
272
+ Returns:
273
+ The index of the key's own line, or None.
274
+ """
275
+ depth = 0
276
+ for index, line in enumerate(lines):
277
+ parsed = _line_key(line)
278
+ if parsed is None:
279
+ continue
280
+ key, indent, _ = parsed
281
+ if depth and indent <= (depth - 1) * len(INDENT):
282
+ return None
283
+ if key == path[depth] and indent == depth * len(INDENT):
284
+ depth += 1
285
+ if depth == len(path):
286
+ return index
287
+ return None
288
+
289
+
290
+ def has_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
291
+ """Whether a nested key is present in the file.
292
+
293
+ Separate from :func:`remove_section` so a caller can find out before doing
294
+ anything irreversible — such as writing a backup copy over the one it made
295
+ the last time it was asked.
296
+
297
+ Args:
298
+ config_file: Path to config.yaml.
299
+ path: Section path, outermost first.
300
+
301
+ Returns:
302
+ True when the key is there.
303
+
304
+ Raises:
305
+ YamlPatchError: If the path is empty.
306
+ """
307
+ if not path:
308
+ raise YamlPatchError("No section path given.")
309
+ lines = Path(config_file).read_text(encoding="utf-8").splitlines(keepends=True)
310
+ return _find_section_line(lines, path) is not None
311
+
312
+
313
+ def remove_section(config_file: str | Path, path: tuple[str, ...]) -> bool:
314
+ """Delete a nested mapping key and everything under it.
315
+
316
+ Written for one job: taking the pre-1.6 ``web.auth`` block out of a
317
+ configuration after its account has been migrated into the hashed store.
318
+ Nothing reads it any more, and it still holds the owner's password in
319
+ plain text — in the file, and in every backup and diagnostic bundle made
320
+ since.
321
+
322
+ Line-based rather than a parse-and-dump, for the usual reason: the file
323
+ belongs to the owner, and round-tripping it through a YAML library would
324
+ return their comments, ordering and ``!include`` directives as something
325
+ they did not write.
326
+
327
+ Comment lines immediately above the key are removed with it. They describe
328
+ the block, and leaving them behind stranded over an unrelated setting is
329
+ worse than taking one comment too many.
330
+
331
+ Args:
332
+ config_file: Path to config.yaml.
333
+ path: Section path, outermost first, e.g. ``("web", "auth")``.
334
+
335
+ Returns:
336
+ True if something was removed, False if the key was not there.
337
+
338
+ Raises:
339
+ YamlPatchError: If the path is empty.
340
+ """
341
+ if not path:
342
+ raise YamlPatchError("No section path given.")
343
+
344
+ file_path = Path(config_file)
345
+ lines = file_path.read_text(encoding="utf-8").splitlines(keepends=True)
346
+
347
+ start = _find_section_line(lines, path)
348
+ if start is None:
349
+ return False
350
+ key_indent = len(lines[start]) - len(lines[start].lstrip())
351
+
352
+ # Everything indented under the key belongs to it, blank lines included
353
+ # while more indented content follows.
354
+ end = start + 1
355
+ while end < len(lines):
356
+ line = lines[end]
357
+ if not line.strip():
358
+ following = next(
359
+ (i for i in range(end + 1, len(lines)) if lines[i].strip()), None
360
+ )
361
+ if following is None:
362
+ break
363
+ next_indent = len(lines[following]) - len(lines[following].lstrip())
364
+ if next_indent <= key_indent:
365
+ break
366
+ end += 1
367
+ continue
368
+ indent = len(line) - len(line.lstrip())
369
+ if indent <= key_indent:
370
+ break
371
+ end += 1
372
+
373
+ # Take the comment block sitting directly on top of it.
374
+ while start > 0:
375
+ above = lines[start - 1].strip()
376
+ if above.startswith("#"):
377
+ start -= 1
378
+ continue
379
+ break
380
+
381
+ del lines[start:end]
382
+ file_path.write_text("".join(lines), encoding="utf-8")
383
+ return True
@@ -55,7 +55,12 @@ _FALLBACK: dict[str, list[str]] = {
55
55
  "restart-caddy": ["docker", "compose", "restart", CADDY_SERVICE],
56
56
  "reload-caddy": [
57
57
  "docker", "compose", "exec", CADDY_SERVICE,
58
- "caddy", "reload", "--config", "/etc/caddy/Caddyfile",
58
+ # /tmp/Caddyfile, not /etc/caddy/Caddyfile: the container runs the
59
+ # file init-certs.sh writes on every start. /etc/caddy/Caddyfile is the
60
+ # stock config baked into the image, and reloading that swaps the
61
+ # working proxy for Caddy's welcome page — HTTPS goes down and stays
62
+ # down until the container is restarted.
63
+ "caddy", "reload", "--config", "/tmp/Caddyfile",
59
64
  ],
60
65
  }
61
66
 
@@ -0,0 +1,297 @@
1
+ """Checking a certificate and key before the device starts serving them.
2
+
3
+ An operator who does not want cloud registration still deserves a panel that
4
+ browsers accept, and the way there is their own certificate: from a company CA,
5
+ or from Let's Encrypt obtained on a machine that can actually run the
6
+ challenge. This is the part that decides whether what they uploaded is usable.
7
+
8
+ The checking is the point. A certificate that does not match its key makes the
9
+ proxy fail to start, and a certificate whose names do not cover the address
10
+ people type produces the same browser warning as before — except now the
11
+ operator believes they fixed it, which is worse than knowing they had not.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import datetime
17
+ import logging
18
+ import os
19
+ from dataclasses import dataclass, field
20
+ from pathlib import Path
21
+
22
+ from cryptography import x509
23
+ from cryptography.hazmat.primitives import hashes, serialization
24
+
25
+ _LOGGER = logging.getLogger(__name__)
26
+
27
+ #: Refuse anything larger. A certificate chain is a few kilobytes; a megabyte
28
+ #: of PEM is somebody uploading the wrong file.
29
+ MAX_PEM_BYTES = 256 * 1024
30
+
31
+
32
+ class CertificateError(Exception):
33
+ """The uploaded material cannot be served."""
34
+
35
+
36
+ @dataclass
37
+ class CertificateInfo:
38
+ """What a usable certificate turned out to be."""
39
+
40
+ subject: str
41
+ issuer: str
42
+ not_before: datetime.datetime
43
+ not_after: datetime.datetime
44
+ names: list[str] = field(default_factory=list)
45
+ fingerprint: str = ""
46
+ #: Names the device is reached by that this certificate does not cover.
47
+ #: Not an error — the operator may know something we do not — but the one
48
+ #: thing worth saying out loud.
49
+ uncovered: list[str] = field(default_factory=list)
50
+
51
+ @property
52
+ def days_left(self) -> int:
53
+ """Whole days until it expires."""
54
+ now = datetime.datetime.now(datetime.UTC)
55
+ return max(0, (self.not_after - now).days)
56
+
57
+ def to_dict(self) -> dict:
58
+ """Serialise for the API."""
59
+ return {
60
+ "subject": self.subject,
61
+ "issuer": self.issuer,
62
+ "not_before": self.not_before.isoformat(),
63
+ "not_after": self.not_after.isoformat(),
64
+ "days_left": self.days_left,
65
+ "names": self.names,
66
+ "fingerprint": self.fingerprint,
67
+ "uncovered": self.uncovered,
68
+ }
69
+
70
+
71
+ def _names_of(cert: x509.Certificate) -> list[str]:
72
+ """Every name the certificate is valid for.
73
+
74
+ Args:
75
+ cert: The parsed certificate.
76
+
77
+ Returns:
78
+ DNS names and IP addresses from the SAN extension.
79
+ """
80
+ try:
81
+ san = cert.extensions.get_extension_for_class(
82
+ x509.SubjectAlternativeName
83
+ ).value
84
+ except x509.ExtensionNotFound:
85
+ return []
86
+ names = [str(n) for n in san.get_values_for_type(x509.DNSName)]
87
+ names += [str(n) for n in san.get_values_for_type(x509.IPAddress)]
88
+ return names
89
+
90
+
91
+ def _covers(names: list[str], wanted: str) -> bool:
92
+ """Whether a certificate's names cover one address.
93
+
94
+ Args:
95
+ names: Names from the certificate.
96
+ wanted: A hostname or IP address the device is reached by.
97
+
98
+ Returns:
99
+ True when a browser would accept the certificate for *wanted*.
100
+ """
101
+ wanted = wanted.strip().lower()
102
+ if not wanted:
103
+ return True
104
+ for name in names:
105
+ name = name.lower()
106
+ if name == wanted:
107
+ return True
108
+ # A wildcard matches one label, and never the bare domain.
109
+ if name.startswith("*.") and "." in wanted:
110
+ if wanted.split(".", 1)[1] == name[2:]:
111
+ return True
112
+ return False
113
+
114
+
115
+ def inspect(cert_pem: bytes, key_pem: bytes, reached_by: list[str] | None = None) -> CertificateInfo:
116
+ """Check a certificate and key, and describe what they are.
117
+
118
+ Args:
119
+ cert_pem: The certificate, or a full chain, in PEM.
120
+ key_pem: The private key in PEM. Must not be encrypted — the proxy
121
+ starts unattended and has nobody to ask for a passphrase.
122
+ reached_by: Hostnames and addresses this device is reached by, checked
123
+ against the certificate's names.
124
+
125
+ Returns:
126
+ What the certificate is.
127
+
128
+ Raises:
129
+ CertificateError: If it cannot be parsed, the key does not match, the
130
+ key is encrypted, or the certificate has expired.
131
+ """
132
+ if len(cert_pem) > MAX_PEM_BYTES or len(key_pem) > MAX_PEM_BYTES:
133
+ raise CertificateError("That file is far too large to be a certificate.")
134
+
135
+ try:
136
+ cert = x509.load_pem_x509_certificate(cert_pem)
137
+ except Exception as err: # noqa: BLE001
138
+ raise CertificateError(f"The certificate is not readable PEM: {err}") from err
139
+
140
+ try:
141
+ key = serialization.load_pem_private_key(key_pem, password=None)
142
+ except TypeError as err:
143
+ raise CertificateError(
144
+ "The private key is protected by a passphrase. The proxy starts "
145
+ "unattended and has nobody to ask, so upload an unencrypted key."
146
+ ) from err
147
+ except Exception as err: # noqa: BLE001
148
+ raise CertificateError(f"The private key is not readable PEM: {err}") from err
149
+
150
+ cert_public = cert.public_key().public_bytes(
151
+ serialization.Encoding.DER,
152
+ serialization.PublicFormat.SubjectPublicKeyInfo,
153
+ )
154
+ key_public = key.public_key().public_bytes(
155
+ serialization.Encoding.DER,
156
+ serialization.PublicFormat.SubjectPublicKeyInfo,
157
+ )
158
+ if cert_public != key_public:
159
+ raise CertificateError(
160
+ "That key does not belong to that certificate. Serving them "
161
+ "together would stop the proxy from starting at all."
162
+ )
163
+
164
+ not_after = cert.not_valid_after_utc
165
+ not_before = cert.not_valid_before_utc
166
+ now = datetime.datetime.now(datetime.UTC)
167
+ if not_after <= now:
168
+ raise CertificateError(
169
+ f"That certificate expired on {not_after.date()}. Browsers would "
170
+ "reject it more loudly than the self-signed one it replaces."
171
+ )
172
+
173
+ names = _names_of(cert)
174
+ uncovered = [
175
+ address
176
+ for address in (reached_by or [])
177
+ if address and not _covers(names, address)
178
+ ]
179
+
180
+ return CertificateInfo(
181
+ subject=cert.subject.rfc4514_string(),
182
+ issuer=cert.issuer.rfc4514_string(),
183
+ not_before=not_before,
184
+ not_after=not_after,
185
+ names=names,
186
+ fingerprint=cert.fingerprint(hashes.SHA256()).hex(),
187
+ uncovered=uncovered,
188
+ )
189
+
190
+
191
+ def device_addresses(hostname: str | None, ip: str | None) -> list[str]:
192
+ """The names a browser is likely to be pointed at this device by.
193
+
194
+ Args:
195
+ hostname: The device's hostname.
196
+ ip: Its address on the local network.
197
+
198
+ Returns:
199
+ Addresses to check a certificate against.
200
+ """
201
+ addresses = []
202
+ for value in (hostname, f"{hostname}.local" if hostname else None, ip):
203
+ if value and value not in addresses:
204
+ addresses.append(value)
205
+ return addresses
206
+
207
+
208
+ # --------------------------------------------------------------- on the device
209
+
210
+ #: Where the proxy reads an uploaded certificate from.
211
+ #:
212
+ #: Inside Caddy's data directory on purpose. That directory is already mounted
213
+ #: into the container and already belongs to the account the panel runs as, so
214
+ #: nothing here needs a change to docker-compose.yaml — which is root-owned and
215
+ #: would have to go out as a migration — and no new mount point can be created
216
+ #: by Docker as root before the panel ever gets to write in it. The cloud
217
+ #: path's own certificate lives elsewhere and is untouched by any of this.
218
+ CERT_DIR = Path.home() / "docker" / "nodered" / "caddy" / "data" / "custom"
219
+ CUSTOM_CERT = CERT_DIR / "fullchain.pem"
220
+ CUSTOM_KEY = CERT_DIR / "privkey.pem"
221
+
222
+ #: Caddy's own certificate authority, created on first start. Offering it for
223
+ #: download is the cheapest way to a panel that browsers accept: no domain, no
224
+ #: DNS credentials, nothing reachable from outside. What it costs is that a
225
+ #: machine trusting it will believe that authority about any name, so it is
226
+ #: offered with that said rather than as the obvious thing to do.
227
+ ROOT_CA = (
228
+ Path.home()
229
+ / "docker" / "nodered" / "caddy" / "data" / "caddy" / "pki"
230
+ / "authorities" / "local" / "root.crt"
231
+ )
232
+
233
+ #: The key is a secret, and it is written by the account the panel runs as.
234
+ KEY_MODE = 0o600
235
+ CERT_MODE = 0o644
236
+
237
+
238
+ def install(cert_pem: bytes, key_pem: bytes) -> None:
239
+ """Write a checked certificate and key where the proxy will find them.
240
+
241
+ Args:
242
+ cert_pem: The certificate or chain.
243
+ key_pem: Its private key.
244
+
245
+ Raises:
246
+ CertificateError: If the files cannot be written.
247
+ """
248
+ try:
249
+ CERT_DIR.mkdir(parents=True, exist_ok=True)
250
+ # The key is created with its mode already set, so it is never even
251
+ # briefly readable by anything else on the device.
252
+ def _private(path: str, flags: int) -> int:
253
+ return os.open(path, flags, KEY_MODE)
254
+
255
+ with open(CUSTOM_KEY, "wb", opener=_private) as handle:
256
+ handle.write(key_pem)
257
+ CUSTOM_KEY.chmod(KEY_MODE)
258
+ CUSTOM_CERT.write_bytes(cert_pem)
259
+ CUSTOM_CERT.chmod(CERT_MODE)
260
+ except OSError as err:
261
+ raise CertificateError(f"Could not store the certificate: {err}") from err
262
+ _LOGGER.warning("A custom TLS certificate was installed at %s", CUSTOM_CERT)
263
+
264
+
265
+ def remove() -> bool:
266
+ """Delete the custom certificate, returning the proxy to its own.
267
+
268
+ Returns:
269
+ True if something was removed.
270
+ """
271
+ removed = False
272
+ for path in (CUSTOM_CERT, CUSTOM_KEY):
273
+ try:
274
+ path.unlink()
275
+ removed = True
276
+ except FileNotFoundError:
277
+ continue
278
+ except OSError as err:
279
+ raise CertificateError(f"Could not remove {path.name}: {err}") from err
280
+ if removed:
281
+ _LOGGER.warning("The custom TLS certificate was removed")
282
+ return removed
283
+
284
+
285
+ def installed() -> CertificateInfo | None:
286
+ """Describe the custom certificate in place, if there is one.
287
+
288
+ Returns:
289
+ Its details, or None when the proxy is using its own.
290
+ """
291
+ if not (CUSTOM_CERT.exists() and CUSTOM_KEY.exists()):
292
+ return None
293
+ try:
294
+ return inspect(CUSTOM_CERT.read_bytes(), CUSTOM_KEY.read_bytes())
295
+ except (OSError, CertificateError) as err:
296
+ _LOGGER.warning("The installed certificate cannot be read: %s", err)
297
+ return None