ramses-rf 0.53.3__tar.gz → 0.53.5__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.
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.github/workflows/check-cov.yml +1 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.pre-commit-config.yaml +5 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/PKG-INFO +1 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/ramses_rf.rst +8 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/pyproject.toml +1 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_cli/client.py +15 -11
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/database.py +34 -32
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/entity_base.py +3 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/gateway.py +30 -11
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/storage.py +55 -29
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/system/heat.py +38 -12
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/version.py +1 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/__init__.py +8 -5
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/const.py +4 -2
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/gateway.py +28 -16
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/logger.py +27 -8
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/parsers.py +1 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/protocol.py +37 -29
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/ramses.py +10 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/transport.py +29 -15
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/version.py +1 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/requirements/requirements_dev.txt +4 -2
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/common.py +1 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/helpers.py +9 -2
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_2210.log +1 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_eavesdrop_schema.py +1 -1
- ramses_rf-0.53.5/tests/tests/test_hgi_id.py +92 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_schemas.py +7 -13
- ramses_rf-0.53.5/tests/tests/test_systems.py +203 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_cli/test_client.py +5 -4
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_entity_base.py +58 -1
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_protocol_fsm.py +3 -2
- ramses_rf-0.53.5/tests/tests_rf/test_system_heat.py +140 -0
- ramses_rf-0.53.5/tests/tests_tx/test_logger.py +78 -0
- ramses_rf-0.53.3/tests/tests/test_systems.py +0 -264
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.github/dependabot.yml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.github/workflows/check-lint.yml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.github/workflows/check-test.yml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.github/workflows/check-type.yml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.github/workflows/publish-hatch.yml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/.gitignore +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/LICENSE +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/README-developers.md +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/README.md +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/client.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/Makefile +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/make.bat +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/_static/CC-BY-NC-SA-4.0.txt +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/_static/ramses_rf_logo.png +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/binding_process.md +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/conf.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/glossary.rst +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/index.rst +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/modules.rst +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/ramses_cli.rst +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/ramses_rf.device.rst +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/ramses_rf.system.rst +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/ramses_tx.rst +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/docs/source/usage.md +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/misc/2411_parser.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/misc/fingerprints.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/misc/ser2net.yaml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/misc/ti_3410/notes.sh +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/misc/ti_3410/ti_3410.fw +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_cli/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_cli/debug.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_cli/discovery.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_cli/py.typed +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_cli/utils/cat_slow.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_cli/utils/convert.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/binding_fsm.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/const.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/device/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/device/base.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/device/heat.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/device/hvac.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/dispatcher.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/exceptions.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/helpers.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/py.typed +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/schemas.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/system/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/system/faultlog.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/system/schedule.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_rf/system/zones.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/address.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/command.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/exceptions.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/fingerprints.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/frame.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/helpers.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/message.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/opentherm.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/packet.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/protocol_fsm.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/py.typed +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/schemas.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/typed_dicts.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/ramses_tx/typing.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/requirements/requirements.txt +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/requirements/requirements_docs.txt +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/_test_apis_mock.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/_test_mock_faultlog.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/_test_mock_schedule.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/_test_packets_bad.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/_test_performance_WIP.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/_test_state_mgt.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/mocked_devices/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/mocked_devices/command.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/mocked_devices/const.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/mocked_devices/device_heat.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/mocked_devices/device_hvac.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/deprecated/mocked_devices/transport.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/test_HA_MQTT/test_transport_callback.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/heat/ctl_bdr_91t.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/heat/dts_ctl_sensor.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/heat/hcw_ctl_sensor.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/heat/rnd_ctl_sensor.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/heat/rnd_ctl_sensor.yaml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/heat/trv_ctl.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/co2_fan_itho.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/co2_fan_itho.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/co2_fan_itho.yaml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/dis_fan_orcon.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/dis_fan_orcon.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/rem_fan_climarad.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/rem_fan_nuaire.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/rem_fan_nuaire.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/rem_fan_nuaire.yaml +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/rem_fan_vasco.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/bindings/hvac/rem_fan_ventura.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/devices/device_02.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/devices/device_04.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/devices/device_10.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/devices/device_13.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/devices/device_22.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_dev_class/hvac/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_trv_actuator_long/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_ufh_circuits/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/app_cntrl/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/trv_actuators/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_000/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_001/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_002/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_003/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_004/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_off.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_on.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/10e0_xxxx.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/_gather.sh +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/01_EvoTouch_Colour.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/01_Evo_Color.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/01_IONA_RAI_Prototype.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/02_HCE80_V3.10_061117..log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/04_HR92 Radiator Ctrl_.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/08_Jasper_EIM.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/10_R8810A_Bridge.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/10_R8820.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/30_Internet_Gateway.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/31_Jasper_Stat_TXXX.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/heat/34_T87RF2025.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/18_BRDG-02A55.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/18_HRA82.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/20.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/21_CCU-12T20.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMC-07RP01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMC-15RP01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMC-17RP01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMN-07LM01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMN-15LF01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMN-17LMP01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMS-15C16.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/29_VMS-17HB01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/30_BRDG-02EM23.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/30_BRDG-02JAS01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMC-15RPS34.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMD-15RMS64.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMD-15RMS86.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMD-17RPS01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMN-23LM33.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMN-23LMH23.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMS-15CM17.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMS-23C33.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMS-23HB33.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/32_VMZ-15V13.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/37_VMD-07RPS13.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/37_VMI-15MC01log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/37_VMI-15WSJ53.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/37_VMS-02J52.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/37_VMS-12C39.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/99_CVE-RF.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/fingerprints/hvac/99_VMS-17C01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/logger/packet_in.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/logger/packet_out.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/logs/pkts_bad_000.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/logs/pkts_tba_000.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/logs/system_cache.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parser_helpers/pkt_addr_set.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parser_helpers/pkt_dev_class.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0001_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0002.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0004_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0005.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0006.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0008.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0009.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_000a.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_000c.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_000e.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_01ff_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_0418.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_042f.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1030.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1060.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_10d0.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_10e0.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1260.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1298.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_12a0.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_12c0.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1300.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1f09.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1fc9.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_1fd4.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22c9.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22d0.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22d9.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22e0.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22e5.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22e9.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22f1.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22f2.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22f3.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22f4.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_22f7.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_2309.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_2349.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_2411_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_2e04.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_2e10_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_30c9.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3110_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3120.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_313e_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3150.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_31d9.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_31da.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3200.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3210.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3220.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3222.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3ef0_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_3ef1_wip.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_4e01.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_4e02.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_4e04.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/parsers/code_4e15.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schedules/_sched_002/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schedules/_sched_002/schedule.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schedules/sched_001/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schedules/sched_001/schedule.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schedules/sched_dhw/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schedules/sched_dhw/schedule.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/jsn_files/schema_100.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/jsn_files/schema_101.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/jsn_files/schema_102.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/jsn_files/schema_103.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/jsn_files/schema_104.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/jsn_files/schema_105.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/jsn_files/schema_108.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_000.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_000.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_001.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_001.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_002.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_002.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_010.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_010.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_011.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_011.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_012.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_012.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_013.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_013.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_014.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_014.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_300.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_300.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_301.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_301.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_302.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_302.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_303.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_303.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_304.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_304.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_310.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/schemas/log_files/schema_310.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_heat_trv_00/config.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_heat_trv_00/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_heat_trv_00/schema.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_hvac_nuaire/config.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_hvac_nuaire/known_list.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_hvac_nuaire/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_hvac_nuaire/schema.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/_hvac_nuaire/status.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_otb_00/config.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_otb_00/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_otb_00/schema.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_simple/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_simple/schema.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_ufc_00/config.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_ufc_00/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_ufc_01/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_zxdavb/config.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_zxdavb/known_list.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_zxdavb/packet.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/systems/heat_zxdavb/schema.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_api_faultlog.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_api_schedule.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_apis_binding.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_apis_common.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_apis_heat.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_apis_hvac.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_cli_transport_factory.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_devices.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_eavesdrop_dev_class.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_helpers.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_parser_helpers.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_parsers.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_ramses_schema.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_schema_bits.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_storage.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests/test_vol_schemas.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_cli/test_cli_utility.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_cli/test_debug.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_cli/test_discovery.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/configs/config_heat.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/configs/config_hvac.json +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/conftest.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/device/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/device/test_hvac_ventilator.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/logs/test_api_faultlog.log +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_api_faultlog.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_api_schedule.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_binding_fsm.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_create_stack.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_database.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_dispatcher.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_hgi_behaviors.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_use_regex.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_virt_network.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/test_virtual_rf.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/virtual_rf/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/virtual_rf/const.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/virtual_rf/helpers.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_rf/virtual_rf/virtual_rf.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_tx/__init__.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_tx/test_command.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/tests_tx/test_const.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/wip/_test_eavesdrop_dhw_sensor.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/wip/_test_eavesdrop_htg_control.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/wip/_test_eavesdrop_ufc_circuits.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/wip/_test_eavesdrop_zone_sensors.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/wip/_test_eavesdrop_zone_type.py +0 -0
- {ramses_rf-0.53.3 → ramses_rf-0.53.5}/tests/wip/test_wip_cli.sh +0 -0
|
@@ -14,7 +14,7 @@ repos:
|
|
|
14
14
|
# Run `python-typing-update` hook manually from time to time
|
|
15
15
|
# to update python typing syntax.
|
|
16
16
|
# Will require manual work, before submitting changes!
|
|
17
|
-
#
|
|
17
|
+
# prek run --hook-stage manual python-typing-update --all-files
|
|
18
18
|
- id: python-typing-update
|
|
19
19
|
stages: [manual]
|
|
20
20
|
args:
|
|
@@ -39,6 +39,10 @@ repos:
|
|
|
39
39
|
hooks:
|
|
40
40
|
- id: check-executables-have-shebangs
|
|
41
41
|
# id: check-json # don't enable this one
|
|
42
|
+
# - id: no-commit-to-branch
|
|
43
|
+
# args:
|
|
44
|
+
# - --branch=master
|
|
45
|
+
# - --branch=stable
|
|
42
46
|
- id: check-toml
|
|
43
47
|
- id: check-yaml
|
|
44
48
|
- id: debug-statements
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ramses_rf
|
|
3
|
-
Version: 0.53.
|
|
3
|
+
Version: 0.53.5
|
|
4
4
|
Summary: A stateful RAMSES-II protocol decoder & analyser.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ramses-rf/ramses_rf
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/ramses-rf/ramses_rf/issues
|
|
@@ -99,6 +99,14 @@ ramses\_rf.schemas module
|
|
|
99
99
|
:show-inheritance:
|
|
100
100
|
:undoc-members:
|
|
101
101
|
|
|
102
|
+
ramses\_rf.storage module
|
|
103
|
+
-------------------------
|
|
104
|
+
|
|
105
|
+
.. automodule:: ramses_rf.storage
|
|
106
|
+
:members:
|
|
107
|
+
:show-inheritance:
|
|
108
|
+
:undoc-members:
|
|
109
|
+
|
|
102
110
|
ramses\_rf.version module
|
|
103
111
|
-------------------------
|
|
104
112
|
|
|
@@ -471,13 +471,8 @@ def print_results(gwy: Gateway, **kwargs: Any) -> None:
|
|
|
471
471
|
system_id, _ = kwargs[GET_SCHED]
|
|
472
472
|
|
|
473
473
|
|
|
474
|
-
def
|
|
475
|
-
"""
|
|
476
|
-
|
|
477
|
-
:param gwy: The gateway instance.
|
|
478
|
-
"""
|
|
479
|
-
schema, msgs = gwy.get_state()
|
|
480
|
-
|
|
474
|
+
def _write_state(schema: dict[str, Any], msgs: dict[str, str]) -> None:
|
|
475
|
+
"""Write the state to the file system (blocking)."""
|
|
481
476
|
with open("state_msgs.log", "w") as f:
|
|
482
477
|
[f.write(f"{dtm} {pkt}\r\n") for dtm, pkt in msgs.items()] # if not m._expired
|
|
483
478
|
|
|
@@ -485,13 +480,22 @@ def _save_state(gwy: Gateway) -> None:
|
|
|
485
480
|
f.write(json.dumps(schema, indent=4))
|
|
486
481
|
|
|
487
482
|
|
|
488
|
-
def
|
|
483
|
+
async def _save_state(gwy: Gateway) -> None:
|
|
484
|
+
"""Save the gateway state to files.
|
|
485
|
+
|
|
486
|
+
:param gwy: The gateway instance.
|
|
487
|
+
"""
|
|
488
|
+
schema, msgs = await gwy.get_state()
|
|
489
|
+
await asyncio.to_thread(_write_state, schema, msgs)
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
async def _print_engine_state(gwy: Gateway, **kwargs: Any) -> None:
|
|
489
493
|
"""Print the current engine state (schema and packets).
|
|
490
494
|
|
|
491
495
|
:param gwy: The gateway instance.
|
|
492
496
|
:param kwargs: Command arguments to determine verbosity.
|
|
493
497
|
"""
|
|
494
|
-
(schema, packets) = gwy.get_state(include_expired=True)
|
|
498
|
+
(schema, packets) = await gwy.get_state(include_expired=True)
|
|
495
499
|
|
|
496
500
|
if kwargs["print_state"] > 0:
|
|
497
501
|
print(f"schema: {json.dumps(schema, indent=4)}\r\n")
|
|
@@ -671,10 +675,10 @@ async def async_main(command: str, lib_kwargs: dict[str, Any], **kwargs: Any) ->
|
|
|
671
675
|
print(f"\r\nclient.py: Engine stopped: {msg}")
|
|
672
676
|
|
|
673
677
|
# if kwargs["save_state"]:
|
|
674
|
-
# _save_state(gwy)
|
|
678
|
+
# await _save_state(gwy)
|
|
675
679
|
|
|
676
680
|
if kwargs["print_state"]:
|
|
677
|
-
_print_engine_state(gwy, **kwargs)
|
|
681
|
+
await _print_engine_state(gwy, **kwargs)
|
|
678
682
|
|
|
679
683
|
elif command == EXECUTE:
|
|
680
684
|
print_results(gwy, **kwargs)
|
|
@@ -35,7 +35,7 @@ from typing import TYPE_CHECKING, Any, NewType
|
|
|
35
35
|
|
|
36
36
|
from ramses_tx import CODES_SCHEMA, RQ, Code, Message, Packet
|
|
37
37
|
|
|
38
|
-
from .storage import StorageWorker
|
|
38
|
+
from .storage import PacketLogEntry, StorageWorker
|
|
39
39
|
|
|
40
40
|
if TYPE_CHECKING:
|
|
41
41
|
DtmStrT = NewType("DtmStrT", str)
|
|
@@ -241,28 +241,30 @@ class MessageIndex:
|
|
|
241
241
|
:param dt_now: current timestamp
|
|
242
242
|
:param _cutoff: the oldest timestamp to retain, default is 24 hours ago
|
|
243
243
|
"""
|
|
244
|
-
msgs = None
|
|
245
244
|
dtm = dt_now - _cutoff
|
|
246
245
|
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
# Submit prune request to worker (Non-blocking I/O)
|
|
247
|
+
self._worker.submit_prune(dtm)
|
|
248
|
+
|
|
249
|
+
# Prune in-memory cache synchronously (Fast CPU-bound op)
|
|
250
|
+
dtm_iso = dtm.isoformat(timespec="microseconds")
|
|
249
251
|
|
|
250
252
|
try: # make this operation atomic, i.e. update self._msgs only on success
|
|
251
253
|
await self._lock.acquire()
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
254
|
+
# Rebuild dict keeping only newer items
|
|
255
|
+
self._msgs = OrderedDict(
|
|
256
|
+
(k, v) for k, v in self._msgs.items() if k >= dtm_iso
|
|
257
|
+
)
|
|
255
258
|
|
|
256
|
-
except
|
|
257
|
-
|
|
259
|
+
except Exception as err:
|
|
260
|
+
_LOGGER.warning("MessageIndex housekeeping error: %s", err)
|
|
258
261
|
else:
|
|
259
|
-
|
|
262
|
+
_LOGGER.debug(
|
|
263
|
+
"MessageIndex housekeeping completed, retained messages >= %s",
|
|
264
|
+
dtm_iso,
|
|
265
|
+
)
|
|
260
266
|
finally:
|
|
261
267
|
self._lock.release()
|
|
262
|
-
if msgs:
|
|
263
|
-
_LOGGER.debug(
|
|
264
|
-
"MessageIndex size was: %d, now: %d", len(rows), len(msgs)
|
|
265
|
-
)
|
|
266
268
|
|
|
267
269
|
while True:
|
|
268
270
|
self._last_housekeeping = dt.now()
|
|
@@ -345,15 +347,15 @@ class MessageIndex:
|
|
|
345
347
|
# Avoid blocking read; worker handles REPLACE on unique constraint collision
|
|
346
348
|
|
|
347
349
|
# Prepare data tuple for worker
|
|
348
|
-
data = (
|
|
349
|
-
_now,
|
|
350
|
-
verb,
|
|
351
|
-
src,
|
|
352
|
-
src,
|
|
353
|
-
code,
|
|
354
|
-
None,
|
|
355
|
-
hdr,
|
|
356
|
-
"|",
|
|
350
|
+
data = PacketLogEntry(
|
|
351
|
+
dtm=_now,
|
|
352
|
+
verb=verb,
|
|
353
|
+
src=src,
|
|
354
|
+
dst=src,
|
|
355
|
+
code=code,
|
|
356
|
+
ctx=None,
|
|
357
|
+
hdr=hdr,
|
|
358
|
+
plk="|",
|
|
357
359
|
)
|
|
358
360
|
|
|
359
361
|
self._worker.submit_packet(data)
|
|
@@ -390,15 +392,15 @@ class MessageIndex:
|
|
|
390
392
|
# _old_msgs = self._delete_from(hdr=msg._pkt._hdr)
|
|
391
393
|
# Refactor: Worker uses INSERT OR REPLACE to handle collision
|
|
392
394
|
|
|
393
|
-
data = (
|
|
394
|
-
msg.dtm,
|
|
395
|
-
str(msg.verb),
|
|
396
|
-
msg.src.id,
|
|
397
|
-
msg.dst.id,
|
|
398
|
-
str(msg.code),
|
|
399
|
-
msg_pkt_ctx,
|
|
400
|
-
msg._pkt._hdr,
|
|
401
|
-
payload_keys(msg.payload),
|
|
395
|
+
data = PacketLogEntry(
|
|
396
|
+
dtm=msg.dtm,
|
|
397
|
+
verb=str(msg.verb),
|
|
398
|
+
src=msg.src.id,
|
|
399
|
+
dst=msg.dst.id,
|
|
400
|
+
code=str(msg.code),
|
|
401
|
+
ctx=msg_pkt_ctx,
|
|
402
|
+
hdr=msg._pkt._hdr,
|
|
403
|
+
plk=payload_keys(msg.payload),
|
|
402
404
|
)
|
|
403
405
|
|
|
404
406
|
self._worker.submit_packet(data)
|
|
@@ -913,7 +913,9 @@ class _Discovery(_MessageDB):
|
|
|
913
913
|
sql, (self.id[:_ID_SLICE], self.id[:_ID_SLICE])
|
|
914
914
|
):
|
|
915
915
|
_LOGGER.debug("Fetched OT ctx from index: %s", rec[0])
|
|
916
|
-
|
|
916
|
+
# SQLite can return int, expected str (hex)
|
|
917
|
+
val = f"{rec[0]:02X}" if isinstance(rec[0], int) else rec[0]
|
|
918
|
+
res.append(val)
|
|
917
919
|
else: # TODO(eb): remove next Q1 2026
|
|
918
920
|
res_dict: dict[bool | str | None, Message] | list[Any] = self._msgz[
|
|
919
921
|
Code._3220
|
|
@@ -12,6 +12,7 @@ from __future__ import annotations
|
|
|
12
12
|
import asyncio
|
|
13
13
|
import logging
|
|
14
14
|
from collections.abc import Awaitable, Callable
|
|
15
|
+
from logging.handlers import QueueListener
|
|
15
16
|
from types import SimpleNamespace
|
|
16
17
|
from typing import TYPE_CHECKING, Any
|
|
17
18
|
|
|
@@ -101,6 +102,7 @@ class Gateway(Engine):
|
|
|
101
102
|
known_list: DeviceListT | None = None,
|
|
102
103
|
loop: asyncio.AbstractEventLoop | None = None,
|
|
103
104
|
transport_constructor: Callable[..., Awaitable[RamsesTransportT]] | None = None,
|
|
105
|
+
hgi_id: str | None = None,
|
|
104
106
|
**kwargs: Any,
|
|
105
107
|
) -> None:
|
|
106
108
|
"""Initialize the Gateway instance.
|
|
@@ -121,6 +123,8 @@ class Gateway(Engine):
|
|
|
121
123
|
:type loop: asyncio.AbstractEventLoop | None, optional
|
|
122
124
|
:param transport_constructor: A factory for creating the transport layer, defaults to None.
|
|
123
125
|
:type transport_constructor: Callable[..., Awaitable[RamsesTransportT]] | None, optional
|
|
126
|
+
:param hgi_id: The Device ID to use for the HGI (gateway), overriding defaults.
|
|
127
|
+
:type hgi_id: str | None, optional
|
|
124
128
|
:param kwargs: Additional configuration parameters passed to the engine and schema.
|
|
125
129
|
:type kwargs: Any
|
|
126
130
|
"""
|
|
@@ -138,6 +142,7 @@ class Gateway(Engine):
|
|
|
138
142
|
block_list=block_list,
|
|
139
143
|
known_list=known_list,
|
|
140
144
|
loop=loop,
|
|
145
|
+
hgi_id=hgi_id,
|
|
141
146
|
transport_constructor=transport_constructor,
|
|
142
147
|
**SCH_ENGINE_CONFIG(config),
|
|
143
148
|
)
|
|
@@ -159,6 +164,7 @@ class Gateway(Engine):
|
|
|
159
164
|
self.device_by_id: dict[DeviceIdT, Device] = {}
|
|
160
165
|
|
|
161
166
|
self.msg_db: MessageIndex | None = None
|
|
167
|
+
self._pkt_log_listener: QueueListener | None = None
|
|
162
168
|
|
|
163
169
|
def __repr__(self) -> str:
|
|
164
170
|
"""Return a string representation of the Gateway.
|
|
@@ -218,10 +224,12 @@ class Gateway(Engine):
|
|
|
218
224
|
if system.dhw:
|
|
219
225
|
system.dhw._start_discovery_poller()
|
|
220
226
|
|
|
221
|
-
await set_pkt_logging_config( # type: ignore[arg-type]
|
|
227
|
+
_, self._pkt_log_listener = await set_pkt_logging_config( # type: ignore[arg-type]
|
|
222
228
|
cc_console=self.config.reduce_processing >= DONT_CREATE_MESSAGES,
|
|
223
229
|
**self._packet_log,
|
|
224
230
|
)
|
|
231
|
+
if self._pkt_log_listener:
|
|
232
|
+
self._pkt_log_listener.start()
|
|
225
233
|
|
|
226
234
|
# initialize SQLite index, set in _tx/Engine
|
|
227
235
|
if self._sqlite_index: # TODO(eb): default to True in Q1 2026
|
|
@@ -267,12 +275,21 @@ class Gateway(Engine):
|
|
|
267
275
|
:returns: None
|
|
268
276
|
:rtype: None
|
|
269
277
|
"""
|
|
278
|
+
# Stop the Engine first to ensure no tasks/callbacks try to write
|
|
279
|
+
# to the DB while we are closing it.
|
|
280
|
+
await super().stop()
|
|
281
|
+
|
|
282
|
+
if self._pkt_log_listener:
|
|
283
|
+
self._pkt_log_listener.stop()
|
|
284
|
+
# Close handlers to ensure files are flushed/closed
|
|
285
|
+
for handler in self._pkt_log_listener.handlers:
|
|
286
|
+
handler.close()
|
|
287
|
+
self._pkt_log_listener = None
|
|
270
288
|
|
|
271
289
|
if self.msg_db:
|
|
272
290
|
self.msg_db.stop()
|
|
273
|
-
await super().stop()
|
|
274
291
|
|
|
275
|
-
def _pause(self, *args: Any) -> None:
|
|
292
|
+
async def _pause(self, *args: Any) -> None:
|
|
276
293
|
"""Pause the (unpaused) gateway (disables sending/discovery).
|
|
277
294
|
|
|
278
295
|
There is the option to save other objects, as `args`.
|
|
@@ -288,12 +305,12 @@ class Gateway(Engine):
|
|
|
288
305
|
self.config.disable_discovery, disc_flag = True, self.config.disable_discovery
|
|
289
306
|
|
|
290
307
|
try:
|
|
291
|
-
super()._pause(disc_flag, *args)
|
|
308
|
+
await super()._pause(disc_flag, *args)
|
|
292
309
|
except RuntimeError:
|
|
293
310
|
self.config.disable_discovery = disc_flag
|
|
294
311
|
raise
|
|
295
312
|
|
|
296
|
-
def _resume(self) -> tuple[Any]:
|
|
313
|
+
async def _resume(self) -> tuple[Any]:
|
|
297
314
|
"""Resume the (paused) gateway (enables sending/discovery, if applicable).
|
|
298
315
|
|
|
299
316
|
Will restore other objects, as `args`.
|
|
@@ -305,11 +322,13 @@ class Gateway(Engine):
|
|
|
305
322
|
|
|
306
323
|
_LOGGER.debug("Gateway: Resuming engine...")
|
|
307
324
|
|
|
308
|
-
|
|
325
|
+
# args_tuple = await super()._resume()
|
|
326
|
+
# self.config.disable_discovery, *args = args_tuple # type: ignore[assignment]
|
|
327
|
+
self.config.disable_discovery, *args = await super()._resume() # type: ignore[assignment]
|
|
309
328
|
|
|
310
329
|
return args
|
|
311
330
|
|
|
312
|
-
def get_state(
|
|
331
|
+
async def get_state(
|
|
313
332
|
self, include_expired: bool = False
|
|
314
333
|
) -> tuple[dict[str, Any], dict[str, str]]:
|
|
315
334
|
"""Return the current schema & state (may include expired packets).
|
|
@@ -320,7 +339,7 @@ class Gateway(Engine):
|
|
|
320
339
|
:rtype: tuple[dict[str, Any], dict[str, str]]
|
|
321
340
|
"""
|
|
322
341
|
|
|
323
|
-
self._pause()
|
|
342
|
+
await self._pause()
|
|
324
343
|
|
|
325
344
|
def wanted_msg(msg: Message, include_expired: bool = False) -> bool:
|
|
326
345
|
if msg.code == Code._313F:
|
|
@@ -357,7 +376,7 @@ class Gateway(Engine):
|
|
|
357
376
|
}
|
|
358
377
|
# _LOGGER.warning("Missing MessageIndex")
|
|
359
378
|
|
|
360
|
-
self._resume()
|
|
379
|
+
await self._resume()
|
|
361
380
|
|
|
362
381
|
return self.schema, dict(sorted(pkts.items()))
|
|
363
382
|
|
|
@@ -392,7 +411,7 @@ class Gateway(Engine):
|
|
|
392
411
|
tmp_transport: RamsesTransportT # mypy hint
|
|
393
412
|
|
|
394
413
|
_LOGGER.debug("Gateway: Restoring a cached packet log...")
|
|
395
|
-
self._pause()
|
|
414
|
+
await self._pause()
|
|
396
415
|
|
|
397
416
|
if _clear_state: # only intended for test suite use
|
|
398
417
|
clear_state()
|
|
@@ -428,7 +447,7 @@ class Gateway(Engine):
|
|
|
428
447
|
await tmp_transport.get_extra_info(SZ_READER_TASK)
|
|
429
448
|
|
|
430
449
|
_LOGGER.debug("Gateway: Restored, resuming")
|
|
431
|
-
self._resume()
|
|
450
|
+
await self._resume()
|
|
432
451
|
|
|
433
452
|
def _add_device(self, dev: Device) -> None: # TODO: also: _add_system()
|
|
434
453
|
"""Add a device to the gateway (called by devices during instantiation).
|
|
@@ -7,24 +7,46 @@ import logging
|
|
|
7
7
|
import queue
|
|
8
8
|
import sqlite3
|
|
9
9
|
import threading
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any, NamedTuple
|
|
11
11
|
|
|
12
12
|
_LOGGER = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
class PacketLogEntry(NamedTuple):
|
|
16
|
+
"""Represents a packet to be written to the database."""
|
|
17
|
+
|
|
18
|
+
dtm: Any
|
|
19
|
+
verb: str
|
|
20
|
+
src: str
|
|
21
|
+
dst: str
|
|
22
|
+
code: str
|
|
23
|
+
ctx: str | None
|
|
24
|
+
hdr: str
|
|
25
|
+
plk: str
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PruneRequest(NamedTuple):
|
|
29
|
+
"""Represents a request to prune old records."""
|
|
30
|
+
|
|
31
|
+
dtm_limit: Any
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
QueueItem = PacketLogEntry | PruneRequest | tuple[str, Any] | None
|
|
35
|
+
|
|
36
|
+
|
|
15
37
|
class StorageWorker:
|
|
16
38
|
"""A background worker thread to handle blocking storage I/O asynchronously."""
|
|
17
39
|
|
|
18
|
-
def __init__(self, db_path: str = ":memory:"):
|
|
40
|
+
def __init__(self, db_path: str = ":memory:") -> None:
|
|
19
41
|
"""Initialize the storage worker thread."""
|
|
20
42
|
self._db_path = db_path
|
|
21
|
-
self._queue: queue.SimpleQueue[
|
|
43
|
+
self._queue: queue.SimpleQueue[QueueItem] = queue.SimpleQueue()
|
|
22
44
|
self._ready_event = threading.Event()
|
|
23
45
|
|
|
24
46
|
self._thread = threading.Thread(
|
|
25
47
|
target=self._run,
|
|
26
48
|
name="RamsesStorage",
|
|
27
|
-
daemon=True, #
|
|
49
|
+
daemon=True, # Allows process exit even if stop() is missed
|
|
28
50
|
)
|
|
29
51
|
self._thread.start()
|
|
30
52
|
|
|
@@ -32,16 +54,16 @@ class StorageWorker:
|
|
|
32
54
|
"""Wait until the database is initialized and ready."""
|
|
33
55
|
return self._ready_event.wait(timeout)
|
|
34
56
|
|
|
35
|
-
def submit_packet(self,
|
|
57
|
+
def submit_packet(self, packet: PacketLogEntry) -> None:
|
|
36
58
|
"""Submit a packet tuple for SQL insertion (Non-blocking)."""
|
|
37
|
-
self._queue.put(
|
|
59
|
+
self._queue.put(packet)
|
|
60
|
+
|
|
61
|
+
def submit_prune(self, dtm_limit: Any) -> None:
|
|
62
|
+
"""Submit a prune request for SQL deletion (Non-blocking)."""
|
|
63
|
+
self._queue.put(PruneRequest(dtm_limit))
|
|
38
64
|
|
|
39
65
|
def flush(self, timeout: float = 10.0) -> None:
|
|
40
66
|
"""Block until all currently pending tasks are processed."""
|
|
41
|
-
# REMOVED: if self._queue.empty(): return
|
|
42
|
-
# This check caused a race condition where flush() returned before
|
|
43
|
-
# the worker finished committing the last item it just popped.
|
|
44
|
-
|
|
45
67
|
# We inject a special marker into the queue
|
|
46
68
|
sentinel = threading.Event()
|
|
47
69
|
self._queue.put(("MARKER", sentinel))
|
|
@@ -89,7 +111,7 @@ class StorageWorker:
|
|
|
89
111
|
detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES,
|
|
90
112
|
check_same_thread=False,
|
|
91
113
|
uri=True,
|
|
92
|
-
timeout=10.0,
|
|
114
|
+
timeout=10.0,
|
|
93
115
|
)
|
|
94
116
|
|
|
95
117
|
# Enable Write-Ahead Logging for concurrency
|
|
@@ -116,16 +138,9 @@ class StorageWorker:
|
|
|
116
138
|
if item is None: # Shutdown signal
|
|
117
139
|
break
|
|
118
140
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if task_type == "MARKER":
|
|
122
|
-
# Flush requested
|
|
123
|
-
data.set()
|
|
124
|
-
continue
|
|
125
|
-
|
|
126
|
-
if task_type == "SQL":
|
|
141
|
+
if isinstance(item, PacketLogEntry):
|
|
127
142
|
# Optimization: Batch processing
|
|
128
|
-
batch = [
|
|
143
|
+
batch = [item]
|
|
129
144
|
# Drain queue of pending SQL tasks to bulk insert
|
|
130
145
|
while not self._queue.empty():
|
|
131
146
|
try:
|
|
@@ -135,22 +150,19 @@ class StorageWorker:
|
|
|
135
150
|
self._queue.put(None) # Re-queue poison pill
|
|
136
151
|
break
|
|
137
152
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
batch.append(next_data)
|
|
141
|
-
elif next_type == "MARKER":
|
|
142
|
-
# Handle marker after this batch
|
|
143
|
-
self._queue.put(next_item) # Re-queue marker
|
|
144
|
-
break
|
|
153
|
+
if isinstance(next_item, PacketLogEntry):
|
|
154
|
+
batch.append(next_item)
|
|
145
155
|
else:
|
|
146
|
-
|
|
156
|
+
# Handle other types after this batch
|
|
157
|
+
self._queue.put(next_item) # Re-queue
|
|
158
|
+
break
|
|
147
159
|
except queue.Empty:
|
|
148
160
|
break
|
|
149
161
|
|
|
150
162
|
try:
|
|
151
163
|
conn.executemany(
|
|
152
164
|
"""
|
|
153
|
-
INSERT OR REPLACE INTO messages
|
|
165
|
+
INSERT OR REPLACE INTO messages
|
|
154
166
|
(dtm, verb, src, dst, code, ctx, hdr, plk)
|
|
155
167
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
156
168
|
""",
|
|
@@ -160,6 +172,20 @@ class StorageWorker:
|
|
|
160
172
|
except sqlite3.Error as err:
|
|
161
173
|
_LOGGER.error("SQL Write Failed: %s", err)
|
|
162
174
|
|
|
175
|
+
elif isinstance(item, PruneRequest):
|
|
176
|
+
try:
|
|
177
|
+
conn.execute(
|
|
178
|
+
"DELETE FROM messages WHERE dtm < ?", (item.dtm_limit,)
|
|
179
|
+
)
|
|
180
|
+
conn.commit()
|
|
181
|
+
_LOGGER.debug("Pruned records older than %s", item.dtm_limit)
|
|
182
|
+
except sqlite3.Error as err:
|
|
183
|
+
_LOGGER.error("SQL Prune Failed: %s", err)
|
|
184
|
+
|
|
185
|
+
elif isinstance(item, tuple) and item[0] == "MARKER":
|
|
186
|
+
# Flush requested
|
|
187
|
+
item[1].set()
|
|
188
|
+
|
|
163
189
|
except Exception as err:
|
|
164
190
|
_LOGGER.exception("StorageWorker encountered an error: %s", err)
|
|
165
191
|
|
|
@@ -137,7 +137,7 @@ class SystemBase(Parent, Entity): # 3B00 (multi-relay)
|
|
|
137
137
|
self._child_id = FF # NOTE: domain_id
|
|
138
138
|
|
|
139
139
|
self._app_cntrl: BdrSwitch | OtbGateway | None = None
|
|
140
|
-
self._heat_demand = None
|
|
140
|
+
self._heat_demand: dict[str, Any] | None = None
|
|
141
141
|
|
|
142
142
|
def __repr__(self) -> str:
|
|
143
143
|
return f"{self.ctl.id} ({self._SLUG})"
|
|
@@ -217,17 +217,33 @@ class SystemBase(Parent, Entity): # 3B00 (multi-relay)
|
|
|
217
217
|
super()._handle_msg(msg)
|
|
218
218
|
|
|
219
219
|
if msg.code == Code._000C:
|
|
220
|
-
if msg.payload
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
220
|
+
if isinstance(msg.payload, dict):
|
|
221
|
+
if msg.payload[SZ_ZONE_TYPE] == DEV_ROLE_MAP.APP and msg.payload.get(
|
|
222
|
+
SZ_DEVICES
|
|
223
|
+
):
|
|
224
|
+
self._gwy.get_device(
|
|
225
|
+
msg.payload[SZ_DEVICES][0], parent=self, child_id=FC
|
|
226
|
+
) # sets self._app_cntrl
|
|
227
|
+
else:
|
|
228
|
+
_LOGGER.warning(
|
|
229
|
+
f"{msg!r} < Unexpected payload type for {msg.code}: {type(msg.payload)} (expected dict)"
|
|
230
|
+
)
|
|
226
231
|
return
|
|
227
232
|
|
|
228
|
-
if msg.code == Code._3150:
|
|
229
|
-
|
|
230
|
-
|
|
233
|
+
if msg.code == Code._3150 and msg.verb in (I_, RP):
|
|
234
|
+
# 3150 payload can be a dict (old) or list (new, multi-zone)
|
|
235
|
+
if isinstance(msg.payload, list):
|
|
236
|
+
if payload := next(
|
|
237
|
+
(d for d in msg.payload if d.get(SZ_DOMAIN_ID) == FC), None
|
|
238
|
+
):
|
|
239
|
+
self._heat_demand = payload
|
|
240
|
+
elif isinstance(msg.payload, dict):
|
|
241
|
+
if msg.payload.get(SZ_DOMAIN_ID) == FC:
|
|
242
|
+
self._heat_demand = msg.payload
|
|
243
|
+
else:
|
|
244
|
+
_LOGGER.warning(
|
|
245
|
+
f"{msg!r} < Unexpected payload type for {msg.code}: {type(msg.payload)} (expected list/dict)"
|
|
246
|
+
)
|
|
231
247
|
|
|
232
248
|
if self._gwy.config.enable_eavesdrop and not self.appliance_control:
|
|
233
249
|
eavesdrop_appliance_control(msg)
|
|
@@ -588,7 +604,12 @@ class ScheduleSync(SystemBase): # 0006 (+/- 0404?)
|
|
|
588
604
|
super()._handle_msg(msg)
|
|
589
605
|
|
|
590
606
|
if msg.code == Code._0006:
|
|
591
|
-
|
|
607
|
+
if isinstance(msg.payload, dict):
|
|
608
|
+
self._msg_0006 = msg
|
|
609
|
+
else:
|
|
610
|
+
_LOGGER.warning(
|
|
611
|
+
f"{msg!r} < Unexpected payload type for {msg.code}: {type(msg.payload)} (expected dict)"
|
|
612
|
+
)
|
|
592
613
|
|
|
593
614
|
async def _schedule_version(self, *, force_io: bool = False) -> tuple[int, bool]:
|
|
594
615
|
"""Return the global schedule version number, and an indication if I/O was done.
|
|
@@ -706,7 +727,12 @@ class Logbook(SystemBase): # 0418
|
|
|
706
727
|
super()._handle_msg(msg)
|
|
707
728
|
|
|
708
729
|
if msg.code == Code._0418: # and msg.verb in (I_, RP):
|
|
709
|
-
|
|
730
|
+
if isinstance(msg.payload, dict):
|
|
731
|
+
self._faultlog.handle_msg(msg)
|
|
732
|
+
else:
|
|
733
|
+
_LOGGER.warning(
|
|
734
|
+
f"{msg!r} < Unexpected payload type for {msg.code}: {type(msg.payload)} (expected dict)"
|
|
735
|
+
)
|
|
710
736
|
|
|
711
737
|
async def get_faultlog(
|
|
712
738
|
self,
|
|
@@ -7,6 +7,7 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
import asyncio
|
|
9
9
|
from functools import partial
|
|
10
|
+
from logging.handlers import QueueListener
|
|
10
11
|
from typing import TYPE_CHECKING, Any
|
|
11
12
|
|
|
12
13
|
from .address import (
|
|
@@ -156,17 +157,19 @@ if TYPE_CHECKING:
|
|
|
156
157
|
from logging import Logger
|
|
157
158
|
|
|
158
159
|
|
|
159
|
-
async def set_pkt_logging_config(**config: Any) -> Logger:
|
|
160
|
+
async def set_pkt_logging_config(**config: Any) -> tuple[Logger, QueueListener | None]:
|
|
160
161
|
"""
|
|
161
162
|
Set up ramses packet logging to a file or port.
|
|
162
|
-
Must run async in executor to prevent HA blocking call opening packet log file
|
|
163
|
+
Must run async in executor to prevent HA blocking call opening packet log file.
|
|
163
164
|
|
|
164
165
|
:param config: if file_name is included, opens packet_log file
|
|
165
|
-
:return: a logging.Logger
|
|
166
|
+
:return: a tuple (logging.Logger, QueueListener)
|
|
166
167
|
"""
|
|
167
168
|
loop = asyncio.get_running_loop()
|
|
168
|
-
await loop.run_in_executor(
|
|
169
|
-
|
|
169
|
+
listener = await loop.run_in_executor(
|
|
170
|
+
None, partial(set_pkt_logging, PKT_LOGGER, **config)
|
|
171
|
+
)
|
|
172
|
+
return PKT_LOGGER, listener
|
|
170
173
|
|
|
171
174
|
|
|
172
175
|
def extract_known_hgi_id(
|
|
@@ -20,10 +20,12 @@ DEFAULT_DISABLE_QOS: Final[bool | None] = None
|
|
|
20
20
|
DEFAULT_WAIT_FOR_REPLY: Final[bool | None] = None
|
|
21
21
|
|
|
22
22
|
#: Waiting for echo pkt after cmd sent (seconds)
|
|
23
|
-
|
|
23
|
+
# NOTE: Increased to 3.0s to support high-latency transports (e.g., MQTT)
|
|
24
|
+
DEFAULT_ECHO_TIMEOUT: Final[float] = 3.00
|
|
24
25
|
|
|
25
26
|
#: Waiting for reply pkt after echo pkt rcvd (seconds)
|
|
26
|
-
|
|
27
|
+
# NOTE: Increased to 3.0s to support high-latency transports (e.g., MQTT)
|
|
28
|
+
DEFAULT_RPLY_TIMEOUT: Final[float] = 3.00
|
|
27
29
|
DEFAULT_BUFFER_SIZE: Final[int] = 32
|
|
28
30
|
|
|
29
31
|
#: Total waiting for successful send (seconds)
|