ramses-rf 0.52.2__tar.gz → 0.52.3__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.
Files changed (375) hide show
  1. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.github/workflows/check-lint.yml +1 -1
  2. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.github/workflows/check-test.yml +1 -1
  3. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.github/workflows/check-type.yml +1 -1
  4. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.github/workflows/publish-hatch.yml +2 -2
  5. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/PKG-INFO +1 -1
  6. ramses_rf-0.52.3/docs/source/binding_process_diagram.md +159 -0
  7. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/conf.py +2 -0
  8. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/index.rst +1 -0
  9. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/usage.md +1 -1
  10. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/binding_fsm.py +18 -4
  11. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/database.py +2 -2
  12. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/device/heat.py +3 -6
  13. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/entity_base.py +89 -35
  14. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/system/zones.py +1 -1
  15. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/version.py +1 -1
  16. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/gateway.py +3 -0
  17. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/logger.py +8 -0
  18. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/schemas.py +4 -0
  19. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/transport.py +14 -3
  20. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/version.py +1 -1
  21. {ramses_rf-0.52.2 → ramses_rf-0.52.3/requirements}/requirements_docs.txt +2 -0
  22. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_systems.py +1 -4
  23. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_database.py +32 -0
  24. ramses_rf-0.52.3/tests/tests_rf/test_entity_base.py +228 -0
  25. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  26. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.github/dependabot.yml +0 -0
  27. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.gitignore +0 -0
  28. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/.pre-commit-config.yaml +0 -0
  29. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/LICENSE +0 -0
  30. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/README-developers.md +0 -0
  31. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/README.md +0 -0
  32. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/client.py +0 -0
  33. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/Makefile +0 -0
  34. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/make.bat +0 -0
  35. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/_static/ramses_rf_logo.png +0 -0
  36. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/glossary.rst +0 -0
  37. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/modules.rst +0 -0
  38. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/ramses_cli.rst +0 -0
  39. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/ramses_rf.device.rst +0 -0
  40. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/ramses_rf.rst +0 -0
  41. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/ramses_rf.system.rst +0 -0
  42. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/docs/source/ramses_tx.rst +0 -0
  43. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/misc/2411_parser.py +0 -0
  44. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/misc/fingerprints.log +0 -0
  45. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/misc/ser2net.yaml +0 -0
  46. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/misc/ti_3410/notes.sh +0 -0
  47. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/misc/ti_3410/ti_3410.fw +0 -0
  48. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/pyproject.toml +0 -0
  49. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_cli/__init__.py +0 -0
  50. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_cli/client.py +0 -0
  51. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_cli/debug.py +0 -0
  52. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_cli/discovery.py +0 -0
  53. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_cli/utils/cat_slow.py +0 -0
  54. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_cli/utils/convert.py +0 -0
  55. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/__init__.py +0 -0
  56. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/const.py +0 -0
  57. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/device/__init__.py +0 -0
  58. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/device/base.py +0 -0
  59. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/device/hvac.py +0 -0
  60. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/dispatcher.py +0 -0
  61. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/exceptions.py +0 -0
  62. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/gateway.py +0 -0
  63. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/helpers.py +0 -0
  64. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/py.typed +0 -0
  65. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/schemas.py +0 -0
  66. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/system/__init__.py +0 -0
  67. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/system/faultlog.py +0 -0
  68. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/system/heat.py +0 -0
  69. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_rf/system/schedule.py +0 -0
  70. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/__init__.py +0 -0
  71. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/address.py +0 -0
  72. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/command.py +0 -0
  73. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/const.py +0 -0
  74. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/exceptions.py +0 -0
  75. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/fingerprints.py +0 -0
  76. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/frame.py +0 -0
  77. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/helpers.py +0 -0
  78. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/message.py +0 -0
  79. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/opentherm.py +0 -0
  80. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/packet.py +0 -0
  81. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/parsers.py +0 -0
  82. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/protocol.py +0 -0
  83. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/protocol_fsm.py +0 -0
  84. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/py.typed +0 -0
  85. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/ramses.py +0 -0
  86. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/typed_dicts.py +0 -0
  87. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/ramses_tx/typing.py +0 -0
  88. {ramses_rf-0.52.2 → ramses_rf-0.52.3/requirements}/requirements.txt +0 -0
  89. {ramses_rf-0.52.2 → ramses_rf-0.52.3/requirements}/requirements_dev.txt +0 -0
  90. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/_test_apis_mock.py +0 -0
  91. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/_test_mock_faultlog.py +0 -0
  92. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/_test_mock_schedule.py +0 -0
  93. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/_test_packets_bad.py +0 -0
  94. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/_test_performance_WIP.py +0 -0
  95. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/_test_state_mgt.py +0 -0
  96. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/common.py +0 -0
  97. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/mocked_devices/__init__.py +0 -0
  98. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/mocked_devices/command.py +0 -0
  99. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/mocked_devices/const.py +0 -0
  100. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/mocked_devices/device_heat.py +0 -0
  101. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/mocked_devices/device_hvac.py +0 -0
  102. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/deprecated/mocked_devices/transport.py +0 -0
  103. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/__init__.py +0 -0
  104. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/heat/ctl_bdr_91t.log +0 -0
  105. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/heat/dts_ctl_sensor.log +0 -0
  106. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/heat/hcw_ctl_sensor.log +0 -0
  107. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/heat/rnd_ctl_sensor.log +0 -0
  108. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/heat/rnd_ctl_sensor.yaml +0 -0
  109. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/heat/trv_ctl.log +0 -0
  110. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/co2_fan_itho.json +0 -0
  111. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/co2_fan_itho.log +0 -0
  112. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/co2_fan_itho.yaml +0 -0
  113. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/dis_fan_orcon.json +0 -0
  114. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/dis_fan_orcon.log +0 -0
  115. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/rem_fan_climarad.log +0 -0
  116. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/rem_fan_nuaire.json +0 -0
  117. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/rem_fan_nuaire.log +0 -0
  118. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/rem_fan_nuaire.yaml +0 -0
  119. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/rem_fan_vasco.log +0 -0
  120. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/bindings/hvac/rem_fan_ventura.log +0 -0
  121. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/devices/device_02.log +0 -0
  122. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/devices/device_04.log +0 -0
  123. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/devices/device_10.log +0 -0
  124. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/devices/device_13.log +0 -0
  125. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/devices/device_22.log +0 -0
  126. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_off.json +0 -0
  127. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_on.json +0 -0
  128. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_dev_class/hvac/packet.log +0 -0
  129. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_trv_actuator_long/packet.log +0 -0
  130. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_off.json +0 -0
  131. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_on.json +0 -0
  132. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/packet.log +0 -0
  133. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_off.json +0 -0
  134. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_on.json +0 -0
  135. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_ufh_circuits/packet.log +0 -0
  136. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_off.json +0 -0
  137. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_on.json +0 -0
  138. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/app_cntrl/packet.log +0 -0
  139. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_off.json +0 -0
  140. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_on.json +0 -0
  141. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/trv_actuators/packet.log +0 -0
  142. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_off.json +0 -0
  143. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_on.json +0 -0
  144. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_000/packet.log +0 -0
  145. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_off.json +0 -0
  146. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_on.json +0 -0
  147. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_001/packet.log +0 -0
  148. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_off.json +0 -0
  149. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_on.json +0 -0
  150. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_002/packet.log +0 -0
  151. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_off.json +0 -0
  152. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_on.json +0 -0
  153. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_003/packet.log +0 -0
  154. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_off.json +0 -0
  155. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_on.json +0 -0
  156. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_004/packet.log +0 -0
  157. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_off.json +0 -0
  158. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_on.json +0 -0
  159. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/10e0_xxxx.log +0 -0
  160. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/_gather.sh +0 -0
  161. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/01_EvoTouch_Colour.log +0 -0
  162. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/01_Evo_Color.log +0 -0
  163. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/01_IONA_RAI_Prototype.log +0 -0
  164. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/02_HCE80_V3.10_061117..log +0 -0
  165. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/04_HR92 Radiator Ctrl_.log +0 -0
  166. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/08_Jasper_EIM.log +0 -0
  167. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/10_R8810A_Bridge.log +0 -0
  168. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/10_R8820.log +0 -0
  169. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/30_Internet_Gateway.log +0 -0
  170. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/31_Jasper_Stat_TXXX.log +0 -0
  171. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/heat/34_T87RF2025.log +0 -0
  172. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/18_BRDG-02A55.log +0 -0
  173. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/18_HRA82.log +0 -0
  174. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/20.log +0 -0
  175. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/21_CCU-12T20.log +0 -0
  176. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMC-07RP01.log +0 -0
  177. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMC-15RP01.log +0 -0
  178. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMC-17RP01.log +0 -0
  179. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMN-07LM01.log +0 -0
  180. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMN-15LF01.log +0 -0
  181. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMN-17LMP01.log +0 -0
  182. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMS-15C16.log +0 -0
  183. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/29_VMS-17HB01.log +0 -0
  184. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/30_BRDG-02EM23.log +0 -0
  185. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/30_BRDG-02JAS01.log +0 -0
  186. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMC-15RPS34.log +0 -0
  187. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMD-15RMS64.log +0 -0
  188. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMD-15RMS86.log +0 -0
  189. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMD-17RPS01.log +0 -0
  190. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMN-23LM33.log +0 -0
  191. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMN-23LMH23.log +0 -0
  192. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMS-15CM17.log +0 -0
  193. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMS-23C33.log +0 -0
  194. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMS-23HB33.log +0 -0
  195. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/32_VMZ-15V13.log +0 -0
  196. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/37_VMD-07RPS13.log +0 -0
  197. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/37_VMI-15MC01log +0 -0
  198. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/37_VMI-15WSJ53.log +0 -0
  199. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/37_VMS-02J52.log +0 -0
  200. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/37_VMS-12C39.log +0 -0
  201. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/99_CVE-RF.log +0 -0
  202. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/fingerprints/hvac/99_VMS-17C01.log +0 -0
  203. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/helpers.py +0 -0
  204. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/logger/packet_in.log +0 -0
  205. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/logger/packet_out.log +0 -0
  206. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/logs/pkts_bad_000.log +0 -0
  207. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/logs/pkts_tba_000.log +0 -0
  208. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/logs/system_cache.json +0 -0
  209. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parser_helpers/pkt_addr_set.log +0 -0
  210. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parser_helpers/pkt_dev_class.log +0 -0
  211. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0001_wip.log +0 -0
  212. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0002.log +0 -0
  213. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0004_wip.log +0 -0
  214. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0005.log +0 -0
  215. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0006.log +0 -0
  216. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0008.log +0 -0
  217. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0009.log +0 -0
  218. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_000a.log +0 -0
  219. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_000c.log +0 -0
  220. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_000e.log +0 -0
  221. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_01ff_wip.log +0 -0
  222. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_0418.log +0 -0
  223. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_042f.log +0 -0
  224. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1030.log +0 -0
  225. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1060.log +0 -0
  226. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_10d0.log +0 -0
  227. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_10e0.log +0 -0
  228. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1260.log +0 -0
  229. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1298.log +0 -0
  230. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_12a0.log +0 -0
  231. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_12c0.log +0 -0
  232. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1300.log +0 -0
  233. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1f09.log +0 -0
  234. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1fc9.log +0 -0
  235. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_1fd4.log +0 -0
  236. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_2210.log +0 -0
  237. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22c9.log +0 -0
  238. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22d0.log +0 -0
  239. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22d9.log +0 -0
  240. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22e0.log +0 -0
  241. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22e5.log +0 -0
  242. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22e9.log +0 -0
  243. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22f1.log +0 -0
  244. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22f2.log +0 -0
  245. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22f3.log +0 -0
  246. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22f4.log +0 -0
  247. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_22f7.log +0 -0
  248. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_2309.log +0 -0
  249. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_2349.log +0 -0
  250. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_2411_wip.log +0 -0
  251. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_2e04.log +0 -0
  252. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_2e10_wip.log +0 -0
  253. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_30c9.log +0 -0
  254. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3110_wip.log +0 -0
  255. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3120.log +0 -0
  256. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_313e_wip.log +0 -0
  257. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3150.log +0 -0
  258. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_31d9.log +0 -0
  259. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_31da.log +0 -0
  260. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3200.log +0 -0
  261. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3210.log +0 -0
  262. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3220.log +0 -0
  263. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3222.log +0 -0
  264. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3ef0_wip.log +0 -0
  265. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_3ef1_wip.log +0 -0
  266. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_4e01.log +0 -0
  267. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_4e02.log +0 -0
  268. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_4e04.log +0 -0
  269. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/parsers/code_4e15.log +0 -0
  270. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schedules/_sched_002/packet.log +0 -0
  271. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schedules/_sched_002/schedule.json +0 -0
  272. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schedules/sched_001/packet.log +0 -0
  273. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schedules/sched_001/schedule.json +0 -0
  274. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schedules/sched_dhw/packet.log +0 -0
  275. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schedules/sched_dhw/schedule.json +0 -0
  276. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/jsn_files/schema_100.json +0 -0
  277. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/jsn_files/schema_101.json +0 -0
  278. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/jsn_files/schema_102.json +0 -0
  279. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/jsn_files/schema_103.json +0 -0
  280. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/jsn_files/schema_104.json +0 -0
  281. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/jsn_files/schema_105.json +0 -0
  282. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/jsn_files/schema_108.json +0 -0
  283. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_000.json +0 -0
  284. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_000.log +0 -0
  285. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_001.json +0 -0
  286. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_001.log +0 -0
  287. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_002.json +0 -0
  288. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_002.log +0 -0
  289. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_010.json +0 -0
  290. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_010.log +0 -0
  291. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_011.json +0 -0
  292. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_011.log +0 -0
  293. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_012.json +0 -0
  294. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_012.log +0 -0
  295. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_013.json +0 -0
  296. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_013.log +0 -0
  297. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_014.json +0 -0
  298. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_014.log +0 -0
  299. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_300.json +0 -0
  300. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_300.log +0 -0
  301. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_301.json +0 -0
  302. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_301.log +0 -0
  303. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_302.json +0 -0
  304. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_302.log +0 -0
  305. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_303.json +0 -0
  306. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_303.log +0 -0
  307. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_304.json +0 -0
  308. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_304.log +0 -0
  309. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_310.json +0 -0
  310. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/schemas/log_files/schema_310.log +0 -0
  311. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_heat_trv_00/config.json +0 -0
  312. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_heat_trv_00/packet.log +0 -0
  313. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_heat_trv_00/schema.json +0 -0
  314. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_hvac_nuaire/config.json +0 -0
  315. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_hvac_nuaire/known_list.json +0 -0
  316. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_hvac_nuaire/packet.log +0 -0
  317. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_hvac_nuaire/schema.json +0 -0
  318. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/_hvac_nuaire/status.json +0 -0
  319. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_otb_00/config.json +0 -0
  320. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_otb_00/packet.log +0 -0
  321. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_otb_00/schema.json +0 -0
  322. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_simple/packet.log +0 -0
  323. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_simple/schema.json +0 -0
  324. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_ufc_00/config.json +0 -0
  325. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_ufc_00/packet.log +0 -0
  326. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_ufc_01/packet.log +0 -0
  327. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_zxdavb/config.json +0 -0
  328. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_zxdavb/known_list.json +0 -0
  329. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_zxdavb/packet.log +0 -0
  330. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/systems/heat_zxdavb/schema.json +0 -0
  331. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_api_faultlog.py +0 -0
  332. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_api_schedule.py +0 -0
  333. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_apis_binding.py +0 -0
  334. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_apis_common.py +0 -0
  335. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_apis_heat.py +0 -0
  336. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_apis_hvac.py +0 -0
  337. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_cli_utility.py +0 -0
  338. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_devices.py +0 -0
  339. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_eavesdrop_dev_class.py +0 -0
  340. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_eavesdrop_schema.py +0 -0
  341. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_helpers.py +0 -0
  342. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_parser_helpers.py +0 -0
  343. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_parsers.py +0 -0
  344. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_ramses_schema.py +0 -0
  345. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_schema_bits.py +0 -0
  346. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_schemas.py +0 -0
  347. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests/test_vol_schemas.py +0 -0
  348. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/__init__.py +0 -0
  349. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/configs/config_heat.json +0 -0
  350. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/configs/config_hvac.json +0 -0
  351. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/conftest.py +0 -0
  352. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/device/__init__.py +0 -0
  353. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/device/test_hvac_ventilator.py +0 -0
  354. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/logs/test_api_faultlog.log +0 -0
  355. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_api_faultlog.py +0 -0
  356. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_api_schedule.py +0 -0
  357. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_binding_fsm.py +0 -0
  358. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_create_stack.py +0 -0
  359. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_dispatcher.py +0 -0
  360. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_hgi_behaviors.py +0 -0
  361. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_protocol_fsm.py +0 -0
  362. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_use_regex.py +0 -0
  363. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/test_virt_network.py +0 -0
  364. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/virtual_rf/__init__.py +0 -0
  365. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/virtual_rf/const.py +0 -0
  366. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/virtual_rf/helpers.py +0 -0
  367. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_rf/virtual_rf/virtual_rf.py +0 -0
  368. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_tx/__init__.py +0 -0
  369. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/tests_tx/test_command.py +0 -0
  370. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/wip/_test_eavesdrop_dhw_sensor.py +0 -0
  371. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/wip/_test_eavesdrop_htg_control.py +0 -0
  372. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/wip/_test_eavesdrop_ufc_circuits.py +0 -0
  373. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/wip/_test_eavesdrop_zone_sensors.py +0 -0
  374. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/wip/_test_eavesdrop_zone_type.py +0 -0
  375. {ramses_rf-0.52.2 → ramses_rf-0.52.3}/tests/wip/test_wip_cli.sh +0 -0
