boneio 1.3.1.dev2__tar.gz → 1.4.0__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.1.dev2/boneio.egg-info → boneio-1.4.0}/PKG-INFO +1 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/cover.py +22 -11
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/time_based.py +2 -2
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/venetian.py +165 -77
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/group/output_group.py +9 -2
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/__init__.py +6 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/detectors.py +87 -0
- boneio-1.4.0/boneio/components/input/remote/__init__.py +22 -0
- boneio-1.4.0/boneio/components/input/remote/base.py +337 -0
- boneio-1.4.0/boneio/components/input/remote/esphome.py +94 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/irrigation/controller.py +363 -47
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/irrigation/water_source.py +39 -6
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/basic.py +22 -28
- boneio-1.4.0/boneio/components/output/remote.py +762 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/alarm_panel.py +68 -18
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/yaml_util.py +3 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/covers.py +1 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/inputs.py +252 -79
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/irrigation.py +124 -54
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/manager.py +562 -128
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/remote.py +63 -2
- boneio-1.4.0/boneio/core/manager/remote_input_registrar.py +236 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/alarm.py +15 -10
- boneio-1.4.0/boneio/core/messaging/lox.py +326 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/esphome.py +520 -275
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/wled.py +36 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/sensor/base.py +7 -2
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/sensor/system.py +24 -8
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/early_oled.py +22 -16
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/oled.py +7 -3
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/input/base.py +4 -2
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/dallas.py +25 -22
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/integration/homeassistant.py +183 -7
- boneio-1.4.0/boneio/integration/lox_template.py +367 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/MANIFEST.sha256 +1 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/sudoers/boneio +1 -1
- boneio-1.4.0/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +35 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/coordinator.py +75 -2
- boneio-1.4.0/boneio/modbus/devices/hvac/eht-topventil-plus.json +311 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/__init__.py +2 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/state.py +14 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/runner.py +6 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/actions.yaml +49 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/remote_devices.yaml +0 -2
- boneio-1.4.0/boneio/schema/remote_inputs.yaml +128 -0
- boneio-1.4.0/boneio/schema/remote_outputs.yaml +188 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/schema.yaml +75 -2
- boneio-1.4.0/boneio/version.py +2 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/action_validation.py +1 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/app.py +30 -20
- boneio-1.4.0/boneio/webui/dashboard_cards.py +310 -0
- boneio-1.4.0/boneio/webui/frontend-dist/assets/ConfigEditor-DqDX4DyY.js +1 -0
- boneio-1.4.0/boneio/webui/frontend-dist/assets/aiConfig-DxFilBWK.js +2 -0
- boneio-1.4.0/boneio/webui/frontend-dist/assets/aiWizardPrompt-CrWwS7zb.js +2 -0
- boneio-1.4.0/boneio/webui/frontend-dist/assets/index-BXbDdVbb.css +2 -0
- boneio-1.4.0/boneio/webui/frontend-dist/assets/index-CtW_O-75.js +100 -0
- boneio-1.4.0/boneio/webui/frontend-dist/assets/useTranslation-DUpbl8sU.js +13 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/index.html +4 -4
- {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/binary_sensor.schema.json +120 -0
- {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/config.schema.json +1030 -2
- {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/cover.schema.json +22 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/event.schema.json +420 -0
- {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/irrigation.schema.json +27 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +4 -1
- {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/remote_devices.schema.json +0 -1
- boneio-1.4.0/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +197 -0
- boneio-1.4.0/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +225 -0
- {boneio-1.3.1.dev2/boneio/webui → boneio-1.4.0/boneio/webui/frontend-dist}/schema/template.schema.json +27 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/sw.js +1 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/can.py +15 -16
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/config.py +87 -25
- boneio-1.4.0/boneio/webui/routes/irrigation.py +721 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/modbus.py +54 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/outputs.py +40 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/remote_devices.py +4 -3
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/sensors.py +5 -2
- {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/binary_sensor.schema.json +120 -0
- {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/config.schema.json +1030 -2
- {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/cover.schema.json +22 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/event.schema.json +420 -0
- {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/irrigation.schema.json +27 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/modbus_devices.schema.json +4 -1
- {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/remote_devices.schema.json +0 -1
- boneio-1.4.0/boneio/webui/schema/remote_inputs.schema.json +197 -0
- boneio-1.4.0/boneio/webui/schema/remote_outputs.schema.json +225 -0
- {boneio-1.3.1.dev2/boneio/webui/frontend-dist → boneio-1.4.0/boneio/webui}/schema/template.schema.json +27 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/SOURCES.txt +20 -7
- {boneio-1.3.1.dev2 → boneio-1.4.0}/pyproject.toml +1 -0
- boneio-1.3.1.dev2/boneio/core/messaging/lox.py +0 -221
- boneio-1.3.1.dev2/boneio/core/messaging/loxone.py +0 -181
- boneio-1.3.1.dev2/boneio/integration/lox_template.py +0 -243
- boneio-1.3.1.dev2/boneio/version.py +0 -2
- boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/ConfigEditor-wi_Mieo6.js +0 -1
- boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/aiConfig-LL3nlemJ.js +0 -2
- boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/aiWizardPrompt-CmumVq54.js +0 -2
- boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/index-C_7FDXG5.js +0 -44
- boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/index-C_S5rhz7.css +0 -2
- boneio-1.3.1.dev2/boneio/webui/frontend-dist/assets/useTranslation-BsWm27qn.js +0 -13
- boneio-1.3.1.dev2/boneio/webui/routes/irrigation.py +0 -323
- {boneio-1.3.1.dev2 → boneio-1.4.0}/LICENSE +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/MANIFEST.in +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/README.md +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_48_4.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_48_4.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/bonecli.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/group/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/input/event.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/irrigation/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/mcp.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/pca.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/output/pcf.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/gate_cover.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/const.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/registration.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/migrations/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/package.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/discovery.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/events/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/events/bus.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/action_conditions.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/canopen.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/display.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/gate_cover.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/templates.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/manager/update.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/composite.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/local.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/base.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/can.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/state/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/state/manager.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/system/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/system/host_data.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/system/monitor.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/conditions.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/filter.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/logger.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/core/utils/util.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/adc.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/config.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/event.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/mqtt.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/48x4/output48x4A.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/can_master.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/can_slave.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/exceptions.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/bridge.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/client.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/interface.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/node.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/node_id.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/can/test_od.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/integration/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/integration/interlock.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/actions.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/daemon.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/journald/journald.conf +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/systemd/boneio.service +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/bootstrap/boneio-migrate +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/bootstrap/install-helper.sh +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/runner.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/cli.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/client.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/inverters/thessla.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/other/wanas415.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/gdfs.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/gdfx.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/modbus/utils.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/actions.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/events.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/files.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/logs.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/models/mqtt.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/condition.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/filters.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/id.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/editor.worker-BVjSvWeP.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/json.worker-CqOJL4FD.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/monaco-B9WiNxkw.css +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/monaco-CAZoGZNF.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/rolldown-runtime-Dw2cE7zH.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/vendor-BD5Ml_Uz.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BJd1pjeW.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/assets/yaml.worker-nZQZSRZ7.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/frontend-dist/workbox-4eca85ba.js +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/migrations.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/system.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/timezone_sudoers.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/tools.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/routes/update.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/boneio.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/can.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/lox_udp.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/mcp23017.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/oled.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/output.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/sensor.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/services/logs.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/web_server.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/setup.cfg +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/setup.py +0 -0
- {boneio-1.3.1.dev2 → boneio-1.4.0}/tests/test_py313_compatibility.py +0 -0
|
@@ -21,7 +21,7 @@ from boneio.const import (
|
|
|
21
21
|
from boneio.core.events import EventBus
|
|
22
22
|
from boneio.core.messaging import BasicMqtt
|
|
23
23
|
from boneio.core.utils import TimePeriod
|
|
24
|
-
from boneio.models import CoverState, PositionDict
|
|
24
|
+
from boneio.models import CoverState, PositionDict, SavedPositionDict
|
|
25
25
|
from boneio.models.events import CoverEvent
|
|
26
26
|
|
|
27
27
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -40,7 +40,7 @@ class BaseCoverABC(ABC):
|
|
|
40
40
|
open_time: TimePeriod,
|
|
41
41
|
close_time: TimePeriod,
|
|
42
42
|
event_bus: EventBus,
|
|
43
|
-
position:
|
|
43
|
+
position: float = 100.0,
|
|
44
44
|
**kwargs,
|
|
45
45
|
) -> None:
|
|
46
46
|
pass
|
|
@@ -106,14 +106,12 @@ class BaseCoverABC(ABC):
|
|
|
106
106
|
pass
|
|
107
107
|
|
|
108
108
|
@abstractmethod
|
|
109
|
-
async def run_cover(
|
|
110
|
-
self, current_operation: str, target_position: float | None = None, target_tilt: float | None = None
|
|
111
|
-
) -> None:
|
|
109
|
+
async def run_cover(self, current_operation: str, target_position: int | None = None, **kwargs) -> None:
|
|
112
110
|
"""This function is called to run cover after calling open, close, toggle, toggle_open, toggle_close, set_cover_position"""
|
|
113
111
|
pass
|
|
114
112
|
|
|
115
113
|
@abstractmethod
|
|
116
|
-
|
|
114
|
+
def send_state(self, state: str, json_position: PositionDict) -> None:
|
|
117
115
|
pass
|
|
118
116
|
|
|
119
117
|
|
|
@@ -159,7 +157,7 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
159
157
|
open_time: TimePeriod,
|
|
160
158
|
close_time: TimePeriod,
|
|
161
159
|
event_bus: EventBus,
|
|
162
|
-
position:
|
|
160
|
+
position: float = 100.0,
|
|
163
161
|
name: str | None = None,
|
|
164
162
|
**kwargs,
|
|
165
163
|
) -> None:
|
|
@@ -175,7 +173,7 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
175
173
|
self._open_time = open_time.total_milliseconds
|
|
176
174
|
self._close_time = close_time.total_milliseconds
|
|
177
175
|
self._position = position
|
|
178
|
-
self._initial_position =
|
|
176
|
+
self._initial_position: float = position
|
|
179
177
|
self._current_operation = IDLE
|
|
180
178
|
self._last_operation = CLOSING
|
|
181
179
|
_LOGGER.debug(
|
|
@@ -188,12 +186,18 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
188
186
|
|
|
189
187
|
self._last_timestamp = time.time()
|
|
190
188
|
|
|
191
|
-
self._last_update_time = 0
|
|
189
|
+
self._last_update_time = 0.0
|
|
192
190
|
self._closed = position <= 0
|
|
193
191
|
|
|
194
192
|
self._movement_thread = None
|
|
195
193
|
self._stop_event = threading.Event()
|
|
196
194
|
|
|
195
|
+
# Flag set by action executor to signal this call originates from a button action.
|
|
196
|
+
# Used by VenetianCover to conditionally skip tilt restore.
|
|
197
|
+
self._from_action: bool = False
|
|
198
|
+
# When True, tilt restore is explicitly requested by the action definition.
|
|
199
|
+
self._action_tilt_restore: bool = False
|
|
200
|
+
|
|
197
201
|
self._event_bus.add_sigterm_listener(self.on_exit)
|
|
198
202
|
|
|
199
203
|
with suppress(RuntimeError):
|
|
@@ -356,7 +360,8 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
356
360
|
|
|
357
361
|
@property
|
|
358
362
|
def position(self) -> int:
|
|
359
|
-
|
|
363
|
+
"""Return current cover position as integer (0-100)."""
|
|
364
|
+
return round(self._position)
|
|
360
365
|
|
|
361
366
|
@property
|
|
362
367
|
def json_position(self) -> PositionDict:
|
|
@@ -384,6 +389,12 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
384
389
|
self._message_bus.send_message(topic=f"{self._send_topic}/state", payload=state)
|
|
385
390
|
self._message_bus.send_message(topic=f"{self._send_topic}/pos", payload=json.dumps(json_position))
|
|
386
391
|
|
|
392
|
+
@property
|
|
393
|
+
def saved_position(self) -> SavedPositionDict:
|
|
394
|
+
"""Raw float position for disk persistence."""
|
|
395
|
+
return {"position": self._position}
|
|
396
|
+
|
|
387
397
|
def send_state_and_save(self, json_position: PositionDict):
|
|
398
|
+
"""Send state to MQTT/WebSocket and save raw float position to disk."""
|
|
388
399
|
self.send_state(self.state, json_position)
|
|
389
|
-
self._state_save(
|
|
400
|
+
self._state_save(self.saved_position)
|
|
@@ -31,7 +31,7 @@ class TimeBasedCover(BaseCover):
|
|
|
31
31
|
restored_state: dict = DEFAULT_RESTORED_STATE,
|
|
32
32
|
**kwargs,
|
|
33
33
|
) -> None:
|
|
34
|
-
position =
|
|
34
|
+
position = float(restored_state.get("position", DEFAULT_RESTORED_STATE["position"]))
|
|
35
35
|
super().__init__(
|
|
36
36
|
open_relay=open_relay,
|
|
37
37
|
close_relay=close_relay,
|
|
@@ -113,7 +113,7 @@ class TimeBasedCover(BaseCover):
|
|
|
113
113
|
self._loop.call_soon_threadsafe(lambda: self.send_state_and_save(self.json_position))
|
|
114
114
|
self._last_update_time = time.monotonic() # Upewnij się, że aktualizacja jest wysłana na końcu ruchu
|
|
115
115
|
|
|
116
|
-
async def run_cover(self, current_operation: str, target_position: int | None = None) -> None:
|
|
116
|
+
async def run_cover(self, current_operation: str, target_position: int | None = None, **kwargs) -> None:
|
|
117
117
|
if self._movement_thread and self._movement_thread.is_alive():
|
|
118
118
|
_LOGGER.warning("Cover movement already in progress. Stopping first.")
|
|
119
119
|
await self.stop()
|
|
@@ -8,7 +8,7 @@ import time
|
|
|
8
8
|
from boneio.components.cover.cover import BaseCover, BaseVenetianCoverABC
|
|
9
9
|
from boneio.const import CLOSE, CLOSING, IDLE, OPEN, OPENING, STOP
|
|
10
10
|
from boneio.core.utils import TimePeriod
|
|
11
|
-
from boneio.models import PositionDict
|
|
11
|
+
from boneio.models import PositionDict, SavedPositionDict
|
|
12
12
|
|
|
13
13
|
_LOGGER = logging.getLogger(__name__)
|
|
14
14
|
COVER_MOVE_UPDATE_INTERVAL = 50 # ms
|
|
@@ -25,26 +25,28 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
25
25
|
tilt_duration: TimePeriod, # ms
|
|
26
26
|
actuator_activation_duration: TimePeriod, # ms
|
|
27
27
|
restored_state: dict = DEFAULT_RESTORED_STATE,
|
|
28
|
+
tilt_restore_after_close: bool = False,
|
|
28
29
|
**kwargs,
|
|
29
30
|
) -> None:
|
|
30
|
-
|
|
31
|
-
tilt_duration.total_milliseconds
|
|
32
|
-
) # Czas trwania ruchu lameli
|
|
33
|
-
self._initial_tilt_position = int(
|
|
34
|
-
restored_state.get("tilt", DEFAULT_RESTORED_STATE["tilt"])
|
|
35
|
-
)
|
|
31
|
+
"""Initialize venetian cover.
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
Args:
|
|
34
|
+
tilt_duration: Duration for full tilt movement.
|
|
35
|
+
actuator_activation_duration: Actuator activation time (unused).
|
|
36
|
+
restored_state: Persisted position/tilt from disk.
|
|
37
|
+
tilt_restore_after_close: If True, restore previous tilt
|
|
38
|
+
position after closing the cover (UI/HA calls).
|
|
39
|
+
"""
|
|
40
|
+
self._tilt_duration = tilt_duration.total_milliseconds # Czas trwania ruchu lameli
|
|
41
|
+
self._initial_tilt_position = float(restored_state.get("tilt", DEFAULT_RESTORED_STATE["tilt"]))
|
|
42
|
+
|
|
43
|
+
position = float(restored_state.get("position", DEFAULT_RESTORED_STATE["position"]))
|
|
40
44
|
# --- TILT ---
|
|
41
|
-
self._tilt_position =
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
self._tilt_position = float(restored_state.get("tilt", DEFAULT_RESTORED_STATE["tilt"]))
|
|
46
|
+
|
|
47
|
+
self._tilt_restore_after_close = tilt_restore_after_close
|
|
48
|
+
self._tilt_before_close: float | None = None
|
|
44
49
|
|
|
45
|
-
# self._actuator_activation_duration = (
|
|
46
|
-
# actuator_activation_duration.total_milliseconds
|
|
47
|
-
# ) # ms
|
|
48
50
|
self._last_tilt_update = 0.0
|
|
49
51
|
|
|
50
52
|
super().__init__(
|
|
@@ -52,8 +54,15 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
52
54
|
**kwargs,
|
|
53
55
|
)
|
|
54
56
|
_LOGGER.debug(
|
|
55
|
-
"VenetianCover %s initialized: open_time=%dms, close_time=%dms, tilt_duration=%dms,
|
|
56
|
-
|
|
57
|
+
"VenetianCover %s initialized: open_time=%dms, close_time=%dms, tilt_duration=%dms, "
|
|
58
|
+
"position=%d%%, tilt=%d%%, tilt_restore=%s",
|
|
59
|
+
self._id,
|
|
60
|
+
self._open_time,
|
|
61
|
+
self._close_time,
|
|
62
|
+
self._tilt_duration,
|
|
63
|
+
position,
|
|
64
|
+
self._tilt_position,
|
|
65
|
+
self._tilt_restore_after_close,
|
|
57
66
|
)
|
|
58
67
|
|
|
59
68
|
def _move_cover(
|
|
@@ -69,20 +78,12 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
69
78
|
if direction == OPEN:
|
|
70
79
|
relay = self._open_relay
|
|
71
80
|
total_steps = 100 - self._position
|
|
72
|
-
total_tilt_step =
|
|
73
|
-
tilt_delta
|
|
74
|
-
if target_tilt_position is not None
|
|
75
|
-
else 100 - self._initial_tilt_position
|
|
76
|
-
)
|
|
81
|
+
total_tilt_step = tilt_delta if target_tilt_position is not None else 100 - self._initial_tilt_position
|
|
77
82
|
|
|
78
83
|
elif direction == CLOSE:
|
|
79
84
|
relay = self._close_relay
|
|
80
85
|
total_steps = self._position
|
|
81
|
-
total_tilt_step =
|
|
82
|
-
tilt_delta
|
|
83
|
-
if target_tilt_position is not None
|
|
84
|
-
else self._initial_tilt_position
|
|
85
|
-
)
|
|
86
|
+
total_tilt_step = tilt_delta if target_tilt_position is not None else self._initial_tilt_position
|
|
86
87
|
else:
|
|
87
88
|
return
|
|
88
89
|
if target_tilt_position is not None:
|
|
@@ -93,9 +94,7 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
93
94
|
|
|
94
95
|
if total_steps == 0 or duration == 0:
|
|
95
96
|
self._current_operation = IDLE
|
|
96
|
-
self._loop.call_soon_threadsafe(
|
|
97
|
-
self.send_state, self.state, self.json_position
|
|
98
|
-
)
|
|
97
|
+
self._loop.call_soon_threadsafe(self.send_state, self.state, self.json_position)
|
|
99
98
|
return
|
|
100
99
|
|
|
101
100
|
# Calculate actual duration based on remaining distance
|
|
@@ -111,17 +110,11 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
111
110
|
needed_tilt_duration = tilt_duration * (total_tilt_step / 100)
|
|
112
111
|
if target_tilt_position is None:
|
|
113
112
|
tilt_delta = 1.0
|
|
114
|
-
|
|
115
113
|
|
|
116
114
|
while not self._stop_event.is_set():
|
|
117
|
-
current_time = (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
elapsed_time = (
|
|
121
|
-
current_time - start_time
|
|
122
|
-
) * 1000 # Konwersja na milisekundy
|
|
123
|
-
|
|
124
|
-
|
|
115
|
+
current_time = time.monotonic() # Pobierz aktualny czas tylko raz na iterację
|
|
116
|
+
elapsed_time = (current_time - start_time) * 1000 # Konwersja na milisekundy
|
|
117
|
+
|
|
125
118
|
if elapsed_time < needed_tilt_duration:
|
|
126
119
|
tilt_progress = elapsed_time / needed_tilt_duration if needed_tilt_duration > 0 else 1.0
|
|
127
120
|
progress = 0.0
|
|
@@ -135,8 +128,10 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
135
128
|
|
|
136
129
|
# Obliczanie _tilt_position dla kierunku OPEN
|
|
137
130
|
if target_tilt_position is not None:
|
|
138
|
-
self._tilt_position = min(
|
|
139
|
-
|
|
131
|
+
self._tilt_position = min(
|
|
132
|
+
target_tilt_position, self._initial_tilt_position + tilt_progress * tilt_delta
|
|
133
|
+
)
|
|
134
|
+
else: # Fallback jeśli nie ma target_tilt_position
|
|
140
135
|
self._tilt_position = min(
|
|
141
136
|
100.0, self._initial_tilt_position + tilt_progress * (100 - self._initial_tilt_position)
|
|
142
137
|
)
|
|
@@ -146,24 +141,23 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
146
141
|
|
|
147
142
|
# Obliczanie _tilt_position dla kierunku CLOSE
|
|
148
143
|
if target_tilt_position is not None:
|
|
149
|
-
self._tilt_position = max(
|
|
150
|
-
|
|
144
|
+
self._tilt_position = max(
|
|
145
|
+
target_tilt_position, self._initial_tilt_position - tilt_progress * tilt_delta
|
|
146
|
+
)
|
|
147
|
+
else: # Fallback jeśli nie ma target_tilt_position
|
|
151
148
|
self._tilt_position = max(
|
|
152
149
|
0.0, self._initial_tilt_position - tilt_progress * self._initial_tilt_position
|
|
153
150
|
)
|
|
154
151
|
|
|
155
152
|
self._last_timestamp = time.time() # Wall clock for display
|
|
156
153
|
if current_time - self._last_update_time >= 1:
|
|
157
|
-
self._loop.call_soon_threadsafe(
|
|
158
|
-
self.send_state, self.state, self.json_position
|
|
159
|
-
)
|
|
154
|
+
self._loop.call_soon_threadsafe(self.send_state, self.state, self.json_position)
|
|
160
155
|
self._last_update_time = current_time
|
|
161
156
|
|
|
162
|
-
if target_tilt_position is not None and (
|
|
163
|
-
direction == OPEN and self._tilt_position >= target_tilt_position
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
)):
|
|
157
|
+
if target_tilt_position is not None and (
|
|
158
|
+
(direction == OPEN and self._tilt_position >= target_tilt_position)
|
|
159
|
+
or (direction == CLOSE and self._tilt_position <= target_tilt_position)
|
|
160
|
+
):
|
|
167
161
|
break
|
|
168
162
|
|
|
169
163
|
if target_position is not None and (
|
|
@@ -183,12 +177,32 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
183
177
|
# Send relay state to WebSocket (not MQTT - that's handled by output_type check)
|
|
184
178
|
self._loop.call_soon_threadsafe(lambda r=relay: asyncio.ensure_future(r.async_send_state()))
|
|
185
179
|
self._current_operation = IDLE
|
|
186
|
-
self._loop.call_soon_threadsafe(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
180
|
+
self._loop.call_soon_threadsafe(self.send_state_and_save, self.json_position)
|
|
181
|
+
self._last_update_time = time.monotonic() # Upewnij się, że aktualizacja jest wysłana na końcu ruchu
|
|
182
|
+
|
|
183
|
+
# Tilt restore: schedule tilt recovery on the event loop.
|
|
184
|
+
# Skip when position reached 0% (fully closed) or 100% (fully open)
|
|
185
|
+
# — at extremes, restoring tilt contradicts user intent.
|
|
186
|
+
if self._tilt_restore_after_close and self._tilt_before_close is not None:
|
|
187
|
+
restore_tilt = self._tilt_before_close
|
|
188
|
+
self._tilt_before_close = None
|
|
189
|
+
at_extreme = self._position <= 0 or self._position >= 100
|
|
190
|
+
if not at_extreme and restore_tilt > 0 and abs(self._tilt_position - restore_tilt) >= 1:
|
|
191
|
+
_LOGGER.info(
|
|
192
|
+
"VenetianCover %s: restoring tilt from %d%% to %d%%",
|
|
193
|
+
self._id,
|
|
194
|
+
round(self._tilt_position),
|
|
195
|
+
round(restore_tilt),
|
|
196
|
+
)
|
|
197
|
+
self._loop.call_soon_threadsafe(
|
|
198
|
+
lambda t=restore_tilt: asyncio.ensure_future(self.set_tilt(int(round(t))))
|
|
199
|
+
)
|
|
200
|
+
elif at_extreme:
|
|
201
|
+
_LOGGER.debug(
|
|
202
|
+
"VenetianCover %s: skipping tilt restore at extreme position %d%%",
|
|
203
|
+
self._id,
|
|
204
|
+
round(self._position),
|
|
205
|
+
)
|
|
192
206
|
|
|
193
207
|
async def set_tilt(self, tilt_position: int) -> None:
|
|
194
208
|
"""Setting tilt position."""
|
|
@@ -200,31 +214,36 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
200
214
|
|
|
201
215
|
tilt_diff = abs(self._tilt_position - tilt_position)
|
|
202
216
|
estimated_time_s = tilt_diff / 100 * self._tilt_duration / 1000
|
|
203
|
-
|
|
217
|
+
|
|
204
218
|
if tilt_position > self._tilt_position:
|
|
205
219
|
_LOGGER.info(
|
|
206
220
|
"Setting tilt %s from %d%% to %d%% (OPENING). Estimated time: %.2fs (tilt_duration=%dms)",
|
|
207
|
-
self._id,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
221
|
+
self._id,
|
|
222
|
+
self._tilt_position,
|
|
223
|
+
tilt_position,
|
|
224
|
+
estimated_time_s,
|
|
225
|
+
self._tilt_duration,
|
|
211
226
|
)
|
|
227
|
+
await self.run_cover(current_operation=OPENING, target_tilt_position=tilt_position)
|
|
212
228
|
elif tilt_position < self._tilt_position:
|
|
213
229
|
_LOGGER.info(
|
|
214
230
|
"Setting tilt %s from %d%% to %d%% (CLOSING). Estimated time: %.2fs (tilt_duration=%dms)",
|
|
215
|
-
self._id,
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
231
|
+
self._id,
|
|
232
|
+
self._tilt_position,
|
|
233
|
+
tilt_position,
|
|
234
|
+
estimated_time_s,
|
|
235
|
+
self._tilt_duration,
|
|
219
236
|
)
|
|
237
|
+
await self.run_cover(current_operation=CLOSING, target_tilt_position=tilt_position)
|
|
220
238
|
|
|
221
239
|
@property
|
|
222
240
|
def json_position(self) -> PositionDict:
|
|
223
|
-
|
|
241
|
+
"""Return position dict with int values for API/MQTT/WebUI."""
|
|
242
|
+
return {"position": self.position, "tilt": self.tilt}
|
|
224
243
|
|
|
225
244
|
@property
|
|
226
245
|
def tilt(self) -> int:
|
|
227
|
-
return
|
|
246
|
+
return round(self._tilt_position)
|
|
228
247
|
|
|
229
248
|
@property
|
|
230
249
|
def tilt_position(self) -> int:
|
|
@@ -245,6 +264,11 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
245
264
|
def kind(self) -> str:
|
|
246
265
|
return "venetian"
|
|
247
266
|
|
|
267
|
+
@property
|
|
268
|
+
def saved_position(self) -> SavedPositionDict:
|
|
269
|
+
"""Raw float position for disk persistence (includes tilt)."""
|
|
270
|
+
return {"position": self._position, "tilt": self._tilt_position}
|
|
271
|
+
|
|
248
272
|
async def set_cover_tilt_position(self, position: int) -> None:
|
|
249
273
|
"""Set cover tilt position (required by BaseVenetianCoverABC)."""
|
|
250
274
|
await self.set_tilt(position)
|
|
@@ -254,7 +278,10 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
254
278
|
estimated_time_s = (100 - self._tilt_position) / 100 * self._tilt_duration / 1000
|
|
255
279
|
_LOGGER.info(
|
|
256
280
|
"Opening tilt cover %s from %d%%. Estimated time: %.2fs (tilt_duration=%dms)",
|
|
257
|
-
self._id,
|
|
281
|
+
self._id,
|
|
282
|
+
self._tilt_position,
|
|
283
|
+
estimated_time_s,
|
|
284
|
+
self._tilt_duration,
|
|
258
285
|
)
|
|
259
286
|
await self.set_tilt(tilt_position=100)
|
|
260
287
|
|
|
@@ -263,16 +290,76 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
263
290
|
estimated_time_s = self._tilt_position / 100 * self._tilt_duration / 1000
|
|
264
291
|
_LOGGER.info(
|
|
265
292
|
"Closing tilt cover %s from %d%%. Estimated time: %.2fs (tilt_duration=%dms)",
|
|
266
|
-
self._id,
|
|
293
|
+
self._id,
|
|
294
|
+
self._tilt_position,
|
|
295
|
+
estimated_time_s,
|
|
296
|
+
self._tilt_duration,
|
|
267
297
|
)
|
|
268
298
|
await self.set_tilt(tilt_position=0)
|
|
269
299
|
|
|
300
|
+
def _save_tilt_for_restore(self) -> None:
|
|
301
|
+
"""Save current tilt position for later restoration.
|
|
302
|
+
|
|
303
|
+
Called before any closing movement. Determines whether to save
|
|
304
|
+
based on the call source:
|
|
305
|
+
- UI/HA calls: uses tilt_restore_after_close setting
|
|
306
|
+
- Action calls: uses _action_tilt_restore flag (set by executor)
|
|
307
|
+
"""
|
|
308
|
+
if self._from_action:
|
|
309
|
+
should_restore = self._action_tilt_restore
|
|
310
|
+
else:
|
|
311
|
+
should_restore = self._tilt_restore_after_close
|
|
312
|
+
|
|
313
|
+
if should_restore and self._tilt_position > 0:
|
|
314
|
+
self._tilt_before_close = self._tilt_position
|
|
315
|
+
_LOGGER.debug(
|
|
316
|
+
"VenetianCover %s: saving tilt=%d%% before close",
|
|
317
|
+
self._id,
|
|
318
|
+
round(self._tilt_position),
|
|
319
|
+
)
|
|
320
|
+
else:
|
|
321
|
+
self._tilt_before_close = None
|
|
322
|
+
|
|
323
|
+
async def close(self) -> None:
|
|
324
|
+
"""Close venetian cover.
|
|
325
|
+
|
|
326
|
+
If tilt_restore_after_close is enabled, saves the current tilt
|
|
327
|
+
position so it can be restored after the closing movement finishes.
|
|
328
|
+
"""
|
|
329
|
+
self._save_tilt_for_restore()
|
|
330
|
+
await super().close()
|
|
331
|
+
|
|
332
|
+
async def set_cover_position(self, position: int) -> None:
|
|
333
|
+
"""Set cover position with tilt restore support.
|
|
334
|
+
|
|
335
|
+
When moving to a lower position (closing direction) and
|
|
336
|
+
tilt_restore_after_close is enabled, saves the current tilt
|
|
337
|
+
so it can be restored after the movement finishes.
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
position: Target position (0-100).
|
|
341
|
+
"""
|
|
342
|
+
if position < self._position:
|
|
343
|
+
self._save_tilt_for_restore()
|
|
344
|
+
else:
|
|
345
|
+
self._tilt_before_close = None
|
|
346
|
+
await super().set_cover_position(position)
|
|
347
|
+
|
|
348
|
+
async def open(self) -> None:
|
|
349
|
+
"""Open venetian cover.
|
|
350
|
+
|
|
351
|
+
Clears any saved tilt-before-close value since opening
|
|
352
|
+
resets the tilt to 100% naturally.
|
|
353
|
+
"""
|
|
354
|
+
self._tilt_before_close = None
|
|
355
|
+
await super().open()
|
|
356
|
+
|
|
270
357
|
def update_config_times(self, config: dict) -> None:
|
|
271
358
|
"""Update cover timing configuration.
|
|
272
|
-
|
|
359
|
+
|
|
273
360
|
Args:
|
|
274
361
|
config: Dictionary with timing values as TimePeriod objects.
|
|
275
|
-
Keys: open_time, close_time, tilt_duration
|
|
362
|
+
Keys: open_time, close_time, tilt_duration, tilt_restore_after_close
|
|
276
363
|
"""
|
|
277
364
|
if "open_time" in config:
|
|
278
365
|
self._open_time = config["open_time"].total_milliseconds
|
|
@@ -280,17 +367,20 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
280
367
|
self._close_time = config["close_time"].total_milliseconds
|
|
281
368
|
if "tilt_duration" in config and config["tilt_duration"]:
|
|
282
369
|
self._tilt_duration = config["tilt_duration"].total_milliseconds
|
|
370
|
+
if "tilt_restore_after_close" in config:
|
|
371
|
+
self._tilt_restore_after_close = bool(config["tilt_restore_after_close"])
|
|
283
372
|
|
|
284
373
|
async def run_cover(
|
|
285
374
|
self,
|
|
286
375
|
current_operation: str,
|
|
287
376
|
target_position: int | None = None,
|
|
288
377
|
target_tilt_position: int | None = None,
|
|
378
|
+
**kwargs,
|
|
289
379
|
) -> None:
|
|
290
380
|
if self._movement_thread and self._movement_thread.is_alive():
|
|
291
381
|
_LOGGER.warning("Cover movement is already in progress. Stopping first.")
|
|
292
382
|
await self.stop()
|
|
293
|
-
|
|
383
|
+
|
|
294
384
|
# If STOP was requested, don't start new movement
|
|
295
385
|
if current_operation == STOP:
|
|
296
386
|
await self.stop()
|
|
@@ -300,9 +390,7 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
300
390
|
self._initial_position = self._position
|
|
301
391
|
self._initial_tilt_position = self._tilt_position
|
|
302
392
|
self._stop_event.clear()
|
|
303
|
-
self._last_update_time = (
|
|
304
|
-
time.monotonic()
|
|
305
|
-
) # Inicjalizacja czasu ostatniej aktualizacji
|
|
393
|
+
self._last_update_time = time.monotonic() # Inicjalizacja czasu ostatniej aktualizacji
|
|
306
394
|
|
|
307
395
|
if current_operation == OPENING:
|
|
308
396
|
self._movement_thread = threading.Thread(
|
|
@@ -84,7 +84,7 @@ class OutputGroup(BasicOutput):
|
|
|
84
84
|
self._state = state
|
|
85
85
|
self._loop.create_task(self.async_send_state())
|
|
86
86
|
|
|
87
|
-
async def async_turn_on(self, timestamp=None) ->
|
|
87
|
+
async def async_turn_on(self, timestamp=None) -> bool:
|
|
88
88
|
"""Turn on all members in the group.
|
|
89
89
|
|
|
90
90
|
Executes turn_on sequentially to prevent I2C bus contention
|
|
@@ -92,9 +92,16 @@ class OutputGroup(BasicOutput):
|
|
|
92
92
|
|
|
93
93
|
Args:
|
|
94
94
|
timestamp: Optional timestamp for the operation
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
True if all members were turned on, False if any was blocked.
|
|
95
98
|
"""
|
|
99
|
+
all_ok = True
|
|
96
100
|
for x in self._group_members:
|
|
97
|
-
await x.async_turn_on(timestamp=timestamp)
|
|
101
|
+
result = await x.async_turn_on(timestamp=timestamp)
|
|
102
|
+
if not result:
|
|
103
|
+
all_ok = False
|
|
104
|
+
return all_ok
|
|
98
105
|
|
|
99
106
|
async def async_turn_off(self, timestamp=None) -> None:
|
|
100
107
|
"""Turn off all members in the group.
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
This module provides high-level input components that combine
|
|
4
4
|
hardware GPIO drivers with business logic, MQTT, and Home Assistant integration.
|
|
5
|
+
|
|
6
|
+
Sub-packages:
|
|
7
|
+
remote: Virtual inputs from remote devices (ESPHome API, CAN bus, …)
|
|
5
8
|
"""
|
|
6
9
|
|
|
7
10
|
from boneio.components.input.binary_sensor import GpioInputBinarySensor
|
|
8
11
|
from boneio.components.input.event import GpioEventButton
|
|
12
|
+
from boneio.components.input.remote import ESPHomeBinarySensorInput, RemoteInputBase
|
|
9
13
|
|
|
10
14
|
__all__ = [
|
|
11
15
|
"GpioInputBinarySensor",
|
|
12
16
|
"GpioEventButton",
|
|
17
|
+
"ESPHomeBinarySensorInput",
|
|
18
|
+
"RemoteInputBase",
|
|
13
19
|
]
|
|
@@ -603,6 +603,93 @@ class MultiClickDetector:
|
|
|
603
603
|
)
|
|
604
604
|
|
|
605
605
|
|
|
606
|
+
def handle_raw_state(self, is_pressed: bool) -> None:
|
|
607
|
+
"""Process a raw state change for virtual/remote inputs.
|
|
608
|
+
|
|
609
|
+
Uses wall-clock time instead of kernel GPIO timestamps.
|
|
610
|
+
Suitable for ESPHome binary sensors and other network-based inputs
|
|
611
|
+
that don't generate gpiod edge events.
|
|
612
|
+
|
|
613
|
+
Args:
|
|
614
|
+
is_pressed: True if the input is now active (pressed)
|
|
615
|
+
"""
|
|
616
|
+
import time
|
|
617
|
+
|
|
618
|
+
timestamp_s = time.time()
|
|
619
|
+
|
|
620
|
+
if is_pressed:
|
|
621
|
+
# Debounce
|
|
622
|
+
if (
|
|
623
|
+
self._state.last_press_ts
|
|
624
|
+
and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds
|
|
625
|
+
):
|
|
626
|
+
return
|
|
627
|
+
|
|
628
|
+
_LOGGER.debug("RAW PRESSED: %s (%s)", self._name, self._pin)
|
|
629
|
+
self._state.last_press_ts = timestamp_s
|
|
630
|
+
self._state.last_press_loop_ts = self._loop.time()
|
|
631
|
+
self._state.last_release_ts = None
|
|
632
|
+
|
|
633
|
+
if self._state.finalizer:
|
|
634
|
+
self._state.finalizer.cancel()
|
|
635
|
+
self._state.finalizer = None
|
|
636
|
+
self._state.finalizer_scheduled_loop_ts = None
|
|
637
|
+
|
|
638
|
+
if self._sequence_mode == "exclusive" and self._state.pending_click_timer:
|
|
639
|
+
self._state.pending_click_timer.cancel()
|
|
640
|
+
self._state.pending_click_timer = None
|
|
641
|
+
|
|
642
|
+
self._state.long_press_scheduled_loop_ts = self._loop.time()
|
|
643
|
+
self._state.long_press_timer = self._loop.call_later(
|
|
644
|
+
self._hold_threshold,
|
|
645
|
+
self._detect_long_press,
|
|
646
|
+
)
|
|
647
|
+
else:
|
|
648
|
+
# Debounce
|
|
649
|
+
if (
|
|
650
|
+
self._state.last_release_ts
|
|
651
|
+
and (timestamp_s - self._state.last_release_ts)
|
|
652
|
+
< self._debounce_seconds
|
|
653
|
+
):
|
|
654
|
+
return
|
|
655
|
+
if (
|
|
656
|
+
self._state.last_press_ts
|
|
657
|
+
and (timestamp_s - self._state.last_press_ts)
|
|
658
|
+
< self._debounce_seconds
|
|
659
|
+
):
|
|
660
|
+
return
|
|
661
|
+
|
|
662
|
+
_LOGGER.debug("RAW RELEASED: %s (%s)", self._name, self._pin)
|
|
663
|
+
self._state.last_release_ts = timestamp_s
|
|
664
|
+
|
|
665
|
+
if self._state.long_hold_periodic_timer:
|
|
666
|
+
self._state.long_hold_periodic_timer.cancel()
|
|
667
|
+
self._state.long_hold_periodic_timer = None
|
|
668
|
+
|
|
669
|
+
if self._state.last_press_loop_ts:
|
|
670
|
+
duration = self._loop.time() - self._state.last_press_loop_ts
|
|
671
|
+
self._emit_click(LONG, duration)
|
|
672
|
+
|
|
673
|
+
def _reset():
|
|
674
|
+
self._state.executed_long_actions = set()
|
|
675
|
+
self._state.last_repeat_times = {}
|
|
676
|
+
|
|
677
|
+
self._loop.call_later(0.05, _reset)
|
|
678
|
+
|
|
679
|
+
if self._state.long_press_timer:
|
|
680
|
+
self._state.long_press_timer.cancel()
|
|
681
|
+
self._state.long_press_timer = None
|
|
682
|
+
self._state.long_press_scheduled_loop_ts = None
|
|
683
|
+
|
|
684
|
+
self._state.click_count += 1
|
|
685
|
+
|
|
686
|
+
self._state.finalizer_scheduled_loop_ts = self._loop.time()
|
|
687
|
+
self._state.finalizer = self._loop.call_later(
|
|
688
|
+
self._multiclick_window,
|
|
689
|
+
self._finalize_clicks,
|
|
690
|
+
)
|
|
691
|
+
|
|
692
|
+
|
|
606
693
|
class BinarySensorDetector:
|
|
607
694
|
"""Detects binary state changes (PRESSED/RELEASED) with software debounce."""
|
|
608
695
|
|