boneio 1.2.0.dev21__tar.gz → 1.2.0.dev25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boneio-1.2.0.dev21/boneio.egg-info → boneio-1.2.0.dev25}/PKG-INFO +1 -1
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/cover.py +37 -6
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/time_based.py +3 -3
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/const.py +28 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/covers.py +27 -3
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/manager.py +4 -1
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/remote.py +1 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/esphome.py +41 -13
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/display/oled.py +254 -7
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/actions.yaml +13 -1
- boneio-1.2.0.dev25/boneio/version.py +2 -0
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/cssMode-B9wgS3nc.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/cssMode-CNfUxfgr.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/freemarker2-BWuFrqIE.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/freemarker2-DWjclh22.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/handlebars-v7145UWi.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/handlebars-i2k_xWAf.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/html-CcwKUEPK.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/html-5waqLOui.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/htmlMode-BSmyjXrA.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/htmlMode-Bwf-0-Bn.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/index-B6BS4-3O.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/index-CRX9Ew8L.js +5 -5
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/javascript-BPdWBFmL.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/javascript-Kj8C4y4i.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/jsonMode-CFXuuy9f.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/jsonMode-CHLWjsUA.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/liquid-CFKk38kG.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/liquid-3gxkDJwa.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/mdx-BNyJdH4w.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/mdx-CvlTe6nf.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/python-D_-BuVF5.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/python-BK_KcnMp.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/razor-DYq6eRVD.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/razor-DiDDF06t.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/tsMode-DwwcYdMs.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/tsMode-B_ZhXLqZ.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/typescript-6vakCrf3.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/typescript-FjIJU2QD.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/xml-DfD5mx75.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/xml-DiHsfIX6.js +1 -1
- boneio-1.2.0.dev21/boneio/webui/frontend-dist/assets/yaml-MkFkM5Hn.js → boneio-1.2.0.dev25/boneio/webui/frontend-dist/assets/yaml-GoVS_T5n.js +1 -1
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/index.html +1 -1
- {boneio-1.2.0.dev21/boneio/webui → boneio-1.2.0.dev25/boneio/webui/frontend-dist}/schema/binary_sensor.schema.json +20 -0
- {boneio-1.2.0.dev21/boneio/webui → boneio-1.2.0.dev25/boneio/webui/frontend-dist}/schema/config.schema.json +90 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/event.schema.json +70 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/sw.js +1 -1
- {boneio-1.2.0.dev21/boneio/webui/frontend-dist → boneio-1.2.0.dev25/boneio/webui}/schema/binary_sensor.schema.json +20 -0
- {boneio-1.2.0.dev21/boneio/webui/frontend-dist → boneio-1.2.0.dev25/boneio/webui}/schema/config.schema.json +90 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/event.schema.json +70 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/SOURCES.txt +16 -16
- boneio-1.2.0.dev21/boneio/version.py +0 -2
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/LICENSE +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/MANIFEST.in +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/README.md +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/bonecli.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/cover/venetian.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/group/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/group/output_group.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/detectors.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/input/event.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/basic.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/mcp.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/pca.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/output/pcf.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/alarm_panel.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/gate_cover.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/registration.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/migrations/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/package.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/config/yaml_util.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/discovery.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/events/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/events/bus.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/display.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/inputs.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/alarm.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/gate_cover.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/templates.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/manager/update.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/local.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/base.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/remote/wled.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/sensor/base.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/sensor/system.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/state/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/state/manager.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/system/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/system/host_data.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/system/monitor.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/filter.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/logger.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/core/utils/util.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/exceptions.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/input/base.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/integration/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/integration/homeassistant.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/integration/interlock.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/cli.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/client.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/inverters/thessla.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/other/wanas415.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/gdfs.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/gdfx.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/modbus/utils.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/actions.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/events.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/files.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/logs.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/mqtt.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/models/state.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/runner.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/filters.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/id.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/remote_devices.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/schema.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/app.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/abap-CRCWOmpq.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/apex-DnsZk_dE.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/azcli-1IWB1ccx.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/bat-DPkNLes8.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/bicep-Corcdgou.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/cameligo-CGrWLZr3.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/clojure-D9WOWImG.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/coffee-B7EJu28W.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/cpp-SEyurbux.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/csharp-BoL64M5l.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/csp-C46ZqvIl.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/css-DQU6DXDx.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/cypher-D84EuPTj.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/dart-D8lhlL1r.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/dockerfile-DLk6rpji.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/ecl-BO6FnfXk.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/editor.worker-B4pQIWZD.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/elixir-BRjLKONM.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/flow9-Cac8vKd7.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/fsharp-fd1GTHhf.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/go-O9LJTZXk.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/graphql-LQdxqEYJ.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/hcl-DxDQ3s82.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/index-BkP1mrhT.css +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/ini-BvajGCUy.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/java-SYsfObOQ.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/json.worker-aFakAbRR.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/julia-DQXNmw_w.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/kotlin-qQ0MG-9I.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/less-GGFNNJHn.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/lexon-Canl7DCW.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/lua-D28Ae8-K.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/m3-DPitgjJI.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/markdown-B811l8j2.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/mips-CdjsipkG.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/msdax-CYqgjx_P.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/mysql-BHd6q0vd.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/objective-c-B1aVtJYH.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pascal-BhNW15KB.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pascaligo-5jv8CcQD.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/perl-DlYyT36c.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pgsql-Dy0bjov7.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/php-120yhfDK.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pla-CjnFlu4u.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/postiats-CQpG440k.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/powerquery-DdJtto1Z.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/powershell-Bu_VLpJB.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/protobuf-IBS6jZEB.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/pug-kFxLfcjb.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/qsharp-q7JyzKFN.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/r-BIFz-_sK.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/redis-CHOsPHWR.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/redshift-CBifECDb.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/restructuredtext-CghPJEOS.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/ruby-CYWGW-b1.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/rust-DMDD0SHb.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sb-BYAiYHFx.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/scala-Bqvq8jcR.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/scheme-Dhb-2j9p.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/scss-CTwUZ5N7.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/shell-CsDZo4DB.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/solidity-CME5AdoB.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sophia-RYC1BQQz.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sparql-KEyrF7De.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/sql-BdTr02Mf.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/st-C7iG7M4S.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/swift-D7IUmUK8.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/systemverilog-DgMryOEJ.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/tcl-PloMZuKG.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/twig-BfRIq3la.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/typespec-CzxlYoT_.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/vb-BwAE3J76.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/wgsl-B_1kOXbF.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BIl4cyR9.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/assets/yaml.worker-DBeHcBRc.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/frontend-dist/workbox-226dbdbf.js +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/config.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/modbus.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/remote_devices.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/system.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/tools.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/routes/update.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/boneio.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/cover.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/mcp23017.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/modbus_devices.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/oled.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/output.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/remote_devices.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/sensor.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/template.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/services/logs.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/web_server.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/pyproject.toml +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/setup.cfg +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/setup.py +0 -0
- {boneio-1.2.0.dev21 → boneio-1.2.0.dev25}/tests/test_py313_compatibility.py +0 -0
|
@@ -16,11 +16,11 @@ from boneio.const import (
|
|
|
16
16
|
OPEN,
|
|
17
17
|
OPENING,
|
|
18
18
|
)
|
|
19
|
-
from boneio.core.events import EventBus
|
|
19
|
+
from boneio.core.events import EventBus
|
|
20
20
|
from boneio.core.messaging import BasicMqtt
|
|
21
21
|
from boneio.core.utils import TimePeriod
|
|
22
22
|
from boneio.models import CoverState, PositionDict
|
|
23
|
-
from boneio.components.output import
|
|
23
|
+
from boneio.components.output import BasicOutput
|
|
24
24
|
from boneio.models.events import CoverEvent
|
|
25
25
|
|
|
26
26
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -30,8 +30,8 @@ class BaseCoverABC(ABC):
|
|
|
30
30
|
|
|
31
31
|
@abstractmethod
|
|
32
32
|
def __init__(self, id: str,
|
|
33
|
-
open_relay:
|
|
34
|
-
close_relay:
|
|
33
|
+
open_relay: BasicOutput,
|
|
34
|
+
close_relay: BasicOutput,
|
|
35
35
|
state_save: Callable,
|
|
36
36
|
open_time: TimePeriod,
|
|
37
37
|
close_time: TimePeriod,
|
|
@@ -147,8 +147,8 @@ class BaseVenetianCoverABC:
|
|
|
147
147
|
|
|
148
148
|
class BaseCover(BaseCoverABC, BasicMqtt):
|
|
149
149
|
def __init__(self, id: str,
|
|
150
|
-
open_relay:
|
|
151
|
-
close_relay:
|
|
150
|
+
open_relay: BasicOutput,
|
|
151
|
+
close_relay: BasicOutput,
|
|
152
152
|
state_save: Callable,
|
|
153
153
|
open_time: TimePeriod,
|
|
154
154
|
close_time: TimePeriod,
|
|
@@ -265,6 +265,10 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
265
265
|
_LOGGER.debug("Toggle cover %s from input.", self._id)
|
|
266
266
|
if self._current_operation != IDLE:
|
|
267
267
|
await self.stop()
|
|
268
|
+
elif self._position >= 100:
|
|
269
|
+
await self.close()
|
|
270
|
+
elif self._position <= 0:
|
|
271
|
+
await self.open()
|
|
268
272
|
elif self._last_operation == CLOSING:
|
|
269
273
|
await self.open()
|
|
270
274
|
else:
|
|
@@ -284,6 +288,33 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
284
288
|
else:
|
|
285
289
|
await self.close()
|
|
286
290
|
|
|
291
|
+
async def smart_toggle(self, always_open_till: int = 50) -> None:
|
|
292
|
+
"""Smart toggle with position threshold.
|
|
293
|
+
|
|
294
|
+
If cover is moving → stop.
|
|
295
|
+
If position <= always_open_till → open (to 100%).
|
|
296
|
+
If position > always_open_till → normal toggle (based on last_operation).
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
always_open_till: Position threshold (0-100%). Below or equal this
|
|
300
|
+
value the cover will always open. Above it, normal toggle applies.
|
|
301
|
+
"""
|
|
302
|
+
_LOGGER.debug(
|
|
303
|
+
"Smart toggle cover %s (position=%d%%, threshold=%d%%)",
|
|
304
|
+
self._id, self._position, always_open_till,
|
|
305
|
+
)
|
|
306
|
+
if self._current_operation != IDLE:
|
|
307
|
+
await self.stop()
|
|
308
|
+
elif self._position <= always_open_till:
|
|
309
|
+
await self.open()
|
|
310
|
+
elif self._position >= 100:
|
|
311
|
+
await self.close()
|
|
312
|
+
elif self._position <= 0:
|
|
313
|
+
await self.open()
|
|
314
|
+
elif self._last_operation == CLOSING:
|
|
315
|
+
await self.open()
|
|
316
|
+
else:
|
|
317
|
+
await self.close()
|
|
287
318
|
|
|
288
319
|
@property
|
|
289
320
|
def state(self) -> str:
|
|
@@ -10,7 +10,7 @@ from boneio.const import CLOSE, CLOSING, IDLE, OPEN, OPENING, STOP
|
|
|
10
10
|
from boneio.components.cover.cover import BaseCover
|
|
11
11
|
from boneio.core.events import EventBus
|
|
12
12
|
from boneio.core.utils import TimePeriod
|
|
13
|
-
from boneio.components.output import
|
|
13
|
+
from boneio.components.output import BasicOutput
|
|
14
14
|
|
|
15
15
|
_LOGGER = logging.getLogger(__name__)
|
|
16
16
|
DEFAULT_RESTORED_STATE = {"position": 100}
|
|
@@ -19,8 +19,8 @@ class TimeBasedCover(BaseCover):
|
|
|
19
19
|
"""Time-based cover algorithm similar to ESPHome."""
|
|
20
20
|
def __init__(
|
|
21
21
|
self,
|
|
22
|
-
open_relay:
|
|
23
|
-
close_relay:
|
|
22
|
+
open_relay: BasicOutput,
|
|
23
|
+
close_relay: BasicOutput,
|
|
24
24
|
state_save: Callable,
|
|
25
25
|
open_time: TimePeriod,
|
|
26
26
|
close_time: TimePeriod,
|
|
@@ -181,11 +181,39 @@ cover_actions = {
|
|
|
181
181
|
"STOP": "stop",
|
|
182
182
|
"TOGGLE_OPEN": "toggle_open",
|
|
183
183
|
"TOGGLE_CLOSE": "toggle_close",
|
|
184
|
+
"SMART_TOGGLE": "smart_toggle",
|
|
184
185
|
"TILT": "set_tilt",
|
|
185
186
|
'TILT_OPEN': 'tilt_open',
|
|
186
187
|
'TILT_CLOSE': 'tilt_close',
|
|
187
188
|
}
|
|
188
189
|
|
|
190
|
+
# Map of cover action method name -> accepted extra_data keys.
|
|
191
|
+
# Actions not listed here (open, close, toggle, stop, etc.) accept no extra params.
|
|
192
|
+
_COVER_ACTION_PARAMS: dict[str, set[str]] = {
|
|
193
|
+
"smart_toggle": {"always_open_till"},
|
|
194
|
+
"set_cover_position": {"position"},
|
|
195
|
+
"set_tilt": {"tilt_position"},
|
|
196
|
+
"set_cover_tilt_position": {"tilt_position"},
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def filter_cover_extra_data(action_name: str, extra_data: dict) -> dict:
|
|
201
|
+
"""Filter extra_data to only include params accepted by the cover action.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
action_name: The cover method name (e.g. 'open', 'toggle', 'smart_toggle')
|
|
205
|
+
extra_data: Raw extra_data dict from action config
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
Filtered dict with only accepted params for the action.
|
|
209
|
+
"""
|
|
210
|
+
if not extra_data:
|
|
211
|
+
return {}
|
|
212
|
+
allowed = _COVER_ACTION_PARAMS.get(action_name)
|
|
213
|
+
if allowed is None:
|
|
214
|
+
return {}
|
|
215
|
+
return {k: v for k, v in extra_data.items() if k in allowed}
|
|
216
|
+
|
|
189
217
|
INA219 = "ina219"
|
|
190
218
|
VIRTUAL_ENERGY_SENSOR = "virtual_energy_sensor"
|
|
191
219
|
PINS = {
|
|
@@ -13,7 +13,7 @@ import json
|
|
|
13
13
|
import logging
|
|
14
14
|
from typing import TYPE_CHECKING, Any
|
|
15
15
|
|
|
16
|
-
from boneio.const import COVER, DEVICE_CLASS, ID, NAME, RESTORE_STATE, SHOW_HA, cover_actions
|
|
16
|
+
from boneio.const import COVER, DEVICE_CLASS, ID, NAME, RESTORE_STATE, SHOW_HA, cover_actions, filter_cover_extra_data
|
|
17
17
|
from boneio.core.utils import TimePeriod, strip_accents
|
|
18
18
|
from boneio.exceptions import CoverConfigurationException
|
|
19
19
|
from boneio.integration import ha_cover_availabilty_message
|
|
@@ -72,6 +72,28 @@ class CoverManager:
|
|
|
72
72
|
config = self._manager._config_helper.reload_config()
|
|
73
73
|
self._config_covers = config.get(COVER, [])
|
|
74
74
|
self._manager._config_helper.clear_autodiscovery_type(ha_type=COVER)
|
|
75
|
+
|
|
76
|
+
# Remove covers that are no longer in config
|
|
77
|
+
new_ids = set()
|
|
78
|
+
for _cfg in self._config_covers:
|
|
79
|
+
if _cfg.get(ID):
|
|
80
|
+
new_ids.add(strip_accents(_cfg[ID]))
|
|
81
|
+
else:
|
|
82
|
+
_open = str(_cfg.get("open_relay", ""))
|
|
83
|
+
_close = str(_cfg.get("close_relay", ""))
|
|
84
|
+
new_ids.add(f"cover_{_open}_{_close}".lower().replace(" ", "_"))
|
|
85
|
+
|
|
86
|
+
removed_ids = [cid for cid in self._covers if cid not in new_ids]
|
|
87
|
+
for cid in removed_ids:
|
|
88
|
+
_LOGGER.info("Cover %s removed from config, cleaning up", cid)
|
|
89
|
+
cover = self._covers.pop(cid)
|
|
90
|
+
# Stop cover movement if running
|
|
91
|
+
try:
|
|
92
|
+
asyncio.ensure_future(cover.stop())
|
|
93
|
+
except Exception:
|
|
94
|
+
pass
|
|
95
|
+
# Remove HA autodiscovery
|
|
96
|
+
self._remove_cover_ha_discovery(cid)
|
|
75
97
|
|
|
76
98
|
for _config in self._config_covers:
|
|
77
99
|
# Get relay outputs for cover
|
|
@@ -365,8 +387,10 @@ class CoverManager:
|
|
|
365
387
|
|
|
366
388
|
try:
|
|
367
389
|
_f = getattr(cover, action_to_execute)
|
|
368
|
-
|
|
369
|
-
|
|
390
|
+
# Filter extra_data to only pass params accepted by the action
|
|
391
|
+
filtered = filter_cover_extra_data(action_to_execute, extra_data or {})
|
|
392
|
+
if filtered:
|
|
393
|
+
await _f(**filtered)
|
|
370
394
|
else:
|
|
371
395
|
await _f()
|
|
372
396
|
except Exception as err:
|
|
@@ -28,6 +28,7 @@ from boneio.const import (
|
|
|
28
28
|
STATE,
|
|
29
29
|
TOGGLE,
|
|
30
30
|
cover_actions,
|
|
31
|
+
filter_cover_extra_data,
|
|
31
32
|
output_actions,
|
|
32
33
|
)
|
|
33
34
|
from boneio.core.config import ConfigHelper
|
|
@@ -669,6 +670,8 @@ class Manager:
|
|
|
669
670
|
continue
|
|
670
671
|
action_to_execute = action_definition.get("action_to_execute")
|
|
671
672
|
extra_data = action_definition.get("extra_data", {})
|
|
673
|
+
# Filter extra_data to only pass params accepted by each action
|
|
674
|
+
filtered_data = filter_cover_extra_data(action_to_execute, extra_data)
|
|
672
675
|
_LOGGER.debug(
|
|
673
676
|
"Executing action %s for cover %s. Duration: %s",
|
|
674
677
|
action_to_execute,
|
|
@@ -676,7 +679,7 @@ class Manager:
|
|
|
676
679
|
time.time() - start_time,
|
|
677
680
|
)
|
|
678
681
|
_f = getattr(cover, action_to_execute)
|
|
679
|
-
await _f(**
|
|
682
|
+
await _f(**filtered_data)
|
|
680
683
|
|
|
681
684
|
elif action == OUTPUT_OVER_MQTT:
|
|
682
685
|
boneio_id = action_definition.get("boneio_id")
|
|
@@ -364,7 +364,10 @@ class ESPHomeRemoteDevice(RemoteDevice):
|
|
|
364
364
|
"current_operation": current_op,
|
|
365
365
|
"last_known_operation": last_op,
|
|
366
366
|
}
|
|
367
|
-
_LOGGER.debug(
|
|
367
|
+
_LOGGER.debug(
|
|
368
|
+
"Cover '%s' state update: position=%.2f, current_op=%s, last_op=%s",
|
|
369
|
+
cover_id, state.position, current_op, last_op,
|
|
370
|
+
)
|
|
368
371
|
break
|
|
369
372
|
except Exception as e:
|
|
370
373
|
_LOGGER.debug("Error processing state change: %s", e)
|
|
@@ -854,27 +857,52 @@ class ESPHomeRemoteDevice(RemoteDevice):
|
|
|
854
857
|
self._client.cover_command(cover_key, position=0.0)
|
|
855
858
|
elif action_upper == "STOP":
|
|
856
859
|
self._client.cover_command(cover_key, stop=True)
|
|
857
|
-
elif action_upper
|
|
858
|
-
# Toggle based on current operation or last known operation
|
|
860
|
+
elif action_upper in ("TOGGLE", "SMART_TOGGLE"):
|
|
861
|
+
# Toggle based on current operation, position, or last known operation
|
|
859
862
|
state = self._cover_states.get(cover_id, {})
|
|
860
863
|
current_op = state.get("current_operation", 0) # 0=IDLE, 1=OPENING, 2=CLOSING
|
|
861
864
|
last_op = state.get("last_known_operation", 2)
|
|
862
865
|
cover_pos = state.get("position")
|
|
866
|
+
always_open_till = kwargs.get("always_open_till", 50) if action_upper == "SMART_TOGGLE" else None
|
|
863
867
|
_LOGGER.debug(
|
|
864
|
-
"
|
|
865
|
-
|
|
866
|
-
{k: v for k, v in self._cover_states.items()},
|
|
868
|
+
"ESPHome %s cover '%s': current_op=%s, last_op=%s, position=%s, always_open_till=%s",
|
|
869
|
+
action_upper, cover_id, current_op, last_op, cover_pos, always_open_till,
|
|
867
870
|
)
|
|
868
871
|
|
|
869
872
|
if current_op != 0: # If moving, stop it
|
|
870
|
-
_LOGGER.debug("
|
|
873
|
+
_LOGGER.debug("%s -> STOP (cover is moving, current_op=%s)", action_upper, current_op)
|
|
871
874
|
self._client.cover_command(cover_key, stop=True)
|
|
872
|
-
elif
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
875
|
+
elif cover_pos is not None:
|
|
876
|
+
# Position is known — use it for smarter decisions
|
|
877
|
+
pos_pct = int(cover_pos * 100)
|
|
878
|
+
if always_open_till is not None and pos_pct <= always_open_till:
|
|
879
|
+
# SMART_TOGGLE: below threshold → always open
|
|
880
|
+
_LOGGER.debug("SMART_TOGGLE -> OPEN (pos=%d%% <= threshold=%d%%)", pos_pct, always_open_till)
|
|
881
|
+
self._client.cover_command(cover_key, position=1.0)
|
|
882
|
+
elif cover_pos >= 0.99:
|
|
883
|
+
# Fully open → close
|
|
884
|
+
_LOGGER.debug("%s -> CLOSE (fully open, pos=%.2f)", action_upper, cover_pos)
|
|
885
|
+
self._client.cover_command(cover_key, position=0.0)
|
|
886
|
+
elif cover_pos <= 0.01:
|
|
887
|
+
# Fully closed → open
|
|
888
|
+
_LOGGER.debug("%s -> OPEN (fully closed, pos=%.2f)", action_upper, cover_pos)
|
|
889
|
+
self._client.cover_command(cover_key, position=1.0)
|
|
890
|
+
elif last_op == 2:
|
|
891
|
+
# Last was closing → open
|
|
892
|
+
_LOGGER.debug("%s -> OPEN (last_op=CLOSING)", action_upper)
|
|
893
|
+
self._client.cover_command(cover_key, position=1.0)
|
|
894
|
+
else:
|
|
895
|
+
# Last was opening → close
|
|
896
|
+
_LOGGER.debug("%s -> CLOSE (last_op=%s)", action_upper, last_op)
|
|
897
|
+
self._client.cover_command(cover_key, position=0.0)
|
|
898
|
+
else:
|
|
899
|
+
# No position known — use last_op only
|
|
900
|
+
if last_op == 2:
|
|
901
|
+
_LOGGER.debug("%s -> OPEN (no position, last_op=CLOSING)", action_upper)
|
|
902
|
+
self._client.cover_command(cover_key, position=1.0)
|
|
903
|
+
else:
|
|
904
|
+
_LOGGER.debug("%s -> CLOSE (no position, last_op=%s)", action_upper, last_op)
|
|
905
|
+
self._client.cover_command(cover_key, position=0.0)
|
|
878
906
|
elif action_upper == "TOGGLE_OPEN":
|
|
879
907
|
state = self._cover_states.get(cover_id, {})
|
|
880
908
|
current_op = state.get("current_operation", 0)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
+
import subprocess
|
|
5
6
|
from itertools import cycle
|
|
6
7
|
from typing import TYPE_CHECKING
|
|
7
8
|
|
|
@@ -13,7 +14,7 @@ from luma.oled.device import sh1106
|
|
|
13
14
|
from PIL import Image, ImageDraw
|
|
14
15
|
from PIL.ImageDraw import ImageDraw as ImageDrawType
|
|
15
16
|
|
|
16
|
-
from boneio.const import OLED_PIN, UPTIME, WHITE
|
|
17
|
+
from boneio.const import LONG, OLED_PIN, SINGLE, UPTIME, WHITE
|
|
17
18
|
from boneio.core.events import EventBus, async_track_point_in_time, utcnow
|
|
18
19
|
from boneio.core.system import HostData
|
|
19
20
|
from boneio.core.utils.font_util import make_font
|
|
@@ -102,6 +103,24 @@ class Oled:
|
|
|
102
103
|
self._cancel_sleep_handle = None
|
|
103
104
|
self._sleep_timeout = sleep_timeout
|
|
104
105
|
|
|
106
|
+
# Shutdown confirmation state machine
|
|
107
|
+
# States: None -> "wait_release" -> "confirm" -> "progress" -> shutdown
|
|
108
|
+
# - First long press → show confirm screen, enter "wait_release"
|
|
109
|
+
# - Release after first long → enter "confirm" (waiting for second long)
|
|
110
|
+
# - Second long press → enter "progress" with filling progress bar
|
|
111
|
+
# - Hold 5s → execute shutdown
|
|
112
|
+
# - Single click or 10s timeout → cancel
|
|
113
|
+
self._shutdown_state: str | None = None
|
|
114
|
+
self._shutdown_cancel_handle = None
|
|
115
|
+
# Timer to detect button release (no LONG event for 300ms = released)
|
|
116
|
+
self._shutdown_release_timer: asyncio.TimerHandle | None = None
|
|
117
|
+
# Last seen long press duration — used to detect new press cycle (duration resets)
|
|
118
|
+
self._shutdown_last_long_duration: float = 0.0
|
|
119
|
+
# Duration (seconds) the user must hold the button to confirm shutdown
|
|
120
|
+
self._shutdown_hold_duration: float = 5.0
|
|
121
|
+
# Timeout (seconds) to cancel shutdown confirmation if no action
|
|
122
|
+
self._shutdown_confirm_timeout: float = 10.0
|
|
123
|
+
|
|
105
124
|
# Initialize I2C display
|
|
106
125
|
try:
|
|
107
126
|
# Use luma.oled for now, but could be refactored to use SMBus2I2C
|
|
@@ -219,14 +238,98 @@ class Oled:
|
|
|
219
238
|
# Display the centered QR code
|
|
220
239
|
self._device.display(display_image)
|
|
221
240
|
|
|
222
|
-
async def _handle_button_press(self, event
|
|
223
|
-
"""Handle button press event from input.
|
|
224
|
-
|
|
241
|
+
async def _handle_button_press(self, event) -> None:
|
|
242
|
+
"""Handle button press event from input.
|
|
243
|
+
|
|
244
|
+
Supports shutdown flow via long press:
|
|
245
|
+
1. First long press → show confirmation screen
|
|
246
|
+
2. User releases button → state moves to "confirm"
|
|
247
|
+
3. Second long press (held 5s) → progress bar fills, then shutdown
|
|
248
|
+
4. Any single click or 10s timeout → cancel shutdown
|
|
249
|
+
|
|
250
|
+
The detector emits periodic LONG events (every 200ms) with growing
|
|
251
|
+
duration while the button is held. A new press cycle is detected
|
|
252
|
+
when duration resets (new duration < last tracked duration).
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
event: InputEvent from EventBus with click_type and duration
|
|
256
|
+
"""
|
|
257
|
+
click_type = getattr(event, "click_type", None)
|
|
258
|
+
duration = getattr(event, "duration", None) or 0.0
|
|
259
|
+
|
|
260
|
+
_LOGGER.debug("OLED button event: click_type=%s, duration=%.2f, shutdown_state=%s",
|
|
261
|
+
click_type, duration, self._shutdown_state)
|
|
262
|
+
|
|
263
|
+
# --- Shutdown state machine ---
|
|
264
|
+
|
|
265
|
+
if self._shutdown_state == "wait_release":
|
|
266
|
+
# Absorb periodic LONG events from the first long press.
|
|
267
|
+
# Detector does NOT emit SINGLE after long press release.
|
|
268
|
+
# Detect release via timer: each LONG resets a 300ms timer.
|
|
269
|
+
# When no more LONG events arrive, timer fires → "confirm".
|
|
270
|
+
if click_type == LONG:
|
|
271
|
+
self._shutdown_last_long_duration = duration
|
|
272
|
+
# Reset release-detection timer
|
|
273
|
+
self._reset_release_timer()
|
|
274
|
+
return
|
|
275
|
+
elif click_type == SINGLE:
|
|
276
|
+
# Shouldn't happen after long, but handle gracefully
|
|
277
|
+
self._cancel_release_timer()
|
|
278
|
+
self._shutdown_state = "confirm"
|
|
279
|
+
self._shutdown_last_long_duration = 0.0
|
|
280
|
+
return
|
|
281
|
+
# Ignore other events
|
|
282
|
+
return
|
|
283
|
+
|
|
284
|
+
if self._shutdown_state == "confirm":
|
|
285
|
+
if click_type == LONG:
|
|
286
|
+
# Second long press — enter progress mode
|
|
287
|
+
self._shutdown_state = "progress"
|
|
288
|
+
self._cancel_shutdown_timeout()
|
|
289
|
+
self._shutdown_last_long_duration = duration
|
|
290
|
+
self._draw_shutdown_progress(duration)
|
|
291
|
+
if duration >= self._shutdown_hold_duration:
|
|
292
|
+
await self._execute_shutdown()
|
|
293
|
+
return
|
|
294
|
+
elif click_type == SINGLE:
|
|
295
|
+
# Single click cancels shutdown confirmation
|
|
296
|
+
self._cancel_shutdown()
|
|
297
|
+
return
|
|
298
|
+
# Ignore other events during confirm
|
|
299
|
+
return
|
|
300
|
+
|
|
301
|
+
if self._shutdown_state == "progress":
|
|
302
|
+
if click_type == LONG:
|
|
303
|
+
if duration < self._shutdown_last_long_duration:
|
|
304
|
+
# Duration reset — user released and pressed again, cancel
|
|
305
|
+
self._cancel_shutdown()
|
|
306
|
+
return
|
|
307
|
+
# Still holding — update progress bar
|
|
308
|
+
self._shutdown_last_long_duration = duration
|
|
309
|
+
self._draw_shutdown_progress(duration)
|
|
310
|
+
if duration >= self._shutdown_hold_duration:
|
|
311
|
+
await self._execute_shutdown()
|
|
312
|
+
return
|
|
313
|
+
else:
|
|
314
|
+
# Released (single) or other — cancel
|
|
315
|
+
self._cancel_shutdown()
|
|
316
|
+
return
|
|
317
|
+
|
|
318
|
+
# --- Normal mode ---
|
|
225
319
|
if self._sleep:
|
|
226
|
-
# Display is sleeping - wake it up
|
|
227
320
|
self.wake_up()
|
|
228
|
-
|
|
229
|
-
|
|
321
|
+
return
|
|
322
|
+
|
|
323
|
+
if click_type == LONG and duration < 1.0:
|
|
324
|
+
# First long press event — show confirmation, enter wait_release
|
|
325
|
+
self._shutdown_state = "wait_release"
|
|
326
|
+
self._shutdown_last_long_duration = duration
|
|
327
|
+
self._draw_shutdown_confirm()
|
|
328
|
+
self._start_shutdown_timeout()
|
|
329
|
+
self._reset_release_timer()
|
|
330
|
+
return
|
|
331
|
+
|
|
332
|
+
if click_type == SINGLE:
|
|
230
333
|
self._next_screen()
|
|
231
334
|
|
|
232
335
|
def _next_screen(self) -> None:
|
|
@@ -240,6 +343,150 @@ class Oled:
|
|
|
240
343
|
self._current_screen = next(self._screen_cycle)
|
|
241
344
|
self.render_display()
|
|
242
345
|
|
|
346
|
+
# --- Shutdown helper methods ---
|
|
347
|
+
|
|
348
|
+
def _draw_shutdown_confirm(self) -> None:
|
|
349
|
+
"""Draw shutdown confirmation screen on OLED.
|
|
350
|
+
|
|
351
|
+
Shows a warning message asking the user to hold the button
|
|
352
|
+
for 5 seconds to confirm system shutdown.
|
|
353
|
+
"""
|
|
354
|
+
with canvas(self._device) as draw:
|
|
355
|
+
# Warning triangle
|
|
356
|
+
draw.polygon([(64, 2), (54, 18), (74, 18)], outline=WHITE)
|
|
357
|
+
draw.text((61, 5), "!", font=fonts["small"], fill=WHITE)
|
|
358
|
+
# Message
|
|
359
|
+
draw.text((10, 24), "Shutdown system?", font=fonts["small"], fill=WHITE)
|
|
360
|
+
draw.text((4, 38), "Hold button 5s to confirm", font=fonts["extraSmall"], fill=WHITE)
|
|
361
|
+
draw.text((8, 52), "Click to cancel (10s)", font=fonts["extraSmall"], fill=WHITE)
|
|
362
|
+
|
|
363
|
+
def _draw_shutdown_progress(self, duration: float) -> None:
|
|
364
|
+
"""Draw shutdown progress bar on OLED.
|
|
365
|
+
|
|
366
|
+
Shows a progress bar that fills proportionally to how long
|
|
367
|
+
the user has been holding the button vs the required duration.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
duration: How long the button has been held (seconds)
|
|
371
|
+
"""
|
|
372
|
+
progress = min(duration / self._shutdown_hold_duration, 1.0)
|
|
373
|
+
bar_x, bar_y = 10, 34
|
|
374
|
+
bar_w, bar_h = 108, 14
|
|
375
|
+
fill_w = int(bar_w * progress)
|
|
376
|
+
|
|
377
|
+
with canvas(self._device) as draw:
|
|
378
|
+
draw.text((20, 4), "Shutting down...", font=fonts["small"], fill=WHITE)
|
|
379
|
+
draw.text((28, 18), f"{int(progress * 100)}%", font=fonts["small"], fill=WHITE)
|
|
380
|
+
# Progress bar outline
|
|
381
|
+
draw.rectangle([bar_x, bar_y, bar_x + bar_w, bar_y + bar_h], outline=WHITE)
|
|
382
|
+
# Progress bar fill
|
|
383
|
+
if fill_w > 0:
|
|
384
|
+
draw.rectangle([bar_x + 1, bar_y + 1, bar_x + fill_w - 1, bar_y + bar_h - 1], fill=WHITE)
|
|
385
|
+
draw.text((22, 54), "Release to cancel", font=fonts["extraSmall"], fill=WHITE)
|
|
386
|
+
|
|
387
|
+
def _start_shutdown_timeout(self) -> None:
|
|
388
|
+
"""Start a 10-second timeout that cancels the shutdown confirmation.
|
|
389
|
+
|
|
390
|
+
If the user doesn't interact within the timeout period,
|
|
391
|
+
the shutdown flow is cancelled and the normal screen is restored.
|
|
392
|
+
"""
|
|
393
|
+
self._cancel_shutdown_timeout()
|
|
394
|
+
loop = self._event_bus._loop
|
|
395
|
+
|
|
396
|
+
def _timeout_callback() -> None:
|
|
397
|
+
"""Cancel shutdown after timeout expires."""
|
|
398
|
+
_LOGGER.info("Shutdown confirmation timed out, cancelling")
|
|
399
|
+
self._shutdown_state = None
|
|
400
|
+
self._shutdown_cancel_handle = None
|
|
401
|
+
self.render_display()
|
|
402
|
+
|
|
403
|
+
self._shutdown_cancel_handle = loop.call_later(
|
|
404
|
+
self._shutdown_confirm_timeout, _timeout_callback
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
def _cancel_shutdown_timeout(self) -> None:
|
|
408
|
+
"""Cancel the pending shutdown timeout timer."""
|
|
409
|
+
if self._shutdown_cancel_handle is not None:
|
|
410
|
+
self._shutdown_cancel_handle.cancel()
|
|
411
|
+
self._shutdown_cancel_handle = None
|
|
412
|
+
|
|
413
|
+
def _reset_release_timer(self) -> None:
|
|
414
|
+
"""Reset the 300ms release-detection timer.
|
|
415
|
+
|
|
416
|
+
Called on each periodic LONG event during wait_release state.
|
|
417
|
+
If no more LONG events arrive within 300ms, the timer fires
|
|
418
|
+
and transitions to 'confirm' state (button was released).
|
|
419
|
+
"""
|
|
420
|
+
self._cancel_release_timer()
|
|
421
|
+
loop = self._event_bus._loop
|
|
422
|
+
|
|
423
|
+
def _on_release_detected() -> None:
|
|
424
|
+
"""No LONG event for 300ms — button was released."""
|
|
425
|
+
self._shutdown_release_timer = None
|
|
426
|
+
if self._shutdown_state == "wait_release":
|
|
427
|
+
_LOGGER.debug("OLED button release detected (no LONG for 300ms)")
|
|
428
|
+
self._shutdown_state = "confirm"
|
|
429
|
+
self._shutdown_last_long_duration = 0.0
|
|
430
|
+
# Timeout already running from first long press
|
|
431
|
+
|
|
432
|
+
self._shutdown_release_timer = loop.call_later(0.3, _on_release_detected)
|
|
433
|
+
|
|
434
|
+
def _cancel_release_timer(self) -> None:
|
|
435
|
+
"""Cancel the pending release-detection timer."""
|
|
436
|
+
if self._shutdown_release_timer is not None:
|
|
437
|
+
self._shutdown_release_timer.cancel()
|
|
438
|
+
self._shutdown_release_timer = None
|
|
439
|
+
|
|
440
|
+
def _cancel_shutdown(self) -> None:
|
|
441
|
+
"""Cancel the shutdown flow and return to normal display.
|
|
442
|
+
|
|
443
|
+
Resets the shutdown state machine and restores the current screen.
|
|
444
|
+
"""
|
|
445
|
+
_LOGGER.info("Shutdown cancelled by user")
|
|
446
|
+
self._cancel_shutdown_timeout()
|
|
447
|
+
self._cancel_release_timer()
|
|
448
|
+
self._shutdown_state = None
|
|
449
|
+
self._shutdown_last_long_duration = 0.0
|
|
450
|
+
self.render_display()
|
|
451
|
+
|
|
452
|
+
async def _execute_shutdown(self) -> None:
|
|
453
|
+
"""Execute system shutdown.
|
|
454
|
+
|
|
455
|
+
Draws a final 'Goodbye' message on the OLED, then runs
|
|
456
|
+
'sudo shutdown -h now' to power off the device.
|
|
457
|
+
"""
|
|
458
|
+
_LOGGER.warning("System shutdown initiated from OLED button")
|
|
459
|
+
self._shutdown_state = None
|
|
460
|
+
self._shutdown_last_long_duration = 0.0
|
|
461
|
+
self._cancel_shutdown_timeout()
|
|
462
|
+
|
|
463
|
+
# Draw goodbye screen
|
|
464
|
+
with canvas(self._device) as draw:
|
|
465
|
+
draw.text((20, 10), "Goodbye!", font=fonts["big"], fill=WHITE)
|
|
466
|
+
draw.text((15, 35), "System shutting down...", font=fonts["extraSmall"], fill=WHITE)
|
|
467
|
+
|
|
468
|
+
# Small delay so the user sees the message
|
|
469
|
+
await asyncio.sleep(1)
|
|
470
|
+
|
|
471
|
+
try:
|
|
472
|
+
subprocess.run(
|
|
473
|
+
["sudo", "shutdown", "-h", "now"],
|
|
474
|
+
check=True,
|
|
475
|
+
capture_output=True,
|
|
476
|
+
text=True,
|
|
477
|
+
)
|
|
478
|
+
except subprocess.CalledProcessError as e:
|
|
479
|
+
_LOGGER.error("Failed to shutdown device: %s", e.stderr)
|
|
480
|
+
# Show error on OLED and return to normal
|
|
481
|
+
with canvas(self._device) as draw:
|
|
482
|
+
draw.text((10, 20), "Shutdown failed!", font=fonts["small"], fill=WHITE)
|
|
483
|
+
draw.text((10, 40), str(e.stderr)[:20], font=fonts["extraSmall"], fill=WHITE)
|
|
484
|
+
await asyncio.sleep(3)
|
|
485
|
+
self.render_display()
|
|
486
|
+
except Exception as e:
|
|
487
|
+
_LOGGER.error("Error shutting down device: %s", e)
|
|
488
|
+
self.render_display()
|
|
489
|
+
|
|
243
490
|
def render_display(self) -> None:
|
|
244
491
|
"""Render display - main method that decides what to display."""
|
|
245
492
|
|
|
@@ -35,7 +35,7 @@ schema:
|
|
|
35
35
|
action: ['cover', 'cover_over_mqtt', 'remote_cover']
|
|
36
36
|
forbidden_if:
|
|
37
37
|
action: ['output', 'mqtt', 'mqtt_output', 'remote_output']
|
|
38
|
-
allowed: ['TOGGLE', 'OPEN', 'CLOSE', 'STOP', 'TOGGLE_OPEN', 'TOGGLE_CLOSE', 'TILT', 'TILT_OPEN', 'TILT_CLOSE']
|
|
38
|
+
allowed: ['TOGGLE', 'OPEN', 'CLOSE', 'STOP', 'TOGGLE_OPEN', 'TOGGLE_CLOSE', 'SMART_TOGGLE', 'TILT', 'TILT_OPEN', 'TILT_CLOSE']
|
|
39
39
|
coerce: action_field
|
|
40
40
|
default: TOGGLE
|
|
41
41
|
case_insensitive: true
|
|
@@ -58,6 +58,18 @@ schema:
|
|
|
58
58
|
required: False
|
|
59
59
|
meta:
|
|
60
60
|
label: Tilt position to set cover to. 0 means closed, 100 means opened.
|
|
61
|
+
always_open_till:
|
|
62
|
+
type: integer
|
|
63
|
+
required: False
|
|
64
|
+
min: 0
|
|
65
|
+
max: 100
|
|
66
|
+
default: 50
|
|
67
|
+
meta:
|
|
68
|
+
label: Smart toggle threshold (0-100%).
|
|
69
|
+
description: |
|
|
70
|
+
Position threshold for SMART_TOGGLE action.
|
|
71
|
+
If cover position is at or below this value, it will always open.
|
|
72
|
+
Above this value, normal toggle behavior applies.
|
|
61
73
|
action_output:
|
|
62
74
|
type: string
|
|
63
75
|
required_if:
|