boneio 1.5.2.dev1__tar.gz → 1.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boneio-1.5.2.dev1/boneio.egg-info → boneio-1.5.4}/PKG-INFO +1 -1
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/cover/cover.py +17 -3
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/input/binary_sensor.py +71 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/input/detectors.py +62 -1
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/input/event.py +34 -11
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/events/bus.py +27 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/inputs.py +14 -3
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/input/base.py +13 -3
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/ina219.py +39 -1
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/sensor/temperature/base.py +9 -1
- boneio-1.5.4/boneio/version.py +2 -0
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/BindingMatrix-D1OvlTso.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/BindingMatrix-Sq_Mfh0a.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/ConfigEditor-Bdpm9_Qo.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/ConfigEditor-bP6Hl3Ew.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/EditItemDialog-BIjzsrqq.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/EditItemDialog-DnzpXVT9.js +2 -2
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/EntityCard-CJ0ccsW1.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/EntityCard-BJr0Z2Vh.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/EntityGrid-xCqfJxkw.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/EntityGrid-J2pMEVAC.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/FormInputToggle-Cn_hJrna.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/FormInputToggle-Bl4JsLEk.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/InputsView-CySRVJ90.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/InputsView-CTczAHKX.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/LogViewer-Bs7Xx9vL.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/LogViewer-3KToSszt.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/ModbusView-8rNY0iJT.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/ModbusView-BKsoFjy7.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/NodeRedView-DD2w3NAX.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/NodeRedView-CeimjpOx.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/OutputsView-B6cZ8NHI.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/OutputsView-DyePKfnd.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/SensorView-DsdnJqni.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/SensorView-DT4Xiwmi.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/SudoPasswordDialog-W42OQ76m.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/SudoPasswordDialog-yANkJZ5k.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/SystemState-De_QpQ-z.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/SystemState-qH4PbU4t.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/TemplatesView-CuLPA7iV.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/TemplatesView-CPj_t86s.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/Tools-DOmBe8W2.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/Tools-Du0szAxd.js +1 -1
- boneio-1.5.4/boneio/webui/frontend-dist/assets/UISettings-CNZ0Z5t9.js +38 -0
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/gi-czqU2m4e.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/gi-DYNMHE5B.js +1 -1
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/index-DCzOrheh.js → boneio-1.5.4/boneio/webui/frontend-dist/assets/index-BuJzdMCI.js +2 -2
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/index.html +1 -1
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/sw.js +1 -1
- {boneio-1.5.2.dev1 → boneio-1.5.4/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio.egg-info/SOURCES.txt +19 -19
- boneio-1.5.2.dev1/boneio/version.py +0 -2
- boneio-1.5.2.dev1/boneio/webui/frontend-dist/assets/UISettings-CtJheTh8.js +0 -38
- {boneio-1.5.2.dev1 → boneio-1.5.4}/LICENSE +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/MANIFEST.in +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/README.md +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.7/output_48_4.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.8/output_48_4.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/1.0/input.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/1.0/output_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/1.0/output_32_10.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/1.0/output_48_4.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/1.0/output_cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/boards/1.0/output_cover_mix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/bonecli.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/cover/time_based.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/cover/venetian.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/group/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/group/output_group.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/input/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/input/remote/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/input/remote/base.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/input/remote/esphome.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/irrigation/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/irrigation/controller.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/irrigation/water_source.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/output/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/output/basic.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/output/buzzer.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/output/mcp.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/output/pca.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/output/pcf.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/output/remote.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/template/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/template/alarm_panel.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/template/gate_cover.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/const.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/cloud/registration.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/migrations/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/migrations/v4_wled_cache.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/migrations/v5_ina_screen.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/package.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/yaml_compat.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/config/yaml_util.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/discovery.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/events/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/action_conditions.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/canopen.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/covers.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/display.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/irrigation.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/manager.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/remote.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/remote_input_registrar.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/templates/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/templates/alarm.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/templates/gate_cover.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/templates.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/manager/update.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/composite.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/local.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/lox.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/remote/base.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/remote/can.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/remote/esphome.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/remote/wled.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/remote/wled_cache.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/sensor/base.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/sensor/system.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/state/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/state/manager.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/system/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/system/host_data.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/system/monitor.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/conditions.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/filter.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/logger.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/overlay.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/core/utils/util.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/48x4/adc.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/48x4/config.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/48x4/event.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/48x4/mqtt.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/48x4/output48x4A.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/can_master.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/can_slave.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/exceptions.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/can/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/can/bridge.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/can/client.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/can/interface.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/can/node.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/can/node_id.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/can/test_od.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/display/early_oled.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/display/oled.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/ina226.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/ina226_driver.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/integration/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/integration/homeassistant.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/integration/interlock.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/integration/lox_template.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/actions.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/MANIFEST.sha256 +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/docker/daemon.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/journald/journald.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/kernel/postinst-boneio-overlay +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/modules-load.d/onewire.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/sudoers/boneio +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/boneio.service +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/dropins/avahi-daemon-defer.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/dropins/bb-usb-gadgets-defer.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/dropins/mosquitto-priority.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/dropins/timer-no-persistent.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/dropins/user-manager-defer.conf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/linger-marker +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/assets/wheels/pyyaml-6.0.3-cp313-cp313-linux_armv7l.whl +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/bootstrap/boneio-migrate +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/bootstrap/install-helper.sh +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/runner.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_10_disable_console_setup.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_11_timer_catchup.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_12_oled_splash_off_critical_path.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_13_mosquitto_priority.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_14_journal_apparent_size.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_15_prune_orphan_journals.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_16_login_linger.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_17_defer_user_manager.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_18_fix_hostname_once.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_1_ufw_lox_udp.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_2_libyaml.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_3_libyaml_retry.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_4_onewire_modules.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_5_overlay_kernel_hook.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_6_boot_service_order.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_7_journald_limits.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_8_apparmor_prune.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/migrations/versions/v1_5_9_defer_nonessential.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/cli.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/client.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/dts1964_3f.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/hvac/thessla.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/hvac/wanas415.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/gdfs.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/gdfx.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/qdw90a.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/mock_coordinator.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/modbus/utils.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/models/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/models/actions.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/models/events.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/models/files.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/models/logs.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/models/mqtt.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/models/state.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/runner.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/actions.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/condition.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/filters.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/id.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/remote_devices.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/remote_inputs.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/remote_outputs.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/schema.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/action_validation.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/app.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/dashboard_cards.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/HelpLabel-BSTjOtDA.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/LongPressWrapper-BHOQV7Wq.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/Sparkline-BGWlVLtt.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/aiConfig-IRYCBmLm.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/aiWizardPrompt-D9OJ-cE7.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/axios-DHUeYRnu.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/basePath-CxHj-SSK.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/clipboard-CCtx29e-.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/configCache-BAkc0Ye7.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/css.worker-CvXBzhp8.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/editor.worker-Cn2oRESe.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/formatters-zOiGPJLh.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/html.worker-BO6WuOEO.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/index-CJSdgTd5.css +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/json.worker-BkJRGcCJ.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/longPress-Dx7OCSyP.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/modbusDeviceCatalog-L6as-BKo.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/monaco-61yH0vfd.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/rolldown-runtime-QTnfLwEv.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/select-B2YDgQ4X.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/tabs-box-Dj36r4_e.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/ts.worker-B0J26iPs.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/utils-C8nShLO6.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/vendor-IzweXARb.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/assets/yaml.worker-BKRoXlmz.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/config.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/ina226.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/frontend-dist/workbox-4918f2f6.js +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/hvac_svg_templates.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/modbus_card_templates.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/can.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/config.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/config_actions.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/config_backups.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/config_core.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/config_discovery.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/config_files.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/dashboard.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/dev_fake_device.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/irrigation.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/migrations.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/modbus.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/mqtt_reference.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/nodered.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/remote_devices.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/system.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/timezone_sudoers.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/tools.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/routes/update.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/binary_sensor.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/boneio.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/can.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/config.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/cover.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/event.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/ina226.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/irrigation.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/mcp23017.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/modbus_devices.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/oled.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/output.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/remote_devices.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/sensor.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/template.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/services/logs.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/sudo_rate_limiter.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/web_server.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/pyproject.toml +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/setup.cfg +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/setup.py +0 -0
- {boneio-1.5.2.dev1 → boneio-1.5.4}/tests/test_py313_compatibility.py +0 -0
|
@@ -210,9 +210,23 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
210
210
|
async def stop(self, on_exit=False) -> None:
|
|
211
211
|
if self._movement_thread and self._movement_thread.is_alive():
|
|
212
212
|
self._stop_event.set()
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
|
|
214
|
+
# Halting is three blocking operations: waiting for the movement
|
|
215
|
+
# thread to notice the stop event, and two relay writes that go out
|
|
216
|
+
# over I2C behind a bus lock shared with every other device. Run
|
|
217
|
+
# inline they were the *event loop's* wait — up to half a second of
|
|
218
|
+
# frozen loop on every cover stop, and a cover stop is the first
|
|
219
|
+
# thing `toggle`, `toggle_open` and `toggle_close` do, so an
|
|
220
|
+
# ordinary button press paid it. Nothing reads GPIO while the loop
|
|
221
|
+
# is stopped. Order is unchanged: join first, then de-energise.
|
|
222
|
+
thread = self._movement_thread
|
|
223
|
+
|
|
224
|
+
def _halt() -> None:
|
|
225
|
+
thread.join(timeout=0.5)
|
|
226
|
+
self._open_relay.turn_off()
|
|
227
|
+
self._close_relay.turn_off()
|
|
228
|
+
|
|
229
|
+
await asyncio.get_running_loop().run_in_executor(None, _halt)
|
|
216
230
|
# Send relay states to WebSocket (not MQTT - that's handled by output_type check)
|
|
217
231
|
with suppress(RuntimeError):
|
|
218
232
|
asyncio.create_task(self._open_relay.async_send_state())
|
|
@@ -8,12 +8,18 @@ from typing import cast
|
|
|
8
8
|
|
|
9
9
|
from boneio.components.input.detectors import BinarySensorDetector
|
|
10
10
|
from boneio.const import PRESSED, RELEASED, BinaryStateTypes, ClickTypes
|
|
11
|
+
from boneio.core.utils.timeperiod import parse_time_to_ms
|
|
11
12
|
from boneio.hardware.gpio.input import GpioBaseClass, get_gpio_manager
|
|
12
13
|
from boneio.models import InputState
|
|
13
14
|
from boneio.models.events import InputEvent
|
|
14
15
|
|
|
15
16
|
_LOGGER = logging.getLogger(__name__)
|
|
16
17
|
|
|
18
|
+
# Matches the binary_sensor bounce_time default in schema.yaml. Needed on the
|
|
19
|
+
# hot-reload path, which reads the YAML without running Cerberus, so an
|
|
20
|
+
# omitted bounce_time arrives as None rather than as the schema default.
|
|
21
|
+
DEFAULT_BOUNCE_TIME_MS = 120
|
|
22
|
+
|
|
17
23
|
|
|
18
24
|
class GpioInputBinarySensor(GpioBaseClass):
|
|
19
25
|
"""Represent Gpio binary sensor on input boards."""
|
|
@@ -57,6 +63,71 @@ class GpioInputBinarySensor(GpioBaseClass):
|
|
|
57
63
|
if kwargs.get("initial_send", False):
|
|
58
64
|
gpio_manager.register_on_start_callback(self._send_initial_state)
|
|
59
65
|
|
|
66
|
+
def update_inverted(self, inverted: bool) -> bool:
|
|
67
|
+
"""Apply a new ``inverted`` setting to a running sensor.
|
|
68
|
+
|
|
69
|
+
Polarity is decided in ``__init__`` and baked into the detector, so a
|
|
70
|
+
config reload alone used to leave the running sensor on the old
|
|
71
|
+
polarity until the application was restarted.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
inverted: New inverted flag from the reloaded config.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
True if the polarity actually changed (caller should re-publish
|
|
78
|
+
the state), False if it was already set that way.
|
|
79
|
+
"""
|
|
80
|
+
inverted = bool(inverted)
|
|
81
|
+
if inverted == self._inverted:
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
self._inverted = inverted
|
|
85
|
+
self._click_type = (RELEASED, PRESSED) if inverted else (PRESSED, RELEASED)
|
|
86
|
+
|
|
87
|
+
# Re-read the pin and re-anchor the detector with the new polarity.
|
|
88
|
+
gpio_manager = get_gpio_manager(loop=self._loop)
|
|
89
|
+
current_value = gpio_manager.read_value(self._pin)
|
|
90
|
+
is_pressed = current_value if inverted else not current_value
|
|
91
|
+
self._detector.resync(inverted=inverted, current_state=is_pressed)
|
|
92
|
+
|
|
93
|
+
_LOGGER.info(
|
|
94
|
+
"Binary sensor %s (%s): inverted changed to %s without restart",
|
|
95
|
+
self._name,
|
|
96
|
+
self._pin,
|
|
97
|
+
inverted,
|
|
98
|
+
)
|
|
99
|
+
return True
|
|
100
|
+
|
|
101
|
+
def update_bounce_time(self, bounce_time) -> bool:
|
|
102
|
+
"""Apply a new debounce window to a running sensor.
|
|
103
|
+
|
|
104
|
+
Like ``inverted``, ``bounce_time`` is read in ``__init__`` and handed to
|
|
105
|
+
the detector, so a config reload used to leave the old window in place
|
|
106
|
+
until the application was restarted.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
bounce_time: Value straight from the reloaded config — a TimePeriod
|
|
110
|
+
at startup, but a bare number of milliseconds (WebUI) or a string
|
|
111
|
+
such as "120ms" (hand-written YAML) on the hot-reload path, which
|
|
112
|
+
skips Cerberus coercion. ``None`` means the schema default.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
True if the window actually changed.
|
|
116
|
+
"""
|
|
117
|
+
seconds = parse_time_to_ms(bounce_time, DEFAULT_BOUNCE_TIME_MS) / 1000.0
|
|
118
|
+
if seconds == self._bounce_time:
|
|
119
|
+
return False
|
|
120
|
+
|
|
121
|
+
self._bounce_time = seconds
|
|
122
|
+
self._detector.set_debounce(seconds)
|
|
123
|
+
_LOGGER.info(
|
|
124
|
+
"Binary sensor %s (%s): bounce_time changed to %.0fms without restart",
|
|
125
|
+
self._name,
|
|
126
|
+
self._pin,
|
|
127
|
+
seconds * 1000,
|
|
128
|
+
)
|
|
129
|
+
return True
|
|
130
|
+
|
|
60
131
|
def _send_initial_state(self) -> None:
|
|
61
132
|
"""Send initial state after setup."""
|
|
62
133
|
self.send_current_state()
|
|
@@ -135,6 +135,14 @@ class MultiClickDetector:
|
|
|
135
135
|
self._delay_click_types.add(first)
|
|
136
136
|
break
|
|
137
137
|
|
|
138
|
+
def set_debounce(self, debounce_seconds: float) -> None:
|
|
139
|
+
"""Change the debounce window on a running detector.
|
|
140
|
+
|
|
141
|
+
Only the window is replaced; timestamps already recorded stay valid
|
|
142
|
+
and are simply compared against the new window from now on.
|
|
143
|
+
"""
|
|
144
|
+
self._debounce_seconds = debounce_seconds
|
|
145
|
+
|
|
138
146
|
def _finalize_clicks(self) -> None:
|
|
139
147
|
"""Finalize a multi-click sequence."""
|
|
140
148
|
count = self._state.click_count
|
|
@@ -415,13 +423,18 @@ class MultiClickDetector:
|
|
|
415
423
|
GPIO state to detect missed RELEASE edge events.
|
|
416
424
|
"""
|
|
417
425
|
if not self._state.last_press_loop_ts or self._state.last_release_ts:
|
|
418
|
-
# Button released or invalid state
|
|
426
|
+
# Button released or invalid state. Drop the handle as well: this
|
|
427
|
+
# chain is ending here, and a handle left pointing at a timer that
|
|
428
|
+
# has already fired reads as "a long press is running" to the
|
|
429
|
+
# release path, which then emits a phantom final LONG on the next
|
|
430
|
+
# ordinary click.
|
|
419
431
|
_LOGGER.debug(
|
|
420
432
|
"Periodic long skipped for %s: press_ts=%s, release_ts=%s",
|
|
421
433
|
self._name,
|
|
422
434
|
self._state.last_press_loop_ts is not None,
|
|
423
435
|
self._state.last_release_ts,
|
|
424
436
|
)
|
|
437
|
+
self._state.long_hold_periodic_timer = None
|
|
425
438
|
return
|
|
426
439
|
|
|
427
440
|
now = self._loop.time()
|
|
@@ -570,6 +583,27 @@ class MultiClickDetector:
|
|
|
570
583
|
return
|
|
571
584
|
|
|
572
585
|
_LOGGER.debug("PRESSED: %s (%s)", self._name, self._pin)
|
|
586
|
+
|
|
587
|
+
# End any long-hold chain still running from the previous press.
|
|
588
|
+
# It can still be running only because that press never saw its
|
|
589
|
+
# release — the edge was lost while the event loop was blocked, or
|
|
590
|
+
# it was swallowed as a bounce. Left alone, the old chain keeps
|
|
591
|
+
# rescheduling itself and now measures against *this* press, so its
|
|
592
|
+
# safety timeout never trips and nothing can ever cancel it: the
|
|
593
|
+
# handle below is about to be overwritten. Every such press adds
|
|
594
|
+
# another immortal chain emitting LONG five times a second.
|
|
595
|
+
if self._state.long_hold_periodic_timer:
|
|
596
|
+
_LOGGER.warning(
|
|
597
|
+
"New press on %s (%s) while a long-hold chain was still "
|
|
598
|
+
"running — the previous release was never seen. Ending it.",
|
|
599
|
+
self._name,
|
|
600
|
+
self._pin,
|
|
601
|
+
)
|
|
602
|
+
self._state.long_hold_periodic_timer.cancel()
|
|
603
|
+
self._state.long_hold_periodic_timer = None
|
|
604
|
+
self._state.executed_long_actions = set()
|
|
605
|
+
self._state.last_repeat_times = {}
|
|
606
|
+
|
|
573
607
|
self._state.last_press_ts = timestamp_s
|
|
574
608
|
self._state.last_press_loop_ts = self._loop.time() # Store loop time for duration calc
|
|
575
609
|
self._state.last_release_ts = None # Reset release timestamp for new press
|
|
@@ -847,6 +881,33 @@ class BinarySensorDetector:
|
|
|
847
881
|
self._pin = pin
|
|
848
882
|
self._state = BinarySensorState()
|
|
849
883
|
|
|
884
|
+
def set_debounce(self, debounce_seconds: float) -> None:
|
|
885
|
+
"""Change the debounce window on a running detector.
|
|
886
|
+
|
|
887
|
+
Only the window is replaced; timestamps already recorded stay valid
|
|
888
|
+
and are simply compared against the new window from now on.
|
|
889
|
+
"""
|
|
890
|
+
self._debounce_seconds = debounce_seconds
|
|
891
|
+
|
|
892
|
+
def resync(self, inverted: bool, current_state: bool) -> None:
|
|
893
|
+
"""Apply a new polarity to a running detector.
|
|
894
|
+
|
|
895
|
+
Called when ``inverted`` is changed in the config and reloaded, so the
|
|
896
|
+
user does not have to restart the application for it to take effect.
|
|
897
|
+
|
|
898
|
+
Args:
|
|
899
|
+
inverted: New inverted flag.
|
|
900
|
+
current_state: Pressed state as read from the pin right now, already
|
|
901
|
+
interpreted with the *new* polarity. Without re-anchoring it the
|
|
902
|
+
cached state would still describe the old polarity and the next
|
|
903
|
+
edge would be dropped by the "state unchanged" guard.
|
|
904
|
+
"""
|
|
905
|
+
self._inverted = bool(inverted)
|
|
906
|
+
self._state.current_state = bool(current_state)
|
|
907
|
+
# Drop the debounce anchor — the pending window belongs to the old
|
|
908
|
+
# polarity and would swallow the first edge after the change.
|
|
909
|
+
self._state.last_press_ts = None
|
|
910
|
+
|
|
850
911
|
def handle_event(self, event: gpiod.EdgeEvent) -> None:
|
|
851
912
|
"""Process a GPIO edge event for binary sensor.
|
|
852
913
|
|
|
@@ -7,7 +7,7 @@ import time
|
|
|
7
7
|
|
|
8
8
|
from boneio.components.input.detectors import MultiClickDetector
|
|
9
9
|
from boneio.const import ClickTypes
|
|
10
|
-
from boneio.core.utils import
|
|
10
|
+
from boneio.core.utils.timeperiod import parse_time_to_ms
|
|
11
11
|
from boneio.hardware.gpio.input import GpioBaseClass, get_gpio_manager
|
|
12
12
|
|
|
13
13
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -16,25 +16,31 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
16
16
|
DEFAULT_DOUBLE_CLICK_DURATION_MS = 220
|
|
17
17
|
DEFAULT_LONG_PRESS_DURATION_MS = 400
|
|
18
18
|
DEFAULT_SEQUENCE_WINDOW_MS = 500
|
|
19
|
+
# Matches the event bounce_time default in schema.yaml. Needed on the hot-reload
|
|
20
|
+
# path, which reads the YAML without running Cerberus, so an omitted bounce_time
|
|
21
|
+
# arrives as None rather than as the schema default.
|
|
22
|
+
DEFAULT_BOUNCE_TIME_MS = 30
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
def _to_milliseconds(value, default_ms: int) -> int:
|
|
22
26
|
"""Convert a value to milliseconds.
|
|
23
27
|
|
|
24
28
|
Args:
|
|
25
|
-
value:
|
|
26
|
-
|
|
29
|
+
value: TimePeriod, bare number of milliseconds, string with a unit
|
|
30
|
+
(e.g. "300ms"), or None.
|
|
31
|
+
default_ms: Default value in milliseconds if value is None or unusable.
|
|
27
32
|
|
|
28
33
|
Returns:
|
|
29
|
-
Value in milliseconds as integer
|
|
34
|
+
Value in milliseconds as integer.
|
|
35
|
+
|
|
36
|
+
Note:
|
|
37
|
+
Strings have to be handled here, not just TimePeriod: Cerberus coerces
|
|
38
|
+
these fields at startup, but the hot-reload path reads the YAML without
|
|
39
|
+
validating, and EventForm writes them as strings like "300ms". Falling
|
|
40
|
+
back to the default for those quietly reset every custom click timing on
|
|
41
|
+
each reload.
|
|
30
42
|
"""
|
|
31
|
-
|
|
32
|
-
return default_ms
|
|
33
|
-
if isinstance(value, TimePeriod):
|
|
34
|
-
return int(value.total_milliseconds)
|
|
35
|
-
if isinstance(value, (int, float)):
|
|
36
|
-
return int(value)
|
|
37
|
-
return default_ms
|
|
43
|
+
return parse_time_to_ms(value, default_ms)
|
|
38
44
|
|
|
39
45
|
|
|
40
46
|
class GpioEventButton(GpioBaseClass):
|
|
@@ -173,6 +179,7 @@ class GpioEventButton(GpioBaseClass):
|
|
|
173
179
|
enable_triple_click: bool | None = None,
|
|
174
180
|
long_press_mqtt_mode: str | None = None,
|
|
175
181
|
max_long_press_duration: int | float | None = None,
|
|
182
|
+
bounce_time: object | None = None,
|
|
176
183
|
) -> None:
|
|
177
184
|
"""Update timing parameters for click detection.
|
|
178
185
|
|
|
@@ -189,6 +196,9 @@ class GpioEventButton(GpioBaseClass):
|
|
|
189
196
|
enable_triple_click: Enable triple click detection
|
|
190
197
|
long_press_mqtt_mode: 'single' or 'periodic' for MQTT long press events
|
|
191
198
|
max_long_press_duration: Safety timeout for long press in ms (default: 120000ms)
|
|
199
|
+
bounce_time: Debounce window — a TimePeriod at startup, but a bare
|
|
200
|
+
number of milliseconds or a string such as "30ms" on the
|
|
201
|
+
hot-reload path, which skips Cerberus coercion
|
|
192
202
|
"""
|
|
193
203
|
from boneio.const import CLICK_SEQUENCES
|
|
194
204
|
|
|
@@ -260,3 +270,16 @@ class GpioEventButton(GpioBaseClass):
|
|
|
260
270
|
if long_press_mqtt_mode is not None:
|
|
261
271
|
self._long_press_mqtt_mode = long_press_mqtt_mode
|
|
262
272
|
_LOGGER.debug("Updated long_press_mqtt_mode to %s for %s", long_press_mqtt_mode, self._name)
|
|
273
|
+
|
|
274
|
+
# bounce_time is handed to the detector in __init__, so it needs pushing
|
|
275
|
+
# through explicitly — None here means "back to the schema default".
|
|
276
|
+
seconds = parse_time_to_ms(bounce_time, DEFAULT_BOUNCE_TIME_MS) / 1000.0
|
|
277
|
+
if seconds != self._bounce_time:
|
|
278
|
+
self._bounce_time = seconds
|
|
279
|
+
self._detector.set_debounce(seconds)
|
|
280
|
+
_LOGGER.info(
|
|
281
|
+
"Event input %s (%s): bounce_time changed to %.0fms without restart",
|
|
282
|
+
self._name,
|
|
283
|
+
self._pin,
|
|
284
|
+
seconds * 1000,
|
|
285
|
+
)
|
|
@@ -138,6 +138,26 @@ class EventBus:
|
|
|
138
138
|
raise
|
|
139
139
|
try:
|
|
140
140
|
await self._handle_event(event)
|
|
141
|
+
except asyncio.CancelledError:
|
|
142
|
+
# Only a cancellation aimed at this worker ends it. A listener
|
|
143
|
+
# can raise CancelledError without this task being cancelled at
|
|
144
|
+
# all — a websocket send whose connection task is torn down
|
|
145
|
+
# underneath it does exactly that. CancelledError is a
|
|
146
|
+
# BaseException, so it used to travel straight through the
|
|
147
|
+
# handler below and out of this coroutine, killing the worker
|
|
148
|
+
# silently: no traceback, because a task that ends this way is
|
|
149
|
+
# merely "cancelled". Nothing restarts it and nothing watches
|
|
150
|
+
# it, so from that moment every input, output, cover and sensor
|
|
151
|
+
# event was queued and never delivered, and the controller had
|
|
152
|
+
# to be restarted to take a button press again.
|
|
153
|
+
if self._shutting_down:
|
|
154
|
+
# `finally` below still runs and marks the item done.
|
|
155
|
+
raise
|
|
156
|
+
_LOGGER.error(
|
|
157
|
+
"Listener for %s raised CancelledError; the event bus is "
|
|
158
|
+
"continuing.",
|
|
159
|
+
type(event).__name__,
|
|
160
|
+
)
|
|
141
161
|
except Exception as exc:
|
|
142
162
|
_LOGGER.error(f"Error handling event: {exc}")
|
|
143
163
|
finally:
|
|
@@ -181,6 +201,13 @@ class EventBus:
|
|
|
181
201
|
await result
|
|
182
202
|
elif result is not None:
|
|
183
203
|
_LOGGER.warning(f"Listener returned non-coroutine: {type(result)}")
|
|
204
|
+
except asyncio.CancelledError:
|
|
205
|
+
# Contain it here so one listener cannot take the others down
|
|
206
|
+
# with it, and re-raise while shutting down so cancellation
|
|
207
|
+
# still works. See _event_worker for what this used to cost.
|
|
208
|
+
if self._shutting_down:
|
|
209
|
+
raise
|
|
210
|
+
_LOGGER.error("Listener cancelled mid-dispatch; skipping it.")
|
|
184
211
|
except Exception as exc:
|
|
185
212
|
_LOGGER.error(f"Listener error: {exc}")
|
|
186
213
|
|
|
@@ -296,6 +296,7 @@ class InputManager:
|
|
|
296
296
|
enable_triple_click=gpio.get("enable_triple_click"),
|
|
297
297
|
long_press_mqtt_mode=gpio.get("long_press_mqtt_mode"),
|
|
298
298
|
max_long_press_duration=gpio.get("max_long_press_duration"),
|
|
299
|
+
bounce_time=gpio.get("bounce_time"),
|
|
299
300
|
)
|
|
300
301
|
|
|
301
302
|
# Re-send HA discovery only if HA-relevant fields changed (name, area, mqtt_sequences)
|
|
@@ -410,6 +411,14 @@ class InputManager:
|
|
|
410
411
|
# Update device_class from new config
|
|
411
412
|
existing_input._device_class = gpio.get(DEVICE_CLASS)
|
|
412
413
|
|
|
414
|
+
# Apply polarity live — 'inverted' is baked into the detector at
|
|
415
|
+
# construction, so without this the change only took effect after
|
|
416
|
+
# an application restart.
|
|
417
|
+
inverted_changed = existing_input.update_inverted(gpio.get("inverted", False))
|
|
418
|
+
|
|
419
|
+
# Same story for the debounce window.
|
|
420
|
+
existing_input.update_bounce_time(gpio.get("bounce_time"))
|
|
421
|
+
|
|
413
422
|
# Re-send HA discovery only if HA-relevant fields changed (name, area)
|
|
414
423
|
# Actions are internal to the controller and don't need HA update
|
|
415
424
|
if ha_fields_changed and gpio.get(SHOW_HA, True):
|
|
@@ -422,9 +431,11 @@ class InputManager:
|
|
|
422
431
|
area=area,
|
|
423
432
|
)
|
|
424
433
|
|
|
425
|
-
#
|
|
426
|
-
|
|
427
|
-
|
|
434
|
+
# Publish the current state when polarity flipped (the reported
|
|
435
|
+
# state is now the opposite one) or when initial_send asks for it,
|
|
436
|
+
# so the user doesn't need to restart.
|
|
437
|
+
if inverted_changed or gpio.get("initial_send", False):
|
|
438
|
+
_LOGGER.debug(f"Sending current state for {input_id} after reload")
|
|
428
439
|
existing_input.send_current_state()
|
|
429
440
|
|
|
430
441
|
return existing_input
|
|
@@ -12,12 +12,17 @@ import time
|
|
|
12
12
|
|
|
13
13
|
from boneio.const import PRESSED, RELEASED, ClickTypes
|
|
14
14
|
from boneio.core.events import EventBus
|
|
15
|
-
from boneio.core.utils import
|
|
15
|
+
from boneio.core.utils.timeperiod import parse_time_to_ms
|
|
16
16
|
from boneio.models import InputState
|
|
17
17
|
from boneio.models.events import InputEvent
|
|
18
18
|
|
|
19
19
|
_LOGGER = logging.getLogger(__name__)
|
|
20
20
|
|
|
21
|
+
# Fallback debounce when a config carries no bounce_time at all. The per-type
|
|
22
|
+
# schema defaults (120ms binary_sensor, 30ms event) normally win long before
|
|
23
|
+
# this, via Cerberus at startup or the update_* methods on reload.
|
|
24
|
+
DEFAULT_BOUNCE_TIME_MS = 50
|
|
25
|
+
|
|
21
26
|
|
|
22
27
|
class GpioBaseClass:
|
|
23
28
|
"""Base class for GPIO inputs.
|
|
@@ -58,8 +63,13 @@ class GpioBaseClass:
|
|
|
58
63
|
) -> None:
|
|
59
64
|
"""Initialize GPIO input base class."""
|
|
60
65
|
self._pin = pin
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
# A TimePeriod at startup, where Cerberus has coerced it — but the
|
|
67
|
+
# hot-reload path reads the YAML without validation, so an input added
|
|
68
|
+
# while the app runs arrives with a bare number of milliseconds (WebUI)
|
|
69
|
+
# or a string such as "30ms" (hand-written config).
|
|
70
|
+
self._bounce_time = (
|
|
71
|
+
parse_time_to_ms(kwargs.get("bounce_time"), DEFAULT_BOUNCE_TIME_MS) / 1000.0
|
|
72
|
+
)
|
|
63
73
|
self._loop = asyncio.get_running_loop()
|
|
64
74
|
self._name = name
|
|
65
75
|
self._actions = actions
|
|
@@ -222,6 +222,26 @@ class INA219(AsyncUpdater):
|
|
|
222
222
|
"""
|
|
223
223
|
return self._sensors
|
|
224
224
|
|
|
225
|
+
def _read_values(self, keys: list[str]) -> dict[str, float]:
|
|
226
|
+
"""Read the requested measurements from the chip.
|
|
227
|
+
|
|
228
|
+
Runs in a worker thread; every access here is a blocking I2C transfer.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
keys: Driver attribute names to read (``current``, ``voltage``, ``power``).
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
The values that could be read. A key is absent when its read failed,
|
|
235
|
+
so one bad measurement does not cost the others.
|
|
236
|
+
"""
|
|
237
|
+
out: dict[str, float] = {}
|
|
238
|
+
for k in keys:
|
|
239
|
+
try:
|
|
240
|
+
out[k] = getattr(self._ina_219, k)
|
|
241
|
+
except Exception as err:
|
|
242
|
+
_LOGGER.error("Error reading INA219 %s: %s", k, err)
|
|
243
|
+
return out
|
|
244
|
+
|
|
225
245
|
async def async_update(self, timestamp: datetime) -> None:
|
|
226
246
|
"""Read sensor values and update all managed sensors.
|
|
227
247
|
|
|
@@ -232,9 +252,27 @@ class INA219(AsyncUpdater):
|
|
|
232
252
|
Args:
|
|
233
253
|
timestamp: Current timestamp
|
|
234
254
|
"""
|
|
255
|
+
# Read the whole chip in one executor hop. Each attribute is a blocking
|
|
256
|
+
# I2C transaction that takes the bus lock, and the bus lock is held by
|
|
257
|
+
# whatever else is mid-transfer — a relay write, the expander watchdog,
|
|
258
|
+
# the OLED. Done inline in this coroutine it is the *event loop* that
|
|
259
|
+
# waits on that lock, which stops the GPIO reader, every timer and the
|
|
260
|
+
# event bus for as long as the bus is busy. Reading in a worker thread
|
|
261
|
+
# keeps the wait off the loop.
|
|
262
|
+
keys = list(self._sensors)
|
|
263
|
+
try:
|
|
264
|
+
values = await asyncio.get_running_loop().run_in_executor(
|
|
265
|
+
None, self._read_values, keys
|
|
266
|
+
)
|
|
267
|
+
except Exception as err:
|
|
268
|
+
_LOGGER.error("Error reading INA219: %s", err)
|
|
269
|
+
return
|
|
270
|
+
|
|
235
271
|
for k, sensor in self._sensors.items():
|
|
236
272
|
try:
|
|
237
|
-
value =
|
|
273
|
+
value = values.get(k)
|
|
274
|
+
if value is None:
|
|
275
|
+
continue
|
|
238
276
|
_LOGGER.debug("Fetched INA219 value: %s = %s %s", k, value, sensor.unit_of_measurement)
|
|
239
277
|
|
|
240
278
|
if sensor.raw_state != value:
|
|
@@ -6,6 +6,7 @@ It extends BaseSensor with temperature-specific functionality.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import asyncio
|
|
9
10
|
import logging
|
|
10
11
|
|
|
11
12
|
from boneio.const import TEMPERATURE
|
|
@@ -132,7 +133,14 @@ class TempSensor(BaseSensor):
|
|
|
132
133
|
timestamp: Current timestamp
|
|
133
134
|
"""
|
|
134
135
|
try:
|
|
135
|
-
|
|
136
|
+
# Off the loop: reading the chip is a blocking I2C transfer that
|
|
137
|
+
# first waits for the shared bus lock. Inline, that wait is the
|
|
138
|
+
# event loop's — and a bus held by a relay write or the expander
|
|
139
|
+
# watchdog then stalls GPIO input handling along with everything
|
|
140
|
+
# else. See the matching change in INA219.async_update.
|
|
141
|
+
_temp = await asyncio.get_running_loop().run_in_executor(
|
|
142
|
+
None, lambda: self.temperature
|
|
143
|
+
)
|
|
136
144
|
|
|
137
145
|
if _temp is None:
|
|
138
146
|
_LOGGER.warning("Temperature reading returned None for sensor %s", self.id)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{c as t}from"./monaco-61yH0vfd.js";import{b as n}from"./vendor-IzweXARb.js";import{r}from"./utils-C8nShLO6.js";import{E as i,Ht as a,K as o,Qt as s,T as c,U as l,Wt as u,X as d,Zt as f,_t as p,k as m,ot as h,p as g,q as _,z as v}from"./index-DCzOrheh.js";import{t as y}from"./EditItemDialog-BIjzsrqq.js";var b=e(t(),1);function x(e){return s({tag:`svg`,attr:{viewBox:`0 0 512 512`},child:[{tag:`path`,attr:{d:`M224 0c17.7 0 32 14.3 32 32l0 12 96-12c17.7 0 32 14.3 32 32s-14.3 32-32 32L256 84l-31-3.9-1-.1-1 .1L192 84 96 96C78.3 96 64 81.7 64 64s14.3-32 32-32l96 12 0-12c0-17.7 14.3-32 32-32zM0 224c0-17.7 14.3-32 32-32l96 0 22.6-22.6c6-6 14.1-9.4 22.6-9.4l18.7 0 0-43.8 32-4 32 4 0 43.8 18.7 0c8.5 0 16.6 3.4 22.6 9.4L320 192l32 0c88.4 0 160 71.6 160 160c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32-14.3-32-32s-14.3-32-32-32l-36.1 0c-20.2 29-53.9 48-91.9 48s-71.7-19-91.9-48L32 320c-17.7 0-32-14.3-32-32l0-64zM436.8 423.4c1.9-4.5 6.3-7.4 11.2-7.4s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1l0 1.2c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-1.2c0-4.5 .9-8.9 2.7-13.1l18.2-42.4z`},child:[]}]})(e)}var S=n();function C({outputType:e,className:t}){switch(e){case`light`:return(0,S.jsx)(h,{className:r(`text-warning`,t)});case`switch`:return(0,S.jsx)(u,{className:r(`text-info`,t)});case`valve`:return(0,S.jsx)(x,{className:r(`text-accent`,t)});case`cover`:return(0,S.jsx)(v,{className:r(`text-secondary`,t)});case`shutter`:case`blind`:case`curtain`:return(0,S.jsx)(f,{className:r(`text-secondary`,t)});default:return null}}var w={single:`1×`,double:`2×`,triple:`3×`,long:`L`,pressed:`P`,released:`R`,double_then_long:`2×L`,single_then_long:`1×L`,double_then_single:`2×1`},T={TOGGLE:`short_toggle`,ON:`short_on`,OFF:`short_off`,OPEN:`short_open`,CLOSE:`short_close`,STOP:`short_stop`},E=[{key:`single`,labelKey:`binding_matrix.legend_single`,icon:`1×`},{key:`double`,labelKey:`binding_matrix.legend_double`,icon:`2×`},{key:`triple`,labelKey:`binding_matrix.legend_triple`,icon:`3×`},{key:`long`,labelKey:`binding_matrix.legend_long`,icon:`L`},{key:`pressed`,labelKey:`binding_matrix.legend_pressed`,icon:`P`},{key:`released`,labelKey:`binding_matrix.legend_released`,icon:`R`}],D=[{labelKey:`actions.toggle`,shortKey:`actions.short_toggle`},{labelKey:`actions.on`,shortKey:`actions.short_on`},{labelKey:`actions.off`,shortKey:`actions.short_off`},{labelKey:`actions.open`,shortKey:`actions.short_open`},{labelKey:`actions.close`,shortKey:`actions.short_close`},{labelKey:`actions.stop`,shortKey:`actions.short_stop`}],O={single:`single`,double:`double`,triple:`triple`,long:`long`,pressed:`pressed`,released:`released`,double_then_long:`sequences`,single_then_long:`sequences`,double_then_single:`sequences`};function k(e,t){let n=w[e.clickType]||e.clickType,r=T[e.actionValue];return`${n} ${r?t(`actions.${r}`):e.actionValue}`}function A(e,t){let n=`actions.${e.actionValue.toLowerCase()}`,r=t(n),i=r===n?e.actionValue:r;return`${e.clickType} → ${i}`}function j(e){let t=e.action||`output`,n=``,r=``,i;switch(t){case`output`:n=e.boneio_output||``,r=e.action_output||`TOGGLE`;break;case`cover`:n=e.boneio_cover||``,r=e.action_cover||`TOGGLE`;break;case`remote_output`:i=e.boneio_id||``,n=i?`${i}/${e.output_id||``}`:e.output_id||``,r=e.action_output||`TOGGLE`;break;case`remote_cover`:i=e.boneio_id||``,n=i?`${i}/${e.cover_id||``}`:e.cover_id||``,r=e.action_cover||`TOGGLE`;break;default:n=``,r=e.action_output||e.action_cover||``;break}return{targetId:n,actionType:t,actionValue:r,remoteDevice:i}}function M(e){let t=[],n=[`single`,`double`,`triple`,`long`,`pressed`,`released`,`double_then_long`,`single_then_long`,`double_then_single`],r=e.local_inputs||[];for(let e=0;e<r.length;e++){let i=r[e],a=i.id||i.boneio_input||i.pin||`local_${e}`,o=[];for(let e of n){let t=i.actions?.[e]||[];for(let n of t){let{targetId:t,actionType:r,actionValue:i,remoteDevice:a}=j(n);t&&o.push({clickType:e,actionType:r,targetId:t,actionValue:i,remoteDevice:a})}}t.push({id:a,name:i.name||i.id||i.boneio_input||i.pin||a,area:i.area||void 0,type:`local`,inputKind:i._type===`binary_sensor`?`binary_sensor`:`event`,bindings:o})}let i=e.remote_inputs||[];for(let e=0;e<i.length;e++){let r=i[e],a=r.boneio_id||r.remote_device||``,o=r.id||r.entity_id||``,s=a?`${a}/${o}`:o||`remote_${e}`,c=[];for(let e of n){let t=r.actions?.[e]||[];for(let n of t){let{targetId:t,actionType:r,actionValue:i,remoteDevice:a}=j(n);t&&c.push({clickType:e,actionType:r,targetId:t,actionValue:i,remoteDevice:a})}}t.push({id:s,name:r.name||r.id||o,area:r.area||void 0,type:`remote`,inputKind:r._type===`binary_sensor`?`binary_sensor`:`event`,remoteDevice:a,bindings:c})}return t}function N(e){let t=[],n=e.output||[];for(let e=0;e<n.length;e++){let r=n[e];if(r.output_type===`cover`||r.output_type===`none`)continue;let i=r.id||`output_${e}`;t.push({id:i,name:r.name||r.id||i,area:r.area||void 0,type:`output`,outputType:r.output_type})}let r=e.cover||[];for(let e=0;e<r.length;e++){let n=r[e],i=n.id||`cover_${e}`;t.push({id:i,name:n.name||n.id||i,area:n.area||void 0,type:`cover`,outputType:n.device_class||`cover`})}let i=e.remote_outputs||[];for(let e=0;e<i.length;e++){let n=i[e],r=n.boneio_id||n.remote_device||``,a=n.id||n.output_id||``,o=r?`${r}/${a}`:a||`remote_out_${e}`;t.push({id:o,name:n.name||n.id||a,area:n.area||void 0,type:`remote_output`,remoteDevice:r,outputType:n.output_type})}return t}function P({inputs:e,outputs:t,t:n}){let r=e.filter(e=>e.type===`local`),i=e.filter(e=>e.type===`remote`),a=t.filter(e=>e.type===`output`),o=t.filter(e=>e.type===`cover`),s=t.filter(e=>e.type===`remote_output`||e.type===`remote_cover`),c=r.filter(e=>e.bindings.length>0),l=i.filter(e=>e.bindings.length>0),u=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),d=a.filter(e=>u.has(e.id)),f=o.filter(e=>u.has(e.id)),p=s.filter(e=>u.has(e.id)),m=e.reduce((e,t)=>e+t.bindings.length,0);return(0,S.jsxs)(`div`,{className:`gap-3 grid grid-cols-1 md:grid-cols-4 mb-4`,children:[(0,S.jsxs)(`div`,{className:`space-y-1 bg-base-200/50 p-3 border border-base-300 rounded-xl`,children:[(0,S.jsx)(`h4`,{className:`font-bold text-xs text-base-content/50 uppercase tracking-wider`,children:n(`binding_matrix.local`)}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📥 `,n(`binding_matrix.inputs`),`: `,r.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,c.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,r.length-c.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`💡 `,n(`binding_matrix.outputs`),`: `,a.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,d.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,a.length-d.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`🚪 `,n(`binding_matrix.covers`),`: `,o.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,f.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,o.length-f.length,` ○)`]})]})]}),(i.length>0||s.length>0)&&(0,S.jsxs)(`div`,{className:`space-y-1 bg-info/5 p-3 border border-info/20 rounded-xl`,children:[(0,S.jsx)(`h4`,{className:`font-bold text-info/70 text-xs uppercase tracking-wider`,children:n(`binding_matrix.remote`)}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📥 `,n(`binding_matrix.inputs`),`: `,i.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,l.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,i.length-l.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📡 `,n(`binding_matrix.outputs`),`: `,s.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,p.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,s.length-p.length,` ○)`]})]})]}),(0,S.jsxs)(`div`,{className:`flex flex-col justify-center bg-primary/5 p-3 border border-primary/20 rounded-xl`,children:[(0,S.jsx)(`p`,{className:`font-extrabold text-primary text-2xl`,children:m}),(0,S.jsx)(`p`,{className:`font-medium text-primary/70 text-xs`,children:n(`binding_matrix.total_bindings`)})]}),(0,S.jsxs)(`div`,{className:`bg-base-200/50 p-3 border border-base-300 rounded-xl`,children:[(0,S.jsx)(`h4`,{className:`mb-1.5 font-bold text-xs text-base-content/50 uppercase tracking-wider`,children:n(`binding_matrix.legend`)}),(0,S.jsx)(`div`,{className:`gap-x-3 gap-y-0.5 grid grid-cols-2`,children:E.map(e=>(0,S.jsxs)(`span`,{className:`text-xxs text-base-content/60`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/80`,children:e.icon}),` `,n(e.labelKey)]},e.key))}),(0,S.jsx)(`div`,{className:`gap-x-2 gap-y-0.5 grid grid-cols-3 mt-1.5 pt-1.5 border-base-300 border-t`,children:D.map(e=>(0,S.jsxs)(`span`,{className:`text-xxs text-base-content/60`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/80`,children:n(e.shortKey)}),` `,n(e.labelKey)]},e.shortKey))})]})]})}function F({inputs:e,outputs:t,t:n}){let[r,a]=(0,b.useState)(!0),[o,s]=(0,b.useState)(!0),c=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),u=e.filter(e=>e.type===`local`&&e.bindings.length===0),d=t.filter(e=>e.type===`output`&&!c.has(e.id)),f=t.filter(e=>e.type===`cover`&&!c.has(e.id)),p=e.filter(e=>e.type===`remote`&&e.bindings.length===0),h=t.filter(e=>(e.type===`remote_output`||e.type===`remote_cover`)&&!c.has(e.id)),g=u.length>0||d.length>0||f.length>0,_=p.length>0||h.length>0;return!g&&!_?null:(0,S.jsxs)(`div`,{className:`space-y-3 mt-4`,children:[g&&(0,S.jsxs)(`div`,{className:`bg-warning/5 border border-warning/20 rounded-xl overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`flex justify-between items-center hover:bg-warning/10 p-3 w-full font-semibold text-warning text-sm transition-colors`,onClick:()=>a(!r),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(l,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_local`)]}),r?(0,S.jsx)(m,{className:`w-3 h-3`}):(0,S.jsx)(i,{className:`w-3 h-3`})]}),r&&(0,S.jsxs)(`div`,{className:`space-y-2 p-3 pt-0`,children:[u.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_inputs`)} (${u.length})`,items:u.map(e=>({id:e.id,name:e.name,area:e.area}))}),d.length>0&&(0,S.jsx)(I,{title:`💡 ${n(`binding_matrix.free_outputs`)} (${d.length})`,items:d.map(e=>({id:e.id,name:e.name,area:e.area}))}),f.length>0&&(0,S.jsx)(I,{title:`🚪 ${n(`binding_matrix.free_covers`)} (${f.length})`,items:f.map(e=>({id:e.id,name:e.name,area:e.area}))})]})]}),_&&(0,S.jsxs)(`div`,{className:`bg-info/5 border border-info/20 rounded-xl overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`flex justify-between items-center hover:bg-info/10 p-3 w-full font-semibold text-info text-sm transition-colors`,onClick:()=>s(!o),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(l,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_remote`)]}),o?(0,S.jsx)(m,{className:`w-3 h-3`}):(0,S.jsx)(i,{className:`w-3 h-3`})]}),o&&(0,S.jsxs)(`div`,{className:`space-y-2 p-3 pt-0`,children:[p.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_remote_inputs`)} (${p.length})`,items:p.map(e=>({id:e.id,name:e.name,area:e.area,badge:e.remoteDevice}))}),h.length>0&&(0,S.jsx)(I,{title:`📡 ${n(`binding_matrix.free_remote_outputs`)} (${h.length})`,items:h.map(e=>({id:e.id,name:e.name,area:e.area,badge:e.remoteDevice}))})]})]})]})}function I({title:e,items:t}){return(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`p`,{className:`mb-1 font-semibold text-xs text-base-content/60`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:t.map(e=>(0,S.jsxs)(`span`,{className:`gap-1 font-mono text-xxs badge badge-sm badge-ghost`,title:e.id,children:[e.name,e.area&&(0,S.jsxs)(`span`,{className:`text-base-content/40`,children:[`(`,e.area,`)`]}),e.badge&&(0,S.jsxs)(`span`,{className:`text-info/60`,children:[`[`,e.badge,`]`]})]},e.id))})]})}function ee({inputs:e,outputs:t,areaFilter:n,hideEmpty:i,t:a,onEditInput:o,onEditOutput:s}){let[c,l]=(0,b.useState)(null),[u,d]=(0,b.useState)(null),f=(0,b.useRef)(null),m=(0,b.useRef)(!1),h=(0,b.useRef)(!1),g=(0,b.useRef)(0),_=(0,b.useRef)(0),[v,y]=(0,b.useState)(null),x=(0,b.useRef)(null),w=(0,b.useCallback)((e,t,n)=>{n||(e.preventDefault(),y({x:e.clientX,y:e.clientY,row:t}))},[]),T=(0,b.useCallback)((e,t,n)=>{if(n)return;let r=`touches`in e?{x:e.touches[0].clientX,y:e.touches[0].clientY}:{x:e.clientX,y:e.clientY};x.current=setTimeout(()=>{y({...r,row:t}),x.current=null},500)},[]),D=(0,b.useCallback)(()=>{x.current&&=(clearTimeout(x.current),null)},[]);(0,b.useEffect)(()=>{if(!v)return;let e=null,t=requestAnimationFrame(()=>{let t=()=>y(null);window.addEventListener(`click`,t),window.addEventListener(`contextmenu`,t,{capture:!0}),window.addEventListener(`scroll`,t,!0),e=()=>{window.removeEventListener(`click`,t),window.removeEventListener(`contextmenu`,t,{capture:!0}),window.removeEventListener(`scroll`,t,!0)}});return()=>{cancelAnimationFrame(t),e?.()}},[v]);let O=(0,b.useMemo)(()=>{let e=new Map;for(let n of t)e.set(n.id,n.area);return e},[t]),j=(0,b.useMemo)(()=>{let t=e;return n.size>0&&(t=t.filter(e=>{let t=e.area||`__none__`;return n.has(t)?!0:e.bindings.some(e=>{let t=O.get(e.targetId)||`__none__`;return n.has(t)})})),i&&(t=t.filter(e=>e.bindings.length>0)),t},[e,n,i,O]),M=(0,b.useMemo)(()=>new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),[e]),N=(0,b.useMemo)(()=>{let t=new Map;for(let n of e){let e=n.area||`__none__`;for(let r of n.bindings)t.has(r.targetId)||t.set(r.targetId,new Set),t.get(r.targetId).add(e)}return t},[e]),P=(0,b.useMemo)(()=>{let e=t;return n.size>0&&(e=e.filter(e=>{let t=e.area||`__none__`;if(n.has(t))return!0;let r=N.get(e.id);if(r){for(let e of r)if(n.has(e))return!0}return!1})),i&&(e=e.filter(e=>M.has(e.id))),e},[t,n,i,M,N]),F=(0,b.useMemo)(()=>{let e=new Map;for(let t of j){let n=new Map;for(let e of t.bindings){let t=n.get(e.targetId)||[];t.push(e),n.set(e.targetId,t)}e.set(t.id,n)}return e},[j]);return j.length===0||P.length===0?(0,S.jsx)(`div`,{className:`py-12 text-base-content/40 text-center`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:a(`binding_matrix.no_data`)})}):(0,S.jsxs)(`div`,{ref:f,className:`border border-base-300 rounded-xl overflow-x-auto cursor-grab active:cursor-grabbing select-none`,onMouseDown:e=>{m.current=!0,h.current=!1,g.current=e.clientX,_.current=f.current?.scrollLeft||0},onMouseMove:e=>{if(!m.current||!f.current)return;let t=e.clientX-g.current;!h.current&&Math.abs(t)>5&&(h.current=!0),h.current&&(f.current.scrollLeft=_.current-t)},onMouseUp:()=>{m.current=!1,h.current=!1},onMouseLeave:()=>{m.current=!1,h.current=!1},onClickCapture:e=>{h.current&&(e.stopPropagation(),e.preventDefault())},children:[(0,S.jsxs)(`table`,{className:`table table-xs w-auto`,children:[(0,S.jsx)(`thead`,{children:(0,S.jsxs)(`tr`,{children:[(0,S.jsx)(`th`,{className:`left-0 z-20 sticky bg-base-200 border-base-300 border-r min-w-30`}),P.map(e=>(0,S.jsxs)(`th`,{className:r(`group/col bg-base-200 px-2 py-2 border-base-300 border-r min-w-20 font-bold text-xxs text-center whitespace-nowrap cursor-pointer`,u===e.id&&`bg-primary/10`),onMouseEnter:()=>d(e.id),onMouseLeave:()=>d(null),onClick:()=>s(e),title:a(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`flex justify-center items-center gap-1`,children:[(0,S.jsx)(C,{outputType:e.outputType,className:`w-3 h-3 shrink-0`}),(0,S.jsx)(`span`,{className:`whitespace-nowrap`,children:e.name}),(0,S.jsx)(p,{className:`opacity-0 group-hover/col:opacity-40 w-2 h-2 transition-opacity shrink-0`})]}),e.area?(0,S.jsx)(`div`,{className:`font-normal text-xxs text-base-content/40 truncate`,children:e.area}):(0,S.jsx)(`div`,{className:`font-normal text-xxs text-base-content/20`,children:`—`}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`font-normal text-info/50 text-xxs truncate`,children:e.remoteDevice})]},e.id))]})}),(0,S.jsx)(`tbody`,{children:j.map(e=>{let t=F.get(e.id);return(0,S.jsxs)(`tr`,{className:r(`hover:bg-base-200/50`,c===e.id&&`bg-base-200/40`),onMouseEnter:()=>l(e.id),onMouseLeave:()=>l(null),children:[(0,S.jsxs)(`td`,{className:r(`group/row left-0 z-10 sticky bg-base-100 border-base-300 border-r font-medium text-xs cursor-pointer`,c===e.id&&`bg-base-200/60`,e.bindings.length===0&&`text-base-content/30`),onClick:()=>o(e),title:a(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-1 max-w-30 font-bold truncate`,title:e.id,children:[e.name,(0,S.jsx)(p,{className:`opacity-0 group-hover/row:opacity-40 w-2.5 h-2.5 transition-opacity shrink-0`})]}),e.area&&(0,S.jsx)(`div`,{className:`text-xxs text-base-content/40`,children:e.area}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`text-info/50 text-xxs`,children:e.remoteDevice})]}),P.map(n=>{let i=t?.get(n.id)||[],s=c===e.id||u===n.id;return(0,S.jsx)(`td`,{className:r(`px-1 py-1 border-base-300 border-r text-xs text-center`,i.length>0?`bg-success/15 text-success font-medium`:`text-base-content/30`,s&&i.length>0&&`bg-success/25`,s&&i.length===0&&`bg-base-200/40`),onMouseEnter:()=>d(n.id),onMouseLeave:()=>{d(null),D()},onContextMenu:t=>w(t,e,i.length>0),onMouseDown:t=>{t.button===0&&T(t,e,i.length>0)},onMouseUp:D,onTouchStart:t=>T(t,e,i.length>0),onTouchEnd:D,onTouchMove:D,children:i.length>0&&(0,S.jsx)(`div`,{className:`flex flex-col gap-0.5`,children:i.map((t,n)=>(0,S.jsx)(`button`,{className:`hover:bg-success/30 px-0.5 rounded text-left whitespace-nowrap transition-colors cursor-pointer`,onClick:()=>o(e,t.clickType),title:`${A(t,a)}\n${a(`binding_matrix.click_to_edit`)}`,children:k(t,a)},n))})},n.id)})]},e.id)})})]}),v&&(0,S.jsxs)(`div`,{className:`z-50 fixed bg-base-100 shadow-xl py-1 border border-base-300 rounded-lg min-w-45 animate-in duration-100 fade-in zoom-in-95`,style:{left:v.x,top:v.y},onClick:e=>e.stopPropagation(),children:[(0,S.jsx)(`div`,{className:`px-3 py-1.5 font-semibold text-xxs text-base-content/40 uppercase tracking-wider`,children:a(`binding_matrix.add_action`)}),E.filter(e=>v.row.inputKind===`binary_sensor`?e.key===`pressed`||e.key===`released`:e.key!==`pressed`&&e.key!==`released`).map(e=>(0,S.jsxs)(`button`,{className:`flex items-center gap-2 hover:bg-primary/10 px-3 py-1.5 w-full text-sm text-left transition-colors`,onClick:()=>{o(v.row,e.key),y(null)},children:[(0,S.jsx)(`span`,{className:`font-mono text-base-content/70`,children:e.icon}),a(`binding_matrix.legend_${e.key}`)]},e.key))]})]})}function te({inputs:e,areaFilter:t,hideEmpty:n,t:o,onEditInput:s}){let[l,u]=(0,b.useState)(null),d=(0,b.useMemo)(()=>{let r=e;return t.size>0&&(r=r.filter(e=>{let n=e.area||`__none__`;return t.has(n)})),n&&(r=r.filter(e=>e.bindings.length>0)),r},[e,t,n]),f=(0,b.useCallback)(e=>{u(t=>t===e?null:e)},[]);return d.length===0?(0,S.jsx)(`div`,{className:`py-12 text-base-content/40 text-center`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:o(`binding_matrix.no_data`)})}):(0,S.jsx)(`div`,{className:`space-y-1.5`,children:d.map(e=>{let t=l===e.id,n=e.bindings.length>0,u=new Map;for(let t of e.bindings){let e=u.get(t.targetId)||[];e.push(t),u.set(t.targetId,e)}return(0,S.jsxs)(`div`,{className:r(`border rounded-xl overflow-hidden transition-colors`,n?`border-success/20 bg-success/5`:`border-base-300 bg-base-200/30`),children:[(0,S.jsxs)(`button`,{className:`flex justify-between items-center hover:bg-base-200/30 p-3 w-full text-sm transition-colors`,onClick:()=>n&&f(e.id),disabled:!n,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[n?(0,S.jsx)(c,{className:`w-3.5 h-3.5 text-success shrink-0`}):(0,S.jsx)(a,{className:`w-3.5 h-3.5 text-base-content/20 shrink-0`}),(0,S.jsxs)(`div`,{className:`min-w-0 text-left`,children:[(0,S.jsx)(`span`,{className:r(`block font-semibold truncate`,!n&&`text-base-content/30`),children:e.name}),e.area&&(0,S.jsx)(`span`,{className:`text-xxs text-base-content/40`,children:e.area})]})]}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[n&&(0,S.jsx)(`span`,{className:`font-bold badge badge-sm badge-success`,children:e.bindings.length}),e.type===`remote`&&(0,S.jsx)(`span`,{className:`font-mono badge badge-xs badge-info`,children:e.remoteDevice}),n&&(t?(0,S.jsx)(m,{className:`w-3 h-3 text-base-content/30`}):(0,S.jsx)(i,{className:`w-3 h-3 text-base-content/30`}))]})]}),t&&n&&(0,S.jsxs)(`div`,{className:`space-y-2 bg-base-100/50 p-3 border-base-300 border-t`,children:[[...u.entries()].map(([e,t])=>(0,S.jsxs)(`div`,{className:`flex items-start gap-2 text-xs`,children:[(0,S.jsx)(`span`,{className:`mt-0.5 font-mono font-bold text-base-content/70 shrink-0`,children:`→`}),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`span`,{className:`font-semibold`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1 mt-0.5`,children:t.map((e,t)=>(0,S.jsx)(`span`,{className:`gap-0.5 font-mono badge badge-xs badge-success`,children:k(e,o)},t))})]})]},e)),(0,S.jsxs)(`button`,{className:`gap-1 mt-1 btn-outline btn btn-xs btn-primary`,onClick:t=>{t.stopPropagation(),s(e)},children:[(0,S.jsx)(p,{className:`w-2.5 h-2.5`}),o(`binding_matrix.edit_input`)]})]})]},e.id)})})}var L=({formData:e,sections:t,onSaveSection:n,onUpdateFormData:r})=>{let{t:a}=g(),[s,c]=(0,b.useState)(new Set),[l,u]=(0,b.useState)(!1),[f,p]=(0,b.useState)(!1),[m,h]=(0,b.useState)(!1),[v,x]=(0,b.useState)(null),[C,w]=(0,b.useState)(``),[T,E]=(0,b.useState)(-1),[D,k]=(0,b.useState)(`basic`),[A,j]=(0,b.useState)(!1),[I,L]=(0,b.useState)(!1),R=(0,b.useRef)(null),[ne,z]=(0,b.useState)(!1),[B,V]=(0,b.useState)(null),[H,re]=(0,b.useState)(``),[U,ie]=(0,b.useState)(-1),[W,G]=(0,b.useState)(!1),K=(0,b.useRef)(null),q=(0,b.useCallback)((t,n)=>{let r=t.type===`remote`?`remote_inputs`:`local_inputs`,i=e[r]||[],a=i.findIndex((e,n)=>{if(t.type===`remote`){let r=e.boneio_id||e.remote_device||``,i=e.id||e.entity_id||``;return(r?`${r}/${i}`:i||`remote_${n}`)===t.id}return(e.id||e.boneio_input||e.pin||`local_${n}`)===t.id});a<0||(w(r),E(a),x(JSON.parse(JSON.stringify(i[a]))),R.current=JSON.stringify(i[a]),k(n&&O[n]||`basic`),j(!1),h(!0))},[e]),ae=(0,b.useCallback)(async()=>{if(A||T<0||!v)return;let t=[...e[C]||[]];t[T]=v,L(!0);try{r(C,t),await n(C,t),h(!1),x(null)}catch(e){console.error(`Failed to save input:`,e)}finally{L(!1)}},[v,T,C,e,A,n,r]),oe=(0,b.useCallback)(()=>{h(!1),x(null)},[]),J=(0,b.useMemo)(()=>M(e),[e]),Y=(0,b.useMemo)(()=>N(e),[e]),se=(0,b.useMemo)(()=>{let e=new Set;return J.forEach(t=>{t.area&&e.add(t.area)}),Y.forEach(t=>{t.area&&e.add(t.area)}),[...e].sort()},[J,Y]),ce=(0,b.useMemo)(()=>J.some(e=>!e.area)||Y.some(e=>!e.area),[J,Y]),X=(0,b.useMemo)(()=>e.output||[],[e.output]),Z=(0,b.useMemo)(()=>e.cover||[],[e.cover]),Q=(0,b.useMemo)(()=>e.output_group||[],[e.output_group]),le=(0,b.useMemo)(()=>e.remote_devices||[],[e.remote_devices]),ue=(0,b.useMemo)(()=>e.remote_inputs||[],[e.remote_inputs]),de=(0,b.useMemo)(()=>(e.local_inputs||[]).filter(e=>e._inputType===`binary_sensor`),[e.local_inputs]),fe=(0,b.useMemo)(()=>(e.local_inputs||[]).filter(e=>e._inputType!==`binary_sensor`),[e.local_inputs]),$=(0,b.useMemo)(()=>e.areas||[],[e.areas]),pe=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`local_inputs`);return e?.schema||e?.normalizedSchema||{}},[t]),me=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`output`);return e?.schema||e?.normalizedSchema||{}},[t]),he=(0,b.useMemo)(()=>t.find(e=>e.name===`output`)?.uiSchema||{},[t]),ge=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`cover`);return e?.schema||e?.normalizedSchema||{}},[t]),_e=(0,b.useCallback)(t=>{let n={output:`output`,cover:`cover`,remote_output:`remote_outputs`,remote_cover:`remote_covers`}[t.type]||`output`,r=e[n]||[],i=r.findIndex((e,n)=>{if(t.type===`remote_output`||t.type===`remote_cover`){let r=e.boneio_id||e.remote_device||``,i=e.id||e.output_id||``;return(r?`${r}/${i}`:i||`remote_out_${n}`)===t.id}return(e.id||``)===t.id});i<0||(re(n),ie(i),V(JSON.parse(JSON.stringify(r[i]))),K.current=JSON.stringify(r[i]),z(!0))},[e]),ve=(0,b.useCallback)(async()=>{if(U<0||!B)return;let t=[...e[H]||[]];t[U]=B,G(!0);try{r(H,t),await n(H,t),z(!1),V(null)}catch(e){console.error(`Failed to save output:`,e)}finally{G(!1)}},[B,U,H,e,n,r]),ye=(0,b.useCallback)(()=>{z(!1),V(null)},[]),be=v&&R.current&&JSON.stringify(v)!==R.current,xe=B&&K.current&&JSON.stringify(B)!==K.current;return(0,S.jsxs)(`div`,{className:`p-4 md:p-6 max-w-full`,children:[(0,S.jsxs)(`div`,{className:`mb-4`,children:[(0,S.jsx)(`h2`,{className:`font-extrabold text-xl tracking-tight`,children:a(`binding_matrix.title`)}),(0,S.jsx)(`p`,{className:`text-sm text-base-content/50`,children:a(`binding_matrix.subtitle`)})]}),(0,S.jsx)(P,{inputs:J,outputs:Y,t:a}),(0,S.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 mb-4`,children:[(0,S.jsxs)(`div`,{className:`relative flex items-center gap-2`,children:[(0,S.jsx)(d,{className:`w-3 h-3 text-base-content/40`}),(0,S.jsxs)(`button`,{className:`justify-between gap-1 btn-outline min-w-40 btn btn-sm`,onClick:()=>u(e=>!e),children:[(0,S.jsx)(`span`,{className:`text-xs truncate`,children:s.size===0?a(`binding_matrix.all_areas`):s.size===1?s.has(`__none__`)?a(`binding_matrix.no_area`):[...s][0]:a(`binding_matrix.areas_selected`,{count:s.size})}),(0,S.jsx)(i,{className:`w-2.5 h-2.5 shrink-0`})]}),l&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`z-40 fixed inset-0`,onClick:()=>u(!1)}),(0,S.jsxs)(`div`,{className:`top-full left-0 z-50 absolute bg-base-100 shadow-xl mt-1 py-1 border border-base-300 rounded-lg min-w-50 max-h-75 overflow-y-auto`,children:[(0,S.jsxs)(`label`,{className:`flex items-center gap-2 hover:bg-base-200/60 px-3 py-1.5 transition-colors cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.size===0,onChange:()=>c(new Set)}),(0,S.jsx)(`span`,{className:`font-semibold text-xs`,children:a(`binding_matrix.all_areas`)})]}),(0,S.jsx)(`div`,{className:`my-0.5 border-base-300 border-t`}),ce&&(0,S.jsxs)(`label`,{className:`flex items-center gap-2 hover:bg-base-200/60 px-3 py-1.5 transition-colors cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.has(`__none__`),onChange:()=>{let e=new Set(s);e.has(`__none__`)?e.delete(`__none__`):e.add(`__none__`),c(e)}}),(0,S.jsx)(`span`,{className:`text-xs text-base-content/50 italic`,children:a(`binding_matrix.no_area`)})]}),se.map(e=>(0,S.jsxs)(`label`,{className:`flex items-center gap-2 hover:bg-base-200/60 px-3 py-1.5 transition-colors cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.has(e),onChange:()=>{let t=new Set(s);t.has(e)?t.delete(e):t.add(e),c(t)}}),(0,S.jsx)(`span`,{className:`text-xs`,children:e})]},e))]})]})]}),(0,S.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-sm checkbox-primary`,checked:f,onChange:e=>p(e.target.checked)}),(0,S.jsxs)(`span`,{className:`flex items-center gap-1 font-medium text-xs text-base-content/60`,children:[f?(0,S.jsx)(_,{className:`w-3 h-3`}):(0,S.jsx)(o,{className:`w-3 h-3`}),a(`binding_matrix.hide_empty`)]})]})]}),(0,S.jsx)(`div`,{className:`hidden md:block`,children:(0,S.jsx)(ee,{inputs:J,outputs:Y,areaFilter:s,hideEmpty:f,t:a,onEditInput:q,onEditOutput:_e})}),(0,S.jsx)(`div`,{className:`md:hidden`,children:(0,S.jsx)(te,{inputs:J,areaFilter:s,hideEmpty:f,t:a,onEditInput:q})}),(0,S.jsx)(F,{inputs:J,outputs:Y,t:a}),(0,S.jsx)(y,{open:m,onOpenChange:h,editingItem:v,editingIndex:T,sectionType:C,schema:C===`remote_inputs`?t.find(e=>e.name===`remote_inputs`)?.schema||t.find(e=>e.name===`remote_inputs`)?.normalizedSchema||{}:pe,allBinarySensors:de,allEvents:fe,allOutputs:X,allOutputGroups:Q,allCovers:Z,allAreas:$,allRemoteDevices:le,allRemoteInputs:ue,savedOutputs:X,savedOutputGroups:Q,savedCovers:Z,onChange:x,onSave:ae,onCancel:oe,onValidationChange:j,saveDisabled:A||!be,isSaving:I,initialTab:D}),(0,S.jsx)(y,{open:ne,onOpenChange:z,editingItem:B,editingIndex:U,sectionType:H,schema:H===`cover`?ge:me,uiSchema:H===`cover`?void 0:he,allOutputs:X,allCovers:Z,allAreas:$,onChange:V,onSave:ve,onCancel:ye,saveDisabled:!xe,isSaving:W})]})};export{L as default};
|
|
1
|
+
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{c as t}from"./monaco-61yH0vfd.js";import{b as n}from"./vendor-IzweXARb.js";import{r}from"./utils-C8nShLO6.js";import{E as i,Ht as a,K as o,Qt as s,T as c,U as l,Wt as u,X as d,Zt as f,_t as p,k as m,ot as h,p as g,q as _,z as v}from"./index-BuJzdMCI.js";import{t as y}from"./EditItemDialog-DnzpXVT9.js";var b=e(t(),1);function x(e){return s({tag:`svg`,attr:{viewBox:`0 0 512 512`},child:[{tag:`path`,attr:{d:`M224 0c17.7 0 32 14.3 32 32l0 12 96-12c17.7 0 32 14.3 32 32s-14.3 32-32 32L256 84l-31-3.9-1-.1-1 .1L192 84 96 96C78.3 96 64 81.7 64 64s14.3-32 32-32l96 12 0-12c0-17.7 14.3-32 32-32zM0 224c0-17.7 14.3-32 32-32l96 0 22.6-22.6c6-6 14.1-9.4 22.6-9.4l18.7 0 0-43.8 32-4 32 4 0 43.8 18.7 0c8.5 0 16.6 3.4 22.6 9.4L320 192l32 0c88.4 0 160 71.6 160 160c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32-14.3-32-32s-14.3-32-32-32l-36.1 0c-20.2 29-53.9 48-91.9 48s-71.7-19-91.9-48L32 320c-17.7 0-32-14.3-32-32l0-64zM436.8 423.4c1.9-4.5 6.3-7.4 11.2-7.4s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1l0 1.2c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-1.2c0-4.5 .9-8.9 2.7-13.1l18.2-42.4z`},child:[]}]})(e)}var S=n();function C({outputType:e,className:t}){switch(e){case`light`:return(0,S.jsx)(h,{className:r(`text-warning`,t)});case`switch`:return(0,S.jsx)(u,{className:r(`text-info`,t)});case`valve`:return(0,S.jsx)(x,{className:r(`text-accent`,t)});case`cover`:return(0,S.jsx)(v,{className:r(`text-secondary`,t)});case`shutter`:case`blind`:case`curtain`:return(0,S.jsx)(f,{className:r(`text-secondary`,t)});default:return null}}var w={single:`1×`,double:`2×`,triple:`3×`,long:`L`,pressed:`P`,released:`R`,double_then_long:`2×L`,single_then_long:`1×L`,double_then_single:`2×1`},T={TOGGLE:`short_toggle`,ON:`short_on`,OFF:`short_off`,OPEN:`short_open`,CLOSE:`short_close`,STOP:`short_stop`},E=[{key:`single`,labelKey:`binding_matrix.legend_single`,icon:`1×`},{key:`double`,labelKey:`binding_matrix.legend_double`,icon:`2×`},{key:`triple`,labelKey:`binding_matrix.legend_triple`,icon:`3×`},{key:`long`,labelKey:`binding_matrix.legend_long`,icon:`L`},{key:`pressed`,labelKey:`binding_matrix.legend_pressed`,icon:`P`},{key:`released`,labelKey:`binding_matrix.legend_released`,icon:`R`}],D=[{labelKey:`actions.toggle`,shortKey:`actions.short_toggle`},{labelKey:`actions.on`,shortKey:`actions.short_on`},{labelKey:`actions.off`,shortKey:`actions.short_off`},{labelKey:`actions.open`,shortKey:`actions.short_open`},{labelKey:`actions.close`,shortKey:`actions.short_close`},{labelKey:`actions.stop`,shortKey:`actions.short_stop`}],O={single:`single`,double:`double`,triple:`triple`,long:`long`,pressed:`pressed`,released:`released`,double_then_long:`sequences`,single_then_long:`sequences`,double_then_single:`sequences`};function k(e,t){let n=w[e.clickType]||e.clickType,r=T[e.actionValue];return`${n} ${r?t(`actions.${r}`):e.actionValue}`}function A(e,t){let n=`actions.${e.actionValue.toLowerCase()}`,r=t(n),i=r===n?e.actionValue:r;return`${e.clickType} → ${i}`}function j(e){let t=e.action||`output`,n=``,r=``,i;switch(t){case`output`:n=e.boneio_output||``,r=e.action_output||`TOGGLE`;break;case`cover`:n=e.boneio_cover||``,r=e.action_cover||`TOGGLE`;break;case`remote_output`:i=e.boneio_id||``,n=i?`${i}/${e.output_id||``}`:e.output_id||``,r=e.action_output||`TOGGLE`;break;case`remote_cover`:i=e.boneio_id||``,n=i?`${i}/${e.cover_id||``}`:e.cover_id||``,r=e.action_cover||`TOGGLE`;break;default:n=``,r=e.action_output||e.action_cover||``;break}return{targetId:n,actionType:t,actionValue:r,remoteDevice:i}}function M(e){let t=[],n=[`single`,`double`,`triple`,`long`,`pressed`,`released`,`double_then_long`,`single_then_long`,`double_then_single`],r=e.local_inputs||[];for(let e=0;e<r.length;e++){let i=r[e],a=i.id||i.boneio_input||i.pin||`local_${e}`,o=[];for(let e of n){let t=i.actions?.[e]||[];for(let n of t){let{targetId:t,actionType:r,actionValue:i,remoteDevice:a}=j(n);t&&o.push({clickType:e,actionType:r,targetId:t,actionValue:i,remoteDevice:a})}}t.push({id:a,name:i.name||i.id||i.boneio_input||i.pin||a,area:i.area||void 0,type:`local`,inputKind:i._type===`binary_sensor`?`binary_sensor`:`event`,bindings:o})}let i=e.remote_inputs||[];for(let e=0;e<i.length;e++){let r=i[e],a=r.boneio_id||r.remote_device||``,o=r.id||r.entity_id||``,s=a?`${a}/${o}`:o||`remote_${e}`,c=[];for(let e of n){let t=r.actions?.[e]||[];for(let n of t){let{targetId:t,actionType:r,actionValue:i,remoteDevice:a}=j(n);t&&c.push({clickType:e,actionType:r,targetId:t,actionValue:i,remoteDevice:a})}}t.push({id:s,name:r.name||r.id||o,area:r.area||void 0,type:`remote`,inputKind:r._type===`binary_sensor`?`binary_sensor`:`event`,remoteDevice:a,bindings:c})}return t}function N(e){let t=[],n=e.output||[];for(let e=0;e<n.length;e++){let r=n[e];if(r.output_type===`cover`||r.output_type===`none`)continue;let i=r.id||`output_${e}`;t.push({id:i,name:r.name||r.id||i,area:r.area||void 0,type:`output`,outputType:r.output_type})}let r=e.cover||[];for(let e=0;e<r.length;e++){let n=r[e],i=n.id||`cover_${e}`;t.push({id:i,name:n.name||n.id||i,area:n.area||void 0,type:`cover`,outputType:n.device_class||`cover`})}let i=e.remote_outputs||[];for(let e=0;e<i.length;e++){let n=i[e],r=n.boneio_id||n.remote_device||``,a=n.id||n.output_id||``,o=r?`${r}/${a}`:a||`remote_out_${e}`;t.push({id:o,name:n.name||n.id||a,area:n.area||void 0,type:`remote_output`,remoteDevice:r,outputType:n.output_type})}return t}function P({inputs:e,outputs:t,t:n}){let r=e.filter(e=>e.type===`local`),i=e.filter(e=>e.type===`remote`),a=t.filter(e=>e.type===`output`),o=t.filter(e=>e.type===`cover`),s=t.filter(e=>e.type===`remote_output`||e.type===`remote_cover`),c=r.filter(e=>e.bindings.length>0),l=i.filter(e=>e.bindings.length>0),u=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),d=a.filter(e=>u.has(e.id)),f=o.filter(e=>u.has(e.id)),p=s.filter(e=>u.has(e.id)),m=e.reduce((e,t)=>e+t.bindings.length,0);return(0,S.jsxs)(`div`,{className:`gap-3 grid grid-cols-1 md:grid-cols-4 mb-4`,children:[(0,S.jsxs)(`div`,{className:`space-y-1 bg-base-200/50 p-3 border border-base-300 rounded-xl`,children:[(0,S.jsx)(`h4`,{className:`font-bold text-xs text-base-content/50 uppercase tracking-wider`,children:n(`binding_matrix.local`)}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📥 `,n(`binding_matrix.inputs`),`: `,r.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,c.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,r.length-c.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`💡 `,n(`binding_matrix.outputs`),`: `,a.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,d.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,a.length-d.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`🚪 `,n(`binding_matrix.covers`),`: `,o.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,f.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,o.length-f.length,` ○)`]})]})]}),(i.length>0||s.length>0)&&(0,S.jsxs)(`div`,{className:`space-y-1 bg-info/5 p-3 border border-info/20 rounded-xl`,children:[(0,S.jsx)(`h4`,{className:`font-bold text-info/70 text-xs uppercase tracking-wider`,children:n(`binding_matrix.remote`)}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📥 `,n(`binding_matrix.inputs`),`: `,i.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,l.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,i.length-l.length,` ○)`]})]}),(0,S.jsxs)(`p`,{className:`text-xs text-base-content/70`,children:[`📡 `,n(`binding_matrix.outputs`),`: `,s.length,(0,S.jsxs)(`span`,{className:`ml-1 text-success`,children:[`(`,p.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`ml-1 text-warning`,children:[`(`,s.length-p.length,` ○)`]})]})]}),(0,S.jsxs)(`div`,{className:`flex flex-col justify-center bg-primary/5 p-3 border border-primary/20 rounded-xl`,children:[(0,S.jsx)(`p`,{className:`font-extrabold text-primary text-2xl`,children:m}),(0,S.jsx)(`p`,{className:`font-medium text-primary/70 text-xs`,children:n(`binding_matrix.total_bindings`)})]}),(0,S.jsxs)(`div`,{className:`bg-base-200/50 p-3 border border-base-300 rounded-xl`,children:[(0,S.jsx)(`h4`,{className:`mb-1.5 font-bold text-xs text-base-content/50 uppercase tracking-wider`,children:n(`binding_matrix.legend`)}),(0,S.jsx)(`div`,{className:`gap-x-3 gap-y-0.5 grid grid-cols-2`,children:E.map(e=>(0,S.jsxs)(`span`,{className:`text-xxs text-base-content/60`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/80`,children:e.icon}),` `,n(e.labelKey)]},e.key))}),(0,S.jsx)(`div`,{className:`gap-x-2 gap-y-0.5 grid grid-cols-3 mt-1.5 pt-1.5 border-base-300 border-t`,children:D.map(e=>(0,S.jsxs)(`span`,{className:`text-xxs text-base-content/60`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/80`,children:n(e.shortKey)}),` `,n(e.labelKey)]},e.shortKey))})]})]})}function F({inputs:e,outputs:t,t:n}){let[r,a]=(0,b.useState)(!0),[o,s]=(0,b.useState)(!0),c=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),u=e.filter(e=>e.type===`local`&&e.bindings.length===0),d=t.filter(e=>e.type===`output`&&!c.has(e.id)),f=t.filter(e=>e.type===`cover`&&!c.has(e.id)),p=e.filter(e=>e.type===`remote`&&e.bindings.length===0),h=t.filter(e=>(e.type===`remote_output`||e.type===`remote_cover`)&&!c.has(e.id)),g=u.length>0||d.length>0||f.length>0,_=p.length>0||h.length>0;return!g&&!_?null:(0,S.jsxs)(`div`,{className:`space-y-3 mt-4`,children:[g&&(0,S.jsxs)(`div`,{className:`bg-warning/5 border border-warning/20 rounded-xl overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`flex justify-between items-center hover:bg-warning/10 p-3 w-full font-semibold text-warning text-sm transition-colors`,onClick:()=>a(!r),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(l,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_local`)]}),r?(0,S.jsx)(m,{className:`w-3 h-3`}):(0,S.jsx)(i,{className:`w-3 h-3`})]}),r&&(0,S.jsxs)(`div`,{className:`space-y-2 p-3 pt-0`,children:[u.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_inputs`)} (${u.length})`,items:u.map(e=>({id:e.id,name:e.name,area:e.area}))}),d.length>0&&(0,S.jsx)(I,{title:`💡 ${n(`binding_matrix.free_outputs`)} (${d.length})`,items:d.map(e=>({id:e.id,name:e.name,area:e.area}))}),f.length>0&&(0,S.jsx)(I,{title:`🚪 ${n(`binding_matrix.free_covers`)} (${f.length})`,items:f.map(e=>({id:e.id,name:e.name,area:e.area}))})]})]}),_&&(0,S.jsxs)(`div`,{className:`bg-info/5 border border-info/20 rounded-xl overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`flex justify-between items-center hover:bg-info/10 p-3 w-full font-semibold text-info text-sm transition-colors`,onClick:()=>s(!o),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(l,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_remote`)]}),o?(0,S.jsx)(m,{className:`w-3 h-3`}):(0,S.jsx)(i,{className:`w-3 h-3`})]}),o&&(0,S.jsxs)(`div`,{className:`space-y-2 p-3 pt-0`,children:[p.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_remote_inputs`)} (${p.length})`,items:p.map(e=>({id:e.id,name:e.name,area:e.area,badge:e.remoteDevice}))}),h.length>0&&(0,S.jsx)(I,{title:`📡 ${n(`binding_matrix.free_remote_outputs`)} (${h.length})`,items:h.map(e=>({id:e.id,name:e.name,area:e.area,badge:e.remoteDevice}))})]})]})]})}function I({title:e,items:t}){return(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`p`,{className:`mb-1 font-semibold text-xs text-base-content/60`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:t.map(e=>(0,S.jsxs)(`span`,{className:`gap-1 font-mono text-xxs badge badge-sm badge-ghost`,title:e.id,children:[e.name,e.area&&(0,S.jsxs)(`span`,{className:`text-base-content/40`,children:[`(`,e.area,`)`]}),e.badge&&(0,S.jsxs)(`span`,{className:`text-info/60`,children:[`[`,e.badge,`]`]})]},e.id))})]})}function ee({inputs:e,outputs:t,areaFilter:n,hideEmpty:i,t:a,onEditInput:o,onEditOutput:s}){let[c,l]=(0,b.useState)(null),[u,d]=(0,b.useState)(null),f=(0,b.useRef)(null),m=(0,b.useRef)(!1),h=(0,b.useRef)(!1),g=(0,b.useRef)(0),_=(0,b.useRef)(0),[v,y]=(0,b.useState)(null),x=(0,b.useRef)(null),w=(0,b.useCallback)((e,t,n)=>{n||(e.preventDefault(),y({x:e.clientX,y:e.clientY,row:t}))},[]),T=(0,b.useCallback)((e,t,n)=>{if(n)return;let r=`touches`in e?{x:e.touches[0].clientX,y:e.touches[0].clientY}:{x:e.clientX,y:e.clientY};x.current=setTimeout(()=>{y({...r,row:t}),x.current=null},500)},[]),D=(0,b.useCallback)(()=>{x.current&&=(clearTimeout(x.current),null)},[]);(0,b.useEffect)(()=>{if(!v)return;let e=null,t=requestAnimationFrame(()=>{let t=()=>y(null);window.addEventListener(`click`,t),window.addEventListener(`contextmenu`,t,{capture:!0}),window.addEventListener(`scroll`,t,!0),e=()=>{window.removeEventListener(`click`,t),window.removeEventListener(`contextmenu`,t,{capture:!0}),window.removeEventListener(`scroll`,t,!0)}});return()=>{cancelAnimationFrame(t),e?.()}},[v]);let O=(0,b.useMemo)(()=>{let e=new Map;for(let n of t)e.set(n.id,n.area);return e},[t]),j=(0,b.useMemo)(()=>{let t=e;return n.size>0&&(t=t.filter(e=>{let t=e.area||`__none__`;return n.has(t)?!0:e.bindings.some(e=>{let t=O.get(e.targetId)||`__none__`;return n.has(t)})})),i&&(t=t.filter(e=>e.bindings.length>0)),t},[e,n,i,O]),M=(0,b.useMemo)(()=>new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),[e]),N=(0,b.useMemo)(()=>{let t=new Map;for(let n of e){let e=n.area||`__none__`;for(let r of n.bindings)t.has(r.targetId)||t.set(r.targetId,new Set),t.get(r.targetId).add(e)}return t},[e]),P=(0,b.useMemo)(()=>{let e=t;return n.size>0&&(e=e.filter(e=>{let t=e.area||`__none__`;if(n.has(t))return!0;let r=N.get(e.id);if(r){for(let e of r)if(n.has(e))return!0}return!1})),i&&(e=e.filter(e=>M.has(e.id))),e},[t,n,i,M,N]),F=(0,b.useMemo)(()=>{let e=new Map;for(let t of j){let n=new Map;for(let e of t.bindings){let t=n.get(e.targetId)||[];t.push(e),n.set(e.targetId,t)}e.set(t.id,n)}return e},[j]);return j.length===0||P.length===0?(0,S.jsx)(`div`,{className:`py-12 text-base-content/40 text-center`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:a(`binding_matrix.no_data`)})}):(0,S.jsxs)(`div`,{ref:f,className:`border border-base-300 rounded-xl overflow-x-auto cursor-grab active:cursor-grabbing select-none`,onMouseDown:e=>{m.current=!0,h.current=!1,g.current=e.clientX,_.current=f.current?.scrollLeft||0},onMouseMove:e=>{if(!m.current||!f.current)return;let t=e.clientX-g.current;!h.current&&Math.abs(t)>5&&(h.current=!0),h.current&&(f.current.scrollLeft=_.current-t)},onMouseUp:()=>{m.current=!1,h.current=!1},onMouseLeave:()=>{m.current=!1,h.current=!1},onClickCapture:e=>{h.current&&(e.stopPropagation(),e.preventDefault())},children:[(0,S.jsxs)(`table`,{className:`table table-xs w-auto`,children:[(0,S.jsx)(`thead`,{children:(0,S.jsxs)(`tr`,{children:[(0,S.jsx)(`th`,{className:`left-0 z-20 sticky bg-base-200 border-base-300 border-r min-w-30`}),P.map(e=>(0,S.jsxs)(`th`,{className:r(`group/col bg-base-200 px-2 py-2 border-base-300 border-r min-w-20 font-bold text-xxs text-center whitespace-nowrap cursor-pointer`,u===e.id&&`bg-primary/10`),onMouseEnter:()=>d(e.id),onMouseLeave:()=>d(null),onClick:()=>s(e),title:a(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`flex justify-center items-center gap-1`,children:[(0,S.jsx)(C,{outputType:e.outputType,className:`w-3 h-3 shrink-0`}),(0,S.jsx)(`span`,{className:`whitespace-nowrap`,children:e.name}),(0,S.jsx)(p,{className:`opacity-0 group-hover/col:opacity-40 w-2 h-2 transition-opacity shrink-0`})]}),e.area?(0,S.jsx)(`div`,{className:`font-normal text-xxs text-base-content/40 truncate`,children:e.area}):(0,S.jsx)(`div`,{className:`font-normal text-xxs text-base-content/20`,children:`—`}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`font-normal text-info/50 text-xxs truncate`,children:e.remoteDevice})]},e.id))]})}),(0,S.jsx)(`tbody`,{children:j.map(e=>{let t=F.get(e.id);return(0,S.jsxs)(`tr`,{className:r(`hover:bg-base-200/50`,c===e.id&&`bg-base-200/40`),onMouseEnter:()=>l(e.id),onMouseLeave:()=>l(null),children:[(0,S.jsxs)(`td`,{className:r(`group/row left-0 z-10 sticky bg-base-100 border-base-300 border-r font-medium text-xs cursor-pointer`,c===e.id&&`bg-base-200/60`,e.bindings.length===0&&`text-base-content/30`),onClick:()=>o(e),title:a(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-1 max-w-30 font-bold truncate`,title:e.id,children:[e.name,(0,S.jsx)(p,{className:`opacity-0 group-hover/row:opacity-40 w-2.5 h-2.5 transition-opacity shrink-0`})]}),e.area&&(0,S.jsx)(`div`,{className:`text-xxs text-base-content/40`,children:e.area}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`text-info/50 text-xxs`,children:e.remoteDevice})]}),P.map(n=>{let i=t?.get(n.id)||[],s=c===e.id||u===n.id;return(0,S.jsx)(`td`,{className:r(`px-1 py-1 border-base-300 border-r text-xs text-center`,i.length>0?`bg-success/15 text-success font-medium`:`text-base-content/30`,s&&i.length>0&&`bg-success/25`,s&&i.length===0&&`bg-base-200/40`),onMouseEnter:()=>d(n.id),onMouseLeave:()=>{d(null),D()},onContextMenu:t=>w(t,e,i.length>0),onMouseDown:t=>{t.button===0&&T(t,e,i.length>0)},onMouseUp:D,onTouchStart:t=>T(t,e,i.length>0),onTouchEnd:D,onTouchMove:D,children:i.length>0&&(0,S.jsx)(`div`,{className:`flex flex-col gap-0.5`,children:i.map((t,n)=>(0,S.jsx)(`button`,{className:`hover:bg-success/30 px-0.5 rounded text-left whitespace-nowrap transition-colors cursor-pointer`,onClick:()=>o(e,t.clickType),title:`${A(t,a)}\n${a(`binding_matrix.click_to_edit`)}`,children:k(t,a)},n))})},n.id)})]},e.id)})})]}),v&&(0,S.jsxs)(`div`,{className:`z-50 fixed bg-base-100 shadow-xl py-1 border border-base-300 rounded-lg min-w-45 animate-in duration-100 fade-in zoom-in-95`,style:{left:v.x,top:v.y},onClick:e=>e.stopPropagation(),children:[(0,S.jsx)(`div`,{className:`px-3 py-1.5 font-semibold text-xxs text-base-content/40 uppercase tracking-wider`,children:a(`binding_matrix.add_action`)}),E.filter(e=>v.row.inputKind===`binary_sensor`?e.key===`pressed`||e.key===`released`:e.key!==`pressed`&&e.key!==`released`).map(e=>(0,S.jsxs)(`button`,{className:`flex items-center gap-2 hover:bg-primary/10 px-3 py-1.5 w-full text-sm text-left transition-colors`,onClick:()=>{o(v.row,e.key),y(null)},children:[(0,S.jsx)(`span`,{className:`font-mono text-base-content/70`,children:e.icon}),a(`binding_matrix.legend_${e.key}`)]},e.key))]})]})}function te({inputs:e,areaFilter:t,hideEmpty:n,t:o,onEditInput:s}){let[l,u]=(0,b.useState)(null),d=(0,b.useMemo)(()=>{let r=e;return t.size>0&&(r=r.filter(e=>{let n=e.area||`__none__`;return t.has(n)})),n&&(r=r.filter(e=>e.bindings.length>0)),r},[e,t,n]),f=(0,b.useCallback)(e=>{u(t=>t===e?null:e)},[]);return d.length===0?(0,S.jsx)(`div`,{className:`py-12 text-base-content/40 text-center`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:o(`binding_matrix.no_data`)})}):(0,S.jsx)(`div`,{className:`space-y-1.5`,children:d.map(e=>{let t=l===e.id,n=e.bindings.length>0,u=new Map;for(let t of e.bindings){let e=u.get(t.targetId)||[];e.push(t),u.set(t.targetId,e)}return(0,S.jsxs)(`div`,{className:r(`border rounded-xl overflow-hidden transition-colors`,n?`border-success/20 bg-success/5`:`border-base-300 bg-base-200/30`),children:[(0,S.jsxs)(`button`,{className:`flex justify-between items-center hover:bg-base-200/30 p-3 w-full text-sm transition-colors`,onClick:()=>n&&f(e.id),disabled:!n,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[n?(0,S.jsx)(c,{className:`w-3.5 h-3.5 text-success shrink-0`}):(0,S.jsx)(a,{className:`w-3.5 h-3.5 text-base-content/20 shrink-0`}),(0,S.jsxs)(`div`,{className:`min-w-0 text-left`,children:[(0,S.jsx)(`span`,{className:r(`block font-semibold truncate`,!n&&`text-base-content/30`),children:e.name}),e.area&&(0,S.jsx)(`span`,{className:`text-xxs text-base-content/40`,children:e.area})]})]}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[n&&(0,S.jsx)(`span`,{className:`font-bold badge badge-sm badge-success`,children:e.bindings.length}),e.type===`remote`&&(0,S.jsx)(`span`,{className:`font-mono badge badge-xs badge-info`,children:e.remoteDevice}),n&&(t?(0,S.jsx)(m,{className:`w-3 h-3 text-base-content/30`}):(0,S.jsx)(i,{className:`w-3 h-3 text-base-content/30`}))]})]}),t&&n&&(0,S.jsxs)(`div`,{className:`space-y-2 bg-base-100/50 p-3 border-base-300 border-t`,children:[[...u.entries()].map(([e,t])=>(0,S.jsxs)(`div`,{className:`flex items-start gap-2 text-xs`,children:[(0,S.jsx)(`span`,{className:`mt-0.5 font-mono font-bold text-base-content/70 shrink-0`,children:`→`}),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`span`,{className:`font-semibold`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1 mt-0.5`,children:t.map((e,t)=>(0,S.jsx)(`span`,{className:`gap-0.5 font-mono badge badge-xs badge-success`,children:k(e,o)},t))})]})]},e)),(0,S.jsxs)(`button`,{className:`gap-1 mt-1 btn-outline btn btn-xs btn-primary`,onClick:t=>{t.stopPropagation(),s(e)},children:[(0,S.jsx)(p,{className:`w-2.5 h-2.5`}),o(`binding_matrix.edit_input`)]})]})]},e.id)})})}var L=({formData:e,sections:t,onSaveSection:n,onUpdateFormData:r})=>{let{t:a}=g(),[s,c]=(0,b.useState)(new Set),[l,u]=(0,b.useState)(!1),[f,p]=(0,b.useState)(!1),[m,h]=(0,b.useState)(!1),[v,x]=(0,b.useState)(null),[C,w]=(0,b.useState)(``),[T,E]=(0,b.useState)(-1),[D,k]=(0,b.useState)(`basic`),[A,j]=(0,b.useState)(!1),[I,L]=(0,b.useState)(!1),R=(0,b.useRef)(null),[ne,z]=(0,b.useState)(!1),[B,V]=(0,b.useState)(null),[H,re]=(0,b.useState)(``),[U,ie]=(0,b.useState)(-1),[W,G]=(0,b.useState)(!1),K=(0,b.useRef)(null),q=(0,b.useCallback)((t,n)=>{let r=t.type===`remote`?`remote_inputs`:`local_inputs`,i=e[r]||[],a=i.findIndex((e,n)=>{if(t.type===`remote`){let r=e.boneio_id||e.remote_device||``,i=e.id||e.entity_id||``;return(r?`${r}/${i}`:i||`remote_${n}`)===t.id}return(e.id||e.boneio_input||e.pin||`local_${n}`)===t.id});a<0||(w(r),E(a),x(JSON.parse(JSON.stringify(i[a]))),R.current=JSON.stringify(i[a]),k(n&&O[n]||`basic`),j(!1),h(!0))},[e]),ae=(0,b.useCallback)(async()=>{if(A||T<0||!v)return;let t=[...e[C]||[]];t[T]=v,L(!0);try{r(C,t),await n(C,t),h(!1),x(null)}catch(e){console.error(`Failed to save input:`,e)}finally{L(!1)}},[v,T,C,e,A,n,r]),oe=(0,b.useCallback)(()=>{h(!1),x(null)},[]),J=(0,b.useMemo)(()=>M(e),[e]),Y=(0,b.useMemo)(()=>N(e),[e]),se=(0,b.useMemo)(()=>{let e=new Set;return J.forEach(t=>{t.area&&e.add(t.area)}),Y.forEach(t=>{t.area&&e.add(t.area)}),[...e].sort()},[J,Y]),ce=(0,b.useMemo)(()=>J.some(e=>!e.area)||Y.some(e=>!e.area),[J,Y]),X=(0,b.useMemo)(()=>e.output||[],[e.output]),Z=(0,b.useMemo)(()=>e.cover||[],[e.cover]),Q=(0,b.useMemo)(()=>e.output_group||[],[e.output_group]),le=(0,b.useMemo)(()=>e.remote_devices||[],[e.remote_devices]),ue=(0,b.useMemo)(()=>e.remote_inputs||[],[e.remote_inputs]),de=(0,b.useMemo)(()=>(e.local_inputs||[]).filter(e=>e._inputType===`binary_sensor`),[e.local_inputs]),fe=(0,b.useMemo)(()=>(e.local_inputs||[]).filter(e=>e._inputType!==`binary_sensor`),[e.local_inputs]),$=(0,b.useMemo)(()=>e.areas||[],[e.areas]),pe=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`local_inputs`);return e?.schema||e?.normalizedSchema||{}},[t]),me=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`output`);return e?.schema||e?.normalizedSchema||{}},[t]),he=(0,b.useMemo)(()=>t.find(e=>e.name===`output`)?.uiSchema||{},[t]),ge=(0,b.useMemo)(()=>{let e=t.find(e=>e.name===`cover`);return e?.schema||e?.normalizedSchema||{}},[t]),_e=(0,b.useCallback)(t=>{let n={output:`output`,cover:`cover`,remote_output:`remote_outputs`,remote_cover:`remote_covers`}[t.type]||`output`,r=e[n]||[],i=r.findIndex((e,n)=>{if(t.type===`remote_output`||t.type===`remote_cover`){let r=e.boneio_id||e.remote_device||``,i=e.id||e.output_id||``;return(r?`${r}/${i}`:i||`remote_out_${n}`)===t.id}return(e.id||``)===t.id});i<0||(re(n),ie(i),V(JSON.parse(JSON.stringify(r[i]))),K.current=JSON.stringify(r[i]),z(!0))},[e]),ve=(0,b.useCallback)(async()=>{if(U<0||!B)return;let t=[...e[H]||[]];t[U]=B,G(!0);try{r(H,t),await n(H,t),z(!1),V(null)}catch(e){console.error(`Failed to save output:`,e)}finally{G(!1)}},[B,U,H,e,n,r]),ye=(0,b.useCallback)(()=>{z(!1),V(null)},[]),be=v&&R.current&&JSON.stringify(v)!==R.current,xe=B&&K.current&&JSON.stringify(B)!==K.current;return(0,S.jsxs)(`div`,{className:`p-4 md:p-6 max-w-full`,children:[(0,S.jsxs)(`div`,{className:`mb-4`,children:[(0,S.jsx)(`h2`,{className:`font-extrabold text-xl tracking-tight`,children:a(`binding_matrix.title`)}),(0,S.jsx)(`p`,{className:`text-sm text-base-content/50`,children:a(`binding_matrix.subtitle`)})]}),(0,S.jsx)(P,{inputs:J,outputs:Y,t:a}),(0,S.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 mb-4`,children:[(0,S.jsxs)(`div`,{className:`relative flex items-center gap-2`,children:[(0,S.jsx)(d,{className:`w-3 h-3 text-base-content/40`}),(0,S.jsxs)(`button`,{className:`justify-between gap-1 btn-outline min-w-40 btn btn-sm`,onClick:()=>u(e=>!e),children:[(0,S.jsx)(`span`,{className:`text-xs truncate`,children:s.size===0?a(`binding_matrix.all_areas`):s.size===1?s.has(`__none__`)?a(`binding_matrix.no_area`):[...s][0]:a(`binding_matrix.areas_selected`,{count:s.size})}),(0,S.jsx)(i,{className:`w-2.5 h-2.5 shrink-0`})]}),l&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`z-40 fixed inset-0`,onClick:()=>u(!1)}),(0,S.jsxs)(`div`,{className:`top-full left-0 z-50 absolute bg-base-100 shadow-xl mt-1 py-1 border border-base-300 rounded-lg min-w-50 max-h-75 overflow-y-auto`,children:[(0,S.jsxs)(`label`,{className:`flex items-center gap-2 hover:bg-base-200/60 px-3 py-1.5 transition-colors cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.size===0,onChange:()=>c(new Set)}),(0,S.jsx)(`span`,{className:`font-semibold text-xs`,children:a(`binding_matrix.all_areas`)})]}),(0,S.jsx)(`div`,{className:`my-0.5 border-base-300 border-t`}),ce&&(0,S.jsxs)(`label`,{className:`flex items-center gap-2 hover:bg-base-200/60 px-3 py-1.5 transition-colors cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.has(`__none__`),onChange:()=>{let e=new Set(s);e.has(`__none__`)?e.delete(`__none__`):e.add(`__none__`),c(e)}}),(0,S.jsx)(`span`,{className:`text-xs text-base-content/50 italic`,children:a(`binding_matrix.no_area`)})]}),se.map(e=>(0,S.jsxs)(`label`,{className:`flex items-center gap-2 hover:bg-base-200/60 px-3 py-1.5 transition-colors cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:s.has(e),onChange:()=>{let t=new Set(s);t.has(e)?t.delete(e):t.add(e),c(t)}}),(0,S.jsx)(`span`,{className:`text-xs`,children:e})]},e))]})]})]}),(0,S.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-sm checkbox-primary`,checked:f,onChange:e=>p(e.target.checked)}),(0,S.jsxs)(`span`,{className:`flex items-center gap-1 font-medium text-xs text-base-content/60`,children:[f?(0,S.jsx)(_,{className:`w-3 h-3`}):(0,S.jsx)(o,{className:`w-3 h-3`}),a(`binding_matrix.hide_empty`)]})]})]}),(0,S.jsx)(`div`,{className:`hidden md:block`,children:(0,S.jsx)(ee,{inputs:J,outputs:Y,areaFilter:s,hideEmpty:f,t:a,onEditInput:q,onEditOutput:_e})}),(0,S.jsx)(`div`,{className:`md:hidden`,children:(0,S.jsx)(te,{inputs:J,areaFilter:s,hideEmpty:f,t:a,onEditInput:q})}),(0,S.jsx)(F,{inputs:J,outputs:Y,t:a}),(0,S.jsx)(y,{open:m,onOpenChange:h,editingItem:v,editingIndex:T,sectionType:C,schema:C===`remote_inputs`?t.find(e=>e.name===`remote_inputs`)?.schema||t.find(e=>e.name===`remote_inputs`)?.normalizedSchema||{}:pe,allBinarySensors:de,allEvents:fe,allOutputs:X,allOutputGroups:Q,allCovers:Z,allAreas:$,allRemoteDevices:le,allRemoteInputs:ue,savedOutputs:X,savedOutputGroups:Q,savedCovers:Z,onChange:x,onSave:ae,onCancel:oe,onValidationChange:j,saveDisabled:A||!be,isSaving:I,initialTab:D}),(0,S.jsx)(y,{open:ne,onOpenChange:z,editingItem:B,editingIndex:U,sectionType:H,schema:H===`cover`?ge:me,uiSchema:H===`cover`?void 0:he,allOutputs:X,allCovers:Z,allAreas:$,onChange:V,onSave:ve,onCancel:ye,saveDisabled:!xe,isSaving:W})]})};export{L as default};
|