@@ -41,7 +41,7 @@ jobs:
41
41
  - name: Install dependencies
42
42
  run: |
43
43
  python -m pip install --upgrade pip
44
- pip install ruff # pip install -r requirements_dev.txt
44
+ pip install ruff # pip install -r requirements/requirements_dev.txt
45
45
 
46
46
  - name: Check with ruff
47
47
  run: ruff check --output-format=github .
@@ -41,7 +41,7 @@ jobs:
41
41
  - name: Install dependencies
42
42
  run: |
43
43
  python -m pip install --upgrade pip
44
- pip install -r requirements_dev.txt
44
+ pip install -r requirements/requirements_dev.txt
45
45
 
46
46
  - name: Install the package (and its dependencies)
47
47
  run: pip install -e .
@@ -41,7 +41,7 @@ jobs:
41
41
  - name: Install dependencies
42
42
  run: |
43
43
  python -m pip install --upgrade pip
44
- pip install -r requirements_dev.txt
44
+ pip install -r requirements/requirements_dev.txt
45
45
 
46
46
  - name: Install the package (its dependencies are needed for typing)
47
47
  run: pip install -e .
@@ -26,7 +26,7 @@ jobs:
26
26
  run: hatch build
27
27
 
28
28
  - name: Upload dist
29
- uses: actions/upload-artifact@v4
29
+ uses: actions/upload-artifact@v5
30
30
  with:
