boneio 1.3.0.dev14__tar.gz → 1.3.0.dev16__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.3.0.dev14/boneio.egg-info → boneio-1.3.0.dev16}/PKG-INFO +1 -1
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/irrigation/controller.py +67 -21
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/sensor/virtual_energy.py +98 -77
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/migrations/__init__.py +2 -1
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/yaml_util.py +23 -12
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/irrigation.py +3 -3
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/update.py +9 -4
- boneio-1.3.0.dev16/boneio/version.py +2 -0
- boneio-1.3.0.dev14/boneio/webui/frontend-dist/assets/ConfigEditor-CrqODtD9.js → boneio-1.3.0.dev16/boneio/webui/frontend-dist/assets/ConfigEditor-BA-Cp1Kt.js +1 -1
- boneio-1.3.0.dev16/boneio/webui/frontend-dist/assets/index-BPw0PLPj.js +39 -0
- boneio-1.3.0.dev14/boneio/webui/frontend-dist/assets/useTranslation-xq1ST8U-.js → boneio-1.3.0.dev16/boneio/webui/frontend-dist/assets/useTranslation-Cdm82kxW.js +2 -2
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/index.html +2 -2
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/sw.js +1 -1
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/irrigation.py +43 -36
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/modbus.py +4 -1
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio.egg-info/SOURCES.txt +3 -3
- boneio-1.3.0.dev14/boneio/version.py +0 -2
- boneio-1.3.0.dev14/boneio/webui/frontend-dist/assets/index-Cdw9RS1j.js +0 -39
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/LICENSE +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/MANIFEST.in +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/README.md +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.7/output_48_4.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.8/output_48_4.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/bonecli.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/cover/cover.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/cover/time_based.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/cover/venetian.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/group/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/group/output_group.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/input/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/input/detectors.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/input/event.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/irrigation/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/irrigation/water_source.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/output/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/output/basic.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/output/mcp.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/output/pca.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/output/pcf.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/template/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/template/alarm_panel.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/template/gate_cover.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/const.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/cloud/registration.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/package.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/discovery.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/events/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/events/bus.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/action_conditions.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/canopen.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/covers.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/display.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/inputs.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/manager.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/remote.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/templates/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/templates/alarm.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/templates/gate_cover.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/manager/templates.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/messaging/local.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/remote/base.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/remote/can.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/remote/esphome.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/remote/wled.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/sensor/base.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/sensor/system.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/state/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/state/manager.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/system/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/system/host_data.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/system/monitor.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/conditions.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/filter.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/logger.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/core/utils/util.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/48x4/adc.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/48x4/config.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/48x4/event.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/48x4/mqtt.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/48x4/output48x4A.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/can_master.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/can_slave.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/exceptions.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/bridge.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/client.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/interface.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/node.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/node_id.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/sudoers.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/can/test_od.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/display/early_oled.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/display/oled.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/input/base.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/integration/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/integration/homeassistant.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/integration/interlock.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/cli.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/client.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/inverters/thessla.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/other/wanas415.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/gdfs.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/gdfx.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/modbus/utils.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/models/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/models/actions.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/models/events.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/models/files.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/models/logs.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/models/mqtt.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/models/state.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/runner.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/actions.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/condition.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/filters.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/id.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/remote_devices.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/schema.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/action_validation.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/app.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/aiConfig-DCT969oj.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/aiWizardPrompt-Dpts0jpN.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/editor.worker-BVjSvWeP.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/index-CCPsr7-u.css +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/json.worker-CqOJL4FD.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/monaco-B9WiNxkw.css +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/monaco-CAZoGZNF.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/rolldown-runtime-Dw2cE7zH.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/vendor-BD5Ml_Uz.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BJd1pjeW.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/assets/yaml.worker-nZQZSRZ7.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/config.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/frontend-dist/workbox-4eca85ba.js +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/can.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/config.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/remote_devices.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/system.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/timezone_sudoers.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/tools.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/routes/update.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/binary_sensor.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/boneio.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/can.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/config.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/cover.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/event.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/irrigation.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/mcp23017.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/modbus_devices.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/oled.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/output.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/remote_devices.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/sensor.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/template.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/services/logs.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/web_server.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/pyproject.toml +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/setup.cfg +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/setup.py +0 -0
- {boneio-1.3.0.dev14 → boneio-1.3.0.dev16}/tests/test_py313_compatibility.py +0 -0
|
@@ -251,7 +251,10 @@ class IrrigationController:
|
|
|
251
251
|
if skip_count >= zone.run_every_n - 1:
|
|
252
252
|
_LOGGER.debug(
|
|
253
253
|
"Irrigation %s: zone %s eligible (skip_count=%d >= %d)",
|
|
254
|
-
self.id,
|
|
254
|
+
self.id,
|
|
255
|
+
zone.id,
|
|
256
|
+
skip_count,
|
|
257
|
+
zone.run_every_n - 1,
|
|
255
258
|
)
|
|
256
259
|
eligible.append((idx, zone))
|
|
257
260
|
# Reset counter — will be saved when zone finishes in _advance_to_next_zone
|
|
@@ -260,7 +263,10 @@ class IrrigationController:
|
|
|
260
263
|
self._save(counter_key, skip_count)
|
|
261
264
|
_LOGGER.debug(
|
|
262
265
|
"Irrigation %s: zone %s NOT eligible (skip_count=%d < %d)",
|
|
263
|
-
self.id,
|
|
266
|
+
self.id,
|
|
267
|
+
zone.id,
|
|
268
|
+
skip_count,
|
|
269
|
+
zone.run_every_n - 1,
|
|
264
270
|
)
|
|
265
271
|
return eligible
|
|
266
272
|
|
|
@@ -268,7 +274,10 @@ class IrrigationController:
|
|
|
268
274
|
controller_state = ON if self._state in (ControllerState.RUNNING, ControllerState.PAUSED) else OFF
|
|
269
275
|
_LOGGER.debug(
|
|
270
276
|
"Irrigation %s publish_all_states: controller=%s (state=%s, active_zone=%s)",
|
|
271
|
-
self.id,
|
|
277
|
+
self.id,
|
|
278
|
+
controller_state,
|
|
279
|
+
self._state.value,
|
|
280
|
+
self._active_zone_idx,
|
|
272
281
|
)
|
|
273
282
|
self._publish(self._state_topic(), {"state": controller_state})
|
|
274
283
|
self._publish(
|
|
@@ -301,14 +310,18 @@ class IrrigationController:
|
|
|
301
310
|
active = ON if self._active_zone_idx == idx and self._state == ControllerState.RUNNING else OFF
|
|
302
311
|
_LOGGER.debug(
|
|
303
312
|
"Irrigation %s: zone %s idx=%d active=%s (active_zone_idx=%s)",
|
|
304
|
-
self.id,
|
|
313
|
+
self.id,
|
|
314
|
+
zone.id,
|
|
315
|
+
idx,
|
|
316
|
+
active,
|
|
317
|
+
self._active_zone_idx,
|
|
305
318
|
)
|
|
306
319
|
self._publish(self._zone_state_topic(zone.id), {"state": active})
|
|
307
320
|
self._publish(
|
|
308
321
|
self._setting_state_topic(f"zone/{zone.id}/enabled"),
|
|
309
322
|
{"state": ON if zone.enabled else OFF},
|
|
310
323
|
)
|
|
311
|
-
self._publish(self._zone_duration_topic(zone.id), {"value": zone.run_duration})
|
|
324
|
+
self._publish(self._zone_duration_topic(zone.id), {"value": max(1, round(zone.run_duration / 60))})
|
|
312
325
|
|
|
313
326
|
for idx, sched in enumerate(self._schedule):
|
|
314
327
|
self._publish(
|
|
@@ -333,7 +346,9 @@ class IrrigationController:
|
|
|
333
346
|
async def shutdown(self) -> None:
|
|
334
347
|
_LOGGER.debug(
|
|
335
348
|
"Irrigation %s shutdown called (state=%s, active_zone=%s). Caller: %s",
|
|
336
|
-
self.id,
|
|
349
|
+
self.id,
|
|
350
|
+
self._state.value,
|
|
351
|
+
self._active_zone_idx,
|
|
337
352
|
"".join(traceback.format_stack(limit=5)),
|
|
338
353
|
)
|
|
339
354
|
self.stop_schedules()
|
|
@@ -378,7 +393,10 @@ class IrrigationController:
|
|
|
378
393
|
async def start_full_cycle(self) -> None:
|
|
379
394
|
_LOGGER.debug(
|
|
380
395
|
"Irrigation %s start_full_cycle: state=%s standby=%s skip_next=%s",
|
|
381
|
-
self.id,
|
|
396
|
+
self.id,
|
|
397
|
+
self._state.value,
|
|
398
|
+
self._standby,
|
|
399
|
+
self._skip_next_run,
|
|
382
400
|
)
|
|
383
401
|
if self._standby:
|
|
384
402
|
_LOGGER.info("Irrigation %s is in standby mode, not starting", self.id)
|
|
@@ -403,7 +421,10 @@ class IrrigationController:
|
|
|
403
421
|
async def start_single_zone(self, zone_id: str) -> None:
|
|
404
422
|
_LOGGER.debug(
|
|
405
423
|
"Irrigation %s start_single_zone('%s') state=%s standby=%s",
|
|
406
|
-
self.id,
|
|
424
|
+
self.id,
|
|
425
|
+
zone_id,
|
|
426
|
+
self._state.value,
|
|
427
|
+
self._standby,
|
|
407
428
|
)
|
|
408
429
|
if self._standby:
|
|
409
430
|
_LOGGER.info("Irrigation %s is in standby mode, not starting zone", self.id)
|
|
@@ -431,7 +452,8 @@ class IrrigationController:
|
|
|
431
452
|
eligible = self._eligible_zones()
|
|
432
453
|
_LOGGER.debug(
|
|
433
454
|
"Irrigation %s _start_cycle_from_eligible: %d eligible zones: %s",
|
|
434
|
-
self.id,
|
|
455
|
+
self.id,
|
|
456
|
+
len(eligible),
|
|
435
457
|
[(idx, z.id) for idx, z in eligible],
|
|
436
458
|
)
|
|
437
459
|
if not eligible:
|
|
@@ -447,7 +469,10 @@ class IrrigationController:
|
|
|
447
469
|
async def _advance_to_next_zone(self, force: bool = False) -> None:
|
|
448
470
|
_LOGGER.debug(
|
|
449
471
|
"Irrigation %s _advance_to_next_zone(force=%s) active_zone=%s single_zone=%s",
|
|
450
|
-
self.id,
|
|
472
|
+
self.id,
|
|
473
|
+
force,
|
|
474
|
+
self._active_zone_idx,
|
|
475
|
+
self._single_zone_mode,
|
|
451
476
|
)
|
|
452
477
|
if self._active_zone_idx is None:
|
|
453
478
|
_LOGGER.debug("Irrigation %s: no active zone, shutting down", self.id)
|
|
@@ -551,8 +576,12 @@ class IrrigationController:
|
|
|
551
576
|
|
|
552
577
|
_LOGGER.debug(
|
|
553
578
|
"Irrigation %s _start_zone: idx=%d, zone=%s, valve=%s, duration=%ds, source=%s",
|
|
554
|
-
self.id,
|
|
555
|
-
|
|
579
|
+
self.id,
|
|
580
|
+
idx,
|
|
581
|
+
zone.id,
|
|
582
|
+
zone.valve.id if zone.valve else "NONE",
|
|
583
|
+
duration,
|
|
584
|
+
src.id if src else "NONE",
|
|
556
585
|
)
|
|
557
586
|
|
|
558
587
|
self._active_zone_idx = idx
|
|
@@ -562,12 +591,19 @@ class IrrigationController:
|
|
|
562
591
|
if src is not None:
|
|
563
592
|
if src.pump_start_valve_delay_s > 0:
|
|
564
593
|
# Source first (pump+valve), then zone valve after delay
|
|
565
|
-
_LOGGER.debug(
|
|
594
|
+
_LOGGER.debug(
|
|
595
|
+
"Irrigation %s: source '%s' ON, then wait %ds", self.id, src.id, src.pump_start_valve_delay_s
|
|
596
|
+
)
|
|
566
597
|
await self._activate_source()
|
|
567
598
|
await asyncio.sleep(src.pump_start_valve_delay_s)
|
|
568
599
|
elif src.pump_start_pump_delay_s > 0:
|
|
569
600
|
# Zone valve first, then source after delay
|
|
570
|
-
_LOGGER.debug(
|
|
601
|
+
_LOGGER.debug(
|
|
602
|
+
"Irrigation %s: zone valve ON first, then source '%s' after %ds",
|
|
603
|
+
self.id,
|
|
604
|
+
src.id,
|
|
605
|
+
src.pump_start_pump_delay_s,
|
|
606
|
+
)
|
|
571
607
|
try:
|
|
572
608
|
await zone.valve.async_turn_on(timestamp=time.time())
|
|
573
609
|
except Exception as err:
|
|
@@ -584,7 +620,10 @@ class IrrigationController:
|
|
|
584
620
|
except BaseException as err:
|
|
585
621
|
_LOGGER.error(
|
|
586
622
|
"Irrigation %s: CRITICAL error after valve ON (pump delay path): %s (%s)",
|
|
587
|
-
self.id,
|
|
623
|
+
self.id,
|
|
624
|
+
err,
|
|
625
|
+
type(err).__name__,
|
|
626
|
+
exc_info=True,
|
|
588
627
|
)
|
|
589
628
|
return
|
|
590
629
|
else:
|
|
@@ -612,7 +651,10 @@ class IrrigationController:
|
|
|
612
651
|
except BaseException as err:
|
|
613
652
|
_LOGGER.error(
|
|
614
653
|
"Irrigation %s: CRITICAL error after valve ON: %s (%s)",
|
|
615
|
-
self.id,
|
|
654
|
+
self.id,
|
|
655
|
+
err,
|
|
656
|
+
type(err).__name__,
|
|
657
|
+
exc_info=True,
|
|
616
658
|
)
|
|
617
659
|
|
|
618
660
|
async def _stop_current_zone(self) -> None:
|
|
@@ -713,24 +755,28 @@ class IrrigationController:
|
|
|
713
755
|
|
|
714
756
|
async def handle_zone_command(self, zone_id: str, payload: str) -> None:
|
|
715
757
|
upper = payload.strip().upper()
|
|
716
|
-
_LOGGER.debug(
|
|
758
|
+
_LOGGER.debug(
|
|
759
|
+
"Irrigation %s handle_zone_command: zone='%s' payload='%s' → upper='%s'", self.id, zone_id, payload, upper
|
|
760
|
+
)
|
|
717
761
|
if upper == ON:
|
|
718
762
|
await self.start_single_zone(zone_id)
|
|
719
763
|
elif upper == OFF:
|
|
720
764
|
await self.shutdown()
|
|
721
765
|
|
|
722
766
|
async def handle_zone_duration_command(self, zone_id: str, payload: str) -> None:
|
|
767
|
+
"""Handle duration change from HA (value in minutes)."""
|
|
723
768
|
try:
|
|
724
|
-
|
|
769
|
+
minutes = int(float(payload))
|
|
725
770
|
except (TypeError, ValueError):
|
|
726
771
|
return
|
|
727
|
-
if
|
|
772
|
+
if minutes <= 0:
|
|
728
773
|
return
|
|
729
774
|
|
|
775
|
+
duration_s = minutes * 60
|
|
730
776
|
for zone in self._zones:
|
|
731
777
|
if zone.id == zone_id:
|
|
732
|
-
zone.run_duration =
|
|
733
|
-
self._save(f"zone/{zone.id}/duration",
|
|
778
|
+
zone.run_duration = duration_s
|
|
779
|
+
self._save(f"zone/{zone.id}/duration", duration_s)
|
|
734
780
|
break
|
|
735
781
|
await self.publish_all_states()
|
|
736
782
|
|
|
@@ -4,6 +4,7 @@ Creates virtual power/energy or water flow sensors linked to outputs.
|
|
|
4
4
|
When the linked output is ON, the sensor calculates consumption based on
|
|
5
5
|
configured power_usage or flow_rate.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
from __future__ import annotations
|
|
8
9
|
|
|
9
10
|
import asyncio
|
|
@@ -26,10 +27,10 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
26
27
|
|
|
27
28
|
class VirtualEnergySensor:
|
|
28
29
|
"""Virtual energy/water sensor linked to an output.
|
|
29
|
-
|
|
30
|
+
|
|
30
31
|
Tracks energy consumption (Wh) or water consumption (L) based on
|
|
31
32
|
configured power_usage (W) or flow_rate (L/h) when the linked output is ON.
|
|
32
|
-
|
|
33
|
+
|
|
33
34
|
Args:
|
|
34
35
|
id: Unique sensor identifier
|
|
35
36
|
name: Display name for Home Assistant
|
|
@@ -68,23 +69,26 @@ class VirtualEnergySensor:
|
|
|
68
69
|
self._power_usage = power_usage
|
|
69
70
|
self._flow_rate = flow_rate
|
|
70
71
|
self._area = area
|
|
71
|
-
|
|
72
|
+
|
|
72
73
|
self._virtual_sensors_task = None
|
|
73
|
-
|
|
74
|
+
|
|
74
75
|
# Counters
|
|
75
76
|
self._energy_consumed_Wh = 0.0
|
|
76
77
|
self._water_consumed_L = 0.0
|
|
77
|
-
self._last_on_timestamp =
|
|
78
|
-
|
|
78
|
+
self._last_on_timestamp = None
|
|
79
|
+
|
|
80
|
+
# State restore gate — prevents sending state=0 before
|
|
81
|
+
# the retained MQTT message with the real value is received.
|
|
82
|
+
self._restore_done = asyncio.Event()
|
|
83
|
+
|
|
79
84
|
# MQTT topic for this sensor
|
|
80
85
|
self._sensor_topic = f"{topic_prefix}/energy/{id}"
|
|
81
|
-
|
|
86
|
+
|
|
82
87
|
# Subscribe to restore state from MQTT
|
|
83
88
|
self._subscribe_restore_state()
|
|
84
|
-
|
|
89
|
+
|
|
85
90
|
_LOGGER.info(
|
|
86
|
-
"Initialized VirtualEnergySensor: id=%s, name=%s, output=%s, type=%s",
|
|
87
|
-
id, name, output.id, sensor_type
|
|
91
|
+
"Initialized VirtualEnergySensor: id=%s, name=%s, output=%s, type=%s", id, name, output.id, sensor_type
|
|
88
92
|
)
|
|
89
93
|
|
|
90
94
|
@property
|
|
@@ -140,18 +144,34 @@ class VirtualEnergySensor:
|
|
|
140
144
|
# Update one last time before stopping
|
|
141
145
|
self._update_consumption()
|
|
142
146
|
self._last_on_timestamp = None
|
|
143
|
-
|
|
147
|
+
|
|
144
148
|
if self._virtual_sensors_task is not None:
|
|
145
149
|
self._virtual_sensors_task.cancel()
|
|
146
150
|
self._virtual_sensors_task = None
|
|
147
|
-
|
|
148
|
-
# Send final state
|
|
149
|
-
self.
|
|
151
|
+
|
|
152
|
+
# Send final state (only if restore is done)
|
|
153
|
+
if self._restore_done.is_set():
|
|
154
|
+
self._send_state()
|
|
150
155
|
_LOGGER.debug("Stopped tracking for virtual sensor %s", self._id)
|
|
151
156
|
|
|
152
157
|
async def _tracking_loop(self):
|
|
153
158
|
"""Periodically update and send state every 30 seconds while output is ON."""
|
|
154
159
|
try:
|
|
160
|
+
# Wait for state restore before sending any state.
|
|
161
|
+
# This prevents overwriting the retained MQTT value with 0.
|
|
162
|
+
# Timeout of 5s ensures we don't hang if MQTT is down.
|
|
163
|
+
try:
|
|
164
|
+
await asyncio.wait_for(self._restore_done.wait(), timeout=5.0)
|
|
165
|
+
except TimeoutError:
|
|
166
|
+
_LOGGER.warning(
|
|
167
|
+
"State restore timeout for %s, starting with energy=%.4f Wh", self._id, self._energy_consumed_Wh
|
|
168
|
+
)
|
|
169
|
+
self._restore_done.set()
|
|
170
|
+
|
|
171
|
+
# Reset on_timestamp after restore so we don't count
|
|
172
|
+
# the time elapsed during the restore wait.
|
|
173
|
+
self._last_on_timestamp = time.time()
|
|
174
|
+
|
|
155
175
|
while self._output.state == ON:
|
|
156
176
|
self._update_consumption()
|
|
157
177
|
self._send_state()
|
|
@@ -164,49 +184,42 @@ class VirtualEnergySensor:
|
|
|
164
184
|
now = time.time()
|
|
165
185
|
if self._output.state == ON and self._last_on_timestamp is not None:
|
|
166
186
|
elapsed = now - self._last_on_timestamp
|
|
167
|
-
|
|
187
|
+
|
|
168
188
|
if self._sensor_type == "power" and self._power_usage is not None:
|
|
169
189
|
self._energy_consumed_Wh += (self._power_usage * elapsed) / 3600.0
|
|
170
|
-
_LOGGER.debug(
|
|
171
|
-
"Energy updated for %s: %.4f Wh",
|
|
172
|
-
self._id, self._energy_consumed_Wh
|
|
173
|
-
)
|
|
190
|
+
_LOGGER.debug("Energy updated for %s: %.4f Wh", self._id, self._energy_consumed_Wh)
|
|
174
191
|
elif self._sensor_type == "water" and self._flow_rate is not None:
|
|
175
192
|
self._water_consumed_L += (self._flow_rate * elapsed) / 3600.0
|
|
176
|
-
_LOGGER.debug(
|
|
177
|
-
|
|
178
|
-
self._id, self._water_consumed_L
|
|
179
|
-
)
|
|
180
|
-
|
|
193
|
+
_LOGGER.debug("Water updated for %s: %.4f L", self._id, self._water_consumed_L)
|
|
194
|
+
|
|
181
195
|
self._last_on_timestamp = now
|
|
182
196
|
|
|
183
197
|
def _subscribe_restore_state(self):
|
|
184
|
-
"""Subscribe to retained MQTT topic to restore state on startup.
|
|
198
|
+
"""Subscribe to retained MQTT topic to restore state on startup.
|
|
199
|
+
|
|
200
|
+
Sets _restore_done event when restore is complete (or if no retained
|
|
201
|
+
message is available). This gates _send_state() to prevent overwriting
|
|
202
|
+
the retained value with 0.
|
|
203
|
+
"""
|
|
204
|
+
|
|
185
205
|
async def on_message(_topic, payload):
|
|
186
206
|
try:
|
|
187
207
|
data = json.loads(payload)
|
|
188
208
|
if isinstance(data, dict):
|
|
189
209
|
if "energy" in data:
|
|
190
210
|
self._energy_consumed_Wh = float(data["energy"])
|
|
191
|
-
_LOGGER.info(
|
|
192
|
-
"Restored energy state for %s: %.4f Wh",
|
|
193
|
-
self._id, self._energy_consumed_Wh
|
|
194
|
-
)
|
|
211
|
+
_LOGGER.info("Restored energy state for %s: %.4f Wh", self._id, self._energy_consumed_Wh)
|
|
195
212
|
if "water" in data:
|
|
196
213
|
self._water_consumed_L = float(data["water"])
|
|
197
|
-
_LOGGER.info(
|
|
198
|
-
"Restored water state for %s: %.4f L",
|
|
199
|
-
self._id, self._water_consumed_L
|
|
200
|
-
)
|
|
214
|
+
_LOGGER.info("Restored water state for %s: %.4f L", self._id, self._water_consumed_L)
|
|
201
215
|
except Exception as e:
|
|
202
216
|
_LOGGER.warning("Failed to restore state for %s: %s", self._id, e)
|
|
203
217
|
finally:
|
|
218
|
+
self._restore_done.set()
|
|
204
219
|
await self._message_bus.unsubscribe_and_stop_listen(self._sensor_topic)
|
|
205
|
-
|
|
220
|
+
|
|
206
221
|
if self._message_bus is not None:
|
|
207
|
-
asyncio.create_task(
|
|
208
|
-
self._message_bus.subscribe_and_listen(self._sensor_topic, on_message)
|
|
209
|
-
)
|
|
222
|
+
asyncio.create_task(self._message_bus.subscribe_and_listen(self._sensor_topic, on_message))
|
|
210
223
|
|
|
211
224
|
def get_current_power(self) -> float:
|
|
212
225
|
"""Get current power usage in W (0 if output is OFF)."""
|
|
@@ -232,58 +245,66 @@ class VirtualEnergySensor:
|
|
|
232
245
|
"""Send current state to MQTT and EventBus (for WebSocket/frontend)."""
|
|
233
246
|
payload = {}
|
|
234
247
|
timestamp = int(time.time())
|
|
235
|
-
|
|
248
|
+
|
|
236
249
|
if self._sensor_type == "power":
|
|
237
250
|
payload["power"] = self.get_current_power()
|
|
238
251
|
payload["energy"] = self.get_total_energy()
|
|
239
|
-
|
|
252
|
+
|
|
240
253
|
# Send SensorEvents to frontend via EventBus
|
|
241
|
-
self._event_bus.trigger_event(
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
254
|
+
self._event_bus.trigger_event(
|
|
255
|
+
SensorEvent(
|
|
256
|
+
entity_id=f"{self._id}_power",
|
|
257
|
+
state=SensorState(
|
|
258
|
+
id=f"{self._id}_power",
|
|
259
|
+
name=f"{self._name} Power",
|
|
260
|
+
state=self.get_current_power(),
|
|
261
|
+
unit="W",
|
|
262
|
+
timestamp=timestamp,
|
|
263
|
+
),
|
|
249
264
|
)
|
|
250
|
-
)
|
|
251
|
-
self._event_bus.trigger_event(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
265
|
+
)
|
|
266
|
+
self._event_bus.trigger_event(
|
|
267
|
+
SensorEvent(
|
|
268
|
+
entity_id=f"{self._id}_energy",
|
|
269
|
+
state=SensorState(
|
|
270
|
+
id=f"{self._id}_energy",
|
|
271
|
+
name=f"{self._name} Energy",
|
|
272
|
+
state=self.get_total_energy(),
|
|
273
|
+
unit="Wh",
|
|
274
|
+
timestamp=timestamp,
|
|
275
|
+
),
|
|
259
276
|
)
|
|
260
|
-
)
|
|
277
|
+
)
|
|
261
278
|
elif self._sensor_type == "water":
|
|
262
279
|
payload["volume_flow_rate"] = self.get_current_flow_rate()
|
|
263
280
|
payload["water"] = self.get_total_water()
|
|
264
|
-
|
|
281
|
+
|
|
265
282
|
# Send SensorEvents to frontend via EventBus
|
|
266
|
-
self._event_bus.trigger_event(
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
283
|
+
self._event_bus.trigger_event(
|
|
284
|
+
SensorEvent(
|
|
285
|
+
entity_id=f"{self._id}_flow",
|
|
286
|
+
state=SensorState(
|
|
287
|
+
id=f"{self._id}_flow",
|
|
288
|
+
name=f"{self._name} Flow Rate",
|
|
289
|
+
state=self.get_current_flow_rate(),
|
|
290
|
+
unit="L/h",
|
|
291
|
+
timestamp=timestamp,
|
|
292
|
+
),
|
|
274
293
|
)
|
|
275
|
-
)
|
|
276
|
-
self._event_bus.trigger_event(
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
294
|
+
)
|
|
295
|
+
self._event_bus.trigger_event(
|
|
296
|
+
SensorEvent(
|
|
297
|
+
entity_id=f"{self._id}_water",
|
|
298
|
+
state=SensorState(
|
|
299
|
+
id=f"{self._id}_water",
|
|
300
|
+
name=f"{self._name} Water",
|
|
301
|
+
state=self.get_total_water(),
|
|
302
|
+
unit="L",
|
|
303
|
+
timestamp=timestamp,
|
|
304
|
+
),
|
|
284
305
|
)
|
|
285
|
-
)
|
|
286
|
-
|
|
306
|
+
)
|
|
307
|
+
|
|
287
308
|
self._message_bus.send_message(
|
|
288
309
|
topic=self._sensor_topic,
|
|
289
310
|
payload=payload,
|
|
@@ -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 = 3
|
|
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.
|
|
@@ -25,6 +25,7 @@ SCHEMA_VERSION_APP_MAP: dict[int, str] = {
|
|
|
25
25
|
0: "1.0.0", # original schema
|
|
26
26
|
1: "1.2.0dev1", # proxy_port rename
|
|
27
27
|
2: "1.3.0dev1", # transition timeperiod
|
|
28
|
+
3: "1.3.0dev7", # irrigation section
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
|
|
@@ -954,7 +954,7 @@ def _full_config_validation(config_file: str, config_yaml: dict) -> dict:
|
|
|
954
954
|
v = CustomValidator(schema, purge_unknown=True)
|
|
955
955
|
_LOGGER.debug("[STARTUP TIMING] CustomValidator init: %.2fs", _time.monotonic() - _t2)
|
|
956
956
|
|
|
957
|
-
# Check if config was created by a newer app version (
|
|
957
|
+
# Check if config was created by a newer app version (downgrade scenario)
|
|
958
958
|
from boneio.core.config.migrations import (
|
|
959
959
|
CURRENT_SCHEMA_VERSION as _CURRENT_SCHEMA,
|
|
960
960
|
)
|
|
@@ -962,7 +962,8 @@ def _full_config_validation(config_file: str, config_yaml: dict) -> dict:
|
|
|
962
962
|
get_config_version as _get_cv,
|
|
963
963
|
)
|
|
964
964
|
_cv = _get_cv(config_yaml)
|
|
965
|
-
|
|
965
|
+
_is_downgraded = _cv > _CURRENT_SCHEMA
|
|
966
|
+
if _is_downgraded:
|
|
966
967
|
_LOGGER.warning(
|
|
967
968
|
"Config version %d is newer than supported schema version %d. "
|
|
968
969
|
"This config was created by a newer version of boneIO. "
|
|
@@ -989,16 +990,26 @@ def _full_config_validation(config_file: str, config_yaml: dict) -> dict:
|
|
|
989
990
|
# Finally validate
|
|
990
991
|
_t6 = _time.monotonic()
|
|
991
992
|
if not v.validate(merged_doc, schema): # type: ignore[attr-defined]
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
993
|
+
if _is_downgraded:
|
|
994
|
+
# Downgrade scenario: log validation errors as warnings and continue
|
|
995
|
+
# with the validated document (cerberus keeps valid fields).
|
|
996
|
+
_LOGGER.warning(
|
|
997
|
+
"Config validation errors (ignored due to downgrade from schema v%d): %s",
|
|
998
|
+
_cv, v.errors,
|
|
999
|
+
)
|
|
1000
|
+
# Use the validated document which has unknown fields purged
|
|
1001
|
+
merged_doc = v.document # type: ignore[attr-defined]
|
|
1002
|
+
else:
|
|
1003
|
+
error_msg = "Configuration validation failed:\n"
|
|
1004
|
+
for field, errors in v.errors.items(): # type: ignore[attr-defined]
|
|
1005
|
+
error_lines = []
|
|
1006
|
+
if "line" in v.errors[field][0]: # type: ignore[attr-defined]
|
|
1007
|
+
error_lines = [
|
|
1008
|
+
f"{v.errors[field][0]['line']+1}: {line}" # type: ignore[attr-defined]
|
|
1009
|
+
for line in config_yaml.splitlines()[v.errors[field][0]["line"]-1:v.errors[field][0]["line"]+1] # type: ignore[attr-defined]
|
|
1010
|
+
]
|
|
1011
|
+
error_msg += f"\n- {field}: {errors}\n{', '.join(error_lines)}"
|
|
1012
|
+
raise ConfigurationException(error_msg)
|
|
1002
1013
|
_LOGGER.debug("[STARTUP TIMING] v.validate: %.2fs", _time.monotonic() - _t6)
|
|
1003
1014
|
|
|
1004
1015
|
# Save to cache for next startup
|
|
@@ -105,7 +105,7 @@ class IrrigationManager:
|
|
|
105
105
|
return None
|
|
106
106
|
|
|
107
107
|
run_duration = int(parse_time_to_seconds(zone_cfg.get("run_duration"), 60))
|
|
108
|
-
run_duration = max(
|
|
108
|
+
run_duration = max(60, run_duration)
|
|
109
109
|
|
|
110
110
|
run_every_n = int(zone_cfg.get("run_every_n", 1))
|
|
111
111
|
run_every_n = max(1, run_every_n)
|
|
@@ -535,9 +535,9 @@ class IrrigationManager:
|
|
|
535
535
|
suffix=f"zone/{zone.id}/duration",
|
|
536
536
|
name=f"{ctrl.name} {zone.name} Duration",
|
|
537
537
|
min_val=1,
|
|
538
|
-
max_val=
|
|
538
|
+
max_val=1440,
|
|
539
539
|
step=1,
|
|
540
|
-
unit="
|
|
540
|
+
unit="min",
|
|
541
541
|
config_helper=cfg,
|
|
542
542
|
),
|
|
543
543
|
)
|
|
@@ -269,17 +269,19 @@ class UpdateManager(AsyncUpdater):
|
|
|
269
269
|
latest_version = update_info.get("latest_version", current_version)
|
|
270
270
|
|
|
271
271
|
# Build state payload (JSON format for HA Update entity)
|
|
272
|
+
# Always include in_progress/update_percentage to clear any retained
|
|
273
|
+
# progress state left by a previous update (e.g., after restart).
|
|
272
274
|
state_payload = {
|
|
273
275
|
"installed_version": current_version,
|
|
274
276
|
"latest_version": latest_version,
|
|
275
277
|
"title": "boneIO Black Firmware",
|
|
276
278
|
"release_url": update_info.get("release_url", ""),
|
|
277
279
|
"release_summary": update_info.get("release_notes", "")[:255], # HA limit
|
|
280
|
+
"entity_picture": "http://boneio.eu/logo_fb_circle.png",
|
|
281
|
+
"in_progress": False,
|
|
282
|
+
"update_percentage": None,
|
|
278
283
|
}
|
|
279
284
|
|
|
280
|
-
# Add entity_picture (boneIO logo from HA brands)
|
|
281
|
-
state_payload["entity_picture"] = "http://boneio.eu/logo_fb_circle.png"
|
|
282
|
-
|
|
283
285
|
# Convert to JSON
|
|
284
286
|
payload_json = json.dumps(state_payload)
|
|
285
287
|
|
|
@@ -535,7 +537,10 @@ class UpdateManager(AsyncUpdater):
|
|
|
535
537
|
if on_progress:
|
|
536
538
|
on_progress(100, "Update complete!", "Restarting service in 2 seconds...")
|
|
537
539
|
|
|
538
|
-
|
|
540
|
+
# Wait long enough for MQTT to drain the final state message
|
|
541
|
+
# before killing the process. Short delays risk the retained
|
|
542
|
+
# "in_progress" message persisting in the broker.
|
|
543
|
+
await asyncio.sleep(5)
|
|
539
544
|
|
|
540
545
|
_LOGGER.info("Restarting BoneIO service after update...")
|
|
541
546
|
os._exit(0)
|