boneio 1.5.0.dev23__tar.gz → 1.5.0.dev25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boneio-1.5.0.dev23/boneio.egg-info → boneio-1.5.0.dev25}/PKG-INFO +1 -1
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/cloud/registration.py +159 -21
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/bootstrap/boneio-migrate +15 -0
- boneio-1.5.0.dev25/boneio/migrations/versions/v1_5_3_libyaml_retry.py +102 -0
- boneio-1.5.0.dev25/boneio/version.py +2 -0
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/BindingMatrix-HeIJ-fdc.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/BindingMatrix-DphUHNCa.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/EditItemDialog-D6sMQCm4.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/EditItemDialog-cqpDHVdm.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/EntityCard-C4CsnsC3.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/EntityCard-JhMoFKqo.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/InputsView-B3IC5g5i.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/InputsView-jxCc1b3T.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/ModbusView-CmCpBs0W.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/ModbusView-CZqwsz7z.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/OutputsView-CjWrKAH6.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/OutputsView-DqYkV6oT.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/SensorView-DVmp-mbx.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/SensorView-BfxRM8qc.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/SudoPasswordDialog-D1FTg4dI.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/SudoPasswordDialog-D31M2rnl.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/SystemState-D2NXOXke.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/SystemState-CO12NlhO.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/TemplatesView-DVOrgw6Y.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/TemplatesView-DbyMxoED.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/Tools-anCB88sw.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/Tools-DXA0CgCa.js +1 -1
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/UISettings-Dwa6-3E-.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/UISettings-CZDMd4AP.js +3 -3
- boneio-1.5.0.dev23/boneio/webui/frontend-dist/assets/index-CuPeVd5n.js → boneio-1.5.0.dev25/boneio/webui/frontend-dist/assets/index-hA5DUgrB.js +2 -2
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/index.html +1 -1
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/sw.js +1 -1
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio.egg-info/SOURCES.txt +14 -13
- boneio-1.5.0.dev23/boneio/version.py +0 -2
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/LICENSE +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/MANIFEST.in +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/README.md +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.7/output_48_4.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.8/output_48_4.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/1.0/input.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/1.0/output_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/1.0/output_32_10.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/1.0/output_48_4.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/1.0/output_cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/boards/1.0/output_cover_mix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/bonecli.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/cover/cover.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/cover/time_based.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/cover/venetian.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/group/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/group/output_group.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/input/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/input/detectors.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/input/event.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/input/remote/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/input/remote/base.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/input/remote/esphome.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/irrigation/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/irrigation/controller.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/irrigation/water_source.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/output/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/output/basic.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/output/buzzer.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/output/mcp.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/output/pca.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/output/pcf.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/output/remote.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/template/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/template/alarm_panel.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/template/gate_cover.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/const.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/migrations/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/migrations/v4_wled_cache.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/package.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/yaml_compat.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/config/yaml_util.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/discovery.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/events/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/events/bus.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/action_conditions.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/canopen.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/covers.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/display.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/inputs.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/irrigation.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/manager.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/remote.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/remote_input_registrar.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/templates/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/templates/alarm.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/templates/gate_cover.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/templates.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/manager/update.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/composite.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/local.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/lox.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/remote/base.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/remote/can.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/remote/esphome.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/remote/wled.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/remote/wled_cache.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/sensor/base.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/sensor/system.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/state/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/state/manager.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/system/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/system/host_data.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/system/monitor.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/conditions.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/filter.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/logger.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/core/utils/util.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/48x4/adc.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/48x4/config.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/48x4/event.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/48x4/mqtt.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/48x4/output48x4A.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/can_master.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/can_slave.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/exceptions.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/can/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/can/bridge.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/can/client.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/can/interface.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/can/node.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/can/node_id.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/can/test_od.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/display/early_oled.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/display/oled.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/input/base.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/integration/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/integration/homeassistant.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/integration/interlock.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/integration/lox_template.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/actions.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/MANIFEST.sha256 +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/docker/daemon.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/journald/journald.conf +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/sudoers/boneio +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/systemd/boneio.service +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/assets/wheels/pyyaml-6.0.3-cp313-cp313-linux_armv7l.whl +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/bootstrap/install-helper.sh +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/runner.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_5_1_ufw_lox_udp.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/migrations/versions/v1_5_2_libyaml.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/cli.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/client.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/dts1964_3f.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/hvac/thessla.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/hvac/wanas415.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/gdfs.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/gdfx.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/mock_coordinator.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/modbus/utils.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/models/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/models/actions.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/models/events.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/models/files.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/models/logs.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/models/mqtt.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/models/state.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/runner.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/actions.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/condition.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/filters.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/id.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/remote_devices.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/remote_inputs.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/remote_outputs.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/schema.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/action_validation.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/app.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/dashboard_cards.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/ConfigEditor-DungnyP9.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/EntityGrid-Cawu3vXH.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/FormInputToggle-CizPsvVx.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/HelpLabel-BSTjOtDA.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/LogViewer-CvSFLDPH.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/LongPressWrapper-BHOQV7Wq.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/NodeRedView-CkLYYTOq.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/Sparkline-BGWlVLtt.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/aiConfig-IRYCBmLm.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/aiWizardPrompt-D9OJ-cE7.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/clipboard-CCtx29e-.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/css.worker-CvXBzhp8.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/editor.worker-Cn2oRESe.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/fa-CHSdWfvR.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/formatters-zOiGPJLh.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/gi-BmJDioil.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/html.worker-BO6WuOEO.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/index-v8R9j1A8.css +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/json.worker-BkJRGcCJ.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/longPress-Dx7OCSyP.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/modbusDeviceCatalog-C2Pi10n6.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/monaco-61yH0vfd.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/rolldown-runtime-QTnfLwEv.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/select-B2YDgQ4X.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/tabs-box-Dj36r4_e.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/ts.worker-B0J26iPs.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/useTranslation-CVJhMndf.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/utils-C8nShLO6.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/vendor-IzweXARb.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/assets/yaml.worker-BKRoXlmz.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/config.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/frontend-dist/workbox-4918f2f6.js +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/hvac_svg_templates.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/modbus_card_templates.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/can.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/config.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/config_actions.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/config_backups.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/config_core.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/config_discovery.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/config_files.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/dashboard.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/dev_fake_device.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/irrigation.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/migrations.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/modbus.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/mqtt_reference.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/nodered.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/remote_devices.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/system.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/timezone_sudoers.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/tools.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/routes/update.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/binary_sensor.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/boneio.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/can.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/config.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/cover.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/event.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/irrigation.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/mcp23017.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/modbus_devices.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/oled.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/output.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/remote_devices.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/sensor.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/template.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/services/logs.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/web_server.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/pyproject.toml +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/setup.cfg +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/setup.py +0 -0
- {boneio-1.5.0.dev23 → boneio-1.5.0.dev25}/tests/test_py313_compatibility.py +0 -0
|
@@ -7,18 +7,21 @@ for PWA support with custom subdomains.
|
|
|
7
7
|
|
|
8
8
|
import asyncio
|
|
9
9
|
import base64
|
|
10
|
+
from datetime import datetime, timezone
|
|
10
11
|
import hashlib
|
|
11
12
|
import hmac
|
|
13
|
+
from importlib.resources import files
|
|
12
14
|
import logging
|
|
13
15
|
import os
|
|
16
|
+
import re
|
|
14
17
|
import shutil
|
|
18
|
+
import socket
|
|
19
|
+
import ssl
|
|
15
20
|
import subprocess
|
|
16
21
|
from contextlib import suppress
|
|
17
22
|
from pathlib import Path
|
|
18
|
-
from typing import TYPE_CHECKING
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
import aiohttp
|
|
24
|
+
import aiohttp
|
|
22
25
|
|
|
23
26
|
from boneio.core.cloud.secrets import MASTER_SECRET as DEFAULT_MASTER_SECRET
|
|
24
27
|
from boneio.core.system.monitor import get_network_info
|
|
@@ -43,6 +46,9 @@ CADDY_ACTIVE_CONFIG = CADDY_CONFIG_DIR / "Caddyfile"
|
|
|
43
46
|
# Registration interval (1 hour)
|
|
44
47
|
REGISTRATION_INTERVAL = 3600
|
|
45
48
|
|
|
49
|
+
# Caddy Docker HTTPS port (host side of the 8443:443 mapping)
|
|
50
|
+
CADDY_HTTPS_PORT = 8443
|
|
51
|
+
|
|
46
52
|
|
|
47
53
|
class CloudRegistration:
|
|
48
54
|
"""
|
|
@@ -152,10 +158,8 @@ class CloudRegistration:
|
|
|
152
158
|
"""
|
|
153
159
|
return {"Authorization": f"Bearer {self._compute_token()}"}
|
|
154
160
|
|
|
155
|
-
async def _get_session(self) ->
|
|
161
|
+
async def _get_session(self) -> aiohttp.ClientSession:
|
|
156
162
|
"""Get or create aiohttp session."""
|
|
157
|
-
import aiohttp
|
|
158
|
-
|
|
159
163
|
if self._session is None or self._session.closed:
|
|
160
164
|
self._session = aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=30))
|
|
161
165
|
return self._session
|
|
@@ -187,6 +191,17 @@ class CloudRegistration:
|
|
|
187
191
|
elif cert_refreshed and self.is_cloud_config_active():
|
|
188
192
|
_LOGGER.info("Certificate refreshed, restarting Caddy...")
|
|
189
193
|
await self._recreate_caddy()
|
|
194
|
+
elif (
|
|
195
|
+
self._cert_exists()
|
|
196
|
+
and self.is_cloud_config_active()
|
|
197
|
+
and not await self._caddy_cert_matches_disk()
|
|
198
|
+
):
|
|
199
|
+
# Disk cert is OK but Caddy is serving a stale
|
|
200
|
+
# certificate (previous restart may have failed).
|
|
201
|
+
_LOGGER.warning(
|
|
202
|
+
"Caddy is serving a different certificate than on disk, restarting Caddy..."
|
|
203
|
+
)
|
|
204
|
+
await self._recreate_caddy()
|
|
190
205
|
else:
|
|
191
206
|
_LOGGER.warning("DNS registration failed, will retry")
|
|
192
207
|
|
|
@@ -205,8 +220,6 @@ class CloudRegistration:
|
|
|
205
220
|
Returns:
|
|
206
221
|
True if registration was successful
|
|
207
222
|
"""
|
|
208
|
-
import aiohttp
|
|
209
|
-
|
|
210
223
|
try:
|
|
211
224
|
session = await self._get_session()
|
|
212
225
|
|
|
@@ -250,8 +263,6 @@ class CloudRegistration:
|
|
|
250
263
|
Returns:
|
|
251
264
|
True if certificate was fetched successfully
|
|
252
265
|
"""
|
|
253
|
-
import aiohttp
|
|
254
|
-
|
|
255
266
|
try:
|
|
256
267
|
session = await self._get_session()
|
|
257
268
|
|
|
@@ -327,8 +338,7 @@ class CloudRegistration:
|
|
|
327
338
|
# Output format: "notAfter=Jun 3 12:00:00 2026 GMT"
|
|
328
339
|
line = result.stdout.strip()
|
|
329
340
|
date_str = line.split("=", 1)[1]
|
|
330
|
-
|
|
331
|
-
from datetime import datetime, timezone
|
|
341
|
+
date_str = re.sub(r"\s+", " ", date_str.strip())
|
|
332
342
|
|
|
333
343
|
expiry = datetime.strptime(date_str, "%b %d %H:%M:%S %Y %Z").replace(
|
|
334
344
|
tzinfo=timezone.utc
|
|
@@ -353,6 +363,128 @@ class CloudRegistration:
|
|
|
353
363
|
_LOGGER.warning("Error checking cert expiry, forcing refresh: %s", e)
|
|
354
364
|
return True
|
|
355
365
|
|
|
366
|
+
async def _caddy_cert_matches_disk(self, port: int = CADDY_HTTPS_PORT) -> bool:
|
|
367
|
+
"""Check if the certificate served by Caddy matches the one on disk.
|
|
368
|
+
|
|
369
|
+
Connects to 127.0.0.1:<port> via TLS (using the registered domain
|
|
370
|
+
as SNI) and compares the serial number of the served certificate
|
|
371
|
+
with the disk certificate. If they differ Caddy needs a restart.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
port: HTTPS port Caddy listens on (default 8443).
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
True if the certificates match (or if the check cannot be
|
|
378
|
+
performed), False if they differ.
|
|
379
|
+
"""
|
|
380
|
+
if not self._cert_exists():
|
|
381
|
+
return True # nothing to compare
|
|
382
|
+
|
|
383
|
+
if not self._domain:
|
|
384
|
+
return True # domain not yet known, skip
|
|
385
|
+
|
|
386
|
+
try:
|
|
387
|
+
# Read serial from disk cert
|
|
388
|
+
disk_serial = await self._get_cert_serial_from_file(CERT_FILE)
|
|
389
|
+
if disk_serial is None:
|
|
390
|
+
return True # can't read disk cert, assume OK
|
|
391
|
+
|
|
392
|
+
# Read serial from Caddy's live TLS cert using the real domain as SNI
|
|
393
|
+
live_serial = await self._get_caddy_live_serial(
|
|
394
|
+
port=port, server_name=self._domain
|
|
395
|
+
)
|
|
396
|
+
if live_serial is None:
|
|
397
|
+
# Caddy unreachable — restart will be attempted anyway
|
|
398
|
+
_LOGGER.debug("Cannot connect to Caddy TLS on port %d", port)
|
|
399
|
+
return False
|
|
400
|
+
|
|
401
|
+
match = disk_serial == live_serial
|
|
402
|
+
if not match:
|
|
403
|
+
_LOGGER.info(
|
|
404
|
+
"Certificate serial mismatch: disk=%s caddy=%s",
|
|
405
|
+
disk_serial,
|
|
406
|
+
live_serial,
|
|
407
|
+
)
|
|
408
|
+
return match
|
|
409
|
+
|
|
410
|
+
except Exception as e:
|
|
411
|
+
_LOGGER.debug("Error comparing Caddy cert with disk: %s", e)
|
|
412
|
+
return True # don't trigger restart on unexpected errors
|
|
413
|
+
|
|
414
|
+
async def _get_cert_serial_from_file(self, cert_path: Path) -> str | None:
|
|
415
|
+
"""Extract hex serial number from a PEM certificate file via openssl.
|
|
416
|
+
|
|
417
|
+
Args:
|
|
418
|
+
cert_path: Path to the PEM certificate.
|
|
419
|
+
|
|
420
|
+
Returns:
|
|
421
|
+
Hex serial string, or None on error.
|
|
422
|
+
"""
|
|
423
|
+
try:
|
|
424
|
+
result = await asyncio.get_event_loop().run_in_executor(
|
|
425
|
+
None,
|
|
426
|
+
lambda: subprocess.run(
|
|
427
|
+
["openssl", "x509", "-serial", "-noout", "-in", str(cert_path)],
|
|
428
|
+
capture_output=True,
|
|
429
|
+
text=True,
|
|
430
|
+
timeout=5,
|
|
431
|
+
),
|
|
432
|
+
)
|
|
433
|
+
if result.returncode != 0:
|
|
434
|
+
return None
|
|
435
|
+
# Output: "serial=AABBCCDD..."
|
|
436
|
+
return result.stdout.strip().split("=", 1)[1].upper()
|
|
437
|
+
except Exception:
|
|
438
|
+
return None
|
|
439
|
+
|
|
440
|
+
async def _get_caddy_live_serial(
|
|
441
|
+
self, port: int = CADDY_HTTPS_PORT, server_name: str = "localhost"
|
|
442
|
+
) -> str | None:
|
|
443
|
+
"""Connect to Caddy via TLS and return the served certificate's serial.
|
|
444
|
+
|
|
445
|
+
Args:
|
|
446
|
+
port: HTTPS port to connect to.
|
|
447
|
+
server_name: SNI server hostname (must match the Caddy vhost).
|
|
448
|
+
|
|
449
|
+
Returns:
|
|
450
|
+
Hex serial string, or None if unreachable.
|
|
451
|
+
"""
|
|
452
|
+
sni = server_name # capture for closure
|
|
453
|
+
|
|
454
|
+
def _probe() -> str | None:
|
|
455
|
+
|
|
456
|
+
ctx = ssl.create_default_context()
|
|
457
|
+
ctx.check_hostname = False
|
|
458
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
459
|
+
|
|
460
|
+
sock = socket.create_connection(("127.0.0.1", port), timeout=5)
|
|
461
|
+
try:
|
|
462
|
+
tls_sock = ctx.wrap_socket(sock, server_hostname=sni)
|
|
463
|
+
try:
|
|
464
|
+
der_cert = tls_sock.getpeercert(binary_form=True)
|
|
465
|
+
if not der_cert:
|
|
466
|
+
return None
|
|
467
|
+
# Parse serial from DER using openssl
|
|
468
|
+
proc = subprocess.run(
|
|
469
|
+
["openssl", "x509", "-serial", "-noout", "-inform", "DER"],
|
|
470
|
+
input=der_cert,
|
|
471
|
+
capture_output=True,
|
|
472
|
+
timeout=5,
|
|
473
|
+
)
|
|
474
|
+
if proc.returncode != 0:
|
|
475
|
+
return None
|
|
476
|
+
return proc.stdout.decode().strip().split("=", 1)[1].upper()
|
|
477
|
+
finally:
|
|
478
|
+
tls_sock.close()
|
|
479
|
+
except Exception:
|
|
480
|
+
sock.close()
|
|
481
|
+
return None
|
|
482
|
+
|
|
483
|
+
try:
|
|
484
|
+
return await asyncio.get_event_loop().run_in_executor(None, _probe)
|
|
485
|
+
except Exception:
|
|
486
|
+
return None
|
|
487
|
+
|
|
356
488
|
def update_ip(self, new_ip: str) -> None:
|
|
357
489
|
"""
|
|
358
490
|
Update local IP address.
|
|
@@ -373,8 +505,6 @@ class CloudRegistration:
|
|
|
373
505
|
"""
|
|
374
506
|
dest = CADDY_CONFIG_DIR / "init-certs-cloud.sh"
|
|
375
507
|
try:
|
|
376
|
-
from importlib.resources import files
|
|
377
|
-
|
|
378
508
|
src = files("boneio.core.cloud.data").joinpath("init-certs-cloud.sh")
|
|
379
509
|
src_bytes = src.read_bytes()
|
|
380
510
|
|
|
@@ -445,8 +575,6 @@ class CloudRegistration:
|
|
|
445
575
|
_LOGGER.info("Backed up docker-compose.yaml to %s", backup)
|
|
446
576
|
|
|
447
577
|
# Replace with bundled cloud template
|
|
448
|
-
from importlib.resources import files
|
|
449
|
-
|
|
450
578
|
cloud_src = files("boneio.core.cloud.data").joinpath("docker-compose-cloud.yaml")
|
|
451
579
|
cloud_content = cloud_src.read_text(encoding="utf-8")
|
|
452
580
|
compose_file.write_text(cloud_content)
|
|
@@ -484,8 +612,6 @@ class CloudRegistration:
|
|
|
484
612
|
if not self._check_compose_writable():
|
|
485
613
|
return False
|
|
486
614
|
|
|
487
|
-
from importlib.resources import files
|
|
488
|
-
|
|
489
615
|
src = files("boneio.core.cloud.data").joinpath("docker-compose.yaml")
|
|
490
616
|
original_content = src.read_text(encoding="utf-8")
|
|
491
617
|
|
|
@@ -515,9 +641,10 @@ class CloudRegistration:
|
|
|
515
641
|
|
|
516
642
|
async def _recreate_caddy(self) -> bool:
|
|
517
643
|
"""
|
|
518
|
-
Recreate Caddy container to apply new docker-compose config.
|
|
644
|
+
Recreate and restart Caddy container to apply new certs or docker-compose config.
|
|
519
645
|
|
|
520
|
-
Uses 'docker compose up -d caddy'
|
|
646
|
+
Uses 'docker compose up -d caddy' and 'docker compose restart caddy' to ensure
|
|
647
|
+
Caddy reloads updated SSL certificates from disk.
|
|
521
648
|
|
|
522
649
|
Returns:
|
|
523
650
|
True if recreate was successful
|
|
@@ -534,8 +661,19 @@ class CloudRegistration:
|
|
|
534
661
|
),
|
|
535
662
|
)
|
|
536
663
|
|
|
664
|
+
# Also restart caddy to ensure mounted TLS certs are reloaded from disk
|
|
665
|
+
await asyncio.get_event_loop().run_in_executor(
|
|
666
|
+
None,
|
|
667
|
+
lambda: subprocess.run(
|
|
668
|
+
["docker", "compose", "restart", "caddy"],
|
|
669
|
+
cwd=compose_dir,
|
|
670
|
+
capture_output=True,
|
|
671
|
+
timeout=60,
|
|
672
|
+
),
|
|
673
|
+
)
|
|
674
|
+
|
|
537
675
|
if result.returncode == 0:
|
|
538
|
-
_LOGGER.info("Caddy container recreated successfully")
|
|
676
|
+
_LOGGER.info("Caddy container recreated and restarted successfully")
|
|
539
677
|
return True
|
|
540
678
|
else:
|
|
541
679
|
_LOGGER.error(
|
|
@@ -589,13 +589,18 @@ def main() -> int:
|
|
|
589
589
|
|
|
590
590
|
_LOGGER.info("Applying migration version=%s (%d actions)", version, len(actions))
|
|
591
591
|
|
|
592
|
+
succeeded_count = 0
|
|
593
|
+
optional_failed_count = 0
|
|
594
|
+
|
|
592
595
|
for i, action in enumerate(actions, start=1):
|
|
593
596
|
action_type = action.get("action", "?")
|
|
594
597
|
_LOGGER.info("[%d/%d] %s", i, len(actions), action_type)
|
|
595
598
|
try:
|
|
596
599
|
dispatch_action(action, assets_base)
|
|
600
|
+
succeeded_count += 1
|
|
597
601
|
except Exception as exc:
|
|
598
602
|
if action.get("optional"):
|
|
603
|
+
optional_failed_count += 1
|
|
599
604
|
_LOGGER.warning(
|
|
600
605
|
"[%d/%d] Optional action %s failed, continuing: %s",
|
|
601
606
|
i, len(actions), action_type, exc,
|
|
@@ -604,6 +609,16 @@ def main() -> int:
|
|
|
604
609
|
_LOGGER.error("[%d/%d] Action %s failed: %s", i, len(actions), action_type, exc)
|
|
605
610
|
return 1
|
|
606
611
|
|
|
612
|
+
# If every action was optional and every one failed, the migration
|
|
613
|
+
# achieved nothing — do NOT mark it as applied so it will be retried.
|
|
614
|
+
if actions and succeeded_count == 0:
|
|
615
|
+
_LOGGER.error(
|
|
616
|
+
"Migration %s: all %d action(s) failed (optional_failed=%d). "
|
|
617
|
+
"NOT marking as applied — will retry on next startup.",
|
|
618
|
+
version, len(actions), optional_failed_count,
|
|
619
|
+
)
|
|
620
|
+
return 2
|
|
621
|
+
|
|
607
622
|
write_applied_flag(version)
|
|
608
623
|
_LOGGER.info("Migration %s completed successfully.", version)
|
|
609
624
|
return 0
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Retry libyaml installation for devices with a false v1.5.2 applied flag.
|
|
2
|
+
|
|
3
|
+
v1.5.2 could be falsely marked as applied when all optional actions
|
|
4
|
+
failed (bug fixed in the boneio-migrate helper). This migration
|
|
5
|
+
repeats the same libyaml install so that affected devices get a
|
|
6
|
+
second attempt automatically.
|
|
7
|
+
|
|
8
|
+
See also: ``v1_5_2_libyaml.py`` for the original migration.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import getpass
|
|
14
|
+
import logging
|
|
15
|
+
import sys
|
|
16
|
+
import sysconfig
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from boneio.migrations.actions import AptInstall, MigrationAction, PipInstallWheel
|
|
20
|
+
|
|
21
|
+
_LOGGER = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
VERSION = "1.5.3"
|
|
24
|
+
DESCRIPTION = "Retry libyaml install (fix false v1.5.2 applied flag)"
|
|
25
|
+
REQUIRES_ROOT = True
|
|
26
|
+
|
|
27
|
+
ASSETS_DIR = Path(__file__).parent.parent / "assets"
|
|
28
|
+
WHEELS_SUBDIR = "wheels"
|
|
29
|
+
|
|
30
|
+
# Expression evaluated by the target interpreter to detect the C backend
|
|
31
|
+
_LIBYAML_CHECK = "__import__('yaml').__with_libyaml__"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _wheel_glob() -> str:
|
|
35
|
+
"""Build the wheel filename pattern for the running interpreter.
|
|
36
|
+
|
|
37
|
+
Uses a case-insensitive prefix because pip normalises the project
|
|
38
|
+
name to lowercase (``pyyaml-*``) while the canonical PyPI name is
|
|
39
|
+
``PyYAML``.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
A glob pattern such as ``[Pp][Yy][Yy][Aa][Mm][Ll]-*-cp313-*linux_armv7l*.whl``.
|
|
43
|
+
"""
|
|
44
|
+
py_tag = f"cp{sys.version_info.major}{sys.version_info.minor}"
|
|
45
|
+
platform_tag = sysconfig.get_platform().replace("-", "_").replace(".", "_")
|
|
46
|
+
# Case-insensitive prefix: matches both "PyYAML" and "pyyaml"
|
|
47
|
+
ci_prefix = "[Pp][Yy][Yy][Aa][Mm][Ll]"
|
|
48
|
+
return f"{ci_prefix}-*-{py_tag}-*{platform_tag}*.whl"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _find_wheel() -> str | None:
|
|
52
|
+
"""Locate a bundled PyYAML wheel matching this interpreter.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Path of the wheel relative to the assets directory, or None when no
|
|
56
|
+
matching wheel is shipped for this Python version / architecture.
|
|
57
|
+
"""
|
|
58
|
+
wheels_dir = ASSETS_DIR / WHEELS_SUBDIR
|
|
59
|
+
if not wheels_dir.is_dir():
|
|
60
|
+
return None
|
|
61
|
+
matches = sorted(wheels_dir.glob(_wheel_glob()))
|
|
62
|
+
if not matches:
|
|
63
|
+
return None
|
|
64
|
+
return f"{WHEELS_SUBDIR}/{matches[0].name}"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def plan() -> list[MigrationAction]:
|
|
68
|
+
"""Return the ordered list of migration actions.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
List of :class:`MigrationAction` to apply in order. Empty when the
|
|
72
|
+
C backend is already active or no matching wheel is bundled.
|
|
73
|
+
"""
|
|
74
|
+
try:
|
|
75
|
+
import yaml
|
|
76
|
+
|
|
77
|
+
if yaml.__with_libyaml__:
|
|
78
|
+
_LOGGER.debug("PyYAML already uses libyaml, nothing to do.")
|
|
79
|
+
return []
|
|
80
|
+
except ImportError:
|
|
81
|
+
return []
|
|
82
|
+
|
|
83
|
+
wheel = _find_wheel()
|
|
84
|
+
if wheel is None:
|
|
85
|
+
_LOGGER.warning(
|
|
86
|
+
"No bundled PyYAML wheel matching %s — keeping the pure-Python parser.",
|
|
87
|
+
_wheel_glob(),
|
|
88
|
+
)
|
|
89
|
+
return []
|
|
90
|
+
|
|
91
|
+
return [
|
|
92
|
+
# Runtime library the wheel links against; usually already present.
|
|
93
|
+
AptInstall(packages=["libyaml-0-2"], optional=True),
|
|
94
|
+
PipInstallWheel(
|
|
95
|
+
wheel=wheel,
|
|
96
|
+
python=sys.executable,
|
|
97
|
+
run_as=getpass.getuser(),
|
|
98
|
+
skip_if=_LIBYAML_CHECK,
|
|
99
|
+
verify=_LIBYAML_CHECK,
|
|
100
|
+
optional=True,
|
|
101
|
+
),
|
|
102
|
+
]
|
|
@@ -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{F as r,Jt as i,Lt as a,O as o,P as s,R as c,Z as l,_ as u,j as d,lt as f,m as p,p as m,qt as h,zt as g}from"./fa-CHSdWfvR.js";import{t as _}from"./useTranslation-CVJhMndf.js";import{r as v}from"./utils-C8nShLO6.js";import{t as y}from"./EditItemDialog-D6sMQCm4.js";var b=e(t(),1);function x(e){return i({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)(l,{className:v(`text-warning`,t)});case`switch`:return(0,S.jsx)(g,{className:v(`text-info`,t)});case`valve`:return(0,S.jsx)(x,{className:v(`text-accent`,t)});case`cover`:return(0,S.jsx)(o,{className:v(`text-secondary`,t)});case`shutter`:case`blind`:case`curtain`:return(0,S.jsx)(h,{className:v(`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:`basic`,released:`basic`,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.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.pin||a,area:i.area||void 0,type:`local`,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`,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:`grid grid-cols-1 md:grid-cols-4 gap-3 mb-4`,children:[(0,S.jsxs)(`div`,{className:`bg-base-200/50 rounded-xl p-3 border border-base-300 space-y-1`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-base-content/50`,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:`text-success ml-1`,children:[`(`,c.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,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:`text-success ml-1`,children:[`(`,d.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,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:`text-success ml-1`,children:[`(`,f.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,o.length-f.length,` ○)`]})]})]}),(i.length>0||s.length>0)&&(0,S.jsxs)(`div`,{className:`bg-info/5 rounded-xl p-3 border border-info/20 space-y-1`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-info/70`,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:`text-success ml-1`,children:[`(`,l.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,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:`text-success ml-1`,children:[`(`,p.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,s.length-p.length,` ○)`]})]})]}),(0,S.jsxs)(`div`,{className:`bg-primary/5 rounded-xl p-3 border border-primary/20 flex flex-col justify-center`,children:[(0,S.jsx)(`p`,{className:`text-2xl font-extrabold text-primary`,children:m}),(0,S.jsx)(`p`,{className:`text-xs font-medium text-primary/70`,children:n(`binding_matrix.total_bindings`)})]}),(0,S.jsxs)(`div`,{className:`bg-base-200/50 rounded-xl p-3 border border-base-300`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-base-content/50 mb-1.5`,children:n(`binding_matrix.legend`)}),(0,S.jsx)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-0.5`,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:`border-t border-base-300 mt-1.5 pt-1.5 grid grid-cols-3 gap-x-2 gap-y-0.5`,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,i]=(0,b.useState)(!0),[a,o]=(0,b.useState)(!0),s=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),c=e.filter(e=>e.type===`local`&&e.bindings.length===0),l=t.filter(e=>e.type===`output`&&!s.has(e.id)),f=t.filter(e=>e.type===`cover`&&!s.has(e.id)),m=e.filter(e=>e.type===`remote`&&e.bindings.length===0),h=t.filter(e=>(e.type===`remote_output`||e.type===`remote_cover`)&&!s.has(e.id)),g=c.length>0||l.length>0||f.length>0,_=m.length>0||h.length>0;return!g&&!_?null:(0,S.jsxs)(`div`,{className:`mt-4 space-y-3`,children:[g&&(0,S.jsxs)(`div`,{className:`border border-warning/20 rounded-xl bg-warning/5 overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm font-semibold text-warning hover:bg-warning/10 transition-colors`,onClick:()=>i(!r),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(d,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_local`)]}),r?(0,S.jsx)(u,{className:`w-3 h-3`}):(0,S.jsx)(p,{className:`w-3 h-3`})]}),r&&(0,S.jsxs)(`div`,{className:`p-3 pt-0 space-y-2`,children:[c.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_inputs`)} (${c.length})`,items:c.map(e=>({id:e.id,name:e.name,area:e.area}))}),l.length>0&&(0,S.jsx)(I,{title:`💡 ${n(`binding_matrix.free_outputs`)} (${l.length})`,items:l.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:`border border-info/20 rounded-xl bg-info/5 overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm font-semibold text-info hover:bg-info/10 transition-colors`,onClick:()=>o(!a),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(d,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_remote`)]}),a?(0,S.jsx)(u,{className:`w-3 h-3`}):(0,S.jsx)(p,{className:`w-3 h-3`})]}),a&&(0,S.jsxs)(`div`,{className:`p-3 pt-0 space-y-2`,children:[m.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_remote_inputs`)} (${m.length})`,items:m.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:`text-xs font-semibold text-base-content/60 mb-1`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:t.map(e=>(0,S.jsxs)(`span`,{className:`badge badge-sm badge-ghost text-xxs font-mono gap-1`,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:r,t:i,onEditInput:a,onEditOutput:o}){let[s,c]=(0,b.useState)(null),[l,u]=(0,b.useState)(null),d=(0,b.useRef)(null),p=(0,b.useRef)(!1),m=(0,b.useRef)(!1),h=(0,b.useRef)(0),g=(0,b.useRef)(0),[_,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(!_)return;let e=null,t=requestAnimationFrame(()=>{let t=()=>y(null);window.addEventListener(`click`,t,{capture:!0}),window.addEventListener(`contextmenu`,t,{capture:!0}),window.addEventListener(`scroll`,t,!0),e=()=>{window.removeEventListener(`click`,t,{capture:!0}),window.removeEventListener(`contextmenu`,t,{capture:!0}),window.removeEventListener(`scroll`,t,!0)}});return()=>{cancelAnimationFrame(t),e?.()}},[_]);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)})})),r&&(t=t.filter(e=>e.bindings.length>0)),t},[e,n,r,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})),r&&(e=e.filter(e=>M.has(e.id))),e},[t,n,r,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:`text-center py-12 text-base-content/40`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:i(`binding_matrix.no_data`)})}):(0,S.jsxs)(`div`,{ref:d,className:`overflow-x-auto rounded-xl border border-base-300 cursor-grab active:cursor-grabbing select-none`,onMouseDown:e=>{p.current=!0,m.current=!1,h.current=e.clientX,g.current=d.current?.scrollLeft||0},onMouseMove:e=>{if(!p.current||!d.current)return;let t=e.clientX-h.current;!m.current&&Math.abs(t)>5&&(m.current=!0),m.current&&(d.current.scrollLeft=g.current-t)},onMouseUp:()=>{p.current=!1,m.current=!1},onMouseLeave:()=>{p.current=!1,m.current=!1},onClickCapture:e=>{m.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:`sticky left-0 z-20 bg-base-200 border-r border-base-300 min-w-[120px]`}),P.map(e=>(0,S.jsxs)(`th`,{className:v(`text-center text-xxs font-bold px-2 py-2 min-w-[80px] border-r border-base-300 bg-base-200 cursor-pointer group/col whitespace-nowrap`,l===e.id&&`bg-primary/10`),onMouseEnter:()=>u(e.id),onMouseLeave:()=>u(null),onClick:()=>o(e),title:i(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-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)(f,{className:`w-2 h-2 opacity-0 group-hover/col:opacity-40 transition-opacity shrink-0`})]}),e.area?(0,S.jsx)(`div`,{className:`text-xxs font-normal text-base-content/40 truncate`,children:e.area}):(0,S.jsx)(`div`,{className:`text-xxs font-normal text-base-content/20`,children:`—`}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`text-xxs font-normal text-info/50 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:v(`hover:bg-base-200/50`,s===e.id&&`bg-base-200/40`),onMouseEnter:()=>c(e.id),onMouseLeave:()=>c(null),children:[(0,S.jsxs)(`td`,{className:v(`sticky left-0 z-10 bg-base-100 border-r border-base-300 font-medium text-xs cursor-pointer group/row`,s===e.id&&`bg-base-200/60`,e.bindings.length===0&&`text-base-content/30`),onClick:()=>a(e),title:i(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`font-bold truncate max-w-[120px] flex items-center gap-1`,title:e.id,children:[e.name,(0,S.jsx)(f,{className:`w-2.5 h-2.5 opacity-0 group-hover/row:opacity-40 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-xxs text-info/50`,children:e.remoteDevice})]}),P.map(n=>{let r=t?.get(n.id)||[],o=s===e.id||l===n.id;return(0,S.jsx)(`td`,{className:v(`text-center text-xs border-r border-base-300 px-1 py-1`,r.length>0?`bg-success/15 text-success font-medium`:`text-base-content/30`,o&&r.length>0&&`bg-success/25`,o&&r.length===0&&`bg-base-200/40`),onMouseEnter:()=>u(n.id),onMouseLeave:()=>{u(null),D()},onContextMenu:t=>w(t,e,r.length>0),onMouseDown:t=>{t.button===0&&T(t,e,r.length>0)},onMouseUp:D,onTouchStart:t=>T(t,e,r.length>0),onTouchEnd:D,onTouchMove:D,children:r.length>0&&(0,S.jsx)(`div`,{className:`flex flex-col gap-0.5`,children:r.map((t,n)=>(0,S.jsx)(`button`,{className:`whitespace-nowrap cursor-pointer hover:bg-success/30 rounded px-0.5 transition-colors text-left`,onClick:()=>a(e,t.clickType),title:`${A(t,i)}\n${i(`binding_matrix.click_to_edit`)}`,children:k(t,i)},n))})},n.id)})]},e.id)})})]}),_&&(0,S.jsxs)(`div`,{className:`fixed z-50 bg-base-100 border border-base-300 rounded-lg shadow-xl py-1 min-w-[180px] animate-in fade-in zoom-in-95 duration-100`,style:{left:_.x,top:_.y},onClick:e=>e.stopPropagation(),children:[(0,S.jsx)(`div`,{className:`px-3 py-1.5 text-xxs font-semibold text-base-content/40 uppercase tracking-wider`,children:i(`binding_matrix.add_action`)}),E.map(e=>(0,S.jsxs)(`button`,{className:`w-full text-left px-3 py-1.5 text-sm hover:bg-primary/10 transition-colors flex items-center gap-2`,onClick:()=>{a(_.row,e.key),y(null)},children:[(0,S.jsx)(`span`,{className:`font-mono text-base-content/70`,children:e.icon}),i(`binding_matrix.legend_${e.key}`)]},e.key))]})]})}function te({inputs:e,areaFilter:t,hideEmpty:n,t:r,onEditInput:i}){let[o,s]=(0,b.useState)(null),c=(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]),l=(0,b.useCallback)(e=>{s(t=>t===e?null:e)},[]);return c.length===0?(0,S.jsx)(`div`,{className:`text-center py-12 text-base-content/40`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:r(`binding_matrix.no_data`)})}):(0,S.jsx)(`div`,{className:`space-y-1.5`,children:c.map(e=>{let t=o===e.id,n=e.bindings.length>0,s=new Map;for(let t of e.bindings){let e=s.get(t.targetId)||[];e.push(t),s.set(t.targetId,e)}return(0,S.jsxs)(`div`,{className:v(`rounded-xl border overflow-hidden transition-colors`,n?`border-success/20 bg-success/5`:`border-base-300 bg-base-200/30`),children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm hover:bg-base-200/30 transition-colors`,onClick:()=>n&&l(e.id),disabled:!n,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[n?(0,S.jsx)(m,{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:v(`font-semibold truncate block`,!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:`badge badge-sm badge-success font-bold`,children:e.bindings.length}),e.type===`remote`&&(0,S.jsx)(`span`,{className:`badge badge-xs badge-info font-mono`,children:e.remoteDevice}),n&&(t?(0,S.jsx)(u,{className:`w-3 h-3 text-base-content/30`}):(0,S.jsx)(p,{className:`w-3 h-3 text-base-content/30`}))]})]}),t&&n&&(0,S.jsxs)(`div`,{className:`border-t border-base-300 p-3 space-y-2 bg-base-100/50`,children:[[...s.entries()].map(([e,t])=>(0,S.jsxs)(`div`,{className:`flex items-start gap-2 text-xs`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/70 shrink-0 mt-0.5`,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:`badge badge-xs badge-success font-mono gap-0.5`,children:k(e,r)},t))})]})]},e)),(0,S.jsxs)(`button`,{className:`btn btn-xs btn-primary btn-outline gap-1 mt-1`,onClick:t=>{t.stopPropagation(),i(e)},children:[(0,S.jsx)(f,{className:`w-2.5 h-2.5`}),r(`binding_matrix.edit_input`)]})]})]},e.id)})})}var L=({formData:e,sections:t,onSaveSection:n,onUpdateFormData:i})=>{let{t:a}=_(),[o,l]=(0,b.useState)(new Set),[u,d]=(0,b.useState)(!1),[f,m]=(0,b.useState)(!1),[h,g]=(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),[ae,W]=(0,b.useState)(!1),G=(0,b.useRef)(null),K=(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.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),g(!0))},[e]),oe=(0,b.useCallback)(async()=>{if(A||T<0||!v)return;let t=[...e[C]||[]];t[T]=v,L(!0);try{i(C,t),await n(C,t),g(!1),x(null)}catch(e){console.error(`Failed to save input:`,e)}finally{L(!1)}},[v,T,C,e,A,n,i]),se=(0,b.useCallback)(()=>{g(!1),x(null)},[]),q=(0,b.useMemo)(()=>M(e),[e]),J=(0,b.useMemo)(()=>N(e),[e]),ce=(0,b.useMemo)(()=>{let e=new Set;return q.forEach(t=>{t.area&&e.add(t.area)}),J.forEach(t=>{t.area&&e.add(t.area)}),[...e].sort()},[q,J]),le=(0,b.useMemo)(()=>q.some(e=>!e.area)||J.some(e=>!e.area),[q,J]),Y=(0,b.useMemo)(()=>e.output||[],[e.output]),X=(0,b.useMemo)(()=>e.cover||[],[e.cover]),Z=(0,b.useMemo)(()=>e.output_group||[],[e.output_group]),ue=(0,b.useMemo)(()=>e.remote_devices||[],[e.remote_devices]),de=(0,b.useMemo)(()=>e.remote_inputs||[],[e.remote_inputs]),Q=(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]))),G.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,W(!0);try{i(H,t),await n(H,t),z(!1),V(null)}catch(e){console.error(`Failed to save output:`,e)}finally{W(!1)}},[B,U,H,e,n,i]),ye=(0,b.useCallback)(()=>{z(!1),V(null)},[]),be=v&&R.current&&JSON.stringify(v)!==R.current,xe=B&&G.current&&JSON.stringify(B)!==G.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:`text-xl font-extrabold 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:q,outputs:J,t:a}),(0,S.jsxs)(`div`,{className:`flex flex-wrap gap-3 mb-4 items-center`,children:[(0,S.jsxs)(`div`,{className:`relative flex items-center gap-2`,children:[(0,S.jsx)(c,{className:`w-3 h-3 text-base-content/40`}),(0,S.jsxs)(`button`,{className:`btn btn-sm btn-outline gap-1 min-w-[160px] justify-between`,onClick:()=>d(e=>!e),children:[(0,S.jsx)(`span`,{className:`truncate text-xs`,children:o.size===0?a(`binding_matrix.all_areas`):o.size===1?o.has(`__none__`)?a(`binding_matrix.no_area`):[...o][0]:a(`binding_matrix.areas_selected`,{count:o.size})}),(0,S.jsx)(p,{className:`w-2.5 h-2.5 shrink-0`})]}),u&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>d(!1)}),(0,S.jsxs)(`div`,{className:`absolute top-full left-0 mt-1 z-50 bg-base-100 border border-base-300 rounded-lg shadow-xl py-1 min-w-[200px] max-h-[300px] overflow-y-auto`,children:[(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:o.size===0,onChange:()=>l(new Set)}),(0,S.jsx)(`span`,{className:`text-xs font-semibold`,children:a(`binding_matrix.all_areas`)})]}),(0,S.jsx)(`div`,{className:`border-t border-base-300 my-0.5`}),le&&(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:o.has(`__none__`),onChange:()=>{let e=new Set(o);e.has(`__none__`)?e.delete(`__none__`):e.add(`__none__`),l(e)}}),(0,S.jsx)(`span`,{className:`text-xs italic text-base-content/50`,children:a(`binding_matrix.no_area`)})]}),ce.map(e=>(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:o.has(e),onChange:()=>{let t=new Set(o);t.has(e)?t.delete(e):t.add(e),l(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=>m(e.target.checked)}),(0,S.jsxs)(`span`,{className:`text-xs font-medium text-base-content/60 flex items-center gap-1`,children:[f?(0,S.jsx)(r,{className:`w-3 h-3`}):(0,S.jsx)(s,{className:`w-3 h-3`}),a(`binding_matrix.hide_empty`)]})]})]}),(0,S.jsx)(`div`,{className:`hidden md:block`,children:(0,S.jsx)(ee,{inputs:q,outputs:J,areaFilter:o,hideEmpty:f,t:a,onEditInput:K,onEditOutput:_e})}),(0,S.jsx)(`div`,{className:`md:hidden`,children:(0,S.jsx)(te,{inputs:q,areaFilter:o,hideEmpty:f,t:a,onEditInput:K})}),(0,S.jsx)(F,{inputs:q,outputs:J,t:a}),(0,S.jsx)(y,{open:h,onOpenChange:g,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:Q,allEvents:fe,allOutputs:Y,allOutputGroups:Z,allCovers:X,allAreas:$,allRemoteDevices:ue,allRemoteInputs:de,savedOutputs:Y,savedOutputGroups:Z,savedCovers:X,onChange:x,onSave:oe,onCancel:se,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:Y,allCovers:X,allAreas:$,onChange:V,onSave:ve,onCancel:ye,saveDisabled:!xe,isSaving:ae})]})};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{F as r,Jt as i,Lt as a,O as o,P as s,R as c,Z as l,_ as u,j as d,lt as f,m as p,p as m,qt as h,zt as g}from"./fa-CHSdWfvR.js";import{t as _}from"./useTranslation-CVJhMndf.js";import{r as v}from"./utils-C8nShLO6.js";import{t as y}from"./EditItemDialog-cqpDHVdm.js";var b=e(t(),1);function x(e){return i({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)(l,{className:v(`text-warning`,t)});case`switch`:return(0,S.jsx)(g,{className:v(`text-info`,t)});case`valve`:return(0,S.jsx)(x,{className:v(`text-accent`,t)});case`cover`:return(0,S.jsx)(o,{className:v(`text-secondary`,t)});case`shutter`:case`blind`:case`curtain`:return(0,S.jsx)(h,{className:v(`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:`basic`,released:`basic`,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.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.pin||a,area:i.area||void 0,type:`local`,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`,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:`grid grid-cols-1 md:grid-cols-4 gap-3 mb-4`,children:[(0,S.jsxs)(`div`,{className:`bg-base-200/50 rounded-xl p-3 border border-base-300 space-y-1`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-base-content/50`,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:`text-success ml-1`,children:[`(`,c.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,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:`text-success ml-1`,children:[`(`,d.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,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:`text-success ml-1`,children:[`(`,f.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,o.length-f.length,` ○)`]})]})]}),(i.length>0||s.length>0)&&(0,S.jsxs)(`div`,{className:`bg-info/5 rounded-xl p-3 border border-info/20 space-y-1`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-info/70`,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:`text-success ml-1`,children:[`(`,l.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,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:`text-success ml-1`,children:[`(`,p.length,` ✓)`]}),(0,S.jsxs)(`span`,{className:`text-warning ml-1`,children:[`(`,s.length-p.length,` ○)`]})]})]}),(0,S.jsxs)(`div`,{className:`bg-primary/5 rounded-xl p-3 border border-primary/20 flex flex-col justify-center`,children:[(0,S.jsx)(`p`,{className:`text-2xl font-extrabold text-primary`,children:m}),(0,S.jsx)(`p`,{className:`text-xs font-medium text-primary/70`,children:n(`binding_matrix.total_bindings`)})]}),(0,S.jsxs)(`div`,{className:`bg-base-200/50 rounded-xl p-3 border border-base-300`,children:[(0,S.jsx)(`h4`,{className:`text-xs font-bold uppercase tracking-wider text-base-content/50 mb-1.5`,children:n(`binding_matrix.legend`)}),(0,S.jsx)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-0.5`,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:`border-t border-base-300 mt-1.5 pt-1.5 grid grid-cols-3 gap-x-2 gap-y-0.5`,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,i]=(0,b.useState)(!0),[a,o]=(0,b.useState)(!0),s=new Set(e.flatMap(e=>e.bindings.map(e=>e.targetId))),c=e.filter(e=>e.type===`local`&&e.bindings.length===0),l=t.filter(e=>e.type===`output`&&!s.has(e.id)),f=t.filter(e=>e.type===`cover`&&!s.has(e.id)),m=e.filter(e=>e.type===`remote`&&e.bindings.length===0),h=t.filter(e=>(e.type===`remote_output`||e.type===`remote_cover`)&&!s.has(e.id)),g=c.length>0||l.length>0||f.length>0,_=m.length>0||h.length>0;return!g&&!_?null:(0,S.jsxs)(`div`,{className:`mt-4 space-y-3`,children:[g&&(0,S.jsxs)(`div`,{className:`border border-warning/20 rounded-xl bg-warning/5 overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm font-semibold text-warning hover:bg-warning/10 transition-colors`,onClick:()=>i(!r),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(d,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_local`)]}),r?(0,S.jsx)(u,{className:`w-3 h-3`}):(0,S.jsx)(p,{className:`w-3 h-3`})]}),r&&(0,S.jsxs)(`div`,{className:`p-3 pt-0 space-y-2`,children:[c.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_inputs`)} (${c.length})`,items:c.map(e=>({id:e.id,name:e.name,area:e.area}))}),l.length>0&&(0,S.jsx)(I,{title:`💡 ${n(`binding_matrix.free_outputs`)} (${l.length})`,items:l.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:`border border-info/20 rounded-xl bg-info/5 overflow-hidden`,children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm font-semibold text-info hover:bg-info/10 transition-colors`,onClick:()=>o(!a),children:[(0,S.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(d,{className:`w-3.5 h-3.5`}),n(`binding_matrix.unconfigured_remote`)]}),a?(0,S.jsx)(u,{className:`w-3 h-3`}):(0,S.jsx)(p,{className:`w-3 h-3`})]}),a&&(0,S.jsxs)(`div`,{className:`p-3 pt-0 space-y-2`,children:[m.length>0&&(0,S.jsx)(I,{title:`📥 ${n(`binding_matrix.free_remote_inputs`)} (${m.length})`,items:m.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:`text-xs font-semibold text-base-content/60 mb-1`,children:e}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-1.5`,children:t.map(e=>(0,S.jsxs)(`span`,{className:`badge badge-sm badge-ghost text-xxs font-mono gap-1`,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:r,t:i,onEditInput:a,onEditOutput:o}){let[s,c]=(0,b.useState)(null),[l,u]=(0,b.useState)(null),d=(0,b.useRef)(null),p=(0,b.useRef)(!1),m=(0,b.useRef)(!1),h=(0,b.useRef)(0),g=(0,b.useRef)(0),[_,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(!_)return;let e=null,t=requestAnimationFrame(()=>{let t=()=>y(null);window.addEventListener(`click`,t,{capture:!0}),window.addEventListener(`contextmenu`,t,{capture:!0}),window.addEventListener(`scroll`,t,!0),e=()=>{window.removeEventListener(`click`,t,{capture:!0}),window.removeEventListener(`contextmenu`,t,{capture:!0}),window.removeEventListener(`scroll`,t,!0)}});return()=>{cancelAnimationFrame(t),e?.()}},[_]);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)})})),r&&(t=t.filter(e=>e.bindings.length>0)),t},[e,n,r,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})),r&&(e=e.filter(e=>M.has(e.id))),e},[t,n,r,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:`text-center py-12 text-base-content/40`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:i(`binding_matrix.no_data`)})}):(0,S.jsxs)(`div`,{ref:d,className:`overflow-x-auto rounded-xl border border-base-300 cursor-grab active:cursor-grabbing select-none`,onMouseDown:e=>{p.current=!0,m.current=!1,h.current=e.clientX,g.current=d.current?.scrollLeft||0},onMouseMove:e=>{if(!p.current||!d.current)return;let t=e.clientX-h.current;!m.current&&Math.abs(t)>5&&(m.current=!0),m.current&&(d.current.scrollLeft=g.current-t)},onMouseUp:()=>{p.current=!1,m.current=!1},onMouseLeave:()=>{p.current=!1,m.current=!1},onClickCapture:e=>{m.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:`sticky left-0 z-20 bg-base-200 border-r border-base-300 min-w-[120px]`}),P.map(e=>(0,S.jsxs)(`th`,{className:v(`text-center text-xxs font-bold px-2 py-2 min-w-[80px] border-r border-base-300 bg-base-200 cursor-pointer group/col whitespace-nowrap`,l===e.id&&`bg-primary/10`),onMouseEnter:()=>u(e.id),onMouseLeave:()=>u(null),onClick:()=>o(e),title:i(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`flex items-center justify-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)(f,{className:`w-2 h-2 opacity-0 group-hover/col:opacity-40 transition-opacity shrink-0`})]}),e.area?(0,S.jsx)(`div`,{className:`text-xxs font-normal text-base-content/40 truncate`,children:e.area}):(0,S.jsx)(`div`,{className:`text-xxs font-normal text-base-content/20`,children:`—`}),e.remoteDevice&&(0,S.jsx)(`div`,{className:`text-xxs font-normal text-info/50 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:v(`hover:bg-base-200/50`,s===e.id&&`bg-base-200/40`),onMouseEnter:()=>c(e.id),onMouseLeave:()=>c(null),children:[(0,S.jsxs)(`td`,{className:v(`sticky left-0 z-10 bg-base-100 border-r border-base-300 font-medium text-xs cursor-pointer group/row`,s===e.id&&`bg-base-200/60`,e.bindings.length===0&&`text-base-content/30`),onClick:()=>a(e),title:i(`binding_matrix.click_to_edit`),children:[(0,S.jsxs)(`div`,{className:`font-bold truncate max-w-[120px] flex items-center gap-1`,title:e.id,children:[e.name,(0,S.jsx)(f,{className:`w-2.5 h-2.5 opacity-0 group-hover/row:opacity-40 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-xxs text-info/50`,children:e.remoteDevice})]}),P.map(n=>{let r=t?.get(n.id)||[],o=s===e.id||l===n.id;return(0,S.jsx)(`td`,{className:v(`text-center text-xs border-r border-base-300 px-1 py-1`,r.length>0?`bg-success/15 text-success font-medium`:`text-base-content/30`,o&&r.length>0&&`bg-success/25`,o&&r.length===0&&`bg-base-200/40`),onMouseEnter:()=>u(n.id),onMouseLeave:()=>{u(null),D()},onContextMenu:t=>w(t,e,r.length>0),onMouseDown:t=>{t.button===0&&T(t,e,r.length>0)},onMouseUp:D,onTouchStart:t=>T(t,e,r.length>0),onTouchEnd:D,onTouchMove:D,children:r.length>0&&(0,S.jsx)(`div`,{className:`flex flex-col gap-0.5`,children:r.map((t,n)=>(0,S.jsx)(`button`,{className:`whitespace-nowrap cursor-pointer hover:bg-success/30 rounded px-0.5 transition-colors text-left`,onClick:()=>a(e,t.clickType),title:`${A(t,i)}\n${i(`binding_matrix.click_to_edit`)}`,children:k(t,i)},n))})},n.id)})]},e.id)})})]}),_&&(0,S.jsxs)(`div`,{className:`fixed z-50 bg-base-100 border border-base-300 rounded-lg shadow-xl py-1 min-w-[180px] animate-in fade-in zoom-in-95 duration-100`,style:{left:_.x,top:_.y},onClick:e=>e.stopPropagation(),children:[(0,S.jsx)(`div`,{className:`px-3 py-1.5 text-xxs font-semibold text-base-content/40 uppercase tracking-wider`,children:i(`binding_matrix.add_action`)}),E.map(e=>(0,S.jsxs)(`button`,{className:`w-full text-left px-3 py-1.5 text-sm hover:bg-primary/10 transition-colors flex items-center gap-2`,onClick:()=>{a(_.row,e.key),y(null)},children:[(0,S.jsx)(`span`,{className:`font-mono text-base-content/70`,children:e.icon}),i(`binding_matrix.legend_${e.key}`)]},e.key))]})]})}function te({inputs:e,areaFilter:t,hideEmpty:n,t:r,onEditInput:i}){let[o,s]=(0,b.useState)(null),c=(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]),l=(0,b.useCallback)(e=>{s(t=>t===e?null:e)},[]);return c.length===0?(0,S.jsx)(`div`,{className:`text-center py-12 text-base-content/40`,children:(0,S.jsx)(`p`,{className:`text-sm`,children:r(`binding_matrix.no_data`)})}):(0,S.jsx)(`div`,{className:`space-y-1.5`,children:c.map(e=>{let t=o===e.id,n=e.bindings.length>0,s=new Map;for(let t of e.bindings){let e=s.get(t.targetId)||[];e.push(t),s.set(t.targetId,e)}return(0,S.jsxs)(`div`,{className:v(`rounded-xl border overflow-hidden transition-colors`,n?`border-success/20 bg-success/5`:`border-base-300 bg-base-200/30`),children:[(0,S.jsxs)(`button`,{className:`w-full p-3 flex items-center justify-between text-sm hover:bg-base-200/30 transition-colors`,onClick:()=>n&&l(e.id),disabled:!n,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[n?(0,S.jsx)(m,{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:v(`font-semibold truncate block`,!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:`badge badge-sm badge-success font-bold`,children:e.bindings.length}),e.type===`remote`&&(0,S.jsx)(`span`,{className:`badge badge-xs badge-info font-mono`,children:e.remoteDevice}),n&&(t?(0,S.jsx)(u,{className:`w-3 h-3 text-base-content/30`}):(0,S.jsx)(p,{className:`w-3 h-3 text-base-content/30`}))]})]}),t&&n&&(0,S.jsxs)(`div`,{className:`border-t border-base-300 p-3 space-y-2 bg-base-100/50`,children:[[...s.entries()].map(([e,t])=>(0,S.jsxs)(`div`,{className:`flex items-start gap-2 text-xs`,children:[(0,S.jsx)(`span`,{className:`font-mono font-bold text-base-content/70 shrink-0 mt-0.5`,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:`badge badge-xs badge-success font-mono gap-0.5`,children:k(e,r)},t))})]})]},e)),(0,S.jsxs)(`button`,{className:`btn btn-xs btn-primary btn-outline gap-1 mt-1`,onClick:t=>{t.stopPropagation(),i(e)},children:[(0,S.jsx)(f,{className:`w-2.5 h-2.5`}),r(`binding_matrix.edit_input`)]})]})]},e.id)})})}var L=({formData:e,sections:t,onSaveSection:n,onUpdateFormData:i})=>{let{t:a}=_(),[o,l]=(0,b.useState)(new Set),[u,d]=(0,b.useState)(!1),[f,m]=(0,b.useState)(!1),[h,g]=(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),[ae,W]=(0,b.useState)(!1),G=(0,b.useRef)(null),K=(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.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),g(!0))},[e]),oe=(0,b.useCallback)(async()=>{if(A||T<0||!v)return;let t=[...e[C]||[]];t[T]=v,L(!0);try{i(C,t),await n(C,t),g(!1),x(null)}catch(e){console.error(`Failed to save input:`,e)}finally{L(!1)}},[v,T,C,e,A,n,i]),se=(0,b.useCallback)(()=>{g(!1),x(null)},[]),q=(0,b.useMemo)(()=>M(e),[e]),J=(0,b.useMemo)(()=>N(e),[e]),ce=(0,b.useMemo)(()=>{let e=new Set;return q.forEach(t=>{t.area&&e.add(t.area)}),J.forEach(t=>{t.area&&e.add(t.area)}),[...e].sort()},[q,J]),le=(0,b.useMemo)(()=>q.some(e=>!e.area)||J.some(e=>!e.area),[q,J]),Y=(0,b.useMemo)(()=>e.output||[],[e.output]),X=(0,b.useMemo)(()=>e.cover||[],[e.cover]),Z=(0,b.useMemo)(()=>e.output_group||[],[e.output_group]),ue=(0,b.useMemo)(()=>e.remote_devices||[],[e.remote_devices]),de=(0,b.useMemo)(()=>e.remote_inputs||[],[e.remote_inputs]),Q=(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]))),G.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,W(!0);try{i(H,t),await n(H,t),z(!1),V(null)}catch(e){console.error(`Failed to save output:`,e)}finally{W(!1)}},[B,U,H,e,n,i]),ye=(0,b.useCallback)(()=>{z(!1),V(null)},[]),be=v&&R.current&&JSON.stringify(v)!==R.current,xe=B&&G.current&&JSON.stringify(B)!==G.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:`text-xl font-extrabold 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:q,outputs:J,t:a}),(0,S.jsxs)(`div`,{className:`flex flex-wrap gap-3 mb-4 items-center`,children:[(0,S.jsxs)(`div`,{className:`relative flex items-center gap-2`,children:[(0,S.jsx)(c,{className:`w-3 h-3 text-base-content/40`}),(0,S.jsxs)(`button`,{className:`btn btn-sm btn-outline gap-1 min-w-[160px] justify-between`,onClick:()=>d(e=>!e),children:[(0,S.jsx)(`span`,{className:`truncate text-xs`,children:o.size===0?a(`binding_matrix.all_areas`):o.size===1?o.has(`__none__`)?a(`binding_matrix.no_area`):[...o][0]:a(`binding_matrix.areas_selected`,{count:o.size})}),(0,S.jsx)(p,{className:`w-2.5 h-2.5 shrink-0`})]}),u&&(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>d(!1)}),(0,S.jsxs)(`div`,{className:`absolute top-full left-0 mt-1 z-50 bg-base-100 border border-base-300 rounded-lg shadow-xl py-1 min-w-[200px] max-h-[300px] overflow-y-auto`,children:[(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:o.size===0,onChange:()=>l(new Set)}),(0,S.jsx)(`span`,{className:`text-xs font-semibold`,children:a(`binding_matrix.all_areas`)})]}),(0,S.jsx)(`div`,{className:`border-t border-base-300 my-0.5`}),le&&(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:o.has(`__none__`),onChange:()=>{let e=new Set(o);e.has(`__none__`)?e.delete(`__none__`):e.add(`__none__`),l(e)}}),(0,S.jsx)(`span`,{className:`text-xs italic text-base-content/50`,children:a(`binding_matrix.no_area`)})]}),ce.map(e=>(0,S.jsxs)(`label`,{className:`flex items-center gap-2 px-3 py-1.5 hover:bg-base-200/60 cursor-pointer transition-colors`,children:[(0,S.jsx)(`input`,{type:`checkbox`,className:`checkbox checkbox-xs checkbox-primary`,checked:o.has(e),onChange:()=>{let t=new Set(o);t.has(e)?t.delete(e):t.add(e),l(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=>m(e.target.checked)}),(0,S.jsxs)(`span`,{className:`text-xs font-medium text-base-content/60 flex items-center gap-1`,children:[f?(0,S.jsx)(r,{className:`w-3 h-3`}):(0,S.jsx)(s,{className:`w-3 h-3`}),a(`binding_matrix.hide_empty`)]})]})]}),(0,S.jsx)(`div`,{className:`hidden md:block`,children:(0,S.jsx)(ee,{inputs:q,outputs:J,areaFilter:o,hideEmpty:f,t:a,onEditInput:K,onEditOutput:_e})}),(0,S.jsx)(`div`,{className:`md:hidden`,children:(0,S.jsx)(te,{inputs:q,areaFilter:o,hideEmpty:f,t:a,onEditInput:K})}),(0,S.jsx)(F,{inputs:q,outputs:J,t:a}),(0,S.jsx)(y,{open:h,onOpenChange:g,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:Q,allEvents:fe,allOutputs:Y,allOutputGroups:Z,allCovers:X,allAreas:$,allRemoteDevices:ue,allRemoteInputs:de,savedOutputs:Y,savedOutputGroups:Z,savedCovers:X,onChange:x,onSave:oe,onCancel:se,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:Y,allCovers:X,allAreas:$,onChange:V,onSave:ve,onCancel:ye,saveDisabled:!xe,isSaving:ae})]})};export{L as default};
|