31
31
  name: dist
32
32
  path: dist/
@@ -40,7 +40,7 @@ jobs:
40
40
  url: https://pypi.org/project/ramses_rf
41
41
  steps:
42
42
  - name: Download dist
43
- uses: actions/download-artifact@v5
43
+ uses: actions/download-artifact@v6
44
44
  with:
45
45
  name: dist
46
46
  path: dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramses_rf
3
- Version: 0.52.2
3
+ Version: 0.52.3
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
@@ -0,0 +1,159 @@
1
+ # RAMSES RF Binding Process Diagram
2
+
3
+ ## Overview
4
+ This diagram shows the binding finite state machine (FSM) for RAMSES RF devices, illustrating the complete process from initial state to binding completion.
5
+
6
+ ## State Machine Diagram
7
+
8
+ ```mermaid
9
+ stateDiagram-v2
10
+ direction LR
11
+ [*] --> DevIsNotBinding
12
+ DevIsNotBinding --> InitiateBindingProcess : initiate_binding_process()
13
+ InitiateBindingProcess --> SuppSendOfferWaitForAccept
14
+ SuppSendOfferWaitForAccept --> OfferSent : _make_offer()
15
+ OfferSent --> SuppSendOfferWaitForAccept : wait_for_accept()
16
+ DevIsNotBinding --> RespIsWaitingForOffer : wait_for_binding_request()
17
+ RespIsWaitingForOffer --> OfferReceived : _wait_for_offer()
18
+ OfferReceived --> RespSendAcceptWaitForConfirm : _accept_offer()
19
+ RespSendAcceptWaitForConfirm --> SuppIsReadyToSendConfirm : wait_for_confirm()
20
+ SuppIsReadyToSendConfirm --> StateDecisionPoint : cast_confirm_accept()
21
+ StateDecisionPoint --> RespHasBoundAsRespondent : No addenda
22
+ StateDecisionPoint --> SuppHasBoundAsSupplicant : Yes addenda / Complete
23
+ RespHasBoundAsRespondent --> DevIsNotBinding
24
+ SuppHasBoundAsSupplicant --> DevIsNotBinding
25
+ DevIsNotBinding --> [*] : Binding Complete
26
+
27
+ subgraph Supplicant Role
28
+ SuppSendOfferWaitForAccept
29
+ OfferSent
30
+ SuppIsReadyToSendConfirm
31
+ SuppHasBoundAsSupplicant
32
+ end
33
+
34
+ subgraph Respondent Role
35
+ RespIsWaitingForOffer
36
+ OfferReceived
37
+ RespSendAcceptWaitForConfirm
38
+ RespHasBoundAsRespondent
39
+ end
40
+
41
+ classDef supplicant fill:#006400,stroke:#ffffff,stroke-width:2px
42
+ classDef respondent fill:#00008B,stroke:#ffffff,stroke-width:2px
43
+
44
+ class SuppSendOfferWaitForAccept,OfferSent,SuppIsReadyToSendConfirm,SuppHasBoundAsSupplicant supplicant
45
+ class RespIsWaitingForOffer,OfferReceived,RespSendAcceptWaitForConfirm,RespHasBoundAsRespondent respondent
46
+ class Supplicant Role supplicant
47
+ class Respondent Role respondent
48
+
49
+ note right of DevIsNotBinding
50
+ Not binding<br/>Ready to start
51
+ end note
52
+
53
+ note right of SuppSendOfferWaitForAccept
54
+ Made Offer<br/>Waiting for Accept
55
+ end note
56
+
57
+ note right of RespIsWaitingForOffer
58
+ Waiting for Offer
59
+ end note
60
+
61
+ note right of RespSendAcceptWaitForConfirm
62
+ Sent Accept<br/>Waiting for Confirm
63
+ end note
64
+
65
+ note right of SuppIsReadyToSendConfirm
66
+ Received Accept<br/>Ready to send Confirm
67
+ end note
68
+
69
+ note right of StateDecisionPoint
70
+ If addenda: SendAddenda<br/>If no addenda: Complete
71
+ end note
72
+
73
+ note right of RespHasBoundAsRespondent
74
+ Binding Complete
75
+ end note
76
+
77
+ note right of SuppHasBoundAsSupplicant
78
+ Binding Complete<br/>Nothing more to do
79
+ end note
80
+ ```
81
+
82
+ ## Method Flow by Role
83
+
84
+ ### Supplicant Flow (Device initiating binding)
85
+ ```python
86
+ async def initiate_binding_process(self, offer_codes, confirm_code=None, ratify_cmd=None):
87
+ 1. _make_offer(offer_codes, oem_code) # Send Offer packet
88
+ 2. _wait_for_accept(tender) # Wait for Accept response
89
+ 3. _confirm_accept(accept, confirm_code) # Send Confirm packet
90
+ 4. _cast_addenda(accept, ratify_cmd) # Optional: Send Addenda
91
+
92
+ # Result: SuppHasBoundAsSupplicant state
93
+ ```
94
+
95
+ ### Respondent Flow (Device responding to binding)
96
+ ```python
97
+ async def wait_for_binding_request(self, accept_codes, idx="00", require_ratify=False):
98
+ 1. _wait_for_offer() # Wait for Offer packet
99
+ 2. _accept_offer(tender, accept_codes, idx) # Send Accept packet
100
+ 3. _wait_for_confirm(accept) # Wait for Confirm packet
101
+ 4. _wait_for_addenda(accept) # Optional: Wait for Addenda
102
+
103
+ # Result: RespHasBoundAsRespondent state
104
+ ```
105
+
106
+ ## State Details
107
+
108
+ | State | Role | Description | Key Methods |
109
+ |-------|------|-------------|-------------|
110
+ | `DevIsNotBinding` | Any | Initial/final state, not participating in binding | - |
111
+ | `RespIsWaitingForOffer` | Respondent | Waiting for binding offer from supplicant | `wait_for_offer()` |
112
+ | `RespSendAcceptWaitForConfirm` | Respondent | Sent Accept, waiting for Confirm | `cast_accept_offer()`, `wait_for_confirm()` |
113
+ | `RespIsWaitingForAddenda` | Respondent | Received Confirm, waiting for optional Addenda | `wait_for_addenda()` |
114
+ | `RespHasBoundAsRespondent` | Respondent | Binding completed successfully | ✅ **NEW LOGGING HERE** |
115
+ | `SuppSendOfferWaitForAccept` | Supplicant | Sent Offer, waiting for Accept | `cast_offer()`, `wait_for_accept()` |
116
+ | `SuppIsReadyToSendConfirm` | Supplicant | Received Accept, ready to send Confirm | `cast_confirm_accept()` |
117
+ | `SuppIsReadyToSendAddenda` | Supplicant | Sent Confirm, ready to send Addenda | `cast_addenda()` |
118
+ | `SuppHasBoundAsSupplicant` | Supplicant | Binding completed successfully | ✅ **NEW LOGGING HERE** |
119
+ | `DevHasFailedBinding` | Any | Binding failed, error state | - |
120
+
121
+ ## Binding Phases (Packet Types)
122
+
123
+ | Phase | Packet Type | Description | Direction |
124
+ |-------|-------------|-------------|-----------|
125
+ | `TENDER` | `1FC9` (I_) | Offer phase - initial binding proposal | Supplicant → Respondent |
126
+ | `ACCEPT` | `1FC9` (W_) | Accept phase - acceptance of offer | Respondent → Supplicant |
127
+ | `AFFIRM` | `1FC9` (I_) | Confirm phase - confirmation of acceptance | Supplicant → Respondent |
128
+ | `RATIFY` | `10E0` (I_) | Addenda phase - optional additional binding info | Either direction |
129
+
130
+ ## New Logging Implementation
131
+
132
+ The following log.info statements have been added at binding completion points:
133
+
134
+ ### 1. Constructor Logging (Immediate Confirmation)
135
+ - **`RespHasBoundAsRespondent.__init__()`**: Logs when respondent binding completes
136
+ - **`SuppHasBoundAsSupplicant.__init__()`**: Logs when supplicant binding completes
137
+
138
+ ### 2. State Transition Logging (Complete Flow)
139
+ - **`BindContextBase.set_state()`**: Logs the complete state transition to bound states, including:
140
+ - Previous state name
141
+ - New bound state name
142
+ - Final role (respondent/supplicant)
143
+
144
+ ## Example Log Output
145
+ ```
146
+ INFO:ramses_rf.binding_fsm:32:123456: Binding completed as respondent
147
+ INFO:ramses_rf.binding_fsm:37:789012: Binding completed as supplicant
148
+ INFO:ramses_rf.binding_fsm:32:123456: Binding process completed: RespSendAcceptWaitForConfirm -> RespHasBoundAsRespondent (role: BindRole.RESPONDENT)
149
+ ```
150
+
151
+ ## Error Handling
152
+ - **Timeout**: Binding fails if expected packets not received within timeout periods
153
+ - **Retry Limits**: Automatic failure after retry limits exceeded
154
+ - **Exception**: `BindingFlowFailed` raised on binding errors
155
+
156
+ ## Configuration Constants
157
+ - `CONFIRM_RETRY_LIMIT`: 3 (automatic binding after this many confirm sends)
158
+ - `CONFIRM_TIMEOUT_SECS`: 3 (automatic binding after this many seconds)
159
+ - `WAITING_TIMEOUT_SECS`: 5 (fail if no packet received within this time)
@@ -36,6 +36,7 @@ extensions = [
36
36
  "sphinx.ext.githubpages",
37
37
  "sphinx_design",
38
38
  "myst_parser", # to use Markdown inside reST
39
+ "sphinxcontrib.mermaid", # to show mermaid diagrams in docs
39
40
  ]
