boneIO 1.0.0.dev21__tar.gz → 1.0.0.dev23__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.0.0.dev21/boneio.egg-info → boneio-1.0.0.dev23}/PKG-INFO +1 -1
- {boneio-1.0.0.dev21/boneio/boards/0.4 → boneio-1.0.0.dev23/boneio/boards/0.2}/output_24_16.yaml +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_24_16.yaml +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/time_based.py +14 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/venetian.py +8 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/binary_sensor.py +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/detectors.py +190 -3
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/event.py +74 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/config_helper.py +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/covers.py +3 -3
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/display.py +18 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/inputs.py +40 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/manager.py +12 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/sensors.py +20 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/system/host_data.py +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/config.yaml +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/config.yaml +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/config.yaml +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/config.yaml +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/display/oled.py +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/input/base.py +34 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/input/manager.py +39 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/ina219.py +12 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/base.py +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/integration/homeassistant.py +32 -6
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/runner.py +1 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/schema.yaml +44 -0
- boneio-1.0.0.dev23/boneio/version.py +2 -0
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/cssMode-Cf6c8Rak.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/cssMode-Cu-5LYe_.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/freemarker2-Dx0BWjru.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/freemarker2-nq6oJG_Y.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/handlebars-BTuLZVfx.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/handlebars-B5W2-m2x.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/html-BB3T_3_K.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/html-vUTSIY6B.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/htmlMode-yP62Fr3K.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/htmlMode-CDTfRhqt.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/index-GG4_twIa.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/index-BQrDKk-6.js +255 -255
- boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/index-CU6eO3xb.css +1 -0
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/javascript-fCd4TqkY.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/javascript-BT4M2_pD.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/jsonMode-CChUrnET.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/jsonMode-D-E2Vrak.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/liquid-DdLOtKyT.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/liquid-D1aceO1w.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/mdx-wnkV-3mF.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/mdx-DohT_XYH.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/python-BU1BlHpX.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/python-C8fD_30g.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/razor-DNgLOtn7.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/razor-090nAgDD.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/tsMode-CINGfPlt.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/tsMode-BAlzCa-y.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/typescript-CkWSk1mf.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/typescript-C3QTnewR.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/xml-DlZcKj6v.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/xml-D3NSlFbJ.js +1 -1
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/yaml-CDmetGCQ.js → boneio-1.0.0.dev23/boneio/webui/frontend-dist/assets/yaml-1y1ho8Rn.js +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/index.html +2 -2
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/adc.schema.json +6 -6
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/areas.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/binary_sensor.schema.json +18 -18
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/boneio.schema.json +4 -4
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/config.schema.json +309 -198
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/cover.schema.json +10 -10
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/ds2482.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/event.schema.json +165 -54
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/ina219.schema.json +8 -8
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/lm75.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/logger.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/mcp23017.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/mcp9808.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/modbus.schema.json +2 -2
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/modbus_devices.schema.json +16 -16
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/mqtt.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/oled.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/output.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/output_group.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/pca9685.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/pcf8575.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/remote_devices.schema.json +20 -20
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/sensor.schema.json +6 -6
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/virtual_energy_sensor.schema.json +2 -2
- {boneio-1.0.0.dev21/boneio/webui/schema → boneio-1.0.0.dev23/boneio/webui/frontend-dist/schem}/web.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/config.py +135 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/update.py +262 -10
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/adc.schema.json +6 -6
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/areas.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/binary_sensor.schema.json +18 -18
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/boneio.schema.json +4 -4
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/config.schema.json +309 -198
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/cover.schema.json +10 -10
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/ds2482.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/event.schema.json +165 -54
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/ina219.schema.json +8 -8
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/lm75.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/logger.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/mcp23017.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/mcp9808.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/modbus.schema.json +2 -2
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/modbus_devices.schema.json +16 -16
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/mqtt.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/oled.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/output.schema.json +6 -6
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/output_group.schema.json +2 -2
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/pca9685.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/pcf8575.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/remote_devices.schema.json +20 -20
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/sensor.schema.json +6 -6
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/virtual_energy_sensor.schema.json +2 -2
- {boneio-1.0.0.dev21/boneio/webui/frontend-dist/schem → boneio-1.0.0.dev23/boneio/webui/schema}/web.schema.json +4 -4
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/SOURCES.txt +17 -17
- boneio-1.0.0.dev21/boneio/version.py +0 -2
- boneio-1.0.0.dev21/boneio/webui/frontend-dist/assets/index-cAyuaVJ4.css +0 -1
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/LICENSE +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/MANIFEST.in +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/README.md +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.0.0.dev21/boneio/boards/0.2 → boneio-1.0.0.dev23/boneio/boards/0.4}/output_24_16.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/bonecli.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/cover.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/cover/previous.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/group/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/group/output_group.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/input/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/basic.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/mcp.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/pca.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/output/pcf.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/const.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/package.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/config/yaml_util.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/discovery.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/events/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/events/bus.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/manager/remote.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/local.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/base.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/esphome.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/sensor/base.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/sensor/system.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/state/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/state/manager.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/system/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/system/monitor.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/filter.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/logger.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/core/utils/util.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/exceptions.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/integration/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/integration/interlock.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/cli.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/client.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/inverters/thessla.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/other/wanas415.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/modbus/utils.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/actions.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/events.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/files.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/logs.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/mqtt.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/models/state.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/actions.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/filters.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/id.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/remote_devices.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/app.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/abap-CRCWOmpq.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/apex-DnsZk_dE.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/azcli-1IWB1ccx.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/bat-DPkNLes8.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/bicep-Corcdgou.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/cameligo-CGrWLZr3.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/clojure-D9WOWImG.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/coffee-B7EJu28W.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/cpp-SEyurbux.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/csharp-BoL64M5l.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/csp-C46ZqvIl.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/css-DQU6DXDx.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/cypher-D84EuPTj.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/dart-D8lhlL1r.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/dockerfile-DLk6rpji.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/ecl-BO6FnfXk.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/editor.worker-DsAeyiJ5.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/elixir-BRjLKONM.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/flow9-Cac8vKd7.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/fsharp-fd1GTHhf.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/go-O9LJTZXk.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/graphql-LQdxqEYJ.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/hcl-DxDQ3s82.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/ini-BvajGCUy.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/java-SYsfObOQ.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/json.worker-DaRII17c.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/julia-DQXNmw_w.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/kotlin-qQ0MG-9I.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/less-GGFNNJHn.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/lexon-Canl7DCW.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/lua-D28Ae8-K.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/m3-DPitgjJI.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/markdown-B811l8j2.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/mips-CdjsipkG.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/msdax-CYqgjx_P.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/mysql-BHd6q0vd.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/objective-c-B1aVtJYH.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pascal-BhNW15KB.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pascaligo-5jv8CcQD.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/perl-DlYyT36c.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pgsql-Dy0bjov7.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/php-120yhfDK.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pla-CjnFlu4u.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/postiats-CQpG440k.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/powerquery-DdJtto1Z.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/powershell-Bu_VLpJB.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/protobuf-IBS6jZEB.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/pug-kFxLfcjb.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/qsharp-q7JyzKFN.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/r-BIFz-_sK.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/redis-CHOsPHWR.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/redshift-CBifECDb.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/restructuredtext-CghPJEOS.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/ruby-CYWGW-b1.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/rust-DMDD0SHb.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sb-BYAiYHFx.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/scala-Bqvq8jcR.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/scheme-Dhb-2j9p.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/scss-CTwUZ5N7.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/shell-CsDZo4DB.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/solidity-CME5AdoB.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sophia-RYC1BQQz.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sparql-KEyrF7De.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/sql-BdTr02Mf.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/st-C7iG7M4S.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/swift-D7IUmUK8.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/systemverilog-DgMryOEJ.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/tcl-PloMZuKG.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/twig-BfRIq3la.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/typespec-CzxlYoT_.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/vb-BwAE3J76.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/wgsl-B_1kOXbF.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/assets/yaml.worker-BTE-_K6g.js +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/frontend-dist/schem/dallas.schema.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/modbus.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/remote_devices.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/routes/system.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/services/logs.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/web_server.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/pyproject.toml +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/setup.cfg +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/setup.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/tests/test_i2c_smbus2.py +0 -0
- {boneio-1.0.0.dev21 → boneio-1.0.0.dev23}/tests/test_py313_compatibility.py +0 -0
|
@@ -41,7 +41,13 @@ class TimeBasedCover(BaseCover):
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
def _move_cover(self, direction: str, duration: float, target_position: int | None = None):
|
|
44
|
-
"""
|
|
44
|
+
"""Run in sepearate thread.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
direction: Direction of movement (OPEN or CLOSE)
|
|
48
|
+
duration: Full time for 0-100% movement in milliseconds
|
|
49
|
+
target_position: Optional target position (0-100)
|
|
50
|
+
"""
|
|
45
51
|
if direction == OPEN:
|
|
46
52
|
relay = self._open_relay
|
|
47
53
|
total_steps = 100 - self._position
|
|
@@ -56,18 +62,22 @@ class TimeBasedCover(BaseCover):
|
|
|
56
62
|
self._loop.call_soon_threadsafe(lambda: self.send_state(self.state, self.json_position))
|
|
57
63
|
return
|
|
58
64
|
|
|
65
|
+
# Calculate actual duration based on remaining distance
|
|
66
|
+
# duration is full time for 100% movement, scale it by actual distance to travel
|
|
67
|
+
actual_duration = duration * (total_steps / 100.0)
|
|
68
|
+
|
|
59
69
|
relay.turn_on()
|
|
60
70
|
start_time = time.monotonic()
|
|
61
71
|
|
|
62
72
|
while not self._stop_event.is_set():
|
|
63
73
|
current_time = time.monotonic() # Pobierz aktualny czas tylko raz na iterację
|
|
64
74
|
elapsed_time = (current_time - start_time) * 1000 # Konwersja na milisekundy
|
|
65
|
-
progress = elapsed_time /
|
|
75
|
+
progress = elapsed_time / actual_duration if actual_duration > 0 else 1.0
|
|
66
76
|
|
|
67
77
|
if direction == OPEN:
|
|
68
|
-
self._position = min(100.0, self._initial_position + progress *
|
|
78
|
+
self._position = min(100.0, self._initial_position + progress * total_steps)
|
|
69
79
|
elif direction == CLOSE:
|
|
70
|
-
self._position = max(0.0, self._initial_position - progress *
|
|
80
|
+
self._position = max(0.0, self._initial_position - progress * total_steps)
|
|
71
81
|
|
|
72
82
|
self._last_timestamp = current_time # Użyj pobranego czasu
|
|
73
83
|
if current_time - self._last_update_time >= 1:
|
|
@@ -97,6 +97,10 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
97
97
|
)
|
|
98
98
|
return
|
|
99
99
|
|
|
100
|
+
# Calculate actual duration based on remaining distance
|
|
101
|
+
# duration is full time for 100% movement, scale it by actual distance to travel
|
|
102
|
+
actual_duration = duration * (total_steps / 100.0)
|
|
103
|
+
|
|
100
104
|
relay.turn_on()
|
|
101
105
|
start_time = time.monotonic()
|
|
102
106
|
progress = 0.0
|
|
@@ -116,15 +120,15 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
116
120
|
|
|
117
121
|
|
|
118
122
|
if elapsed_time < needed_tilt_duration:
|
|
119
|
-
tilt_progress = elapsed_time / needed_tilt_duration
|
|
123
|
+
tilt_progress = elapsed_time / needed_tilt_duration if needed_tilt_duration > 0 else 1.0
|
|
120
124
|
progress = 0.0
|
|
121
125
|
else:
|
|
122
126
|
tilt_progress = 1.0
|
|
123
|
-
progress = (elapsed_time - needed_tilt_duration) /
|
|
127
|
+
progress = (elapsed_time - needed_tilt_duration) / actual_duration if actual_duration > 0 else 1.0
|
|
124
128
|
|
|
125
129
|
if direction == OPEN:
|
|
126
130
|
# Obliczanie _position dla kierunku OPEN
|
|
127
|
-
self._position = min(100.0, self._initial_position + progress *
|
|
131
|
+
self._position = min(100.0, self._initial_position + progress * total_steps)
|
|
128
132
|
|
|
129
133
|
# Obliczanie _tilt_position dla kierunku OPEN
|
|
130
134
|
if target_tilt_position is not None:
|
|
@@ -135,7 +139,7 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
135
139
|
)
|
|
136
140
|
elif direction == CLOSE:
|
|
137
141
|
# Obliczanie _position dla kierunku CLOSE
|
|
138
|
-
self._position = max(0.0, self._initial_position - progress *
|
|
142
|
+
self._position = max(0.0, self._initial_position - progress * total_steps)
|
|
139
143
|
|
|
140
144
|
# Obliczanie _tilt_position dla kierunku CLOSE
|
|
141
145
|
if target_tilt_position is not None:
|
|
@@ -54,9 +54,9 @@ class GpioInputBinarySensor(GpioBaseClass):
|
|
|
54
54
|
_LOGGER.debug("Configured binary sensor %s on pin %s (inverted=%s)",
|
|
55
55
|
self._name, self._pin, inverted)
|
|
56
56
|
|
|
57
|
-
# Send initial state if requested
|
|
57
|
+
# Send initial state if requested - register callback to run after GPIO manager starts
|
|
58
58
|
if kwargs.get("initial_send", False):
|
|
59
|
-
|
|
59
|
+
gpio_manager.register_on_start_callback(self._send_initial_state)
|
|
60
60
|
|
|
61
61
|
def _send_initial_state(self) -> None:
|
|
62
62
|
"""Send initial state after setup."""
|
|
@@ -39,6 +39,10 @@ class ClickState:
|
|
|
39
39
|
# Sequence tracking
|
|
40
40
|
last_click_type: str | None = None
|
|
41
41
|
last_click_time: float | None = None
|
|
42
|
+
# Exclusive mode: pending click waiting for sequence window
|
|
43
|
+
pending_click_type: str | None = None
|
|
44
|
+
pending_click_duration: float | None = None
|
|
45
|
+
pending_click_timer: asyncio.TimerHandle | None = None
|
|
42
46
|
|
|
43
47
|
|
|
44
48
|
@dataclass
|
|
@@ -64,6 +68,9 @@ class MultiClickDetector:
|
|
|
64
68
|
multiclick_window_ms: float = 220.0,
|
|
65
69
|
hold_threshold_ms: float = 400.0,
|
|
66
70
|
sequence_window_ms: float = DEFAULT_SEQUENCE_WINDOW_MS,
|
|
71
|
+
sequence_mode: str = "immediate",
|
|
72
|
+
enabled_sequences: set[str] | None = None,
|
|
73
|
+
enable_triple_click: bool = False,
|
|
67
74
|
name: str = "unknown",
|
|
68
75
|
pin: str = "unknown",
|
|
69
76
|
):
|
|
@@ -76,6 +83,9 @@ class MultiClickDetector:
|
|
|
76
83
|
multiclick_window_ms: Window for double-click detection
|
|
77
84
|
hold_threshold_ms: Time threshold for long press
|
|
78
85
|
sequence_window_ms: Window for sequence detection (e.g., double_then_long)
|
|
86
|
+
sequence_mode: 'immediate' (default) or 'exclusive'
|
|
87
|
+
enabled_sequences: Set of enabled sequence types (e.g., {'double_then_long'})
|
|
88
|
+
enable_triple_click: Enable triple click detection (default: False)
|
|
79
89
|
name: Name of the input
|
|
80
90
|
pin: Pin name for logging
|
|
81
91
|
"""
|
|
@@ -85,9 +95,23 @@ class MultiClickDetector:
|
|
|
85
95
|
self._multiclick_window = multiclick_window_ms / 1000.0
|
|
86
96
|
self._hold_threshold = hold_threshold_ms / 1000.0
|
|
87
97
|
self._sequence_window = sequence_window_ms / 1000.0
|
|
98
|
+
self._sequence_mode = sequence_mode
|
|
99
|
+
self._enabled_sequences = enabled_sequences or set()
|
|
100
|
+
self._enable_triple_click = enable_triple_click
|
|
88
101
|
self._name = name
|
|
89
102
|
self._pin = pin
|
|
90
103
|
self._state = ClickState()
|
|
104
|
+
|
|
105
|
+
# Pre-compute which click types should be delayed in exclusive mode
|
|
106
|
+
# based on enabled sequences
|
|
107
|
+
self._delay_click_types: set[str] = set()
|
|
108
|
+
if sequence_mode == "exclusive" and self._enabled_sequences:
|
|
109
|
+
for seq in self._enabled_sequences:
|
|
110
|
+
# Find which click type starts this sequence
|
|
111
|
+
for (first, _second), seq_name in CLICK_SEQUENCES.items():
|
|
112
|
+
if seq_name == seq:
|
|
113
|
+
self._delay_click_types.add(first)
|
|
114
|
+
break
|
|
91
115
|
|
|
92
116
|
def _finalize_clicks(self) -> None:
|
|
93
117
|
"""Finalize a multi-click sequence."""
|
|
@@ -100,8 +124,18 @@ class MultiClickDetector:
|
|
|
100
124
|
click_type = DOUBLE
|
|
101
125
|
_LOGGER.info("Detected DOUBLE click on %s (%s)", self._name, self._pin)
|
|
102
126
|
elif count == 3:
|
|
103
|
-
|
|
104
|
-
|
|
127
|
+
if self._enable_triple_click:
|
|
128
|
+
click_type = TRIPLE
|
|
129
|
+
_LOGGER.info("Detected TRIPLE click on %s (%s)", self._name, self._pin)
|
|
130
|
+
else:
|
|
131
|
+
# Triple click disabled - emit double + single instead
|
|
132
|
+
_LOGGER.info("Triple click disabled on %s (%s), emitting DOUBLE + SINGLE", self._name, self._pin)
|
|
133
|
+
self._state.click_count = 0
|
|
134
|
+
self._state.finalizer = None
|
|
135
|
+
self._state.finalizer_scheduled_loop_ts = None
|
|
136
|
+
self._emit_click(DOUBLE, None)
|
|
137
|
+
self._emit_click(SINGLE, None)
|
|
138
|
+
return
|
|
105
139
|
else:
|
|
106
140
|
click_type = SINGLE # Fallback for 4+ clicks
|
|
107
141
|
_LOGGER.info("Detected %d clicks on %s (%s), treating as SINGLE", count, self._name, self._pin)
|
|
@@ -116,12 +150,22 @@ class MultiClickDetector:
|
|
|
116
150
|
def _emit_click(self, click_type: ClickTypes, duration: float | None) -> None:
|
|
117
151
|
"""Emit a click event, checking for sequences first.
|
|
118
152
|
|
|
153
|
+
In 'immediate' mode: emit events immediately, sequences are additional.
|
|
154
|
+
In 'exclusive' mode: delay single/double, if sequence detected only emit sequence.
|
|
155
|
+
|
|
119
156
|
Args:
|
|
120
157
|
click_type: The detected click type (single, double, triple, long)
|
|
121
158
|
duration: Duration of the click (for long press)
|
|
122
159
|
"""
|
|
123
160
|
current_time = self._loop.time()
|
|
124
161
|
|
|
162
|
+
if self._sequence_mode == "exclusive":
|
|
163
|
+
self._emit_click_exclusive(click_type, duration, current_time)
|
|
164
|
+
else:
|
|
165
|
+
self._emit_click_immediate(click_type, duration, current_time)
|
|
166
|
+
|
|
167
|
+
def _emit_click_immediate(self, click_type: ClickTypes, duration: float | None, current_time: float) -> None:
|
|
168
|
+
"""Immediate mode: emit events immediately, sequences are additional."""
|
|
125
169
|
# Check if this click forms a sequence with the previous one
|
|
126
170
|
sequence_type = self._check_sequence(click_type, current_time)
|
|
127
171
|
if sequence_type:
|
|
@@ -144,6 +188,138 @@ class MultiClickDetector:
|
|
|
144
188
|
self._state.last_click_type = click_type
|
|
145
189
|
self._state.last_click_time = current_time
|
|
146
190
|
|
|
191
|
+
def _emit_click_exclusive(self, click_type: ClickTypes, duration: float | None, current_time: float) -> None:
|
|
192
|
+
"""Exclusive mode: delay single/double, if sequence detected only emit sequence.
|
|
193
|
+
|
|
194
|
+
Logic:
|
|
195
|
+
- For single/double: store as pending, start timer for sequence_window
|
|
196
|
+
- For long/single: check if pending exists, if so check for sequence
|
|
197
|
+
- Timer expiry: emit the pending click
|
|
198
|
+
|
|
199
|
+
Supported sequences:
|
|
200
|
+
- double_then_long: double (pending) + long
|
|
201
|
+
- single_then_long: single (pending) + long
|
|
202
|
+
- double_then_single: double (pending) + single
|
|
203
|
+
"""
|
|
204
|
+
# Check if there's a pending click and this could form a sequence
|
|
205
|
+
if self._state.pending_click_type:
|
|
206
|
+
# Check if we can form a sequence with current click
|
|
207
|
+
sequence_key = (self._state.pending_click_type, click_type)
|
|
208
|
+
sequence_type = CLICK_SEQUENCES.get(sequence_key)
|
|
209
|
+
|
|
210
|
+
# Only detect sequences that are actually enabled
|
|
211
|
+
if sequence_type and sequence_type in self._enabled_sequences:
|
|
212
|
+
# Cancel pending timer
|
|
213
|
+
if self._state.pending_click_timer:
|
|
214
|
+
self._state.pending_click_timer.cancel()
|
|
215
|
+
self._state.pending_click_timer = None
|
|
216
|
+
|
|
217
|
+
_LOGGER.info(
|
|
218
|
+
"Detected sequence %s on %s (%s) [exclusive mode]",
|
|
219
|
+
sequence_type.upper(), self._name, self._pin
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Clear pending state
|
|
223
|
+
self._state.pending_click_type = None
|
|
224
|
+
self._state.pending_click_duration = None
|
|
225
|
+
|
|
226
|
+
# Emit only the sequence, not the base events
|
|
227
|
+
try:
|
|
228
|
+
self._callback(cast(ClickTypes, sequence_type), duration)
|
|
229
|
+
except Exception as exc:
|
|
230
|
+
_LOGGER.error("Error in sequence callback for %s: %s", self._name, exc, exc_info=True)
|
|
231
|
+
|
|
232
|
+
# Clear sequence tracking
|
|
233
|
+
self._state.last_click_type = None
|
|
234
|
+
self._state.last_click_time = None
|
|
235
|
+
return
|
|
236
|
+
else:
|
|
237
|
+
# Sequence not enabled - emit the pending click now and continue
|
|
238
|
+
# Cancel pending timer
|
|
239
|
+
if self._state.pending_click_timer:
|
|
240
|
+
self._state.pending_click_timer.cancel()
|
|
241
|
+
self._state.pending_click_timer = None
|
|
242
|
+
|
|
243
|
+
pending_type = self._state.pending_click_type
|
|
244
|
+
pending_duration = self._state.pending_click_duration
|
|
245
|
+
|
|
246
|
+
_LOGGER.debug(
|
|
247
|
+
"Sequence %s not enabled, emitting pending click %s on %s",
|
|
248
|
+
sequence_type, pending_type, self._name
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
# Clear pending state
|
|
252
|
+
self._state.pending_click_type = None
|
|
253
|
+
self._state.pending_click_duration = None
|
|
254
|
+
|
|
255
|
+
# Emit the pending click
|
|
256
|
+
try:
|
|
257
|
+
self._callback(cast(ClickTypes, pending_type), pending_duration)
|
|
258
|
+
except Exception as exc:
|
|
259
|
+
_LOGGER.error("Error in click callback for %s: %s", self._name, exc, exc_info=True)
|
|
260
|
+
|
|
261
|
+
# Continue to process current click below (don't return)
|
|
262
|
+
|
|
263
|
+
# Only delay click types that can start a configured sequence
|
|
264
|
+
# e.g., if only double_then_long is enabled, only delay 'double', not 'single'
|
|
265
|
+
if click_type in self._delay_click_types:
|
|
266
|
+
# Cancel any existing pending timer
|
|
267
|
+
if self._state.pending_click_timer:
|
|
268
|
+
self._state.pending_click_timer.cancel()
|
|
269
|
+
|
|
270
|
+
# Store pending click
|
|
271
|
+
self._state.pending_click_type = click_type
|
|
272
|
+
self._state.pending_click_duration = duration
|
|
273
|
+
|
|
274
|
+
# Start timer to emit after sequence window
|
|
275
|
+
self._state.pending_click_timer = self._loop.call_later(
|
|
276
|
+
self._sequence_window,
|
|
277
|
+
self._emit_pending_click
|
|
278
|
+
)
|
|
279
|
+
_LOGGER.debug(
|
|
280
|
+
"Pending click %s on %s, waiting %.0fms for sequence",
|
|
281
|
+
click_type, self._name, self._sequence_window * 1000
|
|
282
|
+
)
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
# For long (without pending) or other types: emit immediately
|
|
286
|
+
try:
|
|
287
|
+
self._callback(click_type, duration)
|
|
288
|
+
except Exception as exc:
|
|
289
|
+
_LOGGER.error("Error in click callback for %s: %s", self._name, exc, exc_info=True)
|
|
290
|
+
|
|
291
|
+
# Remember for sequence detection
|
|
292
|
+
self._state.last_click_type = click_type
|
|
293
|
+
self._state.last_click_time = current_time
|
|
294
|
+
|
|
295
|
+
def _emit_pending_click(self) -> None:
|
|
296
|
+
"""Emit the pending click after sequence window expired (exclusive mode)."""
|
|
297
|
+
if not self._state.pending_click_type:
|
|
298
|
+
return
|
|
299
|
+
|
|
300
|
+
click_type = cast(ClickTypes, self._state.pending_click_type)
|
|
301
|
+
duration = self._state.pending_click_duration
|
|
302
|
+
|
|
303
|
+
_LOGGER.debug(
|
|
304
|
+
"Sequence window expired, emitting pending click %s on %s",
|
|
305
|
+
click_type, self._name
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
# Clear pending state
|
|
309
|
+
self._state.pending_click_type = None
|
|
310
|
+
self._state.pending_click_duration = None
|
|
311
|
+
self._state.pending_click_timer = None
|
|
312
|
+
|
|
313
|
+
# Emit the click
|
|
314
|
+
try:
|
|
315
|
+
self._callback(click_type, duration)
|
|
316
|
+
except Exception as exc:
|
|
317
|
+
_LOGGER.error("Error in pending click callback for %s: %s", self._name, exc, exc_info=True)
|
|
318
|
+
|
|
319
|
+
# Remember for sequence detection (in case of chained sequences)
|
|
320
|
+
self._state.last_click_type = click_type
|
|
321
|
+
self._state.last_click_time = self._loop.time()
|
|
322
|
+
|
|
147
323
|
def _check_sequence(self, current_click: ClickTypes, current_time: float) -> ClickTypes | None:
|
|
148
324
|
"""Check if current click forms a sequence with previous click.
|
|
149
325
|
|
|
@@ -166,7 +342,8 @@ class MultiClickDetector:
|
|
|
166
342
|
sequence_key = (self._state.last_click_type, current_click)
|
|
167
343
|
sequence_type = CLICK_SEQUENCES.get(sequence_key)
|
|
168
344
|
|
|
169
|
-
|
|
345
|
+
# Only detect sequences that are actually enabled
|
|
346
|
+
if sequence_type and sequence_type in self._enabled_sequences:
|
|
170
347
|
# Clear sequence state to prevent chaining
|
|
171
348
|
self._state.last_click_type = None
|
|
172
349
|
self._state.last_click_time = None
|
|
@@ -227,6 +404,16 @@ class MultiClickDetector:
|
|
|
227
404
|
self._state.finalizer = None
|
|
228
405
|
self._state.finalizer_scheduled_loop_ts = None
|
|
229
406
|
|
|
407
|
+
# In exclusive mode: if there's a pending click waiting for sequence,
|
|
408
|
+
# cancel its timer - user is continuing the sequence with this press
|
|
409
|
+
if self._sequence_mode == "exclusive" and self._state.pending_click_timer:
|
|
410
|
+
_LOGGER.debug(
|
|
411
|
+
"Cancelling pending click timer for %s - user continuing sequence",
|
|
412
|
+
self._name
|
|
413
|
+
)
|
|
414
|
+
self._state.pending_click_timer.cancel()
|
|
415
|
+
self._state.pending_click_timer = None
|
|
416
|
+
|
|
230
417
|
# Schedule a check for a long press
|
|
231
418
|
scheduled_at = self._loop.time()
|
|
232
419
|
self._state.long_press_scheduled_loop_ts = scheduled_at
|
|
@@ -65,6 +65,30 @@ class GpioEventButton(GpioBaseClass):
|
|
|
65
65
|
DEFAULT_SEQUENCE_WINDOW_MS
|
|
66
66
|
)
|
|
67
67
|
|
|
68
|
+
# Determine which sequences are enabled based on configured actions OR mqtt_sequences
|
|
69
|
+
# A sequence is enabled if it has actions defined OR is set to publish to MQTT
|
|
70
|
+
enabled_sequences: set[str] = set()
|
|
71
|
+
sequence_types = {'double_then_long', 'single_then_long', 'double_then_single'}
|
|
72
|
+
|
|
73
|
+
# Check actions
|
|
74
|
+
actions = kwargs.get('actions', {})
|
|
75
|
+
if isinstance(actions, dict):
|
|
76
|
+
for seq_type in sequence_types:
|
|
77
|
+
if seq_type in actions and actions[seq_type]:
|
|
78
|
+
enabled_sequences.add(seq_type)
|
|
79
|
+
|
|
80
|
+
# Check mqtt_sequences
|
|
81
|
+
mqtt_sequences = kwargs.get('mqtt_sequences', {})
|
|
82
|
+
if isinstance(mqtt_sequences, dict):
|
|
83
|
+
for seq_type in sequence_types:
|
|
84
|
+
if mqtt_sequences.get(seq_type):
|
|
85
|
+
enabled_sequences.add(seq_type)
|
|
86
|
+
|
|
87
|
+
_LOGGER.debug("Enabled sequences for %s: %s", self._name, enabled_sequences)
|
|
88
|
+
|
|
89
|
+
# Get enable_triple_click setting (default: False)
|
|
90
|
+
enable_triple_click = kwargs.get('enable_triple_click', False)
|
|
91
|
+
|
|
68
92
|
# Create multiclick detector
|
|
69
93
|
self._detector = MultiClickDetector(
|
|
70
94
|
loop=self._loop,
|
|
@@ -73,6 +97,9 @@ class GpioEventButton(GpioBaseClass):
|
|
|
73
97
|
multiclick_window_ms=double_click_duration,
|
|
74
98
|
hold_threshold_ms=long_press_duration,
|
|
75
99
|
sequence_window_ms=sequence_window_duration,
|
|
100
|
+
sequence_mode=self._sequence_mode,
|
|
101
|
+
enabled_sequences=enabled_sequences,
|
|
102
|
+
enable_triple_click=enable_triple_click,
|
|
76
103
|
name=self._name,
|
|
77
104
|
pin=self._pin,
|
|
78
105
|
)
|
|
@@ -116,6 +143,10 @@ class GpioEventButton(GpioBaseClass):
|
|
|
116
143
|
double_click_duration: int | float | None = None,
|
|
117
144
|
long_press_duration: int | float | None = None,
|
|
118
145
|
sequence_window_duration: int | float | None = None,
|
|
146
|
+
sequence_mode: str | None = None,
|
|
147
|
+
actions: dict | None = None,
|
|
148
|
+
mqtt_sequences: dict | None = None,
|
|
149
|
+
enable_triple_click: bool | None = None,
|
|
119
150
|
) -> None:
|
|
120
151
|
"""Update timing parameters for click detection.
|
|
121
152
|
|
|
@@ -126,7 +157,13 @@ class GpioEventButton(GpioBaseClass):
|
|
|
126
157
|
double_click_duration: Time window in ms to detect double click
|
|
127
158
|
long_press_duration: Time in ms to detect long press
|
|
128
159
|
sequence_window_duration: Time window in ms to detect sequences
|
|
160
|
+
sequence_mode: 'immediate' or 'exclusive'
|
|
161
|
+
actions: Actions dict to determine enabled sequences
|
|
162
|
+
mqtt_sequences: MQTT sequences dict to determine enabled sequences
|
|
163
|
+
enable_triple_click: Enable triple click detection
|
|
129
164
|
"""
|
|
165
|
+
from boneio.const import CLICK_SEQUENCES
|
|
166
|
+
|
|
130
167
|
if double_click_duration is not None:
|
|
131
168
|
value_ms = _to_milliseconds(double_click_duration, DEFAULT_DOUBLE_CLICK_DURATION_MS)
|
|
132
169
|
self._detector._multiclick_window = value_ms / 1000.0
|
|
@@ -140,4 +177,40 @@ class GpioEventButton(GpioBaseClass):
|
|
|
140
177
|
if sequence_window_duration is not None:
|
|
141
178
|
value_ms = _to_milliseconds(sequence_window_duration, DEFAULT_SEQUENCE_WINDOW_MS)
|
|
142
179
|
self._detector._sequence_window = value_ms / 1000.0
|
|
143
|
-
_LOGGER.debug("Updated sequence_window_duration to %dms for %s", value_ms, self._name)
|
|
180
|
+
_LOGGER.debug("Updated sequence_window_duration to %dms for %s", value_ms, self._name)
|
|
181
|
+
|
|
182
|
+
if sequence_mode is not None:
|
|
183
|
+
self._sequence_mode = sequence_mode
|
|
184
|
+
self._detector._sequence_mode = sequence_mode
|
|
185
|
+
_LOGGER.debug("Updated sequence_mode to %s for %s", sequence_mode, self._name)
|
|
186
|
+
|
|
187
|
+
if enable_triple_click is not None:
|
|
188
|
+
self._detector._enable_triple_click = enable_triple_click
|
|
189
|
+
_LOGGER.debug("Updated enable_triple_click to %s for %s", enable_triple_click, self._name)
|
|
190
|
+
|
|
191
|
+
# Update enabled sequences based on actions and mqtt_sequences
|
|
192
|
+
sequence_types = {'double_then_long', 'single_then_long', 'double_then_single'}
|
|
193
|
+
enabled_sequences: set[str] = set()
|
|
194
|
+
|
|
195
|
+
if actions is not None and isinstance(actions, dict):
|
|
196
|
+
for seq_type in sequence_types:
|
|
197
|
+
if seq_type in actions and actions[seq_type]:
|
|
198
|
+
enabled_sequences.add(seq_type)
|
|
199
|
+
|
|
200
|
+
if mqtt_sequences is not None and isinstance(mqtt_sequences, dict):
|
|
201
|
+
for seq_type in sequence_types:
|
|
202
|
+
if mqtt_sequences.get(seq_type):
|
|
203
|
+
enabled_sequences.add(seq_type)
|
|
204
|
+
|
|
205
|
+
if actions is not None or mqtt_sequences is not None:
|
|
206
|
+
self._detector._enabled_sequences = enabled_sequences
|
|
207
|
+
|
|
208
|
+
# Recompute delay_click_types
|
|
209
|
+
self._detector._delay_click_types = set()
|
|
210
|
+
if self._detector._sequence_mode == "exclusive" and enabled_sequences:
|
|
211
|
+
for seq in enabled_sequences:
|
|
212
|
+
for (first, _second), seq_name in CLICK_SEQUENCES.items():
|
|
213
|
+
if seq_name == seq:
|
|
214
|
+
self._detector._delay_click_types.add(first)
|
|
215
|
+
break
|
|
216
|
+
_LOGGER.debug("Updated enabled_sequences to %s for %s", enabled_sequences, self._name)
|
|
@@ -146,7 +146,7 @@ class ConfigHelper:
|
|
|
146
146
|
return "https" if self._proxy_port else "http"
|
|
147
147
|
|
|
148
148
|
@property
|
|
149
|
-
def
|
|
149
|
+
def web_configuration_port(self) -> int:
|
|
150
150
|
"""Get port for HA discovery URL. Uses proxy_port if set, otherwise web_port."""
|
|
151
151
|
return self._proxy_port if self._proxy_port else self._web_port
|
|
152
152
|
|
|
@@ -216,7 +216,7 @@ class CoverManager:
|
|
|
216
216
|
restored_state=restored_state,
|
|
217
217
|
tilt_duration=tilt_duration,
|
|
218
218
|
actuator_activation_duration=config.get("actuator_activation_duration", TimePeriod(milliseconds=0)),
|
|
219
|
-
**{k: v for k, v in config.items() if k not in ("platform", "actuator_activation_duration", "tilt_duration", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
|
|
219
|
+
**{k: v for k, v in config.items() if k not in ("id", "platform", "actuator_activation_duration", "tilt_duration", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
|
|
220
220
|
)
|
|
221
221
|
availability_msg_func = ha_cover_with_tilt_availabilty_message
|
|
222
222
|
elif platform == "time_based":
|
|
@@ -236,7 +236,7 @@ class CoverManager:
|
|
|
236
236
|
event_bus=self._manager._event_bus,
|
|
237
237
|
topic_prefix=self._manager._topic_prefix,
|
|
238
238
|
restored_state=restored_state,
|
|
239
|
-
**{k: v for k, v in config.items() if k not in ("platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
|
|
239
|
+
**{k: v for k, v in config.items() if k not in ("id", "platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
|
|
240
240
|
)
|
|
241
241
|
availability_msg_func = ha_cover_availabilty_message
|
|
242
242
|
elif platform == "previous":
|
|
@@ -256,7 +256,7 @@ class CoverManager:
|
|
|
256
256
|
event_bus=self._manager._event_bus,
|
|
257
257
|
topic_prefix=self._manager._topic_prefix,
|
|
258
258
|
restored_state=restored_state,
|
|
259
|
-
**{k: v for k, v in config.items() if k not in ("platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
|
|
259
|
+
**{k: v for k, v in config.items() if k not in ("id", "platform", RESTORE_STATE, SHOW_HA, DEVICE_CLASS, NAME)},
|
|
260
260
|
)
|
|
261
261
|
availability_msg_func = ha_cover_availabilty_message
|
|
262
262
|
|
|
@@ -190,10 +190,28 @@ class DisplayManager:
|
|
|
190
190
|
|
|
191
191
|
except (GPIOInputException, I2CError) as err:
|
|
192
192
|
_LOGGER.error("Can't configure OLED display: %s", err)
|
|
193
|
+
# Store error in manager for WebUI display
|
|
194
|
+
self._manager._hardware_errors.append({
|
|
195
|
+
'type': 'display',
|
|
196
|
+
'id': 'oled',
|
|
197
|
+
'name': 'OLED Display',
|
|
198
|
+
'address': 0x3C,
|
|
199
|
+
'error': str(err),
|
|
200
|
+
'message': f"OLED display at address 0x3C: {err}",
|
|
201
|
+
})
|
|
193
202
|
except ImportError as err:
|
|
194
203
|
_LOGGER.error("Failed to import OLED modules: %s", err)
|
|
195
204
|
except Exception as err:
|
|
196
205
|
_LOGGER.error("Unexpected error configuring OLED: %s", err)
|
|
206
|
+
# Store error in manager for WebUI display
|
|
207
|
+
self._manager._hardware_errors.append({
|
|
208
|
+
'type': 'display',
|
|
209
|
+
'id': 'oled',
|
|
210
|
+
'name': 'OLED Display',
|
|
211
|
+
'address': 0x3C,
|
|
212
|
+
'error': str(err),
|
|
213
|
+
'message': f"OLED display: {err}",
|
|
214
|
+
})
|
|
197
215
|
|
|
198
216
|
def get_oled(self) -> Any | None:
|
|
199
217
|
"""Get OLED display instance.
|