boneio 1.5.0.dev12__tar.gz → 1.5.0.dev14__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.
- {boneio-1.5.0.dev12/boneio.egg-info → boneio-1.5.0.dev14}/PKG-INFO +1 -1
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/migrations/__init__.py +3 -1
- boneio-1.5.0.dev14/boneio/core/config/migrations/v4_wled_cache.py +219 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/yaml_util.py +65 -5
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/remote/wled.py +14 -2
- boneio-1.5.0.dev14/boneio/core/remote/wled_cache.py +143 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/remote_devices.yaml +2 -78
- boneio-1.5.0.dev14/boneio/version.py +2 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/app.py +6 -0
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/BindingMatrix-sPbnkk3q.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/BindingMatrix-aj3riWWZ.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/ConfigEditor-BW5p6czH.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/ConfigEditor-Blrg9Au1.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/EditItemDialog-EXSzv1h-.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/EditItemDialog-cJc7C25R.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/EntityCard-Baa34yvR.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/EntityCard-CVnjkl2Y.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/EntityGrid-ZMMQCacx.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/EntityGrid-B6mC4OZ8.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/InputsView-3TWtNuVX.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/InputsView-C09ulmeN.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/LogViewer-k5Gt8k2O.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/LogViewer-U1DEZ2mc.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/ModbusView-DtvRzQPY.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/ModbusView-MqeWOSDT.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/NodeRedView-BPEkkqIb.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/NodeRedView-CNPh9Kak.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/OutputsView-DUnA3EG0.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/OutputsView-uXH9nyRR.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/SensorView-WmoZT5VM.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/SensorView-DW85dbP7.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/SudoPasswordDialog-fC4HRGtE.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/SudoPasswordDialog-C9jQ6QtB.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/SystemState-BRigO9Bc.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/SystemState-A6TNdNT0.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/TemplatesView-CAXj1gAG.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/TemplatesView-Bmu7KfpS.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/Tools-DfTLLXUx.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/Tools-C-qgHesX.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/UISettings-CEZ5cjTg.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/UISettings-B_Vt1ikn.js +3 -3
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/dialog-DaAuWrWH.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/dialog-Dj_HN1ZA.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/gi-B6VoRVMX.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/gi-Dt8p1sub.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/index-mUeR1ZYi.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/index-CyBZuJ67.js +2 -2
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/modbusDeviceCatalog-DAG4PZPN.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/modbusDeviceCatalog-D8uh5ILp.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/select-CT8v8aH8.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/select-Bxh-o8g9.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/tabs-box-DdJPCk-r.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/tabs-box-Bjw4Iwcm.js +1 -1
- boneio-1.5.0.dev12/boneio/webui/frontend-dist/assets/utils-BgjkKFNC.js → boneio-1.5.0.dev14/boneio/webui/frontend-dist/assets/utils-BmlJVtvk.js +1 -1
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/index.html +1 -1
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/config.schema.json +0 -144
- {boneio-1.5.0.dev12/boneio/webui → boneio-1.5.0.dev14/boneio/webui/frontend-dist}/schema/remote_devices.schema.json +0 -144
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/sw.js +1 -1
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/config.py +27 -1
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/remote_devices.py +36 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/config.schema.json +0 -144
- {boneio-1.5.0.dev12/boneio/webui/frontend-dist → boneio-1.5.0.dev14/boneio/webui}/schema/remote_devices.schema.json +0 -144
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio.egg-info/SOURCES.txt +25 -23
- boneio-1.5.0.dev12/boneio/version.py +0 -2
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/LICENSE +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/MANIFEST.in +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/README.md +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.7/output_48_4.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.8/output_48_4.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/1.0/input.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/1.0/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/1.0/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/1.0/output_48_4.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/1.0/output_cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/boards/1.0/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/bonecli.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/cover/cover.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/cover/time_based.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/cover/venetian.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/group/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/group/output_group.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/input/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/input/detectors.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/input/event.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/input/remote/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/input/remote/base.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/input/remote/esphome.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/irrigation/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/irrigation/controller.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/irrigation/water_source.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/output/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/output/basic.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/output/buzzer.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/output/mcp.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/output/pca.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/output/pcf.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/output/remote.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/template/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/template/alarm_panel.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/template/gate_cover.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/const.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/cloud/registration.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/package.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/discovery.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/events/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/events/bus.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/action_conditions.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/canopen.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/covers.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/display.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/inputs.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/irrigation.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/manager.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/remote.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/remote_input_registrar.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/templates/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/templates/alarm.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/templates/gate_cover.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/templates.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/manager/update.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/composite.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/local.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/lox.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/remote/base.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/remote/can.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/remote/esphome.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/sensor/base.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/sensor/system.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/state/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/state/manager.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/system/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/system/host_data.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/system/monitor.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/conditions.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/filter.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/logger.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/core/utils/util.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/48x4/adc.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/48x4/config.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/48x4/event.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/48x4/mqtt.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/48x4/output48x4A.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/can_master.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/can_slave.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/exceptions.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/can/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/can/bridge.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/can/client.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/can/interface.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/can/node.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/can/node_id.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/can/test_od.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/display/early_oled.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/display/oled.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/input/base.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/integration/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/integration/homeassistant.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/integration/interlock.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/integration/lox_template.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/actions.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/MANIFEST.sha256 +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/docker/daemon.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/journald/journald.conf +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/sudoers/boneio +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/systemd/boneio.service +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/bootstrap/boneio-migrate +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/bootstrap/install-helper.sh +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/runner.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/migrations/versions/v1_5_1_ufw_lox_udp.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/cli.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/client.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/dts1964_3f.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/hvac/thessla.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/hvac/wanas415.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/gdfs.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/gdfx.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/mock_coordinator.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/modbus/utils.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/models/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/models/actions.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/models/events.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/models/files.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/models/logs.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/models/mqtt.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/models/state.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/runner.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/actions.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/condition.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/filters.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/id.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/remote_inputs.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/remote_outputs.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/schema.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/action_validation.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/dashboard_cards.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/HelpView-tDBff8mq.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/LongPressWrapper-B-jkbdNk.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/SearchableEntityPicker-Dr9uF-oT.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/Sparkline-P3-zEZpz.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/aiConfig-IRYCBmLm.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/aiWizardPrompt-D9OJ-cE7.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/basePath-CxHj-SSK.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/clipboard-CCtx29e-.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/css.worker-CvXBzhp8.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/editor.worker-Cn2oRESe.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/formatters-zOiGPJLh.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/html.worker-BO6WuOEO.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/index-CpB8cnDC.css +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/json.worker-BkJRGcCJ.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/monaco-61yH0vfd.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/rolldown-runtime-QTnfLwEv.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/ts.worker-B0J26iPs.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/useTranslation-DWIecEyP.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/vendor-DjFmndpd.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/assets/yaml.worker-BKRoXlmz.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/frontend-dist/workbox-4918f2f6.js +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/hvac_svg_templates.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/modbus_card_templates.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/can.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/dashboard.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/dev_fake_device.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/irrigation.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/migrations.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/modbus.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/system.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/timezone_sudoers.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/tools.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/routes/update.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/binary_sensor.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/boneio.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/can.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/cover.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/event.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/irrigation.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/mcp23017.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/modbus_devices.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/oled.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/output.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/sensor.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/template.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/services/logs.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/web_server.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/pyproject.toml +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/setup.cfg +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/setup.py +0 -0
- {boneio-1.5.0.dev12 → boneio-1.5.0.dev14}/tests/test_py313_compatibility.py +0 -0
|
@@ -17,7 +17,7 @@ from dataclasses import dataclass, field
|
|
|
17
17
|
_LOGGER = logging.getLogger(__name__)
|
|
18
18
|
|
|
19
19
|
# Current schema version — bump this when adding new migrations
|
|
20
|
-
CURRENT_SCHEMA_VERSION =
|
|
20
|
+
CURRENT_SCHEMA_VERSION = 4
|
|
21
21
|
|
|
22
22
|
# Minimum app version that introduced each schema version.
|
|
23
23
|
# Used by the WebUI to warn before rolling back to an incompatible version.
|
|
@@ -26,6 +26,7 @@ SCHEMA_VERSION_APP_MAP: dict[int, str] = {
|
|
|
26
26
|
1: "1.2.0dev1", # proxy_port rename
|
|
27
27
|
2: "1.3.0dev1", # transition timeperiod
|
|
28
28
|
3: "1.3.0dev7", # irrigation section
|
|
29
|
+
4: "1.5.0dev13", # WLED effects/palettes → JSON cache
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
|
|
@@ -230,4 +231,5 @@ def _persist_config_version(config_file: str, version: int) -> None:
|
|
|
230
231
|
from boneio.core.config.migrations import (
|
|
231
232
|
v1_proxy_port, # noqa: E402, F401
|
|
232
233
|
v2_transition, # noqa: E402, F401
|
|
234
|
+
v4_wled_cache, # noqa: E402, F401
|
|
233
235
|
)
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""Migration v4: Extract WLED effects/palettes/segments from config to JSON cache.
|
|
2
|
+
|
|
3
|
+
Before: WLED effects (219 items), palettes (72 items), and segments are stored
|
|
4
|
+
inline in each remote_device's ``wled`` section inside config.yaml.
|
|
5
|
+
This causes 3-5 second YAML serialization delays on ARM hardware.
|
|
6
|
+
|
|
7
|
+
After: These fields are stripped from config and saved to a lightweight
|
|
8
|
+
``.wled_cache.json`` file. The cache auto-regenerates from WLED API
|
|
9
|
+
on device connect, so no data is permanently lost.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import logging
|
|
16
|
+
import re
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from boneio.core.config.migrations import register_migration
|
|
20
|
+
|
|
21
|
+
_LOGGER = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
# Fields to strip from each WLED device config — these are device metadata,
|
|
24
|
+
# not user configuration.
|
|
25
|
+
_WLED_CACHE_FIELDS = ("effects", "palettes", "segments")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _persist_wled_cache_strip(config_file: str) -> None:
|
|
29
|
+
"""Strip effects/palettes/segments from WLED devices in the YAML file.
|
|
30
|
+
|
|
31
|
+
Reads the config file(s), extracts WLED metadata into a JSON cache,
|
|
32
|
+
and rewrites the YAML without those bulky lists.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
config_file: Path to the main config.yaml file.
|
|
36
|
+
"""
|
|
37
|
+
config_dir = Path(config_file).parent
|
|
38
|
+
|
|
39
|
+
# First, find and extract WLED data from the in-memory parse
|
|
40
|
+
# to save into .wled_cache.json before removing from YAML
|
|
41
|
+
try:
|
|
42
|
+
from yaml import SafeLoader, load
|
|
43
|
+
|
|
44
|
+
class IncludeLoader(SafeLoader):
|
|
45
|
+
"""YAML loader that preserves !include tags."""
|
|
46
|
+
|
|
47
|
+
def _include_constructor(
|
|
48
|
+
loader: IncludeLoader, node: object
|
|
49
|
+
) -> object:
|
|
50
|
+
filename = loader.construct_scalar(node) # type: ignore[arg-type]
|
|
51
|
+
return type(
|
|
52
|
+
"Include", (), {"filename": filename, "tag": "!include"}
|
|
53
|
+
)()
|
|
54
|
+
|
|
55
|
+
IncludeLoader.add_constructor("!include", _include_constructor)
|
|
56
|
+
|
|
57
|
+
with open(config_file, encoding="utf-8") as f:
|
|
58
|
+
config = load(f, Loader=IncludeLoader) # noqa: S506
|
|
59
|
+
|
|
60
|
+
if not config:
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
# Determine where remote_devices lives
|
|
64
|
+
rd_section = config.get("remote_devices")
|
|
65
|
+
if rd_section is None:
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
# If it's an !include, load the included file
|
|
69
|
+
if hasattr(rd_section, "tag") and rd_section.tag == "!include":
|
|
70
|
+
include_path = config_dir / rd_section.filename
|
|
71
|
+
if include_path.exists():
|
|
72
|
+
with open(include_path, encoding="utf-8") as f:
|
|
73
|
+
rd_list = load(f, Loader=SafeLoader) # noqa: S506
|
|
74
|
+
_strip_wled_fields_from_file(include_path, rd_list, config_dir)
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
# Inline remote_devices — strip from main config file
|
|
78
|
+
if isinstance(rd_section, list):
|
|
79
|
+
_strip_wled_fields_from_file(
|
|
80
|
+
Path(config_file), rd_section, config_dir
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
except Exception as exc:
|
|
84
|
+
_LOGGER.error("Failed to strip WLED cache fields from file: %s", exc)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _strip_wled_fields_from_file(
|
|
88
|
+
yaml_path: Path, devices: list[dict] | None, config_dir: Path
|
|
89
|
+
) -> None:
|
|
90
|
+
"""Extract WLED metadata to JSON cache, then strip from YAML file.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
yaml_path: Path to the YAML file containing remote_devices.
|
|
94
|
+
devices: Parsed list of remote device dicts.
|
|
95
|
+
config_dir: Config directory for placing the cache file.
|
|
96
|
+
"""
|
|
97
|
+
if not devices:
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
# Extract cache data
|
|
101
|
+
cache_data: dict[str, dict[str, list[dict[str, str | int]]]] = {}
|
|
102
|
+
has_data = False
|
|
103
|
+
|
|
104
|
+
for device in devices:
|
|
105
|
+
if not isinstance(device, dict):
|
|
106
|
+
continue
|
|
107
|
+
wled = device.get("wled")
|
|
108
|
+
if not isinstance(wled, dict):
|
|
109
|
+
continue
|
|
110
|
+
|
|
111
|
+
device_id = device.get("id", "")
|
|
112
|
+
if not device_id:
|
|
113
|
+
continue
|
|
114
|
+
|
|
115
|
+
device_cache: dict[str, list[dict[str, str | int]]] = {}
|
|
116
|
+
for field in _WLED_CACHE_FIELDS:
|
|
117
|
+
if field in wled and isinstance(wled[field], list) and wled[field]:
|
|
118
|
+
device_cache[field] = wled[field]
|
|
119
|
+
has_data = True
|
|
120
|
+
if device_cache:
|
|
121
|
+
cache_data[device_id] = device_cache
|
|
122
|
+
|
|
123
|
+
# Save extracted data to JSON cache
|
|
124
|
+
if has_data:
|
|
125
|
+
cache_path = config_dir / ".wled_cache.json"
|
|
126
|
+
try:
|
|
127
|
+
# Merge with existing cache (other migrations may have run)
|
|
128
|
+
existing: dict[str, dict[str, list[dict[str, str | int]]]] = {}
|
|
129
|
+
if cache_path.exists():
|
|
130
|
+
with open(cache_path, encoding="utf-8") as f:
|
|
131
|
+
existing = json.load(f)
|
|
132
|
+
|
|
133
|
+
existing.update(cache_data)
|
|
134
|
+
|
|
135
|
+
with open(cache_path, "w", encoding="utf-8") as f:
|
|
136
|
+
json.dump(existing, f, indent=2, ensure_ascii=False)
|
|
137
|
+
|
|
138
|
+
_LOGGER.info(
|
|
139
|
+
"Saved WLED metadata for %d device(s) to %s",
|
|
140
|
+
len(cache_data),
|
|
141
|
+
cache_path,
|
|
142
|
+
)
|
|
143
|
+
except Exception as exc:
|
|
144
|
+
_LOGGER.warning("Failed to write WLED cache: %s", exc)
|
|
145
|
+
|
|
146
|
+
# Now strip the fields from the YAML file using regex
|
|
147
|
+
# This is safer than re-serializing the entire file
|
|
148
|
+
with open(yaml_path, encoding="utf-8") as f:
|
|
149
|
+
content = f.read()
|
|
150
|
+
|
|
151
|
+
original_content = content
|
|
152
|
+
|
|
153
|
+
# Remove effects/palettes/segments blocks from YAML
|
|
154
|
+
# Pattern: indented key followed by a list of dicts
|
|
155
|
+
for field in _WLED_CACHE_FIELDS:
|
|
156
|
+
# Match the field key line and all following lines that are more indented
|
|
157
|
+
# or are list items (- ) at deeper indent
|
|
158
|
+
pattern = re.compile(
|
|
159
|
+
rf"^( +){field}:\s*\n" # field key line
|
|
160
|
+
rf"((?:\1 .+\n|\1- .+\n)*)", # indented content below
|
|
161
|
+
re.MULTILINE,
|
|
162
|
+
)
|
|
163
|
+
content = pattern.sub("", content)
|
|
164
|
+
|
|
165
|
+
if content != original_content:
|
|
166
|
+
with open(yaml_path, "w", encoding="utf-8") as f:
|
|
167
|
+
f.write(content)
|
|
168
|
+
_LOGGER.info(
|
|
169
|
+
"Stripped WLED cache fields from %s (saved %d bytes)",
|
|
170
|
+
yaml_path.name,
|
|
171
|
+
len(original_content) - len(content),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@register_migration(
|
|
176
|
+
version=4,
|
|
177
|
+
name="Extract WLED effects/palettes/segments to JSON cache",
|
|
178
|
+
migrate_file=_persist_wled_cache_strip,
|
|
179
|
+
)
|
|
180
|
+
def migrate(doc: dict) -> dict:
|
|
181
|
+
"""Strip effects, palettes, and segments from remote_devices in memory.
|
|
182
|
+
|
|
183
|
+
These fields are device metadata auto-discovered from the WLED API,
|
|
184
|
+
not user configuration. Storing them in config.yaml causes slow saves
|
|
185
|
+
on ARM hardware due to YAML serialization overhead (~64KB per 7 devices).
|
|
186
|
+
|
|
187
|
+
After migration, this data lives in ``.wled_cache.json`` and is
|
|
188
|
+
auto-populated from the WLED API on device connect.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
doc: Raw config dict.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
Migrated config dict with WLED metadata fields removed.
|
|
195
|
+
"""
|
|
196
|
+
remote_devices = doc.get("remote_devices")
|
|
197
|
+
if not isinstance(remote_devices, list):
|
|
198
|
+
return doc
|
|
199
|
+
|
|
200
|
+
for device in remote_devices:
|
|
201
|
+
if not isinstance(device, dict):
|
|
202
|
+
continue
|
|
203
|
+
wled = device.get("wled")
|
|
204
|
+
if not isinstance(wled, dict):
|
|
205
|
+
continue
|
|
206
|
+
|
|
207
|
+
for field in _WLED_CACHE_FIELDS:
|
|
208
|
+
if field in wled:
|
|
209
|
+
items = wled[field]
|
|
210
|
+
count = len(items) if isinstance(items, list) else 0
|
|
211
|
+
_LOGGER.info(
|
|
212
|
+
"Stripping wled.%s (%d items) from device '%s'",
|
|
213
|
+
field,
|
|
214
|
+
count,
|
|
215
|
+
device.get("id", "?"),
|
|
216
|
+
)
|
|
217
|
+
del wled[field]
|
|
218
|
+
|
|
219
|
+
return doc
|
|
@@ -1227,11 +1227,17 @@ def update_config_section(config_file: str, section: str, data: dict | list) ->
|
|
|
1227
1227
|
Returns:
|
|
1228
1228
|
dict: Status response with success/error message
|
|
1229
1229
|
"""
|
|
1230
|
+
import time
|
|
1230
1231
|
from pathlib import Path
|
|
1231
1232
|
|
|
1233
|
+
t_start = time.perf_counter()
|
|
1232
1234
|
config_dir = Path(config_file).parent
|
|
1233
1235
|
|
|
1234
|
-
|
|
1236
|
+
data_size = len(str(data)) if data else 0
|
|
1237
|
+
_LOGGER.info(
|
|
1238
|
+
"[SAVE] START section='%s' data_size=%d bytes",
|
|
1239
|
+
section, data_size,
|
|
1240
|
+
)
|
|
1235
1241
|
|
|
1236
1242
|
# Special handling for mcp23017 - convert hex strings to integers
|
|
1237
1243
|
# This ensures YAML writes them as integers which are then read back as hex
|
|
@@ -1246,9 +1252,25 @@ def update_config_section(config_file: str, section: str, data: dict | list) ->
|
|
|
1246
1252
|
with contextlib.suppress(ValueError):
|
|
1247
1253
|
entry["address"] = int(addr, 10)
|
|
1248
1254
|
|
|
1255
|
+
# Strip WLED device metadata (effects/palettes/segments) from remote_devices.
|
|
1256
|
+
# These are auto-discovered from WLED API and cached in .wled_cache.json,
|
|
1257
|
+
# NOT stored in config.yaml (defense in depth).
|
|
1258
|
+
if section == "remote_devices" and isinstance(data, list):
|
|
1259
|
+
_wled_cache_fields = ("effects", "palettes", "segments")
|
|
1260
|
+
for entry in data:
|
|
1261
|
+
if isinstance(entry, dict):
|
|
1262
|
+
wled = entry.get("wled")
|
|
1263
|
+
if isinstance(wled, dict):
|
|
1264
|
+
for field in _wled_cache_fields:
|
|
1265
|
+
wled.pop(field, None)
|
|
1266
|
+
|
|
1249
1267
|
# Strip default values to keep YAML clean
|
|
1268
|
+
t_strip = time.perf_counter()
|
|
1250
1269
|
cleaned_data = strip_default_values(data, {}, section)
|
|
1251
|
-
_LOGGER.info(
|
|
1270
|
+
_LOGGER.info(
|
|
1271
|
+
"[SAVE] strip_default_values took %.3fs",
|
|
1272
|
+
time.perf_counter() - t_strip,
|
|
1273
|
+
)
|
|
1252
1274
|
|
|
1253
1275
|
# Custom YAML loader that preserves !include tags
|
|
1254
1276
|
class IncludeLoader(SafeLoader):
|
|
@@ -1265,8 +1287,13 @@ def update_config_section(config_file: str, section: str, data: dict | list) ->
|
|
|
1265
1287
|
|
|
1266
1288
|
try:
|
|
1267
1289
|
# Read current config.yaml with custom loader
|
|
1290
|
+
t_load = time.perf_counter()
|
|
1268
1291
|
with open(config_file, encoding="utf-8") as f:
|
|
1269
1292
|
config_content = load(f, Loader=IncludeLoader)
|
|
1293
|
+
_LOGGER.info(
|
|
1294
|
+
"[SAVE] yaml.load(config.yaml) took %.3fs",
|
|
1295
|
+
time.perf_counter() - t_load,
|
|
1296
|
+
)
|
|
1270
1297
|
|
|
1271
1298
|
if config_content is None:
|
|
1272
1299
|
config_content = {}
|
|
@@ -1284,13 +1311,21 @@ def update_config_section(config_file: str, section: str, data: dict | list) ->
|
|
|
1284
1311
|
_LOGGER.info(f"Section '{section}' uses !include '{include_filename}', updating {include_file_path}")
|
|
1285
1312
|
|
|
1286
1313
|
# Save cleaned data to the included file
|
|
1314
|
+
t_dump = time.perf_counter()
|
|
1287
1315
|
content = dump(
|
|
1288
1316
|
cleaned_data, Dumper=TimePeriodDumper, default_flow_style=False, allow_unicode=True, sort_keys=False
|
|
1289
1317
|
)
|
|
1318
|
+
_LOGGER.info(
|
|
1319
|
+
"[SAVE] yaml.dump(!include data) took %.3fs (%d bytes)",
|
|
1320
|
+
time.perf_counter() - t_dump, len(content),
|
|
1321
|
+
)
|
|
1322
|
+
t_write = time.perf_counter()
|
|
1290
1323
|
with open(include_file_path, "w", encoding="utf-8") as f:
|
|
1291
1324
|
f.write(content)
|
|
1292
|
-
|
|
1293
|
-
|
|
1325
|
+
_LOGGER.info(
|
|
1326
|
+
"[SAVE] file write (!include) took %.3fs",
|
|
1327
|
+
time.perf_counter() - t_write,
|
|
1328
|
+
)
|
|
1294
1329
|
|
|
1295
1330
|
else:
|
|
1296
1331
|
# It's a regular section - replace in config.yaml
|
|
@@ -1299,14 +1334,20 @@ def update_config_section(config_file: str, section: str, data: dict | list) ->
|
|
|
1299
1334
|
|
|
1300
1335
|
# Save updated config.yaml (need to handle !include when saving)
|
|
1301
1336
|
# Read original file as text to preserve !include syntax
|
|
1337
|
+
t_reread = time.perf_counter()
|
|
1302
1338
|
with open(config_file, encoding="utf-8") as f:
|
|
1303
1339
|
original_lines = f.readlines()
|
|
1340
|
+
_LOGGER.info(
|
|
1341
|
+
"[SAVE] re-read config as text took %.3fs (%d lines)",
|
|
1342
|
+
time.perf_counter() - t_reread, len(original_lines),
|
|
1343
|
+
)
|
|
1304
1344
|
|
|
1305
1345
|
# Find and replace the section in the original text
|
|
1306
1346
|
updated_lines = []
|
|
1307
1347
|
in_section = False
|
|
1308
1348
|
section_indent = 0
|
|
1309
1349
|
|
|
1350
|
+
t_dump = time.perf_counter()
|
|
1310
1351
|
for line in original_lines:
|
|
1311
1352
|
stripped = line.strip()
|
|
1312
1353
|
# Check if this line starts the target section
|
|
@@ -1340,12 +1381,21 @@ def update_config_section(config_file: str, section: str, data: dict | list) ->
|
|
|
1340
1381
|
# Skip lines that are part of the old section
|
|
1341
1382
|
else:
|
|
1342
1383
|
updated_lines.append(line)
|
|
1384
|
+
_LOGGER.info(
|
|
1385
|
+
"[SAVE] yaml.dump(section) + line replace took %.3fs",
|
|
1386
|
+
time.perf_counter() - t_dump,
|
|
1387
|
+
)
|
|
1343
1388
|
|
|
1344
1389
|
# Write updated config
|
|
1390
|
+
t_write = time.perf_counter()
|
|
1345
1391
|
with open(config_file, "w", encoding="utf-8") as f:
|
|
1346
1392
|
f.writelines(updated_lines)
|
|
1393
|
+
_LOGGER.info(
|
|
1394
|
+
"[SAVE] file write (config.yaml) took %.3fs",
|
|
1395
|
+
time.perf_counter() - t_write,
|
|
1396
|
+
)
|
|
1347
1397
|
|
|
1348
|
-
_LOGGER.info(
|
|
1398
|
+
_LOGGER.info("[SAVE] section '%s' inline update done", section)
|
|
1349
1399
|
else:
|
|
1350
1400
|
# Section doesn't exist - add it to config.yaml
|
|
1351
1401
|
_LOGGER.info(f"Section '{section}' doesn't exist, adding to config.yaml")
|
|
@@ -1363,6 +1413,16 @@ def update_config_section(config_file: str, section: str, data: dict | list) ->
|
|
|
1363
1413
|
|
|
1364
1414
|
_LOGGER.info(f"Successfully added new section '{section}' to config.yaml")
|
|
1365
1415
|
|
|
1416
|
+
t_total = time.perf_counter() - t_start
|
|
1417
|
+
_LOGGER.info(
|
|
1418
|
+
"[SAVE] DONE section='%s' total=%.3fs",
|
|
1419
|
+
section, t_total,
|
|
1420
|
+
)
|
|
1421
|
+
if t_total > 1.0:
|
|
1422
|
+
_LOGGER.warning(
|
|
1423
|
+
"[SAVE] SLOW save detected: section='%s' took %.3fs",
|
|
1424
|
+
section, t_total,
|
|
1425
|
+
)
|
|
1366
1426
|
return {"status": "success", "message": f"Section '{section}' saved successfully"}
|
|
1367
1427
|
|
|
1368
1428
|
except Exception as e:
|
|
@@ -530,12 +530,24 @@ class WLEDRemoteDevice(RemoteDevice):
|
|
|
530
530
|
# Update internal segments list
|
|
531
531
|
self._segments = segments
|
|
532
532
|
|
|
533
|
+
# Persist effects/palettes/segments to JSON cache
|
|
534
|
+
# (they are no longer stored in config.yaml)
|
|
535
|
+
from boneio.core.remote.wled_cache import update_device_metadata
|
|
536
|
+
update_device_metadata(
|
|
537
|
+
self._id,
|
|
538
|
+
effects=effects,
|
|
539
|
+
palettes=palettes,
|
|
540
|
+
segments=segments,
|
|
541
|
+
)
|
|
542
|
+
|
|
533
543
|
_LOGGER.info(
|
|
534
|
-
"Discovered WLED '%s' v%s with %d segments, %d LEDs",
|
|
544
|
+
"Discovered WLED '%s' v%s with %d segments, %d LEDs, %d effects, %d palettes",
|
|
535
545
|
self._device_info["name"],
|
|
536
546
|
self._device_info["version"],
|
|
537
547
|
len(segments),
|
|
538
|
-
self._device_info["led_count"]
|
|
548
|
+
self._device_info["led_count"],
|
|
549
|
+
len(effects),
|
|
550
|
+
len(palettes),
|
|
539
551
|
)
|
|
540
552
|
|
|
541
553
|
return self._device_info
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""WLED metadata cache — JSON-based storage for effects, palettes, and segments.
|
|
2
|
+
|
|
3
|
+
Stores auto-discovered WLED device metadata in ``<config_dir>/.wled_cache.json``
|
|
4
|
+
instead of config.yaml. This avoids slow YAML serialization of ~64KB data
|
|
5
|
+
(219 effects × 72 palettes × N devices) on ARM hardware.
|
|
6
|
+
|
|
7
|
+
The cache is populated from the WLED ``/json`` API on device connect and is
|
|
8
|
+
**not** included in config backups — it auto-regenerates.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import logging
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
_LOGGER = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
# In-memory cache, lazily populated from disk
|
|
21
|
+
_cache: dict[str, dict[str, list[dict[str, str | int]]]] | None = None
|
|
22
|
+
_cache_path: Path | None = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def init_cache(config_dir: str | Path) -> None:
|
|
26
|
+
"""Initialize cache path and load from disk if available.
|
|
27
|
+
|
|
28
|
+
Call this once at startup with the config directory path.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
config_dir: Path to the boneIO config directory.
|
|
32
|
+
"""
|
|
33
|
+
global _cache_path, _cache
|
|
34
|
+
_cache_path = Path(config_dir) / ".wled_cache.json"
|
|
35
|
+
_cache = None # Force reload on next access
|
|
36
|
+
_LOGGER.debug("WLED cache path: %s", _cache_path)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _load_cache() -> dict[str, dict[str, list[dict[str, str | int]]]]:
|
|
40
|
+
"""Load cache from disk.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Dict mapping device_id to {effects, palettes, segments}.
|
|
44
|
+
"""
|
|
45
|
+
global _cache
|
|
46
|
+
if _cache is not None:
|
|
47
|
+
return _cache
|
|
48
|
+
|
|
49
|
+
_cache = {}
|
|
50
|
+
if _cache_path and _cache_path.exists():
|
|
51
|
+
try:
|
|
52
|
+
with open(_cache_path, encoding="utf-8") as f:
|
|
53
|
+
_cache = json.load(f)
|
|
54
|
+
_LOGGER.debug(
|
|
55
|
+
"Loaded WLED cache: %d device(s)", len(_cache)
|
|
56
|
+
)
|
|
57
|
+
except Exception as exc:
|
|
58
|
+
_LOGGER.warning("Failed to load WLED cache: %s", exc)
|
|
59
|
+
_cache = {}
|
|
60
|
+
|
|
61
|
+
return _cache
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_device_metadata(device_id: str) -> dict[str, list[dict[str, str | int]]]:
|
|
65
|
+
"""Get cached metadata for a WLED device.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
device_id: WLED device identifier.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Dict with 'effects', 'palettes', 'segments' lists.
|
|
72
|
+
Empty dict if not cached.
|
|
73
|
+
"""
|
|
74
|
+
cache = _load_cache()
|
|
75
|
+
return cache.get(device_id, {})
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_all_metadata() -> dict[str, dict[str, list[dict[str, str | int]]]]:
|
|
79
|
+
"""Get cached metadata for all WLED devices.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Dict mapping device_id to metadata.
|
|
83
|
+
"""
|
|
84
|
+
return _load_cache()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def update_device_metadata(
|
|
88
|
+
device_id: str,
|
|
89
|
+
*,
|
|
90
|
+
effects: list[dict[str, str | int]] | None = None,
|
|
91
|
+
palettes: list[dict[str, str | int]] | None = None,
|
|
92
|
+
segments: list[dict[str, str | int]] | None = None,
|
|
93
|
+
) -> None:
|
|
94
|
+
"""Update cached metadata for a device and persist to disk.
|
|
95
|
+
|
|
96
|
+
Only updates fields that are provided (not None).
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
device_id: WLED device identifier.
|
|
100
|
+
effects: List of effect dicts with 'id' and 'name'.
|
|
101
|
+
palettes: List of palette dicts with 'id' and 'name'.
|
|
102
|
+
segments: List of segment dicts with 'id', 'name', etc.
|
|
103
|
+
"""
|
|
104
|
+
cache = _load_cache()
|
|
105
|
+
|
|
106
|
+
if device_id not in cache:
|
|
107
|
+
cache[device_id] = {}
|
|
108
|
+
|
|
109
|
+
if effects is not None:
|
|
110
|
+
cache[device_id]["effects"] = effects
|
|
111
|
+
if palettes is not None:
|
|
112
|
+
cache[device_id]["palettes"] = palettes
|
|
113
|
+
if segments is not None:
|
|
114
|
+
cache[device_id]["segments"] = segments
|
|
115
|
+
|
|
116
|
+
_persist_cache(cache)
|
|
117
|
+
|
|
118
|
+
_LOGGER.info(
|
|
119
|
+
"Updated WLED cache for '%s' (effects=%s, palettes=%s, segments=%s)",
|
|
120
|
+
device_id,
|
|
121
|
+
len(effects) if effects is not None else "-",
|
|
122
|
+
len(palettes) if palettes is not None else "-",
|
|
123
|
+
len(segments) if segments is not None else "-",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _persist_cache(
|
|
128
|
+
cache: dict[str, dict[str, list[dict[str, str | int]]]]
|
|
129
|
+
) -> None:
|
|
130
|
+
"""Write cache to disk as JSON.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
cache: Full cache dict to persist.
|
|
134
|
+
"""
|
|
135
|
+
if not _cache_path:
|
|
136
|
+
_LOGGER.warning("WLED cache path not initialized, skipping persist")
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
with open(_cache_path, "w", encoding="utf-8") as f:
|
|
141
|
+
json.dump(cache, f, indent=2, ensure_ascii=False)
|
|
142
|
+
except Exception as exc:
|
|
143
|
+
_LOGGER.warning("Failed to write WLED cache: %s", exc)
|
|
@@ -350,84 +350,8 @@ schema:
|
|
|
350
350
|
default: 80
|
|
351
351
|
meta:
|
|
352
352
|
label: Port
|
|
353
|
-
segments
|
|
354
|
-
|
|
355
|
-
required: False
|
|
356
|
-
meta:
|
|
357
|
-
label: Available Segments
|
|
358
|
-
description: "List of LED segments discovered or manually configured"
|
|
359
|
-
schema:
|
|
360
|
-
type: dict
|
|
361
|
-
schema:
|
|
362
|
-
id:
|
|
363
|
-
type: integer
|
|
364
|
-
required: True
|
|
365
|
-
meta:
|
|
366
|
-
label: Segment ID
|
|
367
|
-
name:
|
|
368
|
-
type: string
|
|
369
|
-
required: False
|
|
370
|
-
meta:
|
|
371
|
-
label: Segment Name
|
|
372
|
-
start:
|
|
373
|
-
type: integer
|
|
374
|
-
required: False
|
|
375
|
-
meta:
|
|
376
|
-
label: Start LED
|
|
377
|
-
stop:
|
|
378
|
-
type: integer
|
|
379
|
-
required: False
|
|
380
|
-
meta:
|
|
381
|
-
label: Stop LED
|
|
382
|
-
len:
|
|
383
|
-
type: integer
|
|
384
|
-
required: False
|
|
385
|
-
meta:
|
|
386
|
-
label: LED Count
|
|
387
|
-
supports_rgb:
|
|
388
|
-
type: boolean
|
|
389
|
-
required: False
|
|
390
|
-
default: true
|
|
391
|
-
meta:
|
|
392
|
-
label: Supports RGB Color
|
|
393
|
-
effects:
|
|
394
|
-
type: list
|
|
395
|
-
required: False
|
|
396
|
-
meta:
|
|
397
|
-
label: Available Effects
|
|
398
|
-
description: "List of WLED effects discovered from the device"
|
|
399
|
-
schema:
|
|
400
|
-
type: dict
|
|
401
|
-
schema:
|
|
402
|
-
id:
|
|
403
|
-
type: integer
|
|
404
|
-
required: True
|
|
405
|
-
meta:
|
|
406
|
-
label: Effect ID
|
|
407
|
-
name:
|
|
408
|
-
type: string
|
|
409
|
-
required: True
|
|
410
|
-
meta:
|
|
411
|
-
label: Effect Name
|
|
412
|
-
palettes:
|
|
413
|
-
type: list
|
|
414
|
-
required: False
|
|
415
|
-
meta:
|
|
416
|
-
label: Available Palettes
|
|
417
|
-
description: "List of WLED color palettes discovered from the device"
|
|
418
|
-
schema:
|
|
419
|
-
type: dict
|
|
420
|
-
schema:
|
|
421
|
-
id:
|
|
422
|
-
type: integer
|
|
423
|
-
required: True
|
|
424
|
-
meta:
|
|
425
|
-
label: Palette ID
|
|
426
|
-
name:
|
|
427
|
-
type: string
|
|
428
|
-
required: True
|
|
429
|
-
meta:
|
|
430
|
-
label: Palette Name
|
|
353
|
+
# NOTE: segments, effects, and palettes are auto-discovered from WLED API
|
|
354
|
+
# and cached in .wled_cache.json — they are NOT stored in config.yaml.
|
|
431
355
|
|
|
432
356
|
# # Lox Parameters (future)
|
|
433
357
|
# lox:
|
|
@@ -701,6 +701,12 @@ def init_app(
|
|
|
701
701
|
_config_cache["mtime"] = _get_config_mtime(yaml_config_file)
|
|
702
702
|
_LOGGER.info("Config cache pre-populated from initial_config")
|
|
703
703
|
|
|
704
|
+
# Initialize WLED metadata cache (effects/palettes/segments)
|
|
705
|
+
from boneio.core.remote.wled_cache import init_cache as init_wled_cache
|
|
706
|
+
|
|
707
|
+
config_dir = os.path.dirname(os.path.abspath(yaml_config_file))
|
|
708
|
+
init_wled_cache(config_dir)
|
|
709
|
+
|
|
704
710
|
# Add auth middleware if configured
|
|
705
711
|
if auth_config:
|
|
706
712
|
username = auth_config.get("username")
|