40
41
  pygments_style = "sphinx" # enable syntax highlighting
41
42
 
@@ -72,3 +73,4 @@ autosummary_generate_overwrite = True
72
73
  # Myst
73
74
  myst_enable_extensions = ["colon_fence"]
74
75
  myst_heading_anchors = 4
76
+ myst_fence_as_directive = ["mermaid"]
@@ -11,6 +11,7 @@ ramses_rf
11
11
 
12
12
  usage
13
13
  glossary
14
+ binding_process_diagram
14
15
 
15
16
  .. toctree::
16
17
  :maxdepth: 2
@@ -15,7 +15,7 @@ MyST [markup](https://myst-parser.readthedocs.io/en/latest/syntax/organising_con
15
15
 
16
16
  - Activate your virtual environment for ramses_rf as described in the [Wiki](https://github.com/ramses-rf/ramses_rf/blob/master/README-developers.md).
17
17
 
18
- - Install the extra required dependencies by running ``pip install -r requirements_docs.txt`` so you can build a local set.
18
+ - Install the extra required dependencies by running ``pip install -r requirements/requirements_docs.txt`` so you can build a local set.
19
19
 
20
20
  - Then, in a Terminal, enter `cd docs/` and run `sphinx-build -b html source build/html`.
21
21
 
@@ -178,6 +178,8 @@ class BindContextBase:
178
178
  self, state: type[BindStateBase], result: asyncio.Future[Message] | None = None
179
179
  ) -> None:
180
180
  """Transition the State of the Context, and process the result, if any."""
181
+ # Ensure prev_state is always available, not only during debugging
182
+ prev_state = self._state
181
183
 
182
184
  # if False and result:
183
185
  # try:
@@ -185,10 +187,6 @@ class BindContextBase:
185
187
  # except exc.BindingError as err:
186
188
  # self._fut.set_result(err)
187
189
 
188
- if _DBG_MAINTAIN_STATE_CHAIN: # HACK for debugging
189
- # if prev_state in (None, )
190
- prev_state = self._state
191
-
192
190
  self._state = state(self)
193
191
  if not self.is_binding:
194
192
  self._is_respondent = None
@@ -197,6 +195,14 @@ class BindContextBase:
197
195
  elif state is SuppSendOfferWaitForAccept:
198
196
  self._is_respondent = False
199
197
 
198
+ # Log binding completion transitions
199
+ if isinstance(
200
+ self._state, (RespHasBoundAsRespondent, SuppHasBoundAsSupplicant)
201
+ ):
202
+ _LOGGER.info(
203
+ f"{self._dev.id}: Binding process completed: {type(prev_state).__name__} -> {state.__name__} (role: {self.role})"
204
+ )
205
+
200
206
  if _DBG_MAINTAIN_STATE_CHAIN: # HACK for debugging
201
207
  setattr(self._state, "_prev_state", prev_state) # noqa: B010
202
208
 
@@ -663,6 +669,10 @@ class RespHasBoundAsRespondent(BindStateBase):
663
669
 
664
670
  _attr_role = BindRole.IS_DORMANT
665
671
 
672
+ def __init__(self, context: BindContextBase) -> None:
673
+ super().__init__(context)
674
+ _LOGGER.info(f"{context._dev.id}: Binding completed as respondent")
675
+
666
676
 
667
677
  class RespIsWaitingForAddenda(_DevIsWaitingForMsg, BindStateBase):
668
678
  """Respondent has received a Confirm & is waiting for an Addenda."""
@@ -715,6 +725,10 @@ class SuppHasBoundAsSupplicant(BindStateBase):
715
725
 
716
726
  _attr_role = BindRole.IS_DORMANT
717
727
 
728
+ def __init__(self, context: BindContextBase) -> None:
729
+ super().__init__(context)
730
+ _LOGGER.info(f"{context._dev.id}: Binding completed as supplicant")
731
+
718
732
 
719
733
  class SuppIsReadyToSendAddenda(
720
734
  _DevIsReadyToSendCmd, BindStateBase
@@ -334,7 +334,7 @@ class MessageIndex:
334
334
  payload_keys(msg.payload),
335
335
  ),
336
336
  )
