boneIO 1.4.2__tar.gz → 1.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boneio-1.4.2/boneio.egg-info → boneio-1.4.4}/PKG-INFO +1 -1
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/input/detectors.py +22 -2
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/cloud/data/docker-compose.yaml +12 -2
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/MANIFEST.sha256 +8 -8
- boneio-1.4.4/boneio/migrations/assets/docker/nodered/caddy/502.html +43 -0
- boneio-1.4.4/boneio/migrations/assets/docker/nodered/caddy/init-certs.sh +107 -0
- boneio-1.4.4/boneio/migrations/assets/docker/nodered/docker-compose.yaml +47 -0
- boneio-1.4.4/boneio/migrations/assets/systemd/boneio-oled-shutdown.service +12 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/systemd/boneio.service +1 -1
- boneio-1.4.4/boneio/migrations/assets/usr-sbin/oled_msg.py +255 -0
- boneio-1.4.4/boneio/migrations/assets/usr-sbin/oled_msg.sh +55 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/bootstrap/boneio-migrate +14 -4
- boneio-1.4.4/boneio/migrations/versions/v1_4_3_oled_shutdown.py +54 -0
- boneio-1.4.4/boneio/migrations/versions/v1_4_4_caddy.py +68 -0
- boneio-1.4.4/boneio/version.py +2 -0
- {boneio-1.4.2 → boneio-1.4.4/boneio.egg-info}/PKG-INFO +1 -1
- {boneio-1.4.2 → boneio-1.4.4}/boneio.egg-info/SOURCES.txt +5 -0
- boneio-1.4.2/boneio/migrations/assets/docker/nodered/docker-compose.yaml +0 -30
- boneio-1.4.2/boneio/migrations/assets/usr-sbin/oled_msg.py +0 -110
- boneio-1.4.2/boneio/migrations/assets/usr-sbin/oled_msg.sh +0 -17
- boneio-1.4.2/boneio/version.py +0 -2
- {boneio-1.4.2 → boneio-1.4.4}/LICENSE +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/MANIFEST.in +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/README.md +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.2/input.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.2/output_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.2/output_32_10.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.2/output_32_5.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.2/output_cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.2/output_cover_mix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.3/input.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.3/output_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.3/output_32_10.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.3/output_32_5.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.3/output_cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.3/output_cover_mix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.4/input.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.4/output_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.4/output_32_10.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.4/output_32_5.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.4/output_cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.4/output_cover_mix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.5/input.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.5/output_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.5/output_32_10.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.5/output_cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.5/output_cover_mix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.6/input.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.6/output_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.6/output_32_10.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.6/output_cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.6/output_cover_mix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.7/input.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.7/output_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.7/output_48_4.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.7/output_cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.7/output_cover_mix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.8/input.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.8/output_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.8/output_48_4.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.8/output_cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/boards/0.8/output_cover_mix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/bonecli.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/cover/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/cover/cover.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/cover/time_based.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/cover/venetian.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/group/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/group/output_group.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/input/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/input/binary_sensor.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/input/event.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/input/remote/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/input/remote/base.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/input/remote/esphome.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/irrigation/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/irrigation/controller.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/irrigation/water_source.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/output/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/output/basic.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/output/mcp.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/output/pca.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/output/pcf.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/output/remote.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/sensor/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/sensor/virtual_energy.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/template/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/template/alarm_panel.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/template/gate_cover.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/components/template/thermostat.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/const.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/cloud/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/cloud/data/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/cloud/data/docker-compose-cloud.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/cloud/data/init-certs-cloud.sh +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/cloud/registration.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/cloud/secrets.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/config_helper.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/migrations/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/migrations/v1_proxy_port.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/migrations/v2_transition.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/package-lock.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/package.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/schema_converter.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/config/yaml_util.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/discovery.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/events/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/events/bus.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/action_conditions.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/canopen.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/covers.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/display.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/inputs.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/irrigation.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/manager.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/modbus.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/outputs.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/remote.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/remote_input_registrar.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/sensors.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/templates/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/templates/alarm.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/templates/gate_cover.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/templates/thermostat.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/templates.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/manager/update.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/basic.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/basic_mqtt.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/composite.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/local.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/lox.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/mqtt.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/messaging/queue.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/remote/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/remote/base.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/remote/can.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/remote/esphome.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/remote/mqtt.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/remote/wled.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/sensor/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/sensor/base.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/sensor/system.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/state/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/state/manager.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/system/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/system/host_data.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/system/monitor.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/async_updater.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/conditions.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/filter.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/font_util.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/logger.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/timeperiod.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/core/utils/util.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/24x16/adc.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/24x16/binary_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/24x16/config.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/24x16/event.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/24x16/mqtt.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/24x16/output24x16A.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/32x10/adc.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/32x10/binary_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/32x10/config.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/32x10/event.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/32x10/mqtt.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/32x10/output32x10A.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/48x4/adc.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/48x4/binary_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/48x4/config.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/48x4/event.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/48x4/mqtt.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/48x4/output48x4A.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/can_master.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/can_slave.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover/adc.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover/binary_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover/config.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover/cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover/event.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover/mqtt.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover/outputCover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover_mix/adc.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover_mix/binary_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover_mix/config.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover_mix/cover.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover_mix/event.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover_mix/mqtt.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/cover_mix/outputCoverMix.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/adc.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/all_binary_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/binary_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/binary_sensor_v_0_7.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/config_24_16.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/event_all.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/event_v_0_7.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/led32x4A.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/output24x16A.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/output24x16A_v0.3.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/output32x10A.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/example_config/different_configs/output32x5A.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/exceptions.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/analog/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/analog/adc.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/can/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/can/bridge.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/can/client.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/can/interface.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/can/node.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/can/node_id.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/can/test_od.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/display/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/display/early_oled.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/display/fonts/danube__.ttf +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/display/oled.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/expanders/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/expanders/mcp23017.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/expanders/pca9685.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/expanders/pcf8575.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/input/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/input/base.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/gpio/input/manager.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/i2c/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/i2c/bus.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/i2c/ina219.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/i2c/ina219_driver.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/i2c/mcp9808.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/i2c/pct2075.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/onewire/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/onewire/bus.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/onewire/dallas.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/onewire/ds2482.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/sensor/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/sensor/temperature/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/sensor/temperature/base.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/sensor/temperature/mcp9808.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/hardware/sensor/temperature/pct2075.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/integration/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/integration/homeassistant.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/integration/interlock.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/integration/lox_template.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/actions.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/docker/daemon.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/docker/nodered/nginx/default.conf +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/docker/nodered/node-red/settings.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/journald/journald.conf +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/mosquitto/boneio.conf +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/sudoers/boneio +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/systemd/boneio-oled-boot.service +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/systemd/set-hostname-once.service +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/usr-local-bin/set-hostname-once.sh +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/usr-sbin/oled_boot_splash.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/assets/usr-sbin/oled_boot_splash.sh +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/bootstrap/install-helper.sh +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/bootstrap/sudoers-migrate +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/runner.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/versions/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/versions/v1_3_0_baseline.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/versions/v1_3_1_fix_oled_boot.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/versions/v1_3_2_cleanup_can_sudoers.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/migrations/versions/v1_4_0_fix_mqtt_sudoers.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/cli.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/client.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/coordinator.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/energy_meters/le-03mw.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/energy_meters/le-03mwct.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/energy_meters/orno-or-we-517.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/energy_meters/sdm120.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/energy_meters/sdm630.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/energy_meters/socomec_e03.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/energy_meters/socomec_e23.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/hvac/eht-topventil-plus.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/hvac/fujitsu-ac.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/hvac/ventclear.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/inverters/sofar.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/inverters/thessla.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/other/esp32_relay_x4_modbus.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/other/n4dsc08.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/other/r4dcb08.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/other/wanas415.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/boneio-edge-temp.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/cwt.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/dts1964_3f.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/dyp-a12-ultrasonic.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/gdfs.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/gdfx.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/liquid-sensor.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/pt100.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/sht20.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/devices/sensors/sht30.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/base.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/derived/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/derived/numeric.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/derived/select.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/derived/switch.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/derived/text.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/sensor/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/sensor/binary.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/sensor/numeric.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/sensor/text.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/writeable/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/writeable/binary.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/entities/writeable/numeric.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/modbus/utils.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/models/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/models/actions.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/models/events.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/models/files.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/models/logs.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/models/mqtt.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/models/state.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/runner.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/actions.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/condition.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/filters.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/id.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/remote_devices.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/remote_inputs.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/remote_outputs.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/schema.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/schema/update_interval.yaml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/action_validation.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/app.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/dashboard_cards.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/ConfigEditor-DqDX4DyY.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/aiConfig-DxFilBWK.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/aiWizardPrompt-CrWwS7zb.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/codicon-DCmgc-ay.ttf +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/editor.worker-BVjSvWeP.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/index-BXbDdVbb.css +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/index-DBT9dXd3.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/json.worker-CqOJL4FD.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/monaco-B9WiNxkw.css +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/monaco-CAZoGZNF.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/rolldown-runtime-Dw2cE7zH.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/useTranslation-DUpbl8sU.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/vendor-BD5Ml_Uz.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/workbox-window.prod.es5-BJd1pjeW.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/assets/yaml.worker-nZQZSRZ7.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/boneio-192.png +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/boneio-512.png +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/index.html +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/adc.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/areas.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/binary_sensor.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/boneio.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/can.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/config.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/cover.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/dallas.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/ds2482.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/event.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/ina219.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/irrigation.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/lm75.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/logger.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/lox_udp.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/mcp23017.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/mcp9808.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/modbus.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/modbus_devices.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/mqtt.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/oled.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/output.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/output_group.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/pca9685.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/pcf8575.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/remote_devices.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/remote_inputs.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/remote_outputs.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/sensor.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/template.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/schema/web.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/sw.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/frontend-dist/workbox-4eca85ba.js +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/middleware/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/middleware/auth.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/auth.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/caddy.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/can.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/config.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/covers.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/irrigation.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/migrations.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/modbus.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/outputs.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/remote_devices.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/sensors.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/system.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/templates.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/timezone_sudoers.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/tools.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/routes/update.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/adc.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/areas.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/binary_sensor.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/boneio.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/can.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/config.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/cover.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/dallas.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/ds2482.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/event.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/ina219.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/irrigation.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/lm75.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/logger.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/lox_udp.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/mcp23017.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/mcp9808.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/modbus.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/modbus_devices.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/mqtt.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/oled.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/output.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/output_group.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/pca9685.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/pcf8575.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/remote_devices.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/remote_inputs.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/remote_outputs.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/sensor.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/template.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/virtual_energy_sensor.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/schema/web.schema.json +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/services/__init__.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/services/logs.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/web_server.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio/webui/websocket_manager.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio.egg-info/dependency_links.txt +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio.egg-info/entry_points.txt +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio.egg-info/requires.txt +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/boneio.egg-info/top_level.txt +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/pyproject.toml +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/setup.cfg +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/setup.py +0 -0
- {boneio-1.4.2 → boneio-1.4.4}/tests/test_py313_compatibility.py +0 -0
|
@@ -467,7 +467,7 @@ class MultiClickDetector:
|
|
|
467
467
|
if event.event_type is event.Type.FALLING_EDGE:
|
|
468
468
|
# Button pressed (FALLING_EDGE on BeagleBone with pull-up)
|
|
469
469
|
|
|
470
|
-
# Software debounce
|
|
470
|
+
# Software debounce (press-vs-press)
|
|
471
471
|
if self._state.last_press_ts and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds:
|
|
472
472
|
delta_ms = (timestamp_s - self._state.last_press_ts) * 1000
|
|
473
473
|
_LOGGER.debug(
|
|
@@ -478,6 +478,19 @@ class MultiClickDetector:
|
|
|
478
478
|
)
|
|
479
479
|
return
|
|
480
480
|
|
|
481
|
+
# Cross-debounce: ignore press too close to release (bounce on falling edge
|
|
482
|
+
# after a real release). Without this, releasing a long-held button can
|
|
483
|
+
# generate a bounce FALLING that starts a new phantom press cycle.
|
|
484
|
+
if self._state.last_release_ts and (timestamp_s - self._state.last_release_ts) < self._debounce_seconds:
|
|
485
|
+
delta_ms = (timestamp_s - self._state.last_release_ts) * 1000
|
|
486
|
+
_LOGGER.debug(
|
|
487
|
+
"Ignoring bounced press on %s (%.3f ms since release, debounce %.3f ms)",
|
|
488
|
+
self._name,
|
|
489
|
+
delta_ms,
|
|
490
|
+
self._debounce_seconds * 1000,
|
|
491
|
+
)
|
|
492
|
+
return
|
|
493
|
+
|
|
481
494
|
_LOGGER.debug("PRESSED: %s (%s)", self._name, self._pin)
|
|
482
495
|
self._state.last_press_ts = timestamp_s
|
|
483
496
|
self._state.last_press_loop_ts = self._loop.time() # Store loop time for duration calc
|
|
@@ -618,13 +631,20 @@ class MultiClickDetector:
|
|
|
618
631
|
timestamp_s = time.time()
|
|
619
632
|
|
|
620
633
|
if is_pressed:
|
|
621
|
-
# Debounce
|
|
634
|
+
# Debounce (press-vs-press)
|
|
622
635
|
if (
|
|
623
636
|
self._state.last_press_ts
|
|
624
637
|
and (timestamp_s - self._state.last_press_ts) < self._debounce_seconds
|
|
625
638
|
):
|
|
626
639
|
return
|
|
627
640
|
|
|
641
|
+
# Cross-debounce: ignore press too close to release (bounce)
|
|
642
|
+
if (
|
|
643
|
+
self._state.last_release_ts
|
|
644
|
+
and (timestamp_s - self._state.last_release_ts) < self._debounce_seconds
|
|
645
|
+
):
|
|
646
|
+
return
|
|
647
|
+
|
|
628
648
|
_LOGGER.debug("RAW PRESSED: %s (%s)", self._name, self._pin)
|
|
629
649
|
self._state.last_press_ts = timestamp_s
|
|
630
650
|
self._state.last_press_loop_ts = self._loop.time()
|
|
@@ -9,17 +9,22 @@ services:
|
|
|
9
9
|
- ./node-red/settings.js:/data/settings.js:ro
|
|
10
10
|
extra_hosts:
|
|
11
11
|
- "host.docker.internal:host-gateway"
|
|
12
|
+
logging:
|
|
13
|
+
driver: json-file
|
|
14
|
+
options:
|
|
15
|
+
max-size: "5m"
|
|
16
|
+
max-file: "2"
|
|
12
17
|
networks:
|
|
13
18
|
- edge
|
|
14
19
|
caddy:
|
|
15
20
|
image: caddy:2-alpine
|
|
16
21
|
restart: unless-stopped
|
|
17
|
-
hostname: ${HOSTNAME}
|
|
22
|
+
hostname: ${HOSTNAME:-boneio}
|
|
18
23
|
ports:
|
|
19
24
|
- "${HTTP_PORT:-8091}:80"
|
|
20
25
|
- "${HTTPS_PORT:-8443}:443"
|
|
21
26
|
environment:
|
|
22
|
-
- HOST_HOSTNAME=${HOSTNAME}
|
|
27
|
+
- HOST_HOSTNAME=${HOSTNAME:-boneio}
|
|
23
28
|
volumes:
|
|
24
29
|
- ./caddy/502.html:/srv/502.html:ro
|
|
25
30
|
- ./caddy/init-certs.sh:/init-certs.sh:ro
|
|
@@ -30,6 +35,11 @@ services:
|
|
|
30
35
|
command: ["/init-certs.sh"]
|
|
31
36
|
extra_hosts:
|
|
32
37
|
- "host.docker.internal:host-gateway"
|
|
38
|
+
logging:
|
|
39
|
+
driver: json-file
|
|
40
|
+
options:
|
|
41
|
+
max-size: "5m"
|
|
42
|
+
max-file: "2"
|
|
33
43
|
networks:
|
|
34
44
|
- edge
|
|
35
45
|
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
# Format: <sha256> <relative-path>
|
|
3
|
-
# Generated by scripts/generate_manifest.py — do not edit manually
|
|
4
|
-
|
|
1
|
+
98b8ed657b4f7394521c3fe6b381a01ca7114e3f31495bab709707886559316a MANIFEST.sha256
|
|
5
2
|
f2ed05c6f5934a15f12571139bdc225804f67b8c83561cc39868f7b2296d2697 docker/daemon.json
|
|
6
|
-
|
|
3
|
+
22dfe7d55e5ed85ea0f4149b7776b7504a12b91905701657a88840ae1208087c docker/nodered/caddy/502.html
|
|
4
|
+
3e4a91a1737ce82c6bcdbbc31fce214790c0432a608ac34de7fc4e5c58cfd550 docker/nodered/caddy/init-certs.sh
|
|
5
|
+
cd90e1bcb6488669179c8e7a40a6265923e0fea045cc79d5b7559ebb309131b6 docker/nodered/docker-compose.yaml
|
|
7
6
|
30467786de3a35e02f9f5049b29ec1808056814e7c2fc5e507ff4b0991cde557 docker/nodered/nginx/default.conf
|
|
8
7
|
66b00c1e480113a098b90d9948284781896c943006c1a3fe882d515f63b9d3e8 docker/nodered/node-red/settings.js
|
|
9
8
|
67b4d45f890f073bee66dcf6d6026bd42515d938566b90d2b2a6f7ea016f3764 journald/journald.conf
|
|
10
9
|
3db75f83033d82ca229e2d3bcb7daf4a5584f65b298d834bd0ee12527ae06e22 mosquitto/boneio.conf
|
|
11
10
|
3fc86895f5fd3e59d2ee2d229ff7ff7c0030752f0c4eca0bb04314ea57ac0ede sudoers/boneio
|
|
12
11
|
80e528c3a0e03a4d269bcb46db4224c8e5b6c75553b266cfc4f301b515ddcd95 systemd/boneio-oled-boot.service
|
|
13
|
-
|
|
12
|
+
df6cbd8ff2361a815917c3a24ca11ebb817fc98c9790833cb2475e0b9f4e9923 systemd/boneio-oled-shutdown.service
|
|
13
|
+
455fe344a251e0162cdf26beff2a041c55340119de917675faafa06d573663c6 systemd/boneio.service
|
|
14
14
|
5abbd8e37720f31d44ad59814c7ebbcfb5ae09ef32d83682dee6479f34270a31 systemd/set-hostname-once.service
|
|
15
15
|
8eaea86c51a17c1bc7b68e9ea65a20b428577a0bc16793768f8dba575532e8ed usr-local-bin/set-hostname-once.sh
|
|
16
16
|
3340abd637e15bb789e20f2e7de5d95dc45d8e427689e0c62312d044cd3ad86e usr-sbin/oled_boot_splash.py
|
|
17
17
|
0537e194700c50d91295517e23bcccce9b23be740b93381dff35b510d562c6fe usr-sbin/oled_boot_splash.sh
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
a95d897f49e1af2468b18a721731a6c679b3a0c54af4bb8338a5906f98898bdd usr-sbin/oled_msg.py
|
|
19
|
+
b30a474473c96ab973a442ea01bd197735a3d75f12d88129895488335bf5401c usr-sbin/oled_msg.sh
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>boneIO — Service Unavailable</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
10
|
+
background: #1a1a2e;
|
|
11
|
+
color: #e0e0e0;
|
|
12
|
+
display: flex;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
align-items: center;
|
|
15
|
+
min-height: 100vh;
|
|
16
|
+
margin: 0;
|
|
17
|
+
}
|
|
18
|
+
.container {
|
|
19
|
+
text-align: center;
|
|
20
|
+
padding: 2rem;
|
|
21
|
+
}
|
|
22
|
+
h1 { color: #e94560; font-size: 2rem; margin-bottom: 0.5rem; }
|
|
23
|
+
p { color: #a0a0b0; font-size: 1.1rem; }
|
|
24
|
+
.retry { margin-top: 1.5rem; }
|
|
25
|
+
.retry a {
|
|
26
|
+
color: #0f3460;
|
|
27
|
+
background: #e94560;
|
|
28
|
+
padding: 0.6rem 1.5rem;
|
|
29
|
+
border-radius: 6px;
|
|
30
|
+
text-decoration: none;
|
|
31
|
+
font-weight: 600;
|
|
32
|
+
}
|
|
33
|
+
</style>
|
|
34
|
+
</head>
|
|
35
|
+
<body>
|
|
36
|
+
<div class="container">
|
|
37
|
+
<h1>Service Unavailable</h1>
|
|
38
|
+
<p>boneIO is starting up or temporarily unavailable.</p>
|
|
39
|
+
<p>Please wait a moment and try again.</p>
|
|
40
|
+
<div class="retry"><a href="/">Retry</a></div>
|
|
41
|
+
</div>
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Caddy init script for non-cloud mode (self-signed HTTPS only).
|
|
3
|
+
# Generates a Caddyfile with HTTP and self-signed HTTPS reverse proxy
|
|
4
|
+
# for boneIO and Node-RED.
|
|
5
|
+
|
|
6
|
+
HOSTNAME_FILE="/data/last_hostname"
|
|
7
|
+
CURRENT_HOSTNAME="${HOST_HOSTNAME:-$(cat /etc/host_hostname 2>/dev/null || hostname)}"
|
|
8
|
+
|
|
9
|
+
echo "Current hostname: $CURRENT_HOSTNAME"
|
|
10
|
+
echo "Mode: local (self-signed HTTPS)"
|
|
11
|
+
|
|
12
|
+
# Check if hostname changed (for self-signed cert regeneration)
|
|
13
|
+
if [ -f "$HOSTNAME_FILE" ]; then
|
|
14
|
+
LAST_HOSTNAME=$(cat "$HOSTNAME_FILE")
|
|
15
|
+
if [ "$LAST_HOSTNAME" != "$CURRENT_HOSTNAME" ]; then
|
|
16
|
+
echo "Hostname changed from $LAST_HOSTNAME to $CURRENT_HOSTNAME"
|
|
17
|
+
echo "Removing old self-signed certificates..."
|
|
18
|
+
rm -rf /data/caddy/certificates/local/*
|
|
19
|
+
rm -rf /data/caddy/pki/*
|
|
20
|
+
rm -rf /config/caddy/*
|
|
21
|
+
fi
|
|
22
|
+
else
|
|
23
|
+
echo "First run on this device, clearing any existing certificates..."
|
|
24
|
+
rm -rf /data/caddy/certificates/local/*
|
|
25
|
+
rm -rf /data/caddy/pki/*
|
|
26
|
+
rm -rf /config/caddy/*
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
echo "$CURRENT_HOSTNAME" > "$HOSTNAME_FILE"
|
|
30
|
+
|
|
31
|
+
# Generate Caddyfile
|
|
32
|
+
cat > /tmp/Caddyfile << EOF
|
|
33
|
+
{
|
|
34
|
+
# Global options - empty for internal issuer
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# HTTP - serve directly
|
|
38
|
+
:80 {
|
|
39
|
+
handle_errors {
|
|
40
|
+
@502-504 expression {err.status_code} >= 502 && {err.status_code} <= 504
|
|
41
|
+
handle @502-504 {
|
|
42
|
+
root * /srv
|
|
43
|
+
rewrite * /502.html
|
|
44
|
+
file_server
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
handle /nodered-status {
|
|
49
|
+
header Content-Type application/json
|
|
50
|
+
header X-NodeRed-Available "true"
|
|
51
|
+
header Access-Control-Expose-Headers "X-NodeRed-Available"
|
|
52
|
+
respond \`{"available": true}\` 200
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
handle /nodered/* {
|
|
56
|
+
reverse_proxy node-red:1880 {
|
|
57
|
+
header_up X-Forwarded-Proto {scheme}
|
|
58
|
+
header_down X-NodeRed-Available "true"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
handle {
|
|
63
|
+
reverse_proxy host.docker.internal:8090 {
|
|
64
|
+
header_up X-Forwarded-Proto {scheme}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# HTTPS with self-signed certificate (catch-all for hostname and IP access)
|
|
70
|
+
https:// {
|
|
71
|
+
tls internal {
|
|
72
|
+
on_demand
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
handle_errors {
|
|
76
|
+
@502-504 expression {err.status_code} >= 502 && {err.status_code} <= 504
|
|
77
|
+
handle @502-504 {
|
|
78
|
+
root * /srv
|
|
79
|
+
rewrite * /502.html
|
|
80
|
+
file_server
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
handle /nodered-status {
|
|
85
|
+
header Content-Type application/json
|
|
86
|
+
header X-NodeRed-Available "true"
|
|
87
|
+
header Access-Control-Expose-Headers "X-NodeRed-Available"
|
|
88
|
+
respond \`{"available": true}\` 200
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
handle /nodered/* {
|
|
92
|
+
reverse_proxy node-red:1880 {
|
|
93
|
+
header_up X-Forwarded-Proto {scheme}
|
|
94
|
+
header_down X-NodeRed-Available "true"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
handle {
|
|
99
|
+
reverse_proxy host.docker.internal:8090 {
|
|
100
|
+
header_up X-Forwarded-Proto {scheme}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
EOF
|
|
105
|
+
|
|
106
|
+
# Start Caddy with generated config
|
|
107
|
+
exec caddy run --config /tmp/Caddyfile --adapter caddyfile
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
services:
|
|
2
|
+
node-red:
|
|
3
|
+
image: nodered/node-red:4.1.2-22-minimal
|
|
4
|
+
restart: unless-stopped
|
|
5
|
+
environment:
|
|
6
|
+
TZ: Europe/Warsaw
|
|
7
|
+
volumes:
|
|
8
|
+
- ./node-red/data:/data
|
|
9
|
+
- ./node-red/settings.js:/data/settings.js:ro
|
|
10
|
+
extra_hosts:
|
|
11
|
+
- "host.docker.internal:host-gateway"
|
|
12
|
+
logging:
|
|
13
|
+
driver: json-file
|
|
14
|
+
options:
|
|
15
|
+
max-size: "5m"
|
|
16
|
+
max-file: "2"
|
|
17
|
+
networks:
|
|
18
|
+
- edge
|
|
19
|
+
caddy:
|
|
20
|
+
image: caddy:2-alpine
|
|
21
|
+
restart: unless-stopped
|
|
22
|
+
hostname: ${HOSTNAME:-boneio}
|
|
23
|
+
ports:
|
|
24
|
+
- "${HTTP_PORT:-8091}:80"
|
|
25
|
+
- "${HTTPS_PORT:-8443}:443"
|
|
26
|
+
environment:
|
|
27
|
+
- HOST_HOSTNAME=${HOSTNAME:-boneio}
|
|
28
|
+
volumes:
|
|
29
|
+
- ./caddy/502.html:/srv/502.html:ro
|
|
30
|
+
- ./caddy/init-certs.sh:/init-certs.sh:ro
|
|
31
|
+
- ./caddy/data:/data
|
|
32
|
+
- ./caddy/config:/config
|
|
33
|
+
- /etc/hostname:/etc/host_hostname:ro
|
|
34
|
+
entrypoint: /bin/sh
|
|
35
|
+
command: ["/init-certs.sh"]
|
|
36
|
+
extra_hosts:
|
|
37
|
+
- "host.docker.internal:host-gateway"
|
|
38
|
+
logging:
|
|
39
|
+
driver: json-file
|
|
40
|
+
options:
|
|
41
|
+
max-size: "5m"
|
|
42
|
+
max-file: "2"
|
|
43
|
+
networks:
|
|
44
|
+
- edge
|
|
45
|
+
|
|
46
|
+
networks:
|
|
47
|
+
edge:
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=OLED shutdown message (runs after network is down)
|
|
3
|
+
DefaultDependencies=no
|
|
4
|
+
Before=final.target
|
|
5
|
+
After=network.target
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=oneshot
|
|
9
|
+
ExecStart=/usr/sbin/oled_msg.sh "boneIO Black" "System stopped." "Safe to unplug."
|
|
10
|
+
|
|
11
|
+
[Install]
|
|
12
|
+
WantedBy=final.target
|
|
@@ -6,7 +6,7 @@ After=multi-user.target network.target boneio-oled-boot.service
|
|
|
6
6
|
Type=simple
|
|
7
7
|
ExecStartPre=-/usr/sbin/oled_msg.sh "boneIO Black" "is starting..." "Please wait..."
|
|
8
8
|
ExecStart=${BONEIO_HOME}/boneio/venv/bin/boneio run -c ${BONEIO_HOME}/boneio/config.yaml
|
|
9
|
-
ExecStopPost
|
|
9
|
+
ExecStopPost=-/bin/sh -c 'if ! systemctl is-system-running --quiet 2>/dev/null; then /usr/sbin/oled_msg.sh "boneIO Black" "Shutting down..."; fi'
|
|
10
10
|
User=${BONEIO_USER}
|
|
11
11
|
Restart=always
|
|
12
12
|
RestartSec=3
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Display a centered message on optional SH1106 OLED.
|
|
3
|
+
|
|
4
|
+
Supports two modes:
|
|
5
|
+
- Direct: oled_msg.py "Line 1" "Line 2" — one-shot render (slow, flickers)
|
|
6
|
+
- Daemon: oled_msg.py --serve — keeps luma in memory, reads
|
|
7
|
+
commands from /tmp/.oled_fifo (fast, no flicker)
|
|
8
|
+
|
|
9
|
+
When the daemon is running, direct calls detect it and send messages
|
|
10
|
+
through the FIFO instead of re-initializing luma.
|
|
11
|
+
|
|
12
|
+
This script is safe to call when no OLED is connected or dependencies are
|
|
13
|
+
missing: it exits quietly with code 0.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import os
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
_FIFO_PATH = "/tmp/.oled_fifo"
|
|
22
|
+
_PID_PATH = "/tmp/.oled_serve.pid"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _fast_clear_oled() -> None:
|
|
26
|
+
"""Clear OLED display via raw I2C before slow luma init.
|
|
27
|
+
|
|
28
|
+
On soft-reboot the SH1106 retains the previous image. Luma's sh1106()
|
|
29
|
+
constructor takes ~9 seconds (device enumeration, contrast setup, etc.).
|
|
30
|
+
This function clears the display in ~50ms using raw smbus2 writes,
|
|
31
|
+
so the stale image disappears almost instantly at boot.
|
|
32
|
+
"""
|
|
33
|
+
try:
|
|
34
|
+
import smbus2
|
|
35
|
+
|
|
36
|
+
bus = smbus2.SMBus(2)
|
|
37
|
+
addr = 0x3C
|
|
38
|
+
# SH1106 init: display on, set page addressing
|
|
39
|
+
for cmd in [
|
|
40
|
+
0xAE,
|
|
41
|
+
0xD5,
|
|
42
|
+
0x80,
|
|
43
|
+
0xA8,
|
|
44
|
+
0x3F,
|
|
45
|
+
0xD3,
|
|
46
|
+
0x00,
|
|
47
|
+
0x40,
|
|
48
|
+
0xAD,
|
|
49
|
+
0x8B,
|
|
50
|
+
0xA1,
|
|
51
|
+
0xC8,
|
|
52
|
+
0xDA,
|
|
53
|
+
0x12,
|
|
54
|
+
0x81,
|
|
55
|
+
0xFF,
|
|
56
|
+
0xD9,
|
|
57
|
+
0x1F,
|
|
58
|
+
0xDB,
|
|
59
|
+
0x40,
|
|
60
|
+
0xA6,
|
|
61
|
+
0xAF,
|
|
62
|
+
]:
|
|
63
|
+
bus.write_byte_data(addr, 0x00, cmd)
|
|
64
|
+
# Clear all 8 pages (128 columns each)
|
|
65
|
+
blank = [0x00] * 128
|
|
66
|
+
for page in range(8):
|
|
67
|
+
bus.write_byte_data(addr, 0x00, 0xB0 | page) # set page
|
|
68
|
+
bus.write_byte_data(addr, 0x00, 0x02) # low col (offset 2 for SH1106)
|
|
69
|
+
bus.write_byte_data(addr, 0x00, 0x10) # high col
|
|
70
|
+
# Write in chunks of 32 (smbus limit)
|
|
71
|
+
for i in range(0, 128, 32):
|
|
72
|
+
bus.write_i2c_block_data(addr, 0x40, blank[i : i + 32])
|
|
73
|
+
bus.close()
|
|
74
|
+
except Exception:
|
|
75
|
+
pass # No OLED or smbus2 not available — ignore
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _is_daemon_running() -> bool:
|
|
79
|
+
"""Check if the oled_msg daemon is running.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
True if daemon PID file exists and process is alive.
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
with open(_PID_PATH) as f:
|
|
86
|
+
pid = int(f.read().strip())
|
|
87
|
+
os.kill(pid, 0) # Check if process exists
|
|
88
|
+
return True
|
|
89
|
+
except (FileNotFoundError, ValueError, ProcessLookupError, PermissionError):
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _send_to_daemon(lines: list[str]) -> bool:
|
|
94
|
+
"""Send a message to the running daemon via FIFO.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
lines: List of text lines to display.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
True if message was sent successfully.
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
# Open FIFO in non-blocking write to avoid hanging if daemon died
|
|
104
|
+
fd = os.open(_FIFO_PATH, os.O_WRONLY | os.O_NONBLOCK)
|
|
105
|
+
msg = "|".join(lines) + "\n"
|
|
106
|
+
os.write(fd, msg.encode())
|
|
107
|
+
os.close(fd)
|
|
108
|
+
return True
|
|
109
|
+
except (OSError, BrokenPipeError):
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _draw(device, font, lines: list[str]) -> None:
|
|
114
|
+
"""Draw centered text lines on the OLED.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
device: luma sh1106 device instance.
|
|
118
|
+
font: PIL ImageFont instance.
|
|
119
|
+
lines: List of 1-4 text strings to display.
|
|
120
|
+
"""
|
|
121
|
+
from luma.core.render import canvas
|
|
122
|
+
|
|
123
|
+
with canvas(device) as draw:
|
|
124
|
+
if len(lines) == 1:
|
|
125
|
+
positions = [(20, 26)]
|
|
126
|
+
elif len(lines) == 2:
|
|
127
|
+
positions = [(12, 20), (12, 36)]
|
|
128
|
+
elif len(lines) == 3:
|
|
129
|
+
positions = [(8, 12), (8, 28), (8, 44)]
|
|
130
|
+
else:
|
|
131
|
+
positions = [(4, 4), (4, 18), (4, 32), (4, 46)]
|
|
132
|
+
for index, line in enumerate(lines):
|
|
133
|
+
draw.text(positions[index], line[:24], font=font, fill="white")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _serve() -> int:
|
|
137
|
+
"""Run as a daemon: initialize luma once, then listen on FIFO for commands.
|
|
138
|
+
|
|
139
|
+
Message format on FIFO: "Line 1|Line 2|Line 3\\n"
|
|
140
|
+
Special messages: "clear\\n" to clear display, "quit\\n" to stop daemon.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Exit code.
|
|
144
|
+
"""
|
|
145
|
+
_fast_clear_oled()
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
from luma.core.interface.serial import i2c
|
|
149
|
+
from luma.oled.device import sh1106
|
|
150
|
+
from PIL import ImageFont
|
|
151
|
+
except Exception:
|
|
152
|
+
return 0
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
serial = i2c(port=2, address=0x3C)
|
|
156
|
+
device = sh1106(serial)
|
|
157
|
+
device.persist = True
|
|
158
|
+
font = ImageFont.load_default()
|
|
159
|
+
except Exception:
|
|
160
|
+
return 0
|
|
161
|
+
|
|
162
|
+
# Create FIFO
|
|
163
|
+
try:
|
|
164
|
+
os.unlink(_FIFO_PATH)
|
|
165
|
+
except FileNotFoundError:
|
|
166
|
+
pass
|
|
167
|
+
os.mkfifo(_FIFO_PATH)
|
|
168
|
+
|
|
169
|
+
# Write PID file
|
|
170
|
+
with open(_PID_PATH, "w") as f:
|
|
171
|
+
f.write(str(os.getpid()))
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
while True:
|
|
175
|
+
# Open FIFO — blocks until a writer connects
|
|
176
|
+
with open(_FIFO_PATH) as fifo:
|
|
177
|
+
for raw_line in fifo:
|
|
178
|
+
msg = raw_line.strip()
|
|
179
|
+
if not msg:
|
|
180
|
+
continue
|
|
181
|
+
if msg == "quit":
|
|
182
|
+
return 0
|
|
183
|
+
if msg == "clear":
|
|
184
|
+
_fast_clear_oled()
|
|
185
|
+
continue
|
|
186
|
+
lines = msg.split("|")
|
|
187
|
+
_draw(device, font, lines)
|
|
188
|
+
except KeyboardInterrupt:
|
|
189
|
+
pass
|
|
190
|
+
finally:
|
|
191
|
+
try:
|
|
192
|
+
os.unlink(_FIFO_PATH)
|
|
193
|
+
except FileNotFoundError:
|
|
194
|
+
pass
|
|
195
|
+
try:
|
|
196
|
+
os.unlink(_PID_PATH)
|
|
197
|
+
except FileNotFoundError:
|
|
198
|
+
pass
|
|
199
|
+
|
|
200
|
+
return 0
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def main(argv: list[str]) -> int:
|
|
204
|
+
"""Display a centered message on optional SH1106 OLED.
|
|
205
|
+
|
|
206
|
+
If --serve is passed, runs as a daemon listening on a FIFO.
|
|
207
|
+
Otherwise, sends message to daemon if running, or falls back
|
|
208
|
+
to direct luma rendering.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
argv: Command-line arguments.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
Exit code (always 0).
|
|
215
|
+
"""
|
|
216
|
+
if len(argv) > 1 and argv[1] == "--serve":
|
|
217
|
+
return _serve()
|
|
218
|
+
|
|
219
|
+
lines = [line[:24] for line in argv[1:5] if line]
|
|
220
|
+
if not lines:
|
|
221
|
+
return 0
|
|
222
|
+
|
|
223
|
+
# Try sending to daemon first (fast path — no Python init overhead)
|
|
224
|
+
if _is_daemon_running() and _send_to_daemon(lines):
|
|
225
|
+
return 0
|
|
226
|
+
|
|
227
|
+
# Fallback: direct rendering (slow but always works)
|
|
228
|
+
_fast_clear_oled()
|
|
229
|
+
|
|
230
|
+
try:
|
|
231
|
+
from luma.core.error import DeviceNotFoundError
|
|
232
|
+
from luma.core.interface.serial import i2c
|
|
233
|
+
from luma.oled.device import sh1106
|
|
234
|
+
from PIL import ImageFont
|
|
235
|
+
except Exception:
|
|
236
|
+
return 0
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
serial = i2c(port=2, address=0x3C)
|
|
240
|
+
device = sh1106(serial)
|
|
241
|
+
device.persist = True
|
|
242
|
+
except (DeviceNotFoundError, OSError, Exception):
|
|
243
|
+
return 0
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
_draw(device, ImageFont.load_default(), lines)
|
|
247
|
+
except Exception:
|
|
248
|
+
return 0
|
|
249
|
+
|
|
250
|
+
return 0
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
if __name__ == "__main__":
|
|
254
|
+
raise SystemExit(main(sys.argv))
|
|
255
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# oled_msg.sh — wrapper for optional Python SH1106 renderer
|
|
3
|
+
# Usage: oled_msg.sh "Line 1" ["Line 2"] ["Line 3"] ["Line 4"]
|
|
4
|
+
# oled_msg.sh --serve # start daemon (keeps luma in memory)
|
|
5
|
+
# oled_msg.sh --stop # stop daemon
|
|
6
|
+
# oled_msg.sh clear # clear display
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
PYTHON_RENDERER="${SCRIPT_DIR}/oled_msg.py"
|
|
10
|
+
VENV_PYTHON="/home/boneio/boneio/venv/bin/python3"
|
|
11
|
+
OLED_FIFO="/tmp/.oled_fifo"
|
|
12
|
+
OLED_PID="/tmp/.oled_serve.pid"
|
|
13
|
+
|
|
14
|
+
if [ ! -f "${PYTHON_RENDERER}" ]; then
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Pick the right Python
|
|
19
|
+
PYTHON=""
|
|
20
|
+
if [ -x "${VENV_PYTHON}" ]; then
|
|
21
|
+
PYTHON="${VENV_PYTHON}"
|
|
22
|
+
elif command -v python3 >/dev/null 2>&1; then
|
|
23
|
+
PYTHON="python3"
|
|
24
|
+
else
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Handle --serve: start daemon in background
|
|
29
|
+
if [ "$1" = "--serve" ]; then
|
|
30
|
+
"${PYTHON}" "${PYTHON_RENDERER}" --serve 2>/dev/null &
|
|
31
|
+
# Wait briefly for FIFO to be created
|
|
32
|
+
for i in $(seq 1 20); do
|
|
33
|
+
[ -p "$OLED_FIFO" ] && break
|
|
34
|
+
sleep 0.1
|
|
35
|
+
done
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Handle --stop: send quit command to daemon
|
|
40
|
+
if [ "$1" = "--stop" ]; then
|
|
41
|
+
if [ -p "$OLED_FIFO" ]; then
|
|
42
|
+
echo "quit" > "$OLED_FIFO" 2>/dev/null || true
|
|
43
|
+
fi
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Normal message: try FIFO (fast), fallback to direct call
|
|
48
|
+
if [ -p "$OLED_FIFO" ] && [ -f "$OLED_PID" ]; then
|
|
49
|
+
# Daemon is running — send via FIFO (instant, no Python startup)
|
|
50
|
+
MSG=$(IFS='|'; echo "$*")
|
|
51
|
+
echo "$MSG" > "$OLED_FIFO" 2>/dev/null && exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Fallback: direct Python call
|
|
55
|
+
"${PYTHON}" "${PYTHON_RENDERER}" "$@" 2>/dev/null || true
|