boneIO 1.2.0.dev6__tar.gz → 1.2.0.dev8__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.2.0.dev6/boneio.egg-info → boneio-1.2.0.dev8}/PKG-INFO +1 -1
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/input/detectors.py +14 -2
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/manager.py +69 -14
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/remote.py +106 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/update.py +268 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/messaging/mqtt.py +8 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/remote/esphome.py +8 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/remote/wled.py +7 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/integration/homeassistant.py +1 -1
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/actions.yaml +35 -11
- boneio-1.2.0.dev8/boneio/version.py +2 -0
- boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/cssMode-xo2BdOZm.js +4 -0
- boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/editor.worker-B4pQIWZD.js +12 -0
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/freemarker2-cdPkYRmQ.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/freemarker2-CpF78_ZW.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/handlebars-Cfxm9RW_.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/handlebars-CTxt7dmO.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/html-BHdohU2S.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/html-BU5yZ3BK.js +1 -1
- boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/htmlMode-Bi7QBmdE.js +4 -0
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/index-BmuRpNYW.css → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/index-CyjBlAI7.css +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/index-B_8cgKDq.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/index-TnEo7N0a.js +245 -245
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/javascript-cpZp1UNX.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/javascript-BTvyG1P5.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/json.worker-DaRII17c.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/json.worker-aFakAbRR.js +22 -22
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/jsonMode-B0FgVMkj.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/jsonMode-HE9dW4cx.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/liquid-Z_DgQ0VL.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/liquid-BxuGpv1s.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/mdx-B8hjkANT.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/mdx-C04Q98IR.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/python-B-sOgkv5.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/python-CKNUIQdp.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/razor-32kHacmJ.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/razor-UrUJyAuF.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/tsMode-B4q7c15W.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/tsMode-AhPw7VFe.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/typescript-C5K4aTtA.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/typescript-CLXQgPoF.js +1 -1
- boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BIl4cyR9.js +2 -0
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/xml-BR1__-Hi.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/xml-DZmKn2me.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/yaml-Bp8ZLmkj.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/yaml-CGKDqmHX.js +1 -1
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/yaml.worker-BTE-_K6g.js → boneio-1.2.0.dev8/boneio/webui/frontend-dist/assets/yaml.worker-DBeHcBRc.js +200 -200
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/index.html +2 -2
- {boneio-1.2.0.dev6/boneio/webui/schema → boneio-1.2.0.dev8/boneio/webui/frontend-dist/schem}/adc.schema.json +8 -8
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/areas.schema.json +4 -4
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/binary_sensor.schema.json +90 -52
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/boneio.schema.json +2 -2
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/config.schema.json +616 -445
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/cover.schema.json +4 -4
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/ds2482.schema.json +4 -4
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/event.schema.json +302 -169
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/ina219.schema.json +14 -14
- {boneio-1.2.0.dev6/boneio/webui/schema → boneio-1.2.0.dev8/boneio/webui/frontend-dist/schem}/lm75.schema.json +10 -10
- {boneio-1.2.0.dev6/boneio/webui/schema → boneio-1.2.0.dev8/boneio/webui/frontend-dist/schem}/logger.schema.json +2 -2
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/mcp23017.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/mcp9808.schema.json +10 -10
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/modbus.schema.json +8 -8
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/modbus_devices.schema.json +22 -22
- {boneio-1.2.0.dev6/boneio/webui/schema → boneio-1.2.0.dev8/boneio/webui/frontend-dist/schem}/mqtt.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/oled.schema.json +8 -8
- {boneio-1.2.0.dev6/boneio/webui/schema → boneio-1.2.0.dev8/boneio/webui/frontend-dist/schem}/output.schema.json +10 -10
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/output_group.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/pca9685.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/pcf8575.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/remote_devices.schema.json +64 -64
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/sensor.schema.json +8 -8
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/virtual_energy_sensor.schema.json +4 -4
- {boneio-1.2.0.dev6/boneio/webui/schema → boneio-1.2.0.dev8/boneio/webui/frontend-dist/schem}/web.schema.json +12 -12
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/sw.js +1 -1
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/system.py +88 -14
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/update.py +44 -113
- {boneio-1.2.0.dev6/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev8/boneio/webui/schema}/adc.schema.json +8 -8
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/areas.schema.json +4 -4
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/binary_sensor.schema.json +90 -52
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/boneio.schema.json +2 -2
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/config.schema.json +616 -445
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/cover.schema.json +4 -4
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/ds2482.schema.json +4 -4
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/event.schema.json +302 -169
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/ina219.schema.json +14 -14
- {boneio-1.2.0.dev6/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev8/boneio/webui/schema}/lm75.schema.json +10 -10
- {boneio-1.2.0.dev6/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev8/boneio/webui/schema}/logger.schema.json +2 -2
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/mcp23017.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/mcp9808.schema.json +10 -10
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/modbus.schema.json +8 -8
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/modbus_devices.schema.json +22 -22
- {boneio-1.2.0.dev6/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev8/boneio/webui/schema}/mqtt.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/oled.schema.json +8 -8
- {boneio-1.2.0.dev6/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev8/boneio/webui/schema}/output.schema.json +10 -10
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/output_group.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/pca9685.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/pcf8575.schema.json +6 -6
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/remote_devices.schema.json +64 -64
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/sensor.schema.json +8 -8
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/virtual_energy_sensor.schema.json +4 -4
- {boneio-1.2.0.dev6/boneio/webui/frontend-dist/schem → boneio-1.2.0.dev8/boneio/webui/schema}/web.schema.json +12 -12
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio.egg-info/SOURCES.txt +21 -21
- boneio-1.2.0.dev6/boneio/version.py +0 -2
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/cssMode-CvZwGOXM.js +0 -4
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/editor.worker-DsAeyiJ5.js +0 -12
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/htmlMode-D09isE-q.js +0 -4
- boneio-1.2.0.dev6/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-vqzQaGvo.js +0 -2
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/LICENSE +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/MANIFEST.in +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/README.md +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/bonecli.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/cover/cover.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/cover/previous.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/cover/time_based.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/cover/venetian.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/group/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/group/output_group.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/input/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/input/event.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/output/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/output/basic.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/output/mcp.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/output/pca.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/output/pcf.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/const.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/cloud/registration.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/config/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/config/package.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/config/yaml_util.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/discovery.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/events/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/events/bus.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/covers.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/display.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/inputs.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/messaging/local.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/remote/base.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/sensor/base.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/sensor/system.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/state/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/state/manager.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/system/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/system/host_data.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/system/monitor.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/utils/filter.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/utils/logger.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/core/utils/util.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/exceptions.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/display/oled.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/input/base.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/integration/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/integration/interlock.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/cli.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/client.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/inverters/thessla.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/other/wanas415.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/modbus/utils.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/models/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/models/actions.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/models/events.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/models/files.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/models/logs.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/models/mqtt.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/models/state.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/runner.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/filters.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/id.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/remote_devices.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/schema.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/app.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/abap-CRCWOmpq.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/apex-DnsZk_dE.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/azcli-1IWB1ccx.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/bat-DPkNLes8.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/bicep-Corcdgou.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/cameligo-CGrWLZr3.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/clojure-D9WOWImG.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/coffee-B7EJu28W.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/cpp-SEyurbux.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/csharp-BoL64M5l.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/csp-C46ZqvIl.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/css-DQU6DXDx.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/cypher-D84EuPTj.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/dart-D8lhlL1r.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/dockerfile-DLk6rpji.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/ecl-BO6FnfXk.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/elixir-BRjLKONM.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/flow9-Cac8vKd7.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/fsharp-fd1GTHhf.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/go-O9LJTZXk.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/graphql-LQdxqEYJ.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/hcl-DxDQ3s82.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/ini-BvajGCUy.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/java-SYsfObOQ.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/julia-DQXNmw_w.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/kotlin-qQ0MG-9I.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/less-GGFNNJHn.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/lexon-Canl7DCW.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/lua-D28Ae8-K.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/m3-DPitgjJI.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/markdown-B811l8j2.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/mips-CdjsipkG.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/msdax-CYqgjx_P.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/mysql-BHd6q0vd.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/objective-c-B1aVtJYH.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/pascal-BhNW15KB.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/pascaligo-5jv8CcQD.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/perl-DlYyT36c.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/pgsql-Dy0bjov7.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/php-120yhfDK.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/pla-CjnFlu4u.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/postiats-CQpG440k.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/powerquery-DdJtto1Z.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/powershell-Bu_VLpJB.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/protobuf-IBS6jZEB.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/pug-kFxLfcjb.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/qsharp-q7JyzKFN.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/r-BIFz-_sK.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/redis-CHOsPHWR.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/redshift-CBifECDb.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/restructuredtext-CghPJEOS.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/ruby-CYWGW-b1.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/rust-DMDD0SHb.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/sb-BYAiYHFx.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/scala-Bqvq8jcR.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/scheme-Dhb-2j9p.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/scss-CTwUZ5N7.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/shell-CsDZo4DB.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/solidity-CME5AdoB.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/sophia-RYC1BQQz.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/sparql-KEyrF7De.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/sql-BdTr02Mf.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/st-C7iG7M4S.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/swift-D7IUmUK8.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/systemverilog-DgMryOEJ.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/tcl-PloMZuKG.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/twig-BfRIq3la.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/typespec-CzxlYoT_.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/vb-BwAE3J76.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/assets/wgsl-B_1kOXbF.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/schem/dallas.schema.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/frontend-dist/workbox-226dbdbf.js +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/config.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/modbus.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/remote_devices.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/services/logs.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/web_server.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/pyproject.toml +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/setup.cfg +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/setup.py +0 -0
- {boneio-1.2.0.dev6 → boneio-1.2.0.dev8}/tests/test_py313_compatibility.py +0 -0
|
@@ -470,7 +470,7 @@ class MultiClickDetector:
|
|
|
470
470
|
elif event.event_type is event.Type.RISING_EDGE:
|
|
471
471
|
# Button released (RISING_EDGE on BeagleBone with pull-up)
|
|
472
472
|
|
|
473
|
-
# Software debounce
|
|
473
|
+
# Software debounce (release-vs-release)
|
|
474
474
|
if self._state.last_release_ts and (timestamp_s - self._state.last_release_ts) < self._debounce_seconds:
|
|
475
475
|
delta_ms = (timestamp_s - self._state.last_release_ts) * 1000
|
|
476
476
|
_LOGGER.debug(
|
|
@@ -479,8 +479,20 @@ class MultiClickDetector:
|
|
|
479
479
|
delta_ms,
|
|
480
480
|
)
|
|
481
481
|
return
|
|
482
|
+
|
|
483
|
+
# Cross-debounce: ignore release too close to press (bounce on rising edge)
|
|
484
|
+
if self._state.last_press_ts and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds:
|
|
485
|
+
delta_ms = (timestamp_s - self._state.last_press_ts) * 1000
|
|
486
|
+
_LOGGER.debug(
|
|
487
|
+
"Ignoring bounced release on %s (%.3f ms since press, debounce %.3f ms)",
|
|
488
|
+
self._name,
|
|
489
|
+
delta_ms,
|
|
490
|
+
self._debounce_seconds * 1000,
|
|
491
|
+
)
|
|
492
|
+
return
|
|
482
493
|
|
|
483
|
-
|
|
494
|
+
press_duration_ms = (timestamp_s - self._state.last_press_ts) * 1000 if self._state.last_press_ts else 0
|
|
495
|
+
_LOGGER.debug("RELEASED: %s (%s) after %.1f ms", self._name, self._pin, press_duration_ms)
|
|
484
496
|
self._state.last_release_ts = timestamp_s
|
|
485
497
|
|
|
486
498
|
_LOGGER.debug(
|
|
@@ -440,7 +440,12 @@ class Manager:
|
|
|
440
440
|
parsed_action[key] = action_definition[key]
|
|
441
441
|
if action_definition.get("repeat"):
|
|
442
442
|
parsed_action["repeat"] = True
|
|
443
|
-
|
|
443
|
+
ri = action_definition.get("repeat_interval", 1000)
|
|
444
|
+
# TimePeriod object from schema validation -> convert to ms
|
|
445
|
+
if hasattr(ri, "total_milliseconds"):
|
|
446
|
+
parsed_action["repeat_interval"] = ri.total_milliseconds
|
|
447
|
+
else:
|
|
448
|
+
parsed_action["repeat_interval"] = ri
|
|
444
449
|
|
|
445
450
|
parsed_actions = {}
|
|
446
451
|
for click_type in actions:
|
|
@@ -552,6 +557,22 @@ class Manager:
|
|
|
552
557
|
"output_id": output_id,
|
|
553
558
|
"action_output": action_output,
|
|
554
559
|
}
|
|
560
|
+
# Copy optional light/WLED parameters
|
|
561
|
+
for opt_key in (
|
|
562
|
+
"brightness", "color_temp", "rgb", "transition",
|
|
563
|
+
"effect", "palette", "effect_speed", "effect_intensity",
|
|
564
|
+
"colors", "presets",
|
|
565
|
+
):
|
|
566
|
+
val = action_definition.get(opt_key)
|
|
567
|
+
if val is not None:
|
|
568
|
+
parsed_action[opt_key] = val
|
|
569
|
+
# Convert transition TimePeriod to float seconds
|
|
570
|
+
if "transition" in parsed_action:
|
|
571
|
+
t_val = parsed_action["transition"]
|
|
572
|
+
if hasattr(t_val, "total_in_seconds"):
|
|
573
|
+
parsed_action["transition"] = t_val.total_in_seconds
|
|
574
|
+
elif not isinstance(t_val, (int, float)):
|
|
575
|
+
parsed_action["transition"] = 0.0
|
|
555
576
|
_copy_long_press_meta(parsed_action, action_definition)
|
|
556
577
|
parsed_actions[click_type].append(parsed_action)
|
|
557
578
|
continue
|
|
@@ -724,19 +745,53 @@ class Manager:
|
|
|
724
745
|
remote_device_id = action_definition.get("remote_device")
|
|
725
746
|
output_id = action_definition.get("output_id")
|
|
726
747
|
action_output = action_definition.get("action_output", "TOGGLE")
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
748
|
+
|
|
749
|
+
# Clamp transition to repeat_interval to avoid overlapping animations
|
|
750
|
+
transition_val = action_definition.get("transition")
|
|
751
|
+
if transition_val and action_definition.get("repeat"):
|
|
752
|
+
repeat_interval = action_definition.get("repeat_interval")
|
|
753
|
+
if repeat_interval:
|
|
754
|
+
ri_seconds = repeat_interval.total_in_seconds if hasattr(repeat_interval, "total_in_seconds") else repeat_interval / 1000.0
|
|
755
|
+
if transition_val > ri_seconds:
|
|
756
|
+
_LOGGER.debug(
|
|
757
|
+
"Clamping transition %.3fs to repeat_interval %.3fs",
|
|
758
|
+
transition_val, ri_seconds,
|
|
759
|
+
)
|
|
760
|
+
transition_val = ri_seconds
|
|
761
|
+
action_definition = {**action_definition, "transition": transition_val}
|
|
762
|
+
|
|
763
|
+
if action_output == "CYCLE_COLOR":
|
|
764
|
+
await self.remote_devices.cycle_color(
|
|
765
|
+
device_id=remote_device_id,
|
|
766
|
+
output_id=output_id,
|
|
767
|
+
colors=action_definition.get("colors", []),
|
|
768
|
+
action_idx=idx,
|
|
769
|
+
transition=action_definition.get("transition"),
|
|
770
|
+
)
|
|
771
|
+
|
|
772
|
+
elif action_output == "CYCLE_PRESET":
|
|
773
|
+
await self.remote_devices.cycle_preset(
|
|
774
|
+
device_id=remote_device_id,
|
|
775
|
+
output_id=output_id,
|
|
776
|
+
presets=action_definition.get("presets", []),
|
|
777
|
+
action_idx=idx,
|
|
778
|
+
transition=action_definition.get("transition"),
|
|
779
|
+
)
|
|
780
|
+
|
|
781
|
+
else:
|
|
782
|
+
await self.remote_devices.control_output(
|
|
783
|
+
device_id=remote_device_id,
|
|
784
|
+
output_id=output_id,
|
|
785
|
+
action=action_output,
|
|
786
|
+
brightness=action_definition.get("brightness"),
|
|
787
|
+
color_temp=action_definition.get("color_temp"),
|
|
788
|
+
rgb=action_definition.get("rgb"),
|
|
789
|
+
transition=action_definition.get("transition"),
|
|
790
|
+
effect=action_definition.get("effect"),
|
|
791
|
+
palette=action_definition.get("palette"),
|
|
792
|
+
effect_speed=action_definition.get("effect_speed"),
|
|
793
|
+
effect_intensity=action_definition.get("effect_intensity"),
|
|
794
|
+
)
|
|
740
795
|
|
|
741
796
|
elif action == REMOTE_COVER:
|
|
742
797
|
# Control cover on remote device (BoneIO MQTT or ESPHome API)
|
|
@@ -64,6 +64,9 @@ class RemoteDeviceManager:
|
|
|
64
64
|
self._autodiscovered_devices: dict[str, MQTTRemoteDevice] = {}
|
|
65
65
|
# Track devices that manage this boneIO (received via discovery/managed_by topic)
|
|
66
66
|
self._managed_by_devices: dict[str, dict[str, Any]] = {}
|
|
67
|
+
# Cycle state for CYCLE_COLOR and CYCLE_PRESET actions
|
|
68
|
+
# Key: "device_id:output_id:type:action_idx", Value: current index
|
|
69
|
+
self._cycle_state: dict[str, int] = {}
|
|
67
70
|
|
|
68
71
|
if remote_devices_config:
|
|
69
72
|
self._configure_devices(remote_devices_config)
|
|
@@ -335,14 +338,18 @@ class RemoteDeviceManager:
|
|
|
335
338
|
"""Stop all persistent connections.
|
|
336
339
|
|
|
337
340
|
This should be called during application shutdown.
|
|
341
|
+
Closes ESPHome connections and WLED aiohttp sessions.
|
|
338
342
|
"""
|
|
339
343
|
for device_id, device in self._devices.items():
|
|
340
|
-
|
|
341
|
-
|
|
344
|
+
try:
|
|
345
|
+
if isinstance(device, ESPHomeRemoteDevice):
|
|
342
346
|
await device.disconnect()
|
|
343
347
|
_LOGGER.info("Stopped connection for ESPHome device '%s'", device_id)
|
|
344
|
-
|
|
345
|
-
|
|
348
|
+
elif isinstance(device, WLEDRemoteDevice):
|
|
349
|
+
await device.close()
|
|
350
|
+
_LOGGER.info("Closed session for WLED device '%s'", device_id)
|
|
351
|
+
except Exception as e:
|
|
352
|
+
_LOGGER.error("Failed to stop connection for device '%s': %s", device_id, e)
|
|
346
353
|
|
|
347
354
|
def get_device(self, device_id: str) -> RemoteDevice | None:
|
|
348
355
|
"""Get remote device by ID.
|
|
@@ -372,7 +379,7 @@ class RemoteDeviceManager:
|
|
|
372
379
|
color_temp: int | None = None,
|
|
373
380
|
rgb: list[int] | tuple[int, int, int] | None = None,
|
|
374
381
|
transition: float | None = None,
|
|
375
|
-
effect: int | None = None,
|
|
382
|
+
effect: int | str | None = None,
|
|
376
383
|
palette: int | None = None,
|
|
377
384
|
effect_speed: int | None = None,
|
|
378
385
|
effect_intensity: int | None = None,
|
|
@@ -391,7 +398,7 @@ class RemoteDeviceManager:
|
|
|
391
398
|
color_temp: Color temperature in mireds - only for ESPHome lights
|
|
392
399
|
rgb: RGB color as [R, G, B] list or tuple (0-255 each) - for ESPHome/WLED lights
|
|
393
400
|
transition: Transition time in seconds - for ESPHome/WLED lights
|
|
394
|
-
effect:
|
|
401
|
+
effect: Effect name (str for ESPHome) or effect ID (int for WLED)
|
|
395
402
|
palette: WLED color palette ID
|
|
396
403
|
effect_speed: WLED effect speed (0-255)
|
|
397
404
|
effect_intensity: WLED effect intensity (0-255)
|
|
@@ -413,6 +420,8 @@ class RemoteDeviceManager:
|
|
|
413
420
|
rgb_tuple: tuple[int, int, int] | None = None
|
|
414
421
|
if rgb and len(rgb) >= 3:
|
|
415
422
|
rgb_tuple = (int(rgb[0]), int(rgb[1]), int(rgb[2]))
|
|
423
|
+
# For ESPHome, effect must be a string
|
|
424
|
+
esphome_effect = str(effect) if effect is not None else None
|
|
416
425
|
return await device.control_light(
|
|
417
426
|
light_id=output_id,
|
|
418
427
|
action=action,
|
|
@@ -420,6 +429,7 @@ class RemoteDeviceManager:
|
|
|
420
429
|
color_temp=color_temp,
|
|
421
430
|
rgb=rgb_tuple,
|
|
422
431
|
transition=transition if transition is not None else 0.0,
|
|
432
|
+
effect=esphome_effect,
|
|
423
433
|
)
|
|
424
434
|
# Otherwise treat as switch
|
|
425
435
|
_LOGGER.debug("Controlling ESPHome switch '%s' on device '%s'", output_id, device_id)
|
|
@@ -456,6 +466,96 @@ class RemoteDeviceManager:
|
|
|
456
466
|
message_bus=self._message_bus,
|
|
457
467
|
)
|
|
458
468
|
|
|
469
|
+
async def cycle_color(
|
|
470
|
+
self,
|
|
471
|
+
device_id: str,
|
|
472
|
+
output_id: str,
|
|
473
|
+
colors: list[list[int]],
|
|
474
|
+
action_idx: int = 0,
|
|
475
|
+
transition: float | None = None,
|
|
476
|
+
) -> bool:
|
|
477
|
+
"""Cycle through a list of RGB colors on a remote device light.
|
|
478
|
+
|
|
479
|
+
Each call advances to the next color in the list, wrapping around.
|
|
480
|
+
|
|
481
|
+
Args:
|
|
482
|
+
device_id: ID of the remote device
|
|
483
|
+
output_id: ID of the light to control
|
|
484
|
+
colors: List of RGB colors, each as [R, G, B] (0-255)
|
|
485
|
+
action_idx: Action index for unique cycle state tracking
|
|
486
|
+
transition: Transition time in seconds
|
|
487
|
+
|
|
488
|
+
Returns:
|
|
489
|
+
True if command was sent successfully
|
|
490
|
+
"""
|
|
491
|
+
if not colors:
|
|
492
|
+
_LOGGER.warning("CYCLE_COLOR: no colors defined for %s:%s", device_id, output_id)
|
|
493
|
+
return False
|
|
494
|
+
|
|
495
|
+
cycle_key = f"{device_id}:{output_id}:color:{action_idx}"
|
|
496
|
+
cycle_idx = self._cycle_state.get(cycle_key, 0) % len(colors)
|
|
497
|
+
rgb = colors[cycle_idx]
|
|
498
|
+
self._cycle_state[cycle_key] = cycle_idx + 1
|
|
499
|
+
|
|
500
|
+
_LOGGER.debug(
|
|
501
|
+
"CYCLE_COLOR: %s:%s -> color %d/%d = %s",
|
|
502
|
+
device_id, output_id, cycle_idx + 1, len(colors), rgb
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
return await self.control_output(
|
|
506
|
+
device_id=device_id,
|
|
507
|
+
output_id=output_id,
|
|
508
|
+
action="ON",
|
|
509
|
+
rgb=rgb,
|
|
510
|
+
transition=transition,
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
async def cycle_preset(
|
|
514
|
+
self,
|
|
515
|
+
device_id: str,
|
|
516
|
+
output_id: str,
|
|
517
|
+
presets: list[str | int],
|
|
518
|
+
action_idx: int = 0,
|
|
519
|
+
transition: float | None = None,
|
|
520
|
+
) -> bool:
|
|
521
|
+
"""Cycle through a list of effects/presets on a remote device light.
|
|
522
|
+
|
|
523
|
+
Each call advances to the next preset in the list, wrapping around.
|
|
524
|
+
For ESPHome: presets are effect name strings.
|
|
525
|
+
For WLED: presets are effect IDs (integers).
|
|
526
|
+
|
|
527
|
+
Args:
|
|
528
|
+
device_id: ID of the remote device
|
|
529
|
+
output_id: ID of the light to control
|
|
530
|
+
presets: List of effect names (str) or effect IDs (int)
|
|
531
|
+
action_idx: Action index for unique cycle state tracking
|
|
532
|
+
transition: Transition time in seconds
|
|
533
|
+
|
|
534
|
+
Returns:
|
|
535
|
+
True if command was sent successfully
|
|
536
|
+
"""
|
|
537
|
+
if not presets:
|
|
538
|
+
_LOGGER.warning("CYCLE_PRESET: no presets defined for %s:%s", device_id, output_id)
|
|
539
|
+
return False
|
|
540
|
+
|
|
541
|
+
cycle_key = f"{device_id}:{output_id}:preset:{action_idx}"
|
|
542
|
+
cycle_idx = self._cycle_state.get(cycle_key, 0) % len(presets)
|
|
543
|
+
preset = presets[cycle_idx]
|
|
544
|
+
self._cycle_state[cycle_key] = cycle_idx + 1
|
|
545
|
+
|
|
546
|
+
_LOGGER.debug(
|
|
547
|
+
"CYCLE_PRESET: %s:%s -> preset %d/%d = %s",
|
|
548
|
+
device_id, output_id, cycle_idx + 1, len(presets), preset
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
return await self.control_output(
|
|
552
|
+
device_id=device_id,
|
|
553
|
+
output_id=output_id,
|
|
554
|
+
action="ON",
|
|
555
|
+
effect=preset,
|
|
556
|
+
transition=transition,
|
|
557
|
+
)
|
|
558
|
+
|
|
459
559
|
async def control_cover(
|
|
460
560
|
self,
|
|
461
561
|
device_id: str,
|
|
@@ -6,13 +6,18 @@ and publishes the update status to Home Assistant via MQTT.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import asyncio
|
|
9
10
|
import json
|
|
10
11
|
import logging
|
|
12
|
+
import os
|
|
13
|
+
import subprocess
|
|
14
|
+
from collections.abc import Callable
|
|
11
15
|
from typing import TYPE_CHECKING
|
|
12
16
|
|
|
13
17
|
from boneio.core.utils.async_updater import AsyncUpdater
|
|
14
18
|
from boneio.core.utils.timeperiod import TimePeriod
|
|
15
19
|
from boneio.version import __version__
|
|
20
|
+
from boneio.webui.services.logs import is_running_as_service
|
|
16
21
|
|
|
17
22
|
if TYPE_CHECKING:
|
|
18
23
|
from boneio.core.manager import Manager
|
|
@@ -52,6 +57,7 @@ class UpdateManager(AsyncUpdater):
|
|
|
52
57
|
self._last_check_result: dict | None = None
|
|
53
58
|
self._last_published_state: str | None = None
|
|
54
59
|
self._ha_discovery_sent: bool = False
|
|
60
|
+
self._update_running: bool = False
|
|
55
61
|
|
|
56
62
|
# Initialize AsyncUpdater (starts periodic task)
|
|
57
63
|
super().__init__(manager=manager, update_interval=update_interval)
|
|
@@ -312,10 +318,16 @@ class UpdateManager(AsyncUpdater):
|
|
|
312
318
|
"""
|
|
313
319
|
return self._last_check_result
|
|
314
320
|
|
|
321
|
+
@property
|
|
322
|
+
def update_running(self) -> bool:
|
|
323
|
+
"""Whether an update is currently in progress."""
|
|
324
|
+
return self._update_running
|
|
325
|
+
|
|
315
326
|
async def handle_install_command(self, payload: str) -> None:
|
|
316
327
|
"""Handle install command from Home Assistant.
|
|
317
328
|
|
|
318
329
|
This is called when HA sends a message to the command topic.
|
|
330
|
+
Performs pip install of the latest version and restarts the service.
|
|
319
331
|
|
|
320
332
|
Args:
|
|
321
333
|
payload: MQTT payload (should be "INSTALL")
|
|
@@ -326,6 +338,14 @@ class UpdateManager(AsyncUpdater):
|
|
|
326
338
|
|
|
327
339
|
_LOGGER.info("Received install command from Home Assistant")
|
|
328
340
|
|
|
341
|
+
if not is_running_as_service():
|
|
342
|
+
_LOGGER.warning("Update via MQTT is only available when running as a service")
|
|
343
|
+
return
|
|
344
|
+
|
|
345
|
+
if self._update_running:
|
|
346
|
+
_LOGGER.warning("Update already in progress, ignoring install command")
|
|
347
|
+
return
|
|
348
|
+
|
|
329
349
|
# Check if update is available
|
|
330
350
|
if not self._last_check_result:
|
|
331
351
|
_LOGGER.warning("No update check result available, checking now...")
|
|
@@ -335,15 +355,257 @@ class UpdateManager(AsyncUpdater):
|
|
|
335
355
|
_LOGGER.warning("No update available to install")
|
|
336
356
|
return
|
|
337
357
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
#
|
|
358
|
+
target_version = self._last_check_result.get("latest_version")
|
|
359
|
+
|
|
360
|
+
# Run update in background task to not block MQTT
|
|
361
|
+
asyncio.create_task(
|
|
362
|
+
self.perform_update(target_version=target_version)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
async def perform_update(
|
|
366
|
+
self,
|
|
367
|
+
target_version: str | None = None,
|
|
368
|
+
on_progress: Callable[[int, str, str | None], None] | None = None,
|
|
369
|
+
) -> None:
|
|
370
|
+
"""Perform the actual update: pip install + restart.
|
|
371
|
+
|
|
372
|
+
This is the single update algorithm used by both MQTT (HA) and WebUI.
|
|
373
|
+
|
|
374
|
+
Handles pre-release versions by adding --pre flag.
|
|
375
|
+
Retries up to 3 times with 30s delay if pip install fails
|
|
376
|
+
(PyPI index may not have the version available immediately).
|
|
377
|
+
|
|
378
|
+
Args:
|
|
379
|
+
target_version: Version to install, or None for latest.
|
|
380
|
+
on_progress: Optional callback(progress_pct, step, log_msg).
|
|
381
|
+
Called at each stage so the caller can track progress.
|
|
382
|
+
If None, only MQTT progress is published.
|
|
383
|
+
"""
|
|
384
|
+
if self._update_running:
|
|
385
|
+
_LOGGER.warning("Update already in progress")
|
|
386
|
+
return
|
|
387
|
+
|
|
388
|
+
self._update_running = True
|
|
389
|
+
current_version = __version__
|
|
341
390
|
_LOGGER.info(
|
|
342
|
-
"
|
|
391
|
+
"Starting update from %s to %s",
|
|
392
|
+
current_version, target_version or "latest"
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
async def _report(progress: int, step: str, log_msg: str | None = None) -> None:
|
|
396
|
+
"""Report progress to both MQTT and optional callback."""
|
|
397
|
+
await self._publish_update_progress(
|
|
398
|
+
current_version=current_version,
|
|
399
|
+
target_version=target_version,
|
|
400
|
+
progress=progress,
|
|
401
|
+
)
|
|
402
|
+
if on_progress:
|
|
403
|
+
on_progress(progress, step, log_msg)
|
|
404
|
+
|
|
405
|
+
try:
|
|
406
|
+
await _report(5, "Finding virtual environment...")
|
|
407
|
+
|
|
408
|
+
# Find virtual environment
|
|
409
|
+
possible_venv_paths = [
|
|
410
|
+
os.path.expanduser("~/boneio/venv"),
|
|
411
|
+
os.path.expanduser("~/venv"),
|
|
412
|
+
"/opt/boneio/venv",
|
|
413
|
+
]
|
|
414
|
+
|
|
415
|
+
pip_path = None
|
|
416
|
+
venv_path = None
|
|
417
|
+
for path in possible_venv_paths:
|
|
418
|
+
pip_candidate = os.path.join(path, "bin", "pip")
|
|
419
|
+
if os.path.exists(pip_candidate):
|
|
420
|
+
venv_path = path
|
|
421
|
+
pip_path = pip_candidate
|
|
422
|
+
_LOGGER.info("Found venv pip at %s", pip_path)
|
|
423
|
+
break
|
|
424
|
+
|
|
425
|
+
if not pip_path:
|
|
426
|
+
_LOGGER.error("Virtual environment not found, cannot update")
|
|
427
|
+
await _report(0, "Failed", "Could not find virtual environment")
|
|
428
|
+
return
|
|
429
|
+
|
|
430
|
+
await _report(10, "Virtual environment found", f"Using venv at {venv_path}")
|
|
431
|
+
await _report(15, "Preparing update...", f"Current version: {current_version}")
|
|
432
|
+
await _report(30, "Upgrading pip...")
|
|
433
|
+
|
|
434
|
+
# Upgrade pip first
|
|
435
|
+
pip_upgrade = subprocess.run(
|
|
436
|
+
[pip_path, "install", "--upgrade", "pip"],
|
|
437
|
+
capture_output=True, text=True, timeout=120
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
if pip_upgrade.returncode == 0:
|
|
441
|
+
await _report(40, "Pip upgraded", "pip upgraded successfully")
|
|
442
|
+
else:
|
|
443
|
+
await _report(40, "Pip upgrade skipped", "pip upgrade failed, continuing...")
|
|
444
|
+
|
|
445
|
+
# Build pip install command
|
|
446
|
+
pip_cmd = [pip_path, "install", "--upgrade"]
|
|
447
|
+
|
|
448
|
+
# Add --pre flag for pre-release versions (dev, alpha, beta, rc)
|
|
449
|
+
needs_pre = False
|
|
450
|
+
if target_version and self._is_prerelease_version(target_version):
|
|
451
|
+
needs_pre = True
|
|
452
|
+
elif not target_version and self._is_prerelease_version(current_version):
|
|
453
|
+
needs_pre = True
|
|
454
|
+
|
|
455
|
+
if needs_pre:
|
|
456
|
+
pip_cmd.append("--pre")
|
|
457
|
+
await _report(42, "Using --pre flag", "Pre-release version detected")
|
|
458
|
+
|
|
459
|
+
if target_version:
|
|
460
|
+
pip_package = f"boneio=={target_version}"
|
|
461
|
+
else:
|
|
462
|
+
pip_package = "boneio"
|
|
463
|
+
|
|
464
|
+
pip_cmd.append(pip_package)
|
|
465
|
+
|
|
466
|
+
await _report(45, f"Downloading and installing {pip_package}...")
|
|
467
|
+
|
|
468
|
+
# Retry logic: PyPI may not have the version available immediately
|
|
469
|
+
max_retries = 3
|
|
470
|
+
retry_delay = 30 # seconds
|
|
471
|
+
result = None
|
|
472
|
+
|
|
473
|
+
for attempt in range(1, max_retries + 1):
|
|
474
|
+
await _report(
|
|
475
|
+
45 + (attempt - 1) * 10,
|
|
476
|
+
f"Installing (attempt {attempt}/{max_retries})...",
|
|
477
|
+
f"Running: {' '.join(pip_cmd)}"
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
result = subprocess.run(
|
|
481
|
+
pip_cmd,
|
|
482
|
+
capture_output=True, text=True, timeout=300
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
if result.returncode == 0:
|
|
486
|
+
break
|
|
487
|
+
|
|
488
|
+
_LOGGER.warning(
|
|
489
|
+
"pip install attempt %d/%d failed: %s",
|
|
490
|
+
attempt, max_retries, result.stderr.strip()
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
if attempt < max_retries:
|
|
494
|
+
await _report(
|
|
495
|
+
45 + attempt * 10,
|
|
496
|
+
f"Retrying in {retry_delay}s...",
|
|
497
|
+
f"Attempt {attempt} failed, PyPI index may not be ready"
|
|
498
|
+
)
|
|
499
|
+
await asyncio.sleep(retry_delay)
|
|
500
|
+
|
|
501
|
+
if not result or result.returncode != 0:
|
|
502
|
+
error_msg = result.stderr.strip() if result else "Unknown error"
|
|
503
|
+
_LOGGER.error(
|
|
504
|
+
"pip install failed after %d attempts: %s",
|
|
505
|
+
max_retries, error_msg
|
|
506
|
+
)
|
|
507
|
+
await _report(0, "Update failed", error_msg)
|
|
508
|
+
return
|
|
509
|
+
|
|
510
|
+
await _report(80, "BoneIO updated", "Package installed successfully")
|
|
511
|
+
await _report(85, "Verifying installation...")
|
|
512
|
+
|
|
513
|
+
# Verify installed version
|
|
514
|
+
version_result = subprocess.run(
|
|
515
|
+
[pip_path, "show", "boneio"],
|
|
516
|
+
capture_output=True, text=True
|
|
517
|
+
)
|
|
518
|
+
new_version = current_version
|
|
519
|
+
if version_result.returncode == 0:
|
|
520
|
+
for line in version_result.stdout.split('\n'):
|
|
521
|
+
if line.startswith('Version:'):
|
|
522
|
+
new_version = line.split(':')[1].strip()
|
|
523
|
+
break
|
|
524
|
+
|
|
525
|
+
_LOGGER.info(
|
|
526
|
+
"Update successful: %s -> %s. Restarting in 2 seconds...",
|
|
527
|
+
current_version, new_version
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
await _report(90, "Installation verified", f"Updated from {current_version} to {new_version}")
|
|
531
|
+
await _report(95, "Finalizing...")
|
|
532
|
+
|
|
533
|
+
# Publish final success state (no longer in progress)
|
|
534
|
+
current_version = new_version # update for final MQTT publish
|
|
535
|
+
await self._publish_update_progress(
|
|
536
|
+
current_version=new_version,
|
|
537
|
+
target_version=None,
|
|
538
|
+
progress=0,
|
|
539
|
+
)
|
|
540
|
+
if on_progress:
|
|
541
|
+
on_progress(100, "Update complete!", f"Restarting service in 2 seconds...")
|
|
542
|
+
|
|
543
|
+
await asyncio.sleep(2)
|
|
544
|
+
|
|
545
|
+
_LOGGER.info("Restarting BoneIO service after update...")
|
|
546
|
+
os._exit(0)
|
|
547
|
+
|
|
548
|
+
except subprocess.TimeoutExpired:
|
|
549
|
+
_LOGGER.error("Update process timed out")
|
|
550
|
+
await _report(0, "Timeout", "Update process timed out")
|
|
551
|
+
except Exception as e:
|
|
552
|
+
_LOGGER.error("Error during update: %s", e, exc_info=True)
|
|
553
|
+
await _report(0, "Error", f"Unexpected error: {e}")
|
|
554
|
+
finally:
|
|
555
|
+
self._update_running = False
|
|
556
|
+
|
|
557
|
+
@staticmethod
|
|
558
|
+
def _is_prerelease_version(version_str: str) -> bool:
|
|
559
|
+
"""Check if version string is a pre-release (dev, alpha, beta, rc).
|
|
560
|
+
|
|
561
|
+
Args:
|
|
562
|
+
version_str: Version string to check
|
|
563
|
+
|
|
564
|
+
Returns:
|
|
565
|
+
True if version is a pre-release
|
|
566
|
+
"""
|
|
567
|
+
ver_lower = version_str.lower()
|
|
568
|
+
return any(x in ver_lower for x in ['dev', 'alpha', 'beta', 'rc'])
|
|
569
|
+
|
|
570
|
+
async def _publish_update_progress(
|
|
571
|
+
self,
|
|
572
|
+
current_version: str,
|
|
573
|
+
target_version: str | None,
|
|
574
|
+
progress: int,
|
|
575
|
+
) -> None:
|
|
576
|
+
"""Publish update progress state to MQTT for HA.
|
|
577
|
+
|
|
578
|
+
HA update entity supports in_progress as:
|
|
579
|
+
- false/0: not updating
|
|
580
|
+
- true: updating (indeterminate)
|
|
581
|
+
- int 1-100: updating with progress percentage
|
|
582
|
+
|
|
583
|
+
Args:
|
|
584
|
+
current_version: Currently installed version
|
|
585
|
+
target_version: Version being installed (None if not updating)
|
|
586
|
+
progress: Update progress percentage (0 = not updating, 1-100 = in progress)
|
|
587
|
+
"""
|
|
588
|
+
# HA interprets 0/false as "not updating", 1-100 as "updating with progress"
|
|
589
|
+
in_progress_value: int | bool = progress if progress > 0 else False
|
|
590
|
+
|
|
591
|
+
state_payload = {
|
|
592
|
+
"installed_version": current_version,
|
|
593
|
+
"latest_version": target_version or current_version,
|
|
594
|
+
"title": "boneIO Black Firmware",
|
|
595
|
+
"release_url": self._last_check_result.get("release_url", "") if self._last_check_result else "",
|
|
596
|
+
"release_summary": self._last_check_result.get("release_notes", "") if self._last_check_result else "",
|
|
597
|
+
"entity_picture": "http://boneio.eu/logo_fb_circle.png",
|
|
598
|
+
"in_progress": in_progress_value,
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
topic_prefix = self._manager._config_helper.topic_prefix
|
|
602
|
+
self._manager.send_message(
|
|
603
|
+
topic=f"{topic_prefix}/update/state",
|
|
604
|
+
payload=json.dumps(state_payload),
|
|
605
|
+
retain=True,
|
|
343
606
|
)
|
|
344
607
|
|
|
345
|
-
|
|
346
|
-
# For now, users should use the WebUI to trigger updates
|
|
608
|
+
_LOGGER.debug("Published update progress: %d%%", progress)
|
|
347
609
|
|
|
348
610
|
async def send_ha_autodiscovery(self) -> None:
|
|
349
611
|
"""Send Home Assistant autodiscovery for Update entity."""
|
|
@@ -144,6 +144,9 @@ class MQTTClient(MessageBus):
|
|
|
144
144
|
@override
|
|
145
145
|
async def subscribe_and_listen(self, topic: str, callback: Callable[[str, str], Awaitable[None]]) -> None:
|
|
146
146
|
self._mqtt_energy_listeners[topic] = callback
|
|
147
|
+
# Subscribe immediately if already connected
|
|
148
|
+
if self._connection_established:
|
|
149
|
+
await self.subscribe(topics=[topic])
|
|
147
150
|
|
|
148
151
|
@override
|
|
149
152
|
async def unsubscribe_and_stop_listen(self, topic: str) -> None:
|
|
@@ -327,12 +330,11 @@ class MQTTClient(MessageBus):
|
|
|
327
330
|
topic=topic, payload=None, retain=True
|
|
328
331
|
)
|
|
329
332
|
break
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
break
|
|
333
|
+
for topic, listener_callback in self._mqtt_energy_listeners.items():
|
|
334
|
+
if message.topic.matches(topic):
|
|
335
|
+
callback_start = False
|
|
336
|
+
await listener_callback(str(message.topic), payload)
|
|
337
|
+
break
|
|
336
338
|
if callback_start:
|
|
337
339
|
_LOGGER.debug(
|
|
338
340
|
"Received message topic: %s, payload: %s",
|