337
- _LOGGER.debug(f"Added {msg} to gwy.msg_db")
337
+ # _LOGGER.debug(f"Added {msg} to gwy.msg_db")
338
338
 
339
339
  return _old_msgs[0] if _old_msgs else None
340
340
 
@@ -435,7 +435,7 @@ class MessageIndex:
435
435
 
436
436
  def qry_dtms(self, **kwargs: bool | dt | str) -> list[Any]:
437
437
  """
438
- Select from the ImageIndex a list of dtms that match the provided arguments.
438
+ Select from the MessageIndex a list of dtms that match the provided arguments.
439
439
 
440
440
  :param kwargs: data table field names and criteria
441
441
  :return: list of unformatted dtms that match, useful for msg lookup, or an empty list if 0 matches
@@ -120,7 +120,7 @@ _LOGGER = logging.getLogger(__name__)
120
120
 
121
121
  class Actuator(DeviceHeat): # 3EF0, 3EF1 (for 10:/13:)
122
122
  # .I --- 13:109598 --:------ 13:109598 3EF0 003 00C8FF # event-driven, 00/C8
123
- # RP --- 13:109598 18:002563 --:------ 0008 002 00C8 # 00/C8, as abobe
123
+ # RP --- 13:109598 18:002563 --:------ 0008 002 00C8 # 00/C8, as above
124
124
  # RP --- 13:109598 18:002563 --:------ 3EF1 007 0000BF-00BFC8FF # 00/C8, as above
125
125
 
126
126
  # RP --- 10:048122 18:140805 --:------ 3EF1 007 007FFF-003C2A10 # 10:s only RP, always 7FFF
@@ -668,11 +668,8 @@ class OtbGateway(Actuator, HeatDemand): # OTB (10): 3220 (22D9, others)
668
668
  self._child_id = FC # NOTE: domain_id
669
669
 
670
670
  # TODO(eb): cleanup
671
- # should fix src/ramses_rf/database.py _add_record try/except when activating next line
672
671
  if self._gwy.msg_db:
673
- self._add_record(
674
- address=self.addr, code=Code._3220, verb="RP"
675
- ) # << essential?
672
+ self._add_record(address=self.addr, code=Code._3220, verb="RP")
676
673
  # adds a "sim" RP opentherm_msg to the SQLite MessageIndex with code _3220
677
674
  # causes exc when fetching ALL, when no "real" msg was added to _msgs_. We skip those.
678
675
  else:
@@ -1411,7 +1408,7 @@ class UfhCircuit(Child, Entity): # FIXME
1411
1408
  def __init__(self, ufc: UfhController, ufh_idx: str) -> None:
1412
1409
  super().__init__(ufc._gwy)
1413
1410
 
1414
- # FIXME: ZZZ entities must know their parent device ID and their own idx
1411
+ # FIXME: gwy.msg_db entities must know their parent device ID and their own idx
1415
1412
  self._z_id = ufc.id
1416
1413
  self._z_idx = ufh_idx
1417
1414
 
@@ -67,8 +67,7 @@ if TYPE_CHECKING:
67
67
 
68
68
 
69
69
  _QOS_TX_LIMIT = 12 # TODO: needs work
70
- _ID_SLICE = 9 # base address only, legacy _msgs 9
71
- _SQL_SLICE = 12 # msg_db dst field query 12
70
+ _ID_SLICE = 9
72
71
  _SZ_LAST_PKT: Final = "last_msg"
73
72
  _SZ_NEXT_DUE: Final = "next_due"
74
73
  _SZ_TIMEOUT: Final = "timeout"
@@ -248,6 +247,7 @@ class _MessageDB(_Entity):
248
247
  "For %s (z_id %s) add msg %s, src %s, dst %s to msg_db.",
249
248
  self.id,
250
249
  self._z_id,
250
+ msg,
251
251
  msg.src,
252
252
  msg.dst,
253
253
  )
@@ -291,7 +291,7 @@ class _MessageDB(_Entity):
291
291
 
292
292
  @property
293
293
  def _msg_list(self) -> list[Message]:
294
- """Return a flattened list of all messages logged on device."""
294
+ """Return a flattened list of all messages logged on this device."""
295
295
  # (only) used in gateway.py#get_state() and in tests/tests/test_eavesdrop_schema.py
296
296
  if self._gwy.msg_db:
297
297
  msg_list_qry: list[Message] = []
@@ -302,6 +302,8 @@ class _MessageDB(_Entity):
302
302
  # safeguard against lookup failures ("sim" packets?)
303
303
  msg_list_qry.append(self._msgs[c])
304
304
  else:
305
+ # evohome has these errors
306
+ # _msg_list could not fetch self._msgs[7FFF] for 18:072981 (z_id 18:072981)
305
307
  _LOGGER.debug(
306
308
  "_msg_list could not fetch self._msgs[%s] for %s (z_id %s)",
307
309
  c,
@@ -428,7 +430,7 @@ class _MessageDB(_Entity):
428
430
  :param code: filter messages by Code or a tuple of Codes, optional
429
431
  :param verb: filter on I, RQ, RP, optional, only with a single Code
430
432
  :param key: value keyword to retrieve, not together with verb RQ
431
- :param kwargs: not used for now
433
+ :param kwargs: extra filter, e.g. zone_idx='01'
432
434
  :return: a dict containing key: value pairs, or a list of those
433
435
  """
434
436
  assert not isinstance(code, tuple) or verb is None, (
@@ -444,7 +446,9 @@ class _MessageDB(_Entity):
444
446
  key = None
445
447
  try:
446
448
  if self._gwy.msg_db: # central SQLite MessageIndex, use verb= kwarg
447
- code = Code(self._msg_qry_by_code_key(code, key, verb=verb))
449
+ code = Code(
450
+ self._msg_qry_by_code_key(code, key, **kwargs, verb=verb)
451
+ )
448
452
  msg = self._msgs.get(code)
449
453
  else: # deprecated lookup in nested _msgz
450
454
  msgs = self._msgz[code][verb]
@@ -456,7 +460,9 @@ class _MessageDB(_Entity):
456
460
  msgs = [m for m in self._msgs.values() if m.code in code]
457
461
  msg = max(msgs) if msgs else None
458
462
  # return highest = latest? value found in code:value pairs
459
- else:
463
+ else: # single Code
464
+ # for Zones, this doesn't work, returns first result = often wrong
465
+ # TODO fix in _msg_qry_by_code_key()
460
466
  msg = self._msgs.get(code)
461
467
 
462
468
  return self._msg_value_msg(msg, key=key, **kwargs)
@@ -531,19 +537,37 @@ class _MessageDB(_Entity):
531
537
 
532
538
  :return: list of Codes or empty list when query returned empty
533
539
  """
540
+
534
541
  if self._gwy.msg_db:
535
542
  # SQLite query on MessageIndex
536
- sql = """
537
- SELECT code from messages WHERE verb in (' I', 'RP')
538
- AND (src = ? OR dst = ?)
539
- """
540
543
  res: list[Code] = []
544
+ if self.id[_ID_SLICE:] == "_HW":
545
+ sql = """
546
+ SELECT code from messages WHERE
547
+ verb in (' I', 'RP')
548
+ AND (src = ? OR dst = ?)
549
+ AND (ctx IN ('FC', 'FA', 'F9', 'FA') OR plk LIKE ?)
550
+ """
551
+ _ctx_qry = "%dhw_idx%" # syntax error ?
552
+ else:
553
+ sql = """
554
+ SELECT code from messages WHERE
555
+ verb in (' I', 'RP')
556
+ AND (src = ? OR dst = ?)
557
+ AND ctx LIKE ?
558
+ """
559
+ _ctx_qry = f"%{self.id[_ID_SLICE + 1 :]}%"
541
560
 
542
561
  for rec in self._gwy.msg_db.qry_field(
543
- sql, (self.id[:_SQL_SLICE], self.id[:_SQL_SLICE])
562
+ sql, (self.id[:_ID_SLICE], self.id[:_ID_SLICE], _ctx_qry)
544
563
  ):
545
- _LOGGER.debug("Fetched from index: %s", rec[0])
546
- # Example: "Fetched from index: code 1FD4"
564
+ _LOGGER.debug(
565
+ "Fetched from index: %s for %s (z_id %s)",
566
+ rec[0],
567
+ self.id,
568
+ self._z_id,
569
+ )
570
+ # Example: "Fetched from index: code 1FD4 for 01:123456 (z_id 01)"
547
571
  res.append(Code(str(rec[0])))
548
572
  return res
549
573
  else:
@@ -566,32 +590,48 @@ class _MessageDB(_Entity):
566
590
  :return: Code of most recent query result message or None when query returned empty
567
591
  """
568
592
  if self._gwy.msg_db:
569
- code_qry: str = ""
593
+ code_qry: str = "= "
570
594
  if code is None:
571
- code_qry = "*"
595
+ code_qry = "LIKE '%'" # wildcard
572
596
  elif isinstance(code, tuple):
573
597
  for cd in code:
574
598
  code_qry += f"'{str(cd)}' OR code = '"
575
599
  code_qry = code_qry[:-13] # trim last OR
576
600
  else:
577
- code_qry = str(code)
578
- key = "*" if key is None else f"%{key}%"
601
+ code_qry += str(code)
579
602
  if kwargs["verb"] and kwargs["verb"] in (" I", "RP"):
580
603
  vb = f"('{str(kwargs['verb'])}',)"
581
604
  else:
582
605
  vb = "(' I', 'RP',)"
606
+ ctx_qry = "%"
607
+ if kwargs["zone_idx"]:
608
+ ctx_qry = f"%{kwargs['zone_idx']}%"
609
+ elif kwargs["dhw_idx"]: # DHW
610
+ ctx_qry = f"%{kwargs['dhw_idx']}%"
611
+ key_qry = "%" if key is None else f"%{key}%"
612
+
583
613
  # SQLite query on MessageIndex
584
614
  sql = """
585
- SELECT dtm, code from messages WHERE verb in ?
615
+ SELECT dtm, code from messages WHERE
616
+ verb in ?
586
617
  AND (src = ? OR dst = ?)
587
- AND (code = ?)
618
+ AND (code ?)
619
+ AND (ctx LIKE ?)
588
620
  AND (plk LIKE ?)
589
621
  """
590
622
  latest: dt = dt(0, 0, 0)
591
623
  res = None
592
624
 
593
625
  for rec in self._gwy.msg_db.qry_field(
594
- sql, (vb, self.id[:_SQL_SLICE], self.id[:_SQL_SLICE], code_qry, key)
626
+ sql,
627
+ (
628
+ vb,
629
+ self.id[:_ID_SLICE],
630
+ self.id[:_ID_SLICE],
631
+ code_qry,
632
+ ctx_qry,
633
+ key_qry,
634
+ ),
595
635
  ):
596
636
  _LOGGER.debug(
597
637
  "_msg_qry_by_code_key fetched rec: %s, code: %s", rec, code_qry
@@ -654,7 +694,7 @@ class _MessageDB(_Entity):
654
694
  # """SELECT code from messages WHERE verb in (' I', 'RP') AND (src = ? OR dst = ?)
655
695
  # AND (code = '31DA' OR ...) AND (plk LIKE '%{SZ_FAN_INFO}%' OR ...)""" = 2 params
656
696
  for rec in self._gwy.msg_db.qry_field(
657
- sql, (self.id[:_SQL_SLICE], self.id[:_SQL_SLICE])
697
+ sql, (self.id[:_ID_SLICE], self.id[:_ID_SLICE])
658
698
  ):
659
699
  _pl = self._msgs[Code(rec[0])].payload
660
700
  # add payload dict to res(ults)
@@ -694,24 +734,38 @@ class _MessageDB(_Entity):
694
734
  # _LOGGER.warning("Missing MessageIndex")
695
735
  # raise NotImplementedError
696
736
 
697
- if self.id[:3] == "18:": # HGI, confirm this is correct, tests suggest so
698
- return {}
737
+ # if self.id[:3] == "18:": # HGI, confirm this is correct, tests suggest so
738
+ # return {}
699
739
 
700
- sql = """
701
- SELECT dtm from messages WHERE verb in (' I', 'RP') AND (src = ? OR dst = ?)
702
- """
703
-
704
- # handy routine to debug dict creation, see test_systems.py
740
+ # a routine to debug dict creation, see test_systems.py:
705
741
  # print(f"Create _msgs for {self.id}:")
706
742
  # results = self._gwy.msg_db._cu.execute("SELECT dtm, src, code from messages WHERE verb in (' I', 'RP') and code is '3150'")
707
743
  # for r in results:
708
744
  # print(r)
709
745
 
710
- _msg_dict = { # ? use ctx (context) instead of just the address?
746
+ if self.id[_ID_SLICE:] == "_HW":
747
+ sql = """
748
+ SELECT dtm from messages WHERE
749
+ verb in (' I', 'RP')
750
+ AND (src = ? OR dst = ?)
751
+ AND (ctx IN ('FC', 'FA', 'F9', 'FA') OR plk LIKE ?)
752
+ """
753
+ _ctx_qry = "%dhw_idx%"
754
+ # TODO add Children messages? self.ctl.dhw
755
+ else:
756
+ sql = """
757
+ SELECT dtm from messages WHERE
758
+ verb in (' I', 'RP')
759
+ AND (src = ? OR dst = ?)
760
+ AND ctx LIKE ?
761
+ """
762
+ _ctx_qry = f"%{self.id[_ID_SLICE + 1 :]}%"
763
+
764
+ _msg_dict = { # since 0.52.3 use ctx (context) instead of just the address
711
765
  m.code: m
712
766
  for m in self._gwy.msg_db.qry(
713
- sql, (self.id[:_SQL_SLICE], self.id[:_SQL_SLICE])
714
- ) # e.g. 01:123456_HW
767
+ sql, (self.id[:_ID_SLICE], self.id[:_ID_SLICE], _ctx_qry)
768
+ ) # e.g. 01:123456_HW, 01:123456_02 (Zone)
715
769
  }
716
770
  # if CTL, remove 3150, 3220 heat_demand, both are only stored on children
717
771
  # HACK
@@ -786,7 +840,7 @@ class _Discovery(_MessageDB):
786
840
  code: CODES_SCHEMA[code][SZ_NAME]
787
841
  for code in sorted(
788
842
  self._gwy.msg_db.get_rp_codes(
789
- (self.id[:_SQL_SLICE], self.id[:_SQL_SLICE])
843
+ (self.id[:_ID_SLICE], self.id[:_ID_SLICE])
790
844
  )
791
845
  )
792
846
  if self._is_not_deprecated_cmd(code)
@@ -818,7 +872,7 @@ class _Discovery(_MessageDB):
818
872
  AND (src = ? OR dst = ?)
819
873
  """
820
874
  for rec in self._gwy.msg_db.qry_field(
821
- sql, (self.id[:_SQL_SLICE], self.id[:_SQL_SLICE])
875
+ sql, (self.id[:_ID_SLICE], self.id[:_ID_SLICE])
822
876
  ):
823
877
  _LOGGER.debug("Fetched OT ctx from index: %s", rec[0])
824
878
  res.append(rec[0])
@@ -949,8 +1003,8 @@ class _Discovery(_MessageDB):
949
1003
  sql,
950
1004
  (
951
1005
  task[_SZ_COMMAND].code,
952
- self.tcs.id[:_ID_SLICE], # OK? not _SQL_SLICE?
953
- self.tcs.id[:_ID_SLICE], # OK? not _SQL_SLICE?
1006
+ self.tcs.id[:_ID_SLICE],
1007
+ self.tcs.id[:_ID_SLICE],
954
1008
  ),
955
1009
  )[0] # expect 1 Message in returned tuple
956
1010
  else: # TODO(eb) remove next Q1 2026
@@ -233,7 +233,7 @@ class DhwZone(ZoneSchedule): # CS92A
233
233
  # def eavesdrop_dhw_sensor(this: Message, *, prev: Message | None = None) -> None:
234
234
  # """Eavesdrop packets, or pairs of packets, to maintain the system state.
235
235
 
236
- # There are only 2 ways to to find a controller's DHW sensor:
236
+ # There are only 2 ways to find a controller's DHW sensor:
237
237
  # 1. The 10A0 RQ/RP *from/to a 07:* (1x/4h) - reliable
238
238
  # 2. Use sensor temp matching - non-deterministic
239
239
 
@@ -1,4 +1,4 @@
1
1
  """RAMSES RF - a RAMSES-II protocol decoder & analyser (application layer)."""
2
2
 
3
- __version__ = "0.52.2"
3
+ __version__ = "0.52.3"
4
4
  VERSION = __version__
@@ -34,6 +34,7 @@ from .schemas import (
34
34
  SZ_DISABLE_QOS,
35
35
  SZ_DISABLE_SENDING,
36
36
  SZ_ENFORCE_KNOWN_LIST,
37
+ SZ_LOG_ALL_MQTT,
37
38
  SZ_PACKET_LOG,
38
39
  SZ_PORT_CONFIG,
39
40
  SZ_PORT_NAME,
@@ -114,6 +115,7 @@ class Engine:
114
115
  self._exclude,
115
116
  )
116
117
  self._sqlite_index = kwargs.pop(SZ_SQLITE_INDEX, False) # default True?
118
+ self._log_all_mqtt = kwargs.pop(SZ_LOG_ALL_MQTT, False)
117
119
  self._kwargs: dict[str, Any] = kwargs # HACK
118
120
 
119
121
  self._engine_lock = Lock() # FIXME: threading lock, or asyncio lock?
@@ -197,6 +199,7 @@ class Engine:
197
199
  self._protocol,
198
200
  disable_sending=self._disable_sending,
199
201
  loop=self._loop,
202
+ log_all=self._log_all_mqtt,
200
203
  **pkt_source,
201
204
  **self._kwargs, # HACK: odd/misc params, e.g. comms_params
202
205
  )
@@ -162,6 +162,14 @@ class StdOutFilter(logging.Filter): # record.levelno < logging.WARNING
162
162
  return record.levelno < logging.WARNING
163
163
 
164
164
 
165
+ class BlockMqttFilter(logging.Filter):
166
+ """Block mqtt traffic"""
167
+
168
+ def filter(self, record: logging.LogRecord) -> bool:
169
+ """Return True if the record is to be processed."""
170
+ return not record.getMessage().startswith("mq Rx: ")
171
+
172
+
165
173
  class TimedRotatingFileHandler(_TimedRotatingFileHandler):
166
174
  def __init__(self, *args: Any, **kwargs: Any) -> None:
167
175
  super().__init__(*args, **kwargs)