boneIO 1.5.0__tar.gz → 1.5.0.dev2__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/boneio.egg-info → boneio-1.5.0.dev2}/PKG-INFO +4 -4
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/bonecli.py +1 -4
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/cover/cover.py +2 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/cover/time_based.py +2 -3
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/cover/venetian.py +17 -17
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/input/detectors.py +6 -113
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/input/event.py +5 -13
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/irrigation/controller.py +7 -52
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/output/__init__.py +0 -3
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/output/basic.py +2 -14
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/output/mcp.py +0 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/output/remote.py +2 -4
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/template/gate_cover.py +2 -6
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/const.py +10 -17
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/cloud/registration.py +21 -159
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/config_helper.py +19 -86
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/migrations/__init__.py +1 -81
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/schema_converter.py +3 -35
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/yaml_util.py +169 -396
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/discovery.py +2 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/action_conditions.py +0 -11
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/covers.py +1 -9
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/display.py +2 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/inputs.py +11 -22
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/irrigation.py +4 -4
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/manager.py +40 -80
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/outputs.py +3 -16
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/remote.py +2 -9
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/sensors.py +75 -159
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/templates/__init__.py +0 -4
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/templates/gate_cover.py +11 -53
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/templates.py +10 -40
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/update.py +29 -86
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/lox.py +4 -44
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/mqtt.py +1 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/remote/wled.py +6 -69
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/sensor/system.py +24 -62
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/state/manager.py +1 -26
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/system/host_data.py +2 -8
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/__init__.py +1 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/timeperiod.py +8 -92
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/24x16/config.yaml +0 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/32x10/config.yaml +0 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/48x4/config.yaml +0 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover/config.yaml +0 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover_mix/config.yaml +0 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/expanders/mcp23017.py +13 -80
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/input/manager.py +0 -99
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/i2c/__init__.py +1 -4
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/i2c/bus.py +1 -1
- boneio-1.5.0.dev2/boneio/hardware/onewire/__init__.py +23 -0
- boneio-1.5.0.dev2/boneio/hardware/onewire/bus.py +324 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/onewire/dallas.py +6 -44
- boneio-1.5.0.dev2/boneio/hardware/onewire/ds2482.py +457 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/integration/homeassistant.py +9 -9
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/integration/interlock.py +0 -16
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/integration/lox_template.py +2 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/actions.py +0 -112
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/MANIFEST.sha256 +0 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/bootstrap/boneio-migrate +0 -222
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/runner.py +0 -82
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/client.py +0 -100
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/energy_meters/le-03mw.json +365 -369
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/energy_meters/le-03mwct.json +365 -369
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +1 -6
- boneio-1.5.0.dev2/boneio/modbus/devices/energy_meters/sdm120.json +126 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/energy_meters/sdm630.json +0 -5
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/energy_meters/socomec_e03.json +11 -74
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/energy_meters/socomec_e23.json +18 -124
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/hvac/eht-topventil-plus.json +8 -37
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/hvac/fujitsu-ac.json +2 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/hvac/ventclear.json +3 -8
- boneio-1.5.0.dev2/boneio/modbus/devices/inverters/sofar.json +267 -0
- {boneio-1.5.0/boneio/modbus/devices/hvac → boneio-1.5.0.dev2/boneio/modbus/devices/inverters}/thessla.json +2 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +2 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/other/n4dsc08.json +2 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/other/r4dcb08.json +9 -70
- {boneio-1.5.0/boneio/modbus/devices/hvac → boneio-1.5.0.dev2/boneio/modbus/devices/other}/wanas415.json +2 -5
- boneio-1.5.0.dev2/boneio/modbus/devices/sensors/boneio-edge-temp.json +148 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/sensors/cwt.json +4 -28
- boneio-1.5.0.dev2/boneio/modbus/devices/sensors/dts1964_3f.json +242 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +2 -14
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/sensors/gdfs.json +2 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/sensors/gdfx.json +2 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/sensors/liquid-sensor.json +3 -18
- boneio-1.5.0.dev2/boneio/modbus/devices/sensors/pt100.json +21 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/sensors/sht20.json +4 -27
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/sensors/sht30.json +4 -27
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/base.py +1 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/derived/text.py +1 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/runner.py +3 -17
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/condition.yaml +2 -3
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/remote_devices.yaml +78 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/schema.yaml +62 -72
- boneio-1.5.0.dev2/boneio/version.py +2 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/app.py +4 -64
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/dashboard_cards.py +0 -39
- boneio-1.5.0.dev2/boneio/webui/frontend-dist/assets/ConfigEditor-DVdxuuOd.js +1 -0
- boneio-1.5.0.dev2/boneio/webui/frontend-dist/assets/aiWizardPrompt-Qk4nus2t.js +2 -0
- boneio-1.5.0.dev2/boneio/webui/frontend-dist/assets/index-Bz9etcWZ.js +130 -0
- boneio-1.5.0.dev2/boneio/webui/frontend-dist/assets/index-CJECcrbK.css +2 -0
- boneio-1.5.0.dev2/boneio/webui/frontend-dist/assets/vendor-pmGLHP0_.js +55 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/index.html +3 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +4 -16
- {boneio-1.5.0/boneio/webui → boneio-1.5.0.dev2/boneio/webui/frontend-dist}/schema/boneio.schema.json +1 -11
- {boneio-1.5.0/boneio/webui → boneio-1.5.0.dev2/boneio/webui/frontend-dist}/schema/config.schema.json +214 -229
- {boneio-1.5.0/boneio/webui → boneio-1.5.0.dev2/boneio/webui/frontend-dist}/schema/event.schema.json +15 -57
- boneio-1.5.0.dev2/boneio/webui/frontend-dist/schema/mcp23017.schema.json +48 -0
- {boneio-1.5.0/boneio/webui → boneio-1.5.0.dev2/boneio/webui/frontend-dist}/schema/modbus_devices.schema.json +1 -10
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/oled.schema.json +1 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/output.schema.json +2 -8
- {boneio-1.5.0/boneio/webui → boneio-1.5.0.dev2/boneio/webui/frontend-dist}/schema/remote_devices.schema.json +144 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/sensor.schema.json +19 -1
- boneio-1.5.0.dev2/boneio/webui/frontend-dist/sw.js +1 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/middleware/auth.py +0 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/__init__.py +0 -7
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/auth.py +3 -13
- boneio-1.5.0.dev2/boneio/webui/routes/config.py +1415 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/dashboard.py +35 -33
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/modbus.py +3 -122
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/outputs.py +0 -22
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/remote_devices.py +0 -36
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/sensors.py +0 -76
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/system.py +12 -489
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/timezone_sudoers.py +2 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/tools.py +1 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/update.py +10 -35
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/binary_sensor.schema.json +4 -16
- {boneio-1.5.0/boneio/webui/frontend-dist → boneio-1.5.0.dev2/boneio/webui}/schema/boneio.schema.json +1 -11
- {boneio-1.5.0/boneio/webui/frontend-dist → boneio-1.5.0.dev2/boneio/webui}/schema/config.schema.json +214 -229
- {boneio-1.5.0/boneio/webui/frontend-dist → boneio-1.5.0.dev2/boneio/webui}/schema/event.schema.json +15 -57
- boneio-1.5.0.dev2/boneio/webui/schema/mcp23017.schema.json +48 -0
- {boneio-1.5.0/boneio/webui/frontend-dist → boneio-1.5.0.dev2/boneio/webui}/schema/modbus_devices.schema.json +1 -10
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/oled.schema.json +1 -2
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/output.schema.json +2 -8
- {boneio-1.5.0/boneio/webui/frontend-dist → boneio-1.5.0.dev2/boneio/webui}/schema/remote_devices.schema.json +144 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/sensor.schema.json +19 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/web_server.py +1 -1
- {boneio-1.5.0 → boneio-1.5.0.dev2/boneio.egg-info}/PKG-INFO +4 -4
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio.egg-info/SOURCES.txt +10 -73
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio.egg-info/requires.txt +3 -3
- {boneio-1.5.0 → boneio-1.5.0.dev2}/pyproject.toml +3 -3
- boneio-1.5.0/boneio/boards/1.0/input.yaml +0 -202
- boneio-1.5.0/boneio/boards/1.0/output_24_16.yaml +0 -131
- boneio-1.5.0/boneio/boards/1.0/output_32_10.yaml +0 -171
- boneio-1.5.0/boneio/boards/1.0/output_48_4.yaml +0 -254
- boneio-1.5.0/boneio/boards/1.0/output_cover.yaml +0 -171
- boneio-1.5.0/boneio/boards/1.0/output_cover_mix.yaml +0 -171
- boneio-1.5.0/boneio/components/output/buzzer.py +0 -85
- boneio-1.5.0/boneio/core/config/migrations/v4_wled_cache.py +0 -221
- boneio-1.5.0/boneio/core/config/migrations/v5_ina_screen.py +0 -71
- boneio-1.5.0/boneio/core/config/yaml_compat.py +0 -45
- boneio-1.5.0/boneio/core/remote/wled_cache.py +0 -143
- boneio-1.5.0/boneio/hardware/i2c/ina226.py +0 -260
- boneio-1.5.0/boneio/hardware/i2c/ina226_driver.py +0 -309
- boneio-1.5.0/boneio/hardware/onewire/__init__.py +0 -11
- boneio-1.5.0/boneio/migrations/assets/modules-load.d/onewire.conf +0 -2
- boneio-1.5.0/boneio/migrations/assets/wheels/pyyaml-6.0.3-cp313-cp313-linux_armv7l.whl +0 -0
- boneio-1.5.0/boneio/migrations/versions/v1_5_1_ufw_lox_udp.py +0 -32
- boneio-1.5.0/boneio/migrations/versions/v1_5_2_libyaml.py +0 -109
- boneio-1.5.0/boneio/migrations/versions/v1_5_3_libyaml_retry.py +0 -102
- boneio-1.5.0/boneio/migrations/versions/v1_5_4_onewire_modules.py +0 -22
- boneio-1.5.0/boneio/modbus/devices/energy_meters/dts1964_3f.json +0 -247
- boneio-1.5.0/boneio/modbus/devices/energy_meters/sdm120.json +0 -130
- boneio-1.5.0/boneio/modbus/devices/inverters/sofar.json +0 -396
- boneio-1.5.0/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -163
- boneio-1.5.0/boneio/modbus/devices/sensors/pt100.json +0 -33
- boneio-1.5.0/boneio/modbus/devices/sensors/qdw90a.json +0 -46
- boneio-1.5.0/boneio/modbus/mock_coordinator.py +0 -283
- boneio-1.5.0/boneio/version.py +0 -2
- boneio-1.5.0/boneio/webui/frontend-dist/assets/BindingMatrix-nIxlEHTd.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/ConfigEditor-set_Qoo1.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/EditItemDialog-_53aIb2_.js +0 -66
- boneio-1.5.0/boneio/webui/frontend-dist/assets/EntityCard-D74vPKzA.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/EntityGrid-BN3hkCWK.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/FormInputToggle-C3N_UWzy.js +0 -11
- boneio-1.5.0/boneio/webui/frontend-dist/assets/HelpLabel-BSTjOtDA.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/InputsView-B7on4rOh.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/LogViewer-RefUkoWR.js +0 -2
- boneio-1.5.0/boneio/webui/frontend-dist/assets/LongPressWrapper-BHOQV7Wq.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/ModbusView-Dwd3_KJS.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/NodeRedView--ogT6Dbm.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/OutputsView-BxFJRwd4.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/SensorView-C3kPKCFf.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/Sparkline-BGWlVLtt.js +0 -10
- boneio-1.5.0/boneio/webui/frontend-dist/assets/SudoPasswordDialog-DS-3pCx-.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/SystemState-CUmudnMp.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/TemplatesView-CFa1qlRa.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/Tools-CUS0azhR.js +0 -14
- boneio-1.5.0/boneio/webui/frontend-dist/assets/UISettings-BWNODvh7.js +0 -38
- boneio-1.5.0/boneio/webui/frontend-dist/assets/aiConfig-IRYCBmLm.js +0 -2
- boneio-1.5.0/boneio/webui/frontend-dist/assets/aiWizardPrompt-D9OJ-cE7.js +0 -2
- boneio-1.5.0/boneio/webui/frontend-dist/assets/axios-DHUeYRnu.js +0 -10
- boneio-1.5.0/boneio/webui/frontend-dist/assets/basePath-CxHj-SSK.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/clipboard-CCtx29e-.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/configCache-BAkc0Ye7.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/formatters-zOiGPJLh.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/gi-7Mj_ioeM.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/index-FA3V0TxG.css +0 -2
- boneio-1.5.0/boneio/webui/frontend-dist/assets/index-N_Atf1i3.js +0 -6
- boneio-1.5.0/boneio/webui/frontend-dist/assets/longPress-Dx7OCSyP.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/modbusDeviceCatalog-L6as-BKo.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/select-B2YDgQ4X.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/tabs-box-Dj36r4_e.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/utils-C8nShLO6.js +0 -1
- boneio-1.5.0/boneio/webui/frontend-dist/assets/vendor-IzweXARb.js +0 -11
- boneio-1.5.0/boneio/webui/frontend-dist/schema/ina226.schema.json +0 -109
- boneio-1.5.0/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -69
- boneio-1.5.0/boneio/webui/frontend-dist/sw.js +0 -1
- boneio-1.5.0/boneio/webui/hvac_svg_templates.py +0 -240
- boneio-1.5.0/boneio/webui/modbus_card_templates.py +0 -576
- boneio-1.5.0/boneio/webui/routes/config.py +0 -109
- boneio-1.5.0/boneio/webui/routes/config_actions.py +0 -848
- boneio-1.5.0/boneio/webui/routes/config_backups.py +0 -568
- boneio-1.5.0/boneio/webui/routes/config_core.py +0 -486
- boneio-1.5.0/boneio/webui/routes/config_discovery.py +0 -159
- boneio-1.5.0/boneio/webui/routes/config_files.py +0 -147
- boneio-1.5.0/boneio/webui/routes/dev_fake_device.py +0 -703
- boneio-1.5.0/boneio/webui/routes/mqtt_reference.py +0 -365
- boneio-1.5.0/boneio/webui/routes/nodered.py +0 -920
- boneio-1.5.0/boneio/webui/schema/ina226.schema.json +0 -109
- boneio-1.5.0/boneio/webui/schema/mcp23017.schema.json +0 -69
- boneio-1.5.0/boneio/webui/sudo_rate_limiter.py +0 -152
- {boneio-1.5.0 → boneio-1.5.0.dev2}/LICENSE +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/MANIFEST.in +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/README.md +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.7/output_48_4.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.8/output_48_4.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/group/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/group/output_group.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/input/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/input/remote/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/input/remote/base.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/input/remote/esphome.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/irrigation/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/irrigation/water_source.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/output/pca.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/output/pcf.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/template/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/template/alarm_panel.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/cloud/data/docker-compose.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/config/package.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/events/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/events/bus.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/canopen.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/remote_input_registrar.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/templates/alarm.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/composite.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/local.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/remote/base.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/remote/can.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/remote/esphome.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/sensor/base.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/state/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/system/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/system/monitor.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/conditions.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/filter.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/logger.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/core/utils/util.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/48x4/adc.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/48x4/event.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/48x4/mqtt.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/48x4/output48x4A.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/can_master.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/can_slave.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/exceptions.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/can/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/can/bridge.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/can/client.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/can/interface.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/can/node.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/can/node_id.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/can/test_od.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/display/early_oled.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/display/oled.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/gpio/input/base.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/integration/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/docker/daemon.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/docker/nodered/caddy/502.html +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/journald/journald.conf +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/sudoers/boneio +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/systemd/boneio.service +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/bootstrap/install-helper.sh +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/v1_4_3_oled_shutdown.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/v1_4_4_caddy.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/migrations/versions/v1_5_0_fix_oled_fifo_permissions.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/cli.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/modbus/utils.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/models/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/models/actions.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/models/events.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/models/files.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/models/logs.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/models/mqtt.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/models/state.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/actions.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/filters.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/id.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/remote_inputs.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/remote_outputs.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/action_validation.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/css.worker-CvXBzhp8.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/editor.worker-Cn2oRESe.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/html.worker-BO6WuOEO.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/json.worker-BkJRGcCJ.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/monaco-61yH0vfd.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/monaco-Br_kD0ds.css +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/rolldown-runtime-QTnfLwEv.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/ts.worker-B0J26iPs.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-Bd17z0YL.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/assets/yaml.worker-BKRoXlmz.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/frontend-dist/workbox-4918f2f6.js +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/can.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/irrigation.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/migrations.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/can.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/cover.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/irrigation.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/lox_udp.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/remote_inputs.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/remote_outputs.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/template.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/services/logs.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/setup.cfg +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/setup.py +0 -0
- {boneio-1.5.0 → boneio-1.5.0.dev2}/tests/test_py313_compatibility.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boneio
|
|
3
|
-
Version: 1.5.0
|
|
3
|
+
Version: 1.5.0.dev2
|
|
4
4
|
Summary: Python App for BoneIO
|
|
5
5
|
Author-email: Paweł Szafer <pszafer@gmail.com>
|
|
6
6
|
License: GNU General Public License v3.0
|
|
@@ -13,7 +13,7 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: smbus2==0.4.3
|
|
15
15
|
Requires-Dist: aiomqtt==2.4.0
|
|
16
|
-
Requires-Dist: aiohttp==3.
|
|
16
|
+
Requires-Dist: aiohttp==3.13.3
|
|
17
17
|
Requires-Dist: Cerberus==1.3.7
|
|
18
18
|
Requires-Dist: colorlog==6.9.0
|
|
19
19
|
Requires-Dist: luma-core==2.5.1
|
|
@@ -21,11 +21,11 @@ Requires-Dist: luma-oled==3.14.0
|
|
|
21
21
|
Requires-Dist: pymodbus==3.11.3
|
|
22
22
|
Requires-Dist: pyserial-asyncio-fast==0.16
|
|
23
23
|
Requires-Dist: PyYAML==6.0.3
|
|
24
|
-
Requires-Dist: psutil==7.
|
|
24
|
+
Requires-Dist: psutil==7.1.0
|
|
25
25
|
Requires-Dist: w1thermsensor[async]==2.3.0
|
|
26
26
|
Requires-Dist: fastapi==0.118.0
|
|
27
27
|
Requires-Dist: pydantic==2.11.9
|
|
28
|
-
Requires-Dist: hypercorn==0.
|
|
28
|
+
Requires-Dist: hypercorn==0.17.3
|
|
29
29
|
Requires-Dist: websockets==15.0.1
|
|
30
30
|
Requires-Dist: python-jose[cryptography]==3.5.0
|
|
31
31
|
Requires-Dist: python-multipart==0.0.22
|
|
@@ -132,7 +132,7 @@ def get_arguments() -> argparse.Namespace:
|
|
|
132
132
|
set_modbus_parser.add_argument(
|
|
133
133
|
"--device",
|
|
134
134
|
type=str,
|
|
135
|
-
choices=["cwt", "r4dcb08", "liquid-sensor", "
|
|
135
|
+
choices=["cwt", "r4dcb08", "liquid-sensor", "sht20", "sht30", "custom"],
|
|
136
136
|
help="Choose device to set modbus address/baudrate. For custom you must provide --custom-value and --custom-register-address",
|
|
137
137
|
required=True,
|
|
138
138
|
)
|
|
@@ -217,9 +217,6 @@ def run(
|
|
|
217
217
|
_t0 = _time.monotonic()
|
|
218
218
|
setup_logging(debug_level=debug)
|
|
219
219
|
_LOGGER.info("BoneIO %s starting.", __version__)
|
|
220
|
-
from boneio.core.config.yaml_compat import log_yaml_backend
|
|
221
|
-
|
|
222
|
-
log_yaml_backend()
|
|
223
220
|
_LOGGER.debug("[STARTUP TIMING] after setup_logging: %.2fs", _time.monotonic() - _t0)
|
|
224
221
|
|
|
225
222
|
# --- Initialize OLED before anything else (independent of config) ---
|
|
@@ -386,8 +386,8 @@ class BaseCover(BaseCoverABC, BasicMqtt):
|
|
|
386
386
|
**json_position,
|
|
387
387
|
)
|
|
388
388
|
self._event_bus.trigger_event(CoverEvent(entity_id=self.id, state=event))
|
|
389
|
-
self._message_bus.send_message(topic=f"{self._send_topic}/state", payload=state
|
|
390
|
-
self._message_bus.send_message(topic=f"{self._send_topic}/pos", payload=json.dumps(json_position)
|
|
389
|
+
self._message_bus.send_message(topic=f"{self._send_topic}/state", payload=state)
|
|
390
|
+
self._message_bus.send_message(topic=f"{self._send_topic}/pos", payload=json.dumps(json_position))
|
|
391
391
|
|
|
392
392
|
@property
|
|
393
393
|
def saved_position(self) -> SavedPositionDict:
|
|
@@ -12,7 +12,6 @@ from boneio.components.output import BasicOutput
|
|
|
12
12
|
from boneio.const import CLOSE, CLOSING, IDLE, OPEN, OPENING, STOP
|
|
13
13
|
from boneio.core.events import EventBus
|
|
14
14
|
from boneio.core.utils import TimePeriod
|
|
15
|
-
from boneio.core.utils.timeperiod import ensure_time_period
|
|
16
15
|
|
|
17
16
|
_LOGGER = logging.getLogger(__name__)
|
|
18
17
|
DEFAULT_RESTORED_STATE = {"position": 100}
|
|
@@ -152,6 +151,6 @@ class TimeBasedCover(BaseCover):
|
|
|
152
151
|
Keys: open_time, close_time
|
|
153
152
|
"""
|
|
154
153
|
if "open_time" in config:
|
|
155
|
-
self._open_time =
|
|
154
|
+
self._open_time = config["open_time"].total_milliseconds
|
|
156
155
|
if "close_time" in config:
|
|
157
|
-
self._close_time =
|
|
156
|
+
self._close_time = config["close_time"].total_milliseconds
|
|
@@ -8,7 +8,6 @@ import time
|
|
|
8
8
|
from boneio.components.cover.cover import BaseCover, BaseVenetianCoverABC
|
|
9
9
|
from boneio.const import CLOSE, CLOSING, IDLE, OPEN, OPENING, STOP
|
|
10
10
|
from boneio.core.utils import TimePeriod
|
|
11
|
-
from boneio.core.utils.timeperiod import ensure_time_period
|
|
12
11
|
from boneio.models import PositionDict, SavedPositionDict
|
|
13
12
|
|
|
14
13
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -182,12 +181,9 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
182
181
|
self._last_update_time = time.monotonic() # Upewnij się, że aktualizacja jest wysłana na końcu ruchu
|
|
183
182
|
|
|
184
183
|
# Tilt restore: schedule tilt recovery on the event loop.
|
|
185
|
-
# _tilt_before_close is only set by _save_tilt_for_restore() when
|
|
186
|
-
# the appropriate flag (UI or action) was enabled, so its presence
|
|
187
|
-
# is the authoritative signal that restore was requested.
|
|
188
184
|
# Skip when position reached 0% (fully closed) or 100% (fully open)
|
|
189
185
|
# — at extremes, restoring tilt contradicts user intent.
|
|
190
|
-
if self._tilt_before_close is not None:
|
|
186
|
+
if self._tilt_restore_after_close and self._tilt_before_close is not None:
|
|
191
187
|
restore_tilt = self._tilt_before_close
|
|
192
188
|
self._tilt_before_close = None
|
|
193
189
|
at_extreme = self._position <= 0 or self._position >= 100
|
|
@@ -304,8 +300,8 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
304
300
|
def _save_tilt_for_restore(self) -> None:
|
|
305
301
|
"""Save current tilt position for later restoration.
|
|
306
302
|
|
|
307
|
-
Called before any movement
|
|
308
|
-
|
|
303
|
+
Called before any closing movement. Determines whether to save
|
|
304
|
+
based on the call source:
|
|
309
305
|
- UI/HA calls: uses tilt_restore_after_close setting
|
|
310
306
|
- Action calls: uses _action_tilt_restore flag (set by executor)
|
|
311
307
|
"""
|
|
@@ -317,7 +313,7 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
317
313
|
if should_restore and self._tilt_position > 0:
|
|
318
314
|
self._tilt_before_close = self._tilt_position
|
|
319
315
|
_LOGGER.debug(
|
|
320
|
-
"VenetianCover %s: saving tilt=%d%% before
|
|
316
|
+
"VenetianCover %s: saving tilt=%d%% before close",
|
|
321
317
|
self._id,
|
|
322
318
|
round(self._tilt_position),
|
|
323
319
|
)
|
|
@@ -336,22 +332,26 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
336
332
|
async def set_cover_position(self, position: int) -> None:
|
|
337
333
|
"""Set cover position with tilt restore support.
|
|
338
334
|
|
|
339
|
-
|
|
340
|
-
|
|
335
|
+
When moving to a lower position (closing direction) and
|
|
336
|
+
tilt_restore_after_close is enabled, saves the current tilt
|
|
337
|
+
so it can be restored after the movement finishes.
|
|
341
338
|
|
|
342
339
|
Args:
|
|
343
340
|
position: Target position (0-100).
|
|
344
341
|
"""
|
|
345
|
-
self.
|
|
342
|
+
if position < self._position:
|
|
343
|
+
self._save_tilt_for_restore()
|
|
344
|
+
else:
|
|
345
|
+
self._tilt_before_close = None
|
|
346
346
|
await super().set_cover_position(position)
|
|
347
347
|
|
|
348
348
|
async def open(self) -> None:
|
|
349
349
|
"""Open venetian cover.
|
|
350
350
|
|
|
351
|
-
|
|
352
|
-
|
|
351
|
+
Clears any saved tilt-before-close value since opening
|
|
352
|
+
resets the tilt to 100% naturally.
|
|
353
353
|
"""
|
|
354
|
-
self.
|
|
354
|
+
self._tilt_before_close = None
|
|
355
355
|
await super().open()
|
|
356
356
|
|
|
357
357
|
def update_config_times(self, config: dict) -> None:
|
|
@@ -362,11 +362,11 @@ class VenetianCover(BaseCover, BaseVenetianCoverABC):
|
|
|
362
362
|
Keys: open_time, close_time, tilt_duration, tilt_restore_after_close
|
|
363
363
|
"""
|
|
364
364
|
if "open_time" in config:
|
|
365
|
-
self._open_time =
|
|
365
|
+
self._open_time = config["open_time"].total_milliseconds
|
|
366
366
|
if "close_time" in config:
|
|
367
|
-
self._close_time =
|
|
367
|
+
self._close_time = config["close_time"].total_milliseconds
|
|
368
368
|
if "tilt_duration" in config and config["tilt_duration"]:
|
|
369
|
-
self._tilt_duration =
|
|
369
|
+
self._tilt_duration = config["tilt_duration"].total_milliseconds
|
|
370
370
|
if "tilt_restore_after_close" in config:
|
|
371
371
|
self._tilt_restore_after_close = bool(config["tilt_restore_after_close"])
|
|
372
372
|
|
|
@@ -65,9 +65,6 @@ class MultiClickDetector:
|
|
|
65
65
|
Based on multiclick_detector.py from tests.
|
|
66
66
|
"""
|
|
67
67
|
|
|
68
|
-
# How often (in seconds) to verify physical GPIO state during long press
|
|
69
|
-
_GPIO_READBACK_INTERVAL_S = 3.0
|
|
70
|
-
|
|
71
68
|
def __init__(
|
|
72
69
|
self,
|
|
73
70
|
loop: asyncio.AbstractEventLoop,
|
|
@@ -81,7 +78,7 @@ class MultiClickDetector:
|
|
|
81
78
|
enable_triple_click: bool = False,
|
|
82
79
|
name: str = "unknown",
|
|
83
80
|
pin: str = "unknown",
|
|
84
|
-
max_long_press_seconds: float =
|
|
81
|
+
max_long_press_seconds: float = 120.0,
|
|
85
82
|
):
|
|
86
83
|
"""Initialize multiclick detector.
|
|
87
84
|
|
|
@@ -97,7 +94,7 @@ class MultiClickDetector:
|
|
|
97
94
|
enable_triple_click: Enable triple click detection (default: False)
|
|
98
95
|
name: Name of the input
|
|
99
96
|
pin: Pin name for logging
|
|
100
|
-
max_long_press_seconds: Safety timeout for long press in seconds (default:
|
|
97
|
+
max_long_press_seconds: Safety timeout for long press in seconds (default: 120s)
|
|
101
98
|
"""
|
|
102
99
|
self._loop = loop
|
|
103
100
|
self._callback = callback
|
|
@@ -110,19 +107,8 @@ class MultiClickDetector:
|
|
|
110
107
|
self._enable_triple_click = enable_triple_click
|
|
111
108
|
self._name = name
|
|
112
109
|
self._pin = pin
|
|
113
|
-
self._max_long_press_seconds =
|
|
110
|
+
self._max_long_press_seconds = max_long_press_seconds
|
|
114
111
|
self._state = ClickState()
|
|
115
|
-
self._boot_press_suppressed = False # Set by GpioManager._seed_initial_states
|
|
116
|
-
# Optional GPIO readback function: returns True if pin is HIGH (released)
|
|
117
|
-
# Set by GpioManager after startup to enable physical state verification
|
|
118
|
-
self._gpio_readback_fn: Callable[[], bool | None] | None = None
|
|
119
|
-
# Track last readback time to avoid reading GPIO too often
|
|
120
|
-
self._last_readback_time: float = 0.0
|
|
121
|
-
|
|
122
|
-
_LOGGER.debug(
|
|
123
|
-
"MultiClickDetector init: %s (%s) max_long_press=%.1fs",
|
|
124
|
-
name, pin, self._max_long_press_seconds,
|
|
125
|
-
)
|
|
126
112
|
|
|
127
113
|
# Pre-compute which click types should be delayed in exclusive mode
|
|
128
114
|
# based on enabled sequences
|
|
@@ -376,20 +362,15 @@ class MultiClickDetector:
|
|
|
376
362
|
def _detect_long_press(self) -> None:
|
|
377
363
|
"""Detect and report a long press and start periodic updates."""
|
|
378
364
|
if not self._state.last_press_loop_ts:
|
|
379
|
-
_LOGGER.debug(
|
|
380
|
-
"_detect_long_press called for %s but no last_press_loop_ts — ignoring",
|
|
381
|
-
self._name,
|
|
382
|
-
)
|
|
383
365
|
return
|
|
384
366
|
|
|
385
367
|
# Reset executed actions for new long press
|
|
386
368
|
self._state.executed_long_actions = set()
|
|
387
369
|
self._state.last_repeat_times = {}
|
|
388
|
-
self._last_readback_time = self._loop.time() # Reset readback timer
|
|
389
370
|
|
|
390
371
|
duration = self._loop.time() - self._state.last_press_loop_ts
|
|
391
372
|
|
|
392
|
-
_LOGGER.info("Detected LONG press on %s (%s)
|
|
373
|
+
_LOGGER.info("Detected LONG press on %s (%s)", self._name, self._pin)
|
|
393
374
|
|
|
394
375
|
self._state.click_count = 0 # Reset click counter
|
|
395
376
|
self._state.long_press_timer = None
|
|
@@ -403,29 +384,14 @@ class MultiClickDetector:
|
|
|
403
384
|
0.2, # 200ms
|
|
404
385
|
self._send_periodic_long_event
|
|
405
386
|
)
|
|
406
|
-
_LOGGER.debug(
|
|
407
|
-
"Started periodic long timer for %s (interval=200ms, max=%.0fs)",
|
|
408
|
-
self._name, self._max_long_press_seconds,
|
|
409
|
-
)
|
|
410
387
|
|
|
411
388
|
def _send_periodic_long_event(self) -> None:
|
|
412
|
-
"""Send periodic 'long' event with updated duration.
|
|
413
|
-
|
|
414
|
-
Every _GPIO_READBACK_INTERVAL_S seconds, also reads the physical
|
|
415
|
-
GPIO state to detect missed RELEASE edge events.
|
|
416
|
-
"""
|
|
389
|
+
"""Send periodic 'long' event with updated duration."""
|
|
417
390
|
if not self._state.last_press_loop_ts or self._state.last_release_ts:
|
|
418
391
|
# Button released or invalid state
|
|
419
|
-
_LOGGER.debug(
|
|
420
|
-
"Periodic long skipped for %s: press_ts=%s, release_ts=%s",
|
|
421
|
-
self._name,
|
|
422
|
-
self._state.last_press_loop_ts is not None,
|
|
423
|
-
self._state.last_release_ts,
|
|
424
|
-
)
|
|
425
392
|
return
|
|
426
393
|
|
|
427
|
-
|
|
428
|
-
duration = now - self._state.last_press_loop_ts
|
|
394
|
+
duration = self._loop.time() - self._state.last_press_loop_ts
|
|
429
395
|
|
|
430
396
|
# Safety timeout: stop periodic events if duration exceeds max
|
|
431
397
|
if duration > self._max_long_press_seconds:
|
|
@@ -440,35 +406,6 @@ class MultiClickDetector:
|
|
|
440
406
|
self._force_stop_long_press()
|
|
441
407
|
return
|
|
442
408
|
|
|
443
|
-
# GPIO readback check: every _GPIO_READBACK_INTERVAL_S, verify physical
|
|
444
|
-
# pin state to catch missed RELEASE edge events (EMI, kernel bugs, etc.)
|
|
445
|
-
if (
|
|
446
|
-
self._gpio_readback_fn is not None
|
|
447
|
-
and (now - self._last_readback_time) >= self._GPIO_READBACK_INTERVAL_S
|
|
448
|
-
):
|
|
449
|
-
self._last_readback_time = now
|
|
450
|
-
try:
|
|
451
|
-
pin_is_high = self._gpio_readback_fn()
|
|
452
|
-
if pin_is_high is not None and pin_is_high:
|
|
453
|
-
# Pin is HIGH = button released (pull-up), but we never got RISING_EDGE
|
|
454
|
-
_LOGGER.warning(
|
|
455
|
-
"GPIO readback: %s (%s) pin is HIGH (released) but no RELEASE event received! "
|
|
456
|
-
"duration=%.1fs. Forcing stop — likely missed RISING_EDGE.",
|
|
457
|
-
self._name,
|
|
458
|
-
self._pin,
|
|
459
|
-
duration,
|
|
460
|
-
)
|
|
461
|
-
self._force_stop_long_press()
|
|
462
|
-
return
|
|
463
|
-
_LOGGER.debug(
|
|
464
|
-
"GPIO readback: %s (%s) pin is LOW (still pressed), duration=%.1fs",
|
|
465
|
-
self._name, self._pin, duration,
|
|
466
|
-
)
|
|
467
|
-
except Exception as exc:
|
|
468
|
-
_LOGGER.debug(
|
|
469
|
-
"GPIO readback failed for %s: %s", self._name, exc,
|
|
470
|
-
)
|
|
471
|
-
|
|
472
409
|
_LOGGER.debug(
|
|
473
410
|
"Periodic long event on %s (%s), duration=%.3fs",
|
|
474
411
|
self._name,
|
|
@@ -554,21 +491,6 @@ class MultiClickDetector:
|
|
|
554
491
|
)
|
|
555
492
|
return
|
|
556
493
|
|
|
557
|
-
# Boot-press suppression: if GpioManager detected this pin was
|
|
558
|
-
# LOW at startup, the first FALLING_EDGE is a phantom boot event.
|
|
559
|
-
# Record the timestamp (for debounce) but do NOT schedule timers.
|
|
560
|
-
if self._boot_press_suppressed:
|
|
561
|
-
_LOGGER.info(
|
|
562
|
-
"Suppressing phantom boot press on %s (%s) — recording timestamp only",
|
|
563
|
-
self._name,
|
|
564
|
-
self._pin,
|
|
565
|
-
)
|
|
566
|
-
self._state.last_press_ts = timestamp_s
|
|
567
|
-
self._state.last_press_loop_ts = None
|
|
568
|
-
self._state.last_release_ts = None
|
|
569
|
-
self._boot_press_suppressed = False
|
|
570
|
-
return
|
|
571
|
-
|
|
572
494
|
_LOGGER.debug("PRESSED: %s (%s)", self._name, self._pin)
|
|
573
495
|
self._state.last_press_ts = timestamp_s
|
|
574
496
|
self._state.last_press_loop_ts = self._loop.time() # Store loop time for duration calc
|
|
@@ -630,35 +552,6 @@ class MultiClickDetector:
|
|
|
630
552
|
|
|
631
553
|
press_duration_ms = (timestamp_s - self._state.last_press_ts) * 1000 if self._state.last_press_ts else 0
|
|
632
554
|
_LOGGER.debug("RELEASED: %s (%s) after %.1f ms", self._name, self._pin, press_duration_ms)
|
|
633
|
-
|
|
634
|
-
# Guard: stale release from phantom press at boot.
|
|
635
|
-
# If time since press exceeds max_long_press_seconds, the press
|
|
636
|
-
# was a startup artifact (GPIO settling at boot), not a real user
|
|
637
|
-
# action. Reset the detector so the next real press is accepted.
|
|
638
|
-
if self._state.last_press_ts and press_duration_ms > self._max_long_press_seconds * 1000:
|
|
639
|
-
_LOGGER.warning(
|
|
640
|
-
"Stale release on %s (%s): %.1fs since press exceeds max %.0fs. "
|
|
641
|
-
"Likely phantom press from boot. Resetting detector.",
|
|
642
|
-
self._name,
|
|
643
|
-
self._pin,
|
|
644
|
-
press_duration_ms / 1000,
|
|
645
|
-
self._max_long_press_seconds,
|
|
646
|
-
)
|
|
647
|
-
self._state.last_press_ts = None
|
|
648
|
-
self._state.last_press_loop_ts = None
|
|
649
|
-
self._state.last_release_ts = timestamp_s
|
|
650
|
-
self._state.click_count = 0
|
|
651
|
-
if self._state.long_press_timer:
|
|
652
|
-
self._state.long_press_timer.cancel()
|
|
653
|
-
self._state.long_press_timer = None
|
|
654
|
-
self._state.long_press_scheduled_loop_ts = None
|
|
655
|
-
if self._state.long_hold_periodic_timer:
|
|
656
|
-
self._state.long_hold_periodic_timer.cancel()
|
|
657
|
-
self._state.long_hold_periodic_timer = None
|
|
658
|
-
self._state.executed_long_actions = set()
|
|
659
|
-
self._state.last_repeat_times = {}
|
|
660
|
-
return
|
|
661
|
-
|
|
662
555
|
self._state.last_release_ts = timestamp_s
|
|
663
556
|
|
|
664
557
|
_LOGGER.debug(
|
|
@@ -80,32 +80,24 @@ class GpioEventButton(GpioBaseClass):
|
|
|
80
80
|
# Get enable_triple_click setting (default: False)
|
|
81
81
|
enable_triple_click = kwargs.get("enable_triple_click", False)
|
|
82
82
|
|
|
83
|
-
# Safety timeout for long press (default:
|
|
83
|
+
# Safety timeout for long press (default: 120s)
|
|
84
84
|
max_long_press_seconds = (
|
|
85
85
|
_to_milliseconds(
|
|
86
86
|
kwargs.get("max_long_press_duration"),
|
|
87
|
-
|
|
87
|
+
120 * 1000, # 120s default
|
|
88
88
|
)
|
|
89
89
|
/ 1000.0
|
|
90
90
|
)
|
|
91
|
-
#
|
|
92
|
-
if max_long_press_seconds > 30.0:
|
|
93
|
-
_LOGGER.info(
|
|
94
|
-
"max_long_press_duration for %s clamped from %.1fs to 30s (hard max)",
|
|
95
|
-
kwargs.get("name", "unknown"),
|
|
96
|
-
max_long_press_seconds,
|
|
97
|
-
)
|
|
98
|
-
max_long_press_seconds = 30.0
|
|
99
|
-
# Guard: if resolved to < 0.8s (misconfigured or zero), use default 30s
|
|
91
|
+
# Guard: if resolved to < 0.8s (misconfigured or zero), use default 120s
|
|
100
92
|
if max_long_press_seconds < 0.8:
|
|
101
93
|
raw = kwargs.get("max_long_press_duration")
|
|
102
94
|
if raw is not None:
|
|
103
95
|
_LOGGER.warning(
|
|
104
|
-
"max_long_press_duration for %s resolved to %.1fs (too small), using default
|
|
96
|
+
"max_long_press_duration for %s resolved to %.1fs (too small), using default 120s",
|
|
105
97
|
kwargs.get("name", "unknown"),
|
|
106
98
|
max_long_press_seconds,
|
|
107
99
|
)
|
|
108
|
-
max_long_press_seconds =
|
|
100
|
+
max_long_press_seconds = 120.0
|
|
109
101
|
_LOGGER.debug(
|
|
110
102
|
"max_long_press_seconds for %s = %.1fs",
|
|
111
103
|
kwargs.get("name", "unknown"),
|
|
@@ -113,7 +113,6 @@ class IrrigationController:
|
|
|
113
113
|
self._schedule = schedule or []
|
|
114
114
|
self._water_sources = water_sources or []
|
|
115
115
|
self._active_water_source_idx: int = 0
|
|
116
|
-
self._running_water_source: WaterSource | None = None
|
|
117
116
|
self._valve_open_delay_s = max(0, valve_open_delay_s)
|
|
118
117
|
self._valve_overlap_s = max(0, valve_overlap_s)
|
|
119
118
|
self._standby = standby
|
|
@@ -420,12 +419,6 @@ class IrrigationController:
|
|
|
420
419
|
)
|
|
421
420
|
|
|
422
421
|
async def shutdown(self) -> None:
|
|
423
|
-
"""Stop the active irrigation cycle without killing schedule tasks.
|
|
424
|
-
|
|
425
|
-
This method is safe to call from within a schedule task — it does NOT
|
|
426
|
-
cancel schedule loops. Use :meth:`full_stop` to tear down the
|
|
427
|
-
controller completely (including schedule tasks).
|
|
428
|
-
"""
|
|
429
422
|
_LOGGER.debug(
|
|
430
423
|
"Irrigation %s shutdown called (state=%s, active_zone=%s). Caller: %s",
|
|
431
424
|
self.id,
|
|
@@ -433,10 +426,10 @@ class IrrigationController:
|
|
|
433
426
|
self._active_zone_idx,
|
|
434
427
|
"".join(traceback.format_stack(limit=5)),
|
|
435
428
|
)
|
|
429
|
+
self.stop_schedules()
|
|
436
430
|
self._cancel_pause_timer()
|
|
437
431
|
await self._stop_current_zone()
|
|
438
432
|
await self._handle_pump_stop_sequence()
|
|
439
|
-
self._running_water_source = None
|
|
440
433
|
self._state = ControllerState.IDLE
|
|
441
434
|
self._active_zone_idx = None
|
|
442
435
|
self._active_zone_remaining_s = None
|
|
@@ -444,16 +437,6 @@ class IrrigationController:
|
|
|
444
437
|
self._single_zone_target_idx = None
|
|
445
438
|
await self.publish_all_states()
|
|
446
439
|
|
|
447
|
-
async def full_stop(self) -> None:
|
|
448
|
-
"""Fully stop the controller including schedule tasks.
|
|
449
|
-
|
|
450
|
-
Should only be called by the IrrigationManager when stopping
|
|
451
|
-
or reloading controllers — never from within a schedule task.
|
|
452
|
-
"""
|
|
453
|
-
_LOGGER.info("Irrigation %s full_stop: stopping schedules and active cycle", self.id)
|
|
454
|
-
self.stop_schedules()
|
|
455
|
-
await self.shutdown()
|
|
456
|
-
|
|
457
440
|
async def pause(self) -> None:
|
|
458
441
|
if self._state != ControllerState.RUNNING or self._active_zone_idx is None:
|
|
459
442
|
return
|
|
@@ -652,7 +635,7 @@ class IrrigationController:
|
|
|
652
635
|
await self._stop_current_zone()
|
|
653
636
|
|
|
654
637
|
# Handle valve_open_delay between zones
|
|
655
|
-
src = self.
|
|
638
|
+
src = self.active_water_source
|
|
656
639
|
if self._valve_open_delay_s > 0:
|
|
657
640
|
if src and src.pump_switch_off_during_valve_open_delay:
|
|
658
641
|
await self._deactivate_source()
|
|
@@ -820,17 +803,12 @@ class IrrigationController:
|
|
|
820
803
|
async def _activate_source(self) -> bool:
|
|
821
804
|
"""Turn ON all outputs of the active water source.
|
|
822
805
|
|
|
823
|
-
Locks the source as ``_running_water_source`` so that mid-cycle
|
|
824
|
-
changes via HA select do not affect which outputs get deactivated
|
|
825
|
-
during shutdown.
|
|
826
|
-
|
|
827
806
|
Returns:
|
|
828
807
|
True if source was activated, False if blocked by interlock.
|
|
829
808
|
"""
|
|
830
809
|
src = self.active_water_source
|
|
831
810
|
if src is None:
|
|
832
811
|
return True
|
|
833
|
-
self._running_water_source = src
|
|
834
812
|
try:
|
|
835
813
|
_LOGGER.debug("Irrigation %s: activating source '%s' outputs=%s", self.id, src.id, src.output_ids)
|
|
836
814
|
return await src.activate(timestamp=time.time())
|
|
@@ -839,13 +817,8 @@ class IrrigationController:
|
|
|
839
817
|
return False
|
|
840
818
|
|
|
841
819
|
async def _deactivate_source(self) -> None:
|
|
842
|
-
"""Turn OFF all outputs of the
|
|
843
|
-
|
|
844
|
-
Uses ``_running_water_source`` (set during activation) instead of
|
|
845
|
-
``active_water_source`` so that mid-cycle HA select changes don't
|
|
846
|
-
cause us to deactivate the wrong source's outputs.
|
|
847
|
-
"""
|
|
848
|
-
src = self._running_water_source or self.active_water_source
|
|
820
|
+
"""Turn OFF all outputs of the active water source."""
|
|
821
|
+
src = self.active_water_source
|
|
849
822
|
if src is None:
|
|
850
823
|
return
|
|
851
824
|
try:
|
|
@@ -904,12 +877,8 @@ class IrrigationController:
|
|
|
904
877
|
await self.publish_all_states()
|
|
905
878
|
|
|
906
879
|
async def _handle_pump_stop_sequence(self) -> None:
|
|
907
|
-
"""Handle pump stop timing according to
|
|
908
|
-
|
|
909
|
-
Uses ``_running_water_source`` to ensure we deactivate the source
|
|
910
|
-
that was actually used during the cycle, not the one currently selected.
|
|
911
|
-
"""
|
|
912
|
-
src = self._running_water_source or self.active_water_source
|
|
880
|
+
"""Handle pump stop timing according to active water source's delays."""
|
|
881
|
+
src = self.active_water_source
|
|
913
882
|
if src is None:
|
|
914
883
|
return
|
|
915
884
|
if src.pump_stop_valve_delay_s > 0:
|
|
@@ -1079,11 +1048,6 @@ class IrrigationController:
|
|
|
1079
1048
|
async def set_water_source(self, source_id: str) -> None:
|
|
1080
1049
|
"""Switch active water source by ID.
|
|
1081
1050
|
|
|
1082
|
-
If the controller is currently running, the change is deferred.
|
|
1083
|
-
The selected source index is updated and persisted immediately,
|
|
1084
|
-
but ``_running_water_source`` (used for activation/deactivation)
|
|
1085
|
-
remains unchanged until the next cycle starts.
|
|
1086
|
-
|
|
1087
1051
|
Args:
|
|
1088
1052
|
source_id: ID of the water source to activate.
|
|
1089
1053
|
"""
|
|
@@ -1091,16 +1055,7 @@ class IrrigationController:
|
|
|
1091
1055
|
if ws.id == source_id:
|
|
1092
1056
|
self._active_water_source_idx = i
|
|
1093
1057
|
self._save("active_water_source", source_id)
|
|
1094
|
-
|
|
1095
|
-
_LOGGER.info(
|
|
1096
|
-
"Irrigation %s: water source will change to '%s' after current cycle ends "
|
|
1097
|
-
"(running source '%s' stays active)",
|
|
1098
|
-
self.id,
|
|
1099
|
-
source_id,
|
|
1100
|
-
self._running_water_source.id if self._running_water_source else "none",
|
|
1101
|
-
)
|
|
1102
|
-
else:
|
|
1103
|
-
_LOGGER.info("Irrigation %s: water source changed to '%s'", self.id, source_id)
|
|
1058
|
+
_LOGGER.info("Irrigation %s: water source changed to '%s'", self.id, source_id)
|
|
1104
1059
|
await self.publish_all_states()
|
|
1105
1060
|
return
|
|
1106
1061
|
_LOGGER.warning("Irrigation %s: unknown water source '%s'", self.id, source_id)
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
"""Output components (relays, PWM, switches, lights)."""
|
|
2
2
|
|
|
3
3
|
from boneio.components.output.basic import BasicOutput
|
|
4
|
-
from boneio.components.output.buzzer import BuzzerOutput
|
|
5
4
|
from boneio.components.output.mcp import MCPOutput
|
|
6
5
|
from boneio.components.output.pca import PWMOutput
|
|
7
6
|
from boneio.components.output.pcf import PCFOutput
|
|
8
7
|
|
|
9
8
|
__all__ = [
|
|
10
9
|
"BasicOutput",
|
|
11
|
-
"BuzzerOutput",
|
|
12
10
|
"MCPOutput",
|
|
13
11
|
"PCFOutput",
|
|
14
12
|
"PWMOutput",
|
|
15
13
|
]
|
|
16
|
-
|
|
@@ -186,13 +186,7 @@ class BasicOutput(BasicMqtt):
|
|
|
186
186
|
"""
|
|
187
187
|
can_turn_on = self.check_interlock()
|
|
188
188
|
if can_turn_on:
|
|
189
|
-
|
|
190
|
-
await self._loop.run_in_executor(None, self.turn_on, timestamp)
|
|
191
|
-
except RuntimeError as err:
|
|
192
|
-
if "Executor shutdown" in str(err):
|
|
193
|
-
self.turn_on(timestamp) # Fall back to sync during shutdown
|
|
194
|
-
else:
|
|
195
|
-
raise
|
|
189
|
+
await self._loop.run_in_executor(None, self.turn_on, timestamp)
|
|
196
190
|
else:
|
|
197
191
|
_LOGGER.warning("Interlock active: cannot turn on %s.", self.id)
|
|
198
192
|
# Workaround for HA is sendind state ON/OFF without physically changing the relay.
|
|
@@ -203,13 +197,7 @@ class BasicOutput(BasicMqtt):
|
|
|
203
197
|
|
|
204
198
|
async def async_turn_off(self, timestamp=None) -> None:
|
|
205
199
|
"""Turn off the relay asynchronously."""
|
|
206
|
-
|
|
207
|
-
await self._loop.run_in_executor(None, self.turn_off, timestamp)
|
|
208
|
-
except RuntimeError as err:
|
|
209
|
-
if "Executor shutdown" in str(err):
|
|
210
|
-
self.turn_off(timestamp) # Fall back to sync during shutdown
|
|
211
|
-
else:
|
|
212
|
-
raise
|
|
200
|
+
await self._loop.run_in_executor(None, self.turn_off, timestamp)
|
|
213
201
|
await self.async_send_state()
|
|
214
202
|
|
|
215
203
|
async def async_toggle(self, timestamp=None) -> None:
|
|
@@ -37,8 +37,6 @@ class MCPOutput(BasicOutput):
|
|
|
37
37
|
):
|
|
38
38
|
_LOGGER.warning(f"Interlock active: cannot restore ON state for {self._pin_id} at startup")
|
|
39
39
|
restored_state = False
|
|
40
|
-
# Fix: also reset the software state that was set in BasicOutput.__init__
|
|
41
|
-
self._state = OFF
|
|
42
40
|
self._mcp.configure_pin_as_output(self._pin_id, restored_state)
|
|
43
41
|
|
|
44
42
|
@property
|
|
@@ -79,7 +79,6 @@ class RemoteOutputBase:
|
|
|
79
79
|
duration_min: float = 1.0,
|
|
80
80
|
duration_max: float = 3600.0,
|
|
81
81
|
duration_unit: str = "s",
|
|
82
|
-
supports_brightness: bool = False,
|
|
83
82
|
) -> None:
|
|
84
83
|
self._id = id
|
|
85
84
|
self._name = name
|
|
@@ -118,7 +117,6 @@ class RemoteOutputBase:
|
|
|
118
117
|
self._state: str = OFF
|
|
119
118
|
self._last_timestamp: float = 0.0
|
|
120
119
|
self._available: bool = False
|
|
121
|
-
self._supports_brightness: bool = supports_brightness
|
|
122
120
|
self._brightness: int | None = None # 0-255, None if not a dimmable light
|
|
123
121
|
self._loop: asyncio.AbstractEventLoop | None = None
|
|
124
122
|
|
|
@@ -235,9 +233,9 @@ class RemoteOutputBase:
|
|
|
235
233
|
)
|
|
236
234
|
return
|
|
237
235
|
|
|
238
|
-
# If
|
|
236
|
+
# If output_type is 'light', initialize brightness to 0 so the
|
|
239
237
|
# slider renders immediately (will update on first state event).
|
|
240
|
-
if self.
|
|
238
|
+
if self._output_type == "light":
|
|
241
239
|
self._brightness = 0
|
|
242
240
|
_LOGGER.debug(
|
|
243
241
|
"Initialized brightness=0 for remote light '%s' (no state yet)",
|
|
@@ -191,14 +191,10 @@ class BoneIOGateCover:
|
|
|
191
191
|
# -- MQTT ----------------------------------------------------------------
|
|
192
192
|
|
|
193
193
|
async def start(self) -> None:
|
|
194
|
-
"""Subscribe to MQTT command topic
|
|
195
|
-
|
|
196
|
-
Initial sensor state is already set by TemplateManager during
|
|
197
|
-
configuration, so start() just subscribes and publishes.
|
|
198
|
-
"""
|
|
194
|
+
"""Subscribe to MQTT command topic."""
|
|
199
195
|
await self._message_bus.subscribe_and_listen(self._cmd_topic, self.handle_command)
|
|
200
196
|
self._publish_state()
|
|
201
|
-
_LOGGER.info("GateCover %s started
|
|
197
|
+
_LOGGER.info("GateCover %s started, subscribed to %s", self._id, self._cmd_topic)
|
|
202
198
|
|
|
203
199
|
async def stop(self) -> None:
|
|
204
200
|
"""Unsubscribe from MQTT and cancel timers."""
|