ramses-rf 0.51.9__tar.gz → 0.52.0__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 (359) hide show
  1. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/PKG-INFO +1 -1
  2. ramses_rf-0.52.0/misc/2411_parser.py +492 -0
  3. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_cli/client.py +21 -9
  4. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_cli/discovery.py +1 -1
  5. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/database.py +109 -54
  6. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/device/base.py +10 -5
  7. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/device/heat.py +15 -7
  8. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/device/hvac.py +31 -7
  9. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/dispatcher.py +4 -4
  10. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/entity_base.py +477 -116
  11. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/gateway.py +16 -6
  12. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/version.py +1 -1
  13. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/gateway.py +2 -0
  14. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/message.py +3 -1
  15. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/parsers.py +2 -0
  16. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/ramses.py +11 -3
  17. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/schemas.py +8 -2
  18. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/version.py +1 -1
  19. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/helpers.py +2 -0
  20. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_2411_wip.log +31 -3
  21. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_ufc_01/packet.log +3 -3
  22. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_apis_binding.py +2 -1
  23. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_ramses_schema.py +1 -1
  24. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_systems.py +21 -3
  25. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/device/test_hvac_ventilator.py +7 -8
  26. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_binding_fsm.py +3 -2
  27. ramses_rf-0.52.0/tests/tests_rf/test_database.py +179 -0
  28. ramses_rf-0.52.0/tests/tests_rf/test_dispatcher.py +99 -0
  29. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_virt_network.py +22 -10
  30. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  31. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.github/dependabot.yml +0 -0
  32. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.github/workflows/check-lint.yml +0 -0
  33. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.github/workflows/check-test.yml +0 -0
  34. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.github/workflows/check-type.yml +0 -0
  35. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.github/workflows/publish-hatch.yml +0 -0
  36. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.gitignore +0 -0
  37. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/.pre-commit-config.yaml +0 -0
  38. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/LICENSE +0 -0
  39. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/README-developers.md +0 -0
  40. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/README.md +0 -0
  41. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/client.py +0 -0
  42. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/misc/fingerprints.log +0 -0
  43. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/misc/ser2net.yaml +0 -0
  44. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/misc/ti_3410/notes.sh +0 -0
  45. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/misc/ti_3410/ti_3410.fw +0 -0
  46. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/pyproject.toml +0 -0
  47. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_cli/__init__.py +0 -0
  48. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_cli/debug.py +0 -0
  49. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_cli/utils/cat_slow.py +0 -0
  50. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_cli/utils/convert.py +0 -0
  51. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/__init__.py +0 -0
  52. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/binding_fsm.py +0 -0
  53. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/const.py +0 -0
  54. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/device/__init__.py +0 -0
  55. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/exceptions.py +0 -0
  56. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/helpers.py +0 -0
  57. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/py.typed +0 -0
  58. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/schemas.py +0 -0
  59. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/system/__init__.py +0 -0
  60. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/system/faultlog.py +0 -0
  61. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/system/heat.py +0 -0
  62. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/system/schedule.py +0 -0
  63. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_rf/system/zones.py +0 -0
  64. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/__init__.py +0 -0
  65. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/address.py +0 -0
  66. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/command.py +0 -0
  67. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/const.py +0 -0
  68. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/exceptions.py +0 -0
  69. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/fingerprints.py +0 -0
  70. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/frame.py +0 -0
  71. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/helpers.py +0 -0
  72. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/logger.py +0 -0
  73. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/opentherm.py +0 -0
  74. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/packet.py +0 -0
  75. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/protocol.py +0 -0
  76. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/protocol_fsm.py +0 -0
  77. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/py.typed +0 -0
  78. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/transport.py +0 -0
  79. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/typed_dicts.py +0 -0
  80. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/ramses_tx/typing.py +0 -0
  81. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/requirements.txt +0 -0
  82. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/requirements_dev.txt +0 -0
  83. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/_test_apis_mock.py +0 -0
  84. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/_test_mock_faultlog.py +0 -0
  85. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/_test_mock_schedule.py +0 -0
  86. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/_test_packets_bad.py +0 -0
  87. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/_test_performance_WIP.py +0 -0
  88. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/_test_state_mgt.py +0 -0
  89. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/common.py +0 -0
  90. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/mocked_devices/__init__.py +0 -0
  91. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/mocked_devices/command.py +0 -0
  92. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/mocked_devices/const.py +0 -0
  93. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/mocked_devices/device_heat.py +0 -0
  94. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/mocked_devices/device_hvac.py +0 -0
  95. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/deprecated/mocked_devices/transport.py +0 -0
  96. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/__init__.py +0 -0
  97. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/heat/ctl_bdr_91t.log +0 -0
  98. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/heat/dts_ctl_sensor.log +0 -0
  99. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/heat/hcw_ctl_sensor.log +0 -0
  100. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/heat/rnd_ctl_sensor.log +0 -0
  101. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/heat/rnd_ctl_sensor.yaml +0 -0
  102. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/heat/trv_ctl.log +0 -0
  103. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/co2_fan_itho.json +0 -0
  104. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/co2_fan_itho.log +0 -0
  105. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/co2_fan_itho.yaml +0 -0
  106. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/dis_fan_orcon.json +0 -0
  107. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/dis_fan_orcon.log +0 -0
  108. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/rem_fan_climarad.log +0 -0
  109. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/rem_fan_nuaire.json +0 -0
  110. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/rem_fan_nuaire.log +0 -0
  111. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/rem_fan_nuaire.yaml +0 -0
  112. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/rem_fan_vasco.log +0 -0
  113. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/bindings/hvac/rem_fan_ventura.log +0 -0
  114. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/devices/device_02.log +0 -0
  115. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/devices/device_04.log +0 -0
  116. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/devices/device_10.log +0 -0
  117. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/devices/device_13.log +0 -0
  118. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/devices/device_22.log +0 -0
  119. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_off.json +0 -0
  120. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_on.json +0 -0
  121. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_dev_class/hvac/packet.log +0 -0
  122. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_trv_actuator_long/packet.log +0 -0
  123. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_off.json +0 -0
  124. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_on.json +0 -0
  125. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/packet.log +0 -0
  126. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_off.json +0 -0
  127. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_on.json +0 -0
  128. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_ufh_circuits/packet.log +0 -0
  129. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_off.json +0 -0
  130. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_on.json +0 -0
  131. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/app_cntrl/packet.log +0 -0
  132. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_off.json +0 -0
  133. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_on.json +0 -0
  134. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/trv_actuators/packet.log +0 -0
  135. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_off.json +0 -0
  136. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_on.json +0 -0
  137. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_000/packet.log +0 -0
  138. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_off.json +0 -0
  139. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_on.json +0 -0
  140. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_001/packet.log +0 -0
  141. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_off.json +0 -0
  142. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_on.json +0 -0
  143. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_002/packet.log +0 -0
  144. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_off.json +0 -0
  145. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_on.json +0 -0
  146. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_003/packet.log +0 -0
  147. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_off.json +0 -0
  148. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_on.json +0 -0
  149. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_004/packet.log +0 -0
  150. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_off.json +0 -0
  151. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_on.json +0 -0
  152. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/10e0_xxxx.log +0 -0
  153. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/_gather.sh +0 -0
  154. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/01_EvoTouch_Colour.log +0 -0
  155. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/01_Evo_Color.log +0 -0
  156. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/01_IONA_RAI_Prototype.log +0 -0
  157. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/02_HCE80_V3.10_061117..log +0 -0
  158. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/04_HR92 Radiator Ctrl_.log +0 -0
  159. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/08_Jasper_EIM.log +0 -0
  160. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/10_R8810A_Bridge.log +0 -0
  161. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/10_R8820.log +0 -0
  162. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/30_Internet_Gateway.log +0 -0
  163. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/31_Jasper_Stat_TXXX.log +0 -0
  164. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/heat/34_T87RF2025.log +0 -0
  165. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/18_BRDG-02A55.log +0 -0
  166. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/18_HRA82.log +0 -0
  167. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/20.log +0 -0
  168. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/21_CCU-12T20.log +0 -0
  169. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMC-07RP01.log +0 -0
  170. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMC-15RP01.log +0 -0
  171. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMC-17RP01.log +0 -0
  172. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMN-07LM01.log +0 -0
  173. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMN-15LF01.log +0 -0
  174. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMN-17LMP01.log +0 -0
  175. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMS-15C16.log +0 -0
  176. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/29_VMS-17HB01.log +0 -0
  177. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/30_BRDG-02EM23.log +0 -0
  178. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/30_BRDG-02JAS01.log +0 -0
  179. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMC-15RPS34.log +0 -0
  180. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMD-15RMS64.log +0 -0
  181. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMD-15RMS86.log +0 -0
  182. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMD-17RPS01.log +0 -0
  183. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMN-23LM33.log +0 -0
  184. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMN-23LMH23.log +0 -0
  185. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMS-15CM17.log +0 -0
  186. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMS-23C33.log +0 -0
  187. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMS-23HB33.log +0 -0
  188. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/32_VMZ-15V13.log +0 -0
  189. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/37_VMD-07RPS13.log +0 -0
  190. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/37_VMI-15MC01log +0 -0
  191. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/37_VMI-15WSJ53.log +0 -0
  192. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/37_VMS-02J52.log +0 -0
  193. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/37_VMS-12C39.log +0 -0
  194. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/99_CVE-RF.log +0 -0
  195. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/fingerprints/hvac/99_VMS-17C01.log +0 -0
  196. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/logger/packet_in.log +0 -0
  197. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/logger/packet_out.log +0 -0
  198. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/logs/pkts_bad_000.log +0 -0
  199. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/logs/pkts_tba_000.log +0 -0
  200. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/logs/system_cache.json +0 -0
  201. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parser_helpers/pkt_addr_set.log +0 -0
  202. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parser_helpers/pkt_dev_class.log +0 -0
  203. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0001_wip.log +0 -0
  204. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0002.log +0 -0
  205. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0004_wip.log +0 -0
  206. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0005.log +0 -0
  207. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0006.log +0 -0
  208. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0008.log +0 -0
  209. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0009.log +0 -0
  210. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_000a.log +0 -0
  211. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_000c.log +0 -0
  212. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_000e.log +0 -0
  213. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_01ff_wip.log +0 -0
  214. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_0418.log +0 -0
  215. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_042f.log +0 -0
  216. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1030.log +0 -0
  217. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1060.log +0 -0
  218. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_10d0.log +0 -0
  219. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_10e0.log +0 -0
  220. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1260.log +0 -0
  221. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1298.log +0 -0
  222. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_12a0.log +0 -0
  223. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_12c0.log +0 -0
  224. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1300.log +0 -0
  225. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1f09.log +0 -0
  226. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1fc9.log +0 -0
  227. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_1fd4.log +0 -0
  228. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_2210.log +0 -0
  229. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22c9.log +0 -0
  230. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22d0.log +0 -0
  231. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22d9.log +0 -0
  232. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22e0.log +0 -0
  233. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22e5.log +0 -0
  234. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22e9.log +0 -0
  235. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22f1.log +0 -0
  236. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22f2.log +0 -0
  237. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22f3.log +0 -0
  238. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22f4.log +0 -0
  239. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_22f7.log +0 -0
  240. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_2309.log +0 -0
  241. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_2349.log +0 -0
  242. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_2e04.log +0 -0
  243. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_2e10_wip.log +0 -0
  244. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_30c9.log +0 -0
  245. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3110_wip.log +0 -0
  246. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3120.log +0 -0
  247. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_313e_wip.log +0 -0
  248. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3150.log +0 -0
  249. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_31d9.log +0 -0
  250. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_31da.log +0 -0
  251. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3200.log +0 -0
  252. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3210.log +0 -0
  253. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3220.log +0 -0
  254. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3222.log +0 -0
  255. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3ef0_wip.log +0 -0
  256. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_3ef1_wip.log +0 -0
  257. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_4e01.log +0 -0
  258. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_4e02.log +0 -0
  259. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_4e04.log +0 -0
  260. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/parsers/code_4e15.log +0 -0
  261. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schedules/_sched_002/packet.log +0 -0
  262. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schedules/_sched_002/schedule.json +0 -0
  263. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schedules/sched_001/packet.log +0 -0
  264. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schedules/sched_001/schedule.json +0 -0
  265. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schedules/sched_dhw/packet.log +0 -0
  266. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schedules/sched_dhw/schedule.json +0 -0
  267. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/jsn_files/schema_100.json +0 -0
  268. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/jsn_files/schema_101.json +0 -0
  269. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/jsn_files/schema_102.json +0 -0
  270. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/jsn_files/schema_103.json +0 -0
  271. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/jsn_files/schema_104.json +0 -0
  272. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/jsn_files/schema_105.json +0 -0
  273. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/jsn_files/schema_108.json +0 -0
  274. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_000.json +0 -0
  275. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_000.log +0 -0
  276. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_001.json +0 -0
  277. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_001.log +0 -0
  278. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_002.json +0 -0
  279. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_002.log +0 -0
  280. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_010.json +0 -0
  281. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_010.log +0 -0
  282. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_011.json +0 -0
  283. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_011.log +0 -0
  284. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_012.json +0 -0
  285. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_012.log +0 -0
  286. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_013.json +0 -0
  287. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_013.log +0 -0
  288. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_014.json +0 -0
  289. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_014.log +0 -0
  290. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_300.json +0 -0
  291. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_300.log +0 -0
  292. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_301.json +0 -0
  293. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_301.log +0 -0
  294. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_302.json +0 -0
  295. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_302.log +0 -0
  296. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_303.json +0 -0
  297. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_303.log +0 -0
  298. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_304.json +0 -0
  299. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_304.log +0 -0
  300. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_310.json +0 -0
  301. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/schemas/log_files/schema_310.log +0 -0
  302. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_heat_trv_00/config.json +0 -0
  303. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_heat_trv_00/packet.log +0 -0
  304. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_heat_trv_00/schema.json +0 -0
  305. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_hvac_nuaire/config.json +0 -0
  306. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_hvac_nuaire/known_list.json +0 -0
  307. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_hvac_nuaire/packet.log +0 -0
  308. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_hvac_nuaire/schema.json +0 -0
  309. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/_hvac_nuaire/status.json +0 -0
  310. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_otb_00/config.json +0 -0
  311. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_otb_00/packet.log +0 -0
  312. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_otb_00/schema.json +0 -0
  313. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_simple/packet.log +0 -0
  314. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_simple/schema.json +0 -0
  315. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_ufc_00/config.json +0 -0
  316. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_ufc_00/packet.log +0 -0
  317. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_zxdavb/config.json +0 -0
  318. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_zxdavb/known_list.json +0 -0
  319. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_zxdavb/packet.log +0 -0
  320. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/systems/heat_zxdavb/schema.json +0 -0
  321. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_api_faultlog.py +0 -0
  322. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_api_schedule.py +0 -0
  323. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_apis_common.py +0 -0
  324. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_apis_heat.py +0 -0
  325. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_apis_hvac.py +0 -0
  326. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_cli_utility.py +0 -0
  327. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_devices.py +0 -0
  328. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_eavesdrop_dev_class.py +0 -0
  329. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_eavesdrop_schema.py +0 -0
  330. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_helpers.py +0 -0
  331. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_parser_helpers.py +0 -0
  332. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_parsers.py +0 -0
  333. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_schema_bits.py +0 -0
  334. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_schemas.py +0 -0
  335. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests/test_vol_schemas.py +0 -0
  336. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/__init__.py +0 -0
  337. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/configs/config_heat.json +0 -0
  338. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/configs/config_hvac.json +0 -0
  339. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/conftest.py +0 -0
  340. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/device/__init__.py +0 -0
  341. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/logs/test_api_faultlog.log +0 -0
  342. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_api_faultlog.py +0 -0
  343. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_api_schedule.py +0 -0
  344. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_create_stack.py +0 -0
  345. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_hgi_behaviors.py +0 -0
  346. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_protocol_fsm.py +0 -0
  347. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/test_use_regex.py +0 -0
  348. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/virtual_rf/__init__.py +0 -0
  349. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/virtual_rf/const.py +0 -0
  350. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/virtual_rf/helpers.py +0 -0
  351. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_rf/virtual_rf/virtual_rf.py +0 -0
  352. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_tx/__init__.py +0 -0
  353. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/tests_tx/test_command.py +0 -0
  354. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/wip/_test_eavesdrop_dhw_sensor.py +0 -0
  355. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/wip/_test_eavesdrop_htg_control.py +0 -0
  356. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/wip/_test_eavesdrop_ufc_circuits.py +0 -0
  357. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/wip/_test_eavesdrop_zone_sensors.py +0 -0
  358. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/wip/_test_eavesdrop_zone_type.py +0 -0
  359. {ramses_rf-0.51.9 → ramses_rf-0.52.0}/tests/wip/test_wip_cli.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramses_rf
3
- Version: 0.51.9
3
+ Version: 0.52.0
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,492 @@
1
+ """Parser for 2411 parameter messages.
2
+
3
+ At the end of the file you can find test_messages that can be used to test the parser.
4
+ Known_2411_PARAMS(at the top) holds params that we decoded (partly)
5
+ _parse_hex_value is used to parse unknown params in different formats.
6
+ Check these if you see any values that make sense to find the right format.
7
+ Just run it from the terminal as python3 2411_parser.py
8
+ """
9
+
10
+ import logging
11
+ from typing import Any
12
+
13
+ _LOGGER = logging.getLogger(__name__)
14
+
15
+
16
+ # Parameter definitions
17
+ # Add parameters that we know how to parse (or parts of it)
18
+
19
+ Known_2411_PARAMS = {
20
+ # TODO: add params that were decoded.
21
+ # "000007": {
22
+ # "name": "base_vent_enabled",
23
+ # "description": "Base Ventilation Enable/Disable",
24
+ # "parser": lambda payload, offset: {
25
+ # "unknown1": payload[6:16],
26
+ # "enabled": payload[16:18] == "01",
27
+ # "unknown2": payload[18:],
28
+ # },
29
+ # },
30
+ }
31
+
32
+
33
+ def parser_2411(payload: str, msg: Any) -> dict[str, Any]:
34
+ """
35
+ Parser for 2411 messages.
36
+ Params not listed in Known_2411_PARAMS are parsed by _parse_unknown_parameter
37
+ as 4byte, 6byte or 8byte blocks, in different formats.
38
+
39
+ :param payload: Hex string payload
40
+ :param msg: Message object with verb attribute (RQ/RP/W/I)
41
+ :return: Dictionary with parsed parameter data including all structure components
42
+ """
43
+
44
+ # Extract 3-byte parameter ID
45
+ param_id = payload[:6]
46
+
47
+ result: dict[str, Any] = {
48
+ "parameter_id": param_id,
49
+ "parameter_hex": f"0x{param_id}",
50
+ }
51
+
52
+ # Get parameter definition
53
+ param_def_raw = Known_2411_PARAMS.get(param_id)
54
+ param_def: dict[str, Any] | None = (
55
+ param_def_raw if isinstance(param_def_raw, dict) else None
56
+ )
57
+
58
+ if param_def:
59
+ result["parameter_name"] = param_def["name"]
60
+ result["description"] = param_def["description"]
61
+ else:
62
+ result["parameter_name"] = f"unknown_{param_id}"
63
+ result["description"] = "Unknown"
64
+ _LOGGER.warning(f"Unknown parameter ID: {param_id}. Payload: {payload}")
65
+
66
+ # For RQ (request) messages, just return parameter info
67
+ if hasattr(msg, "verb") and msg.verb == "RQ":
68
+ return result
69
+
70
+ try:
71
+ if param_def and "parser" in param_def:
72
+ # Use the custom parser function from the parameter definition
73
+ parser_func = param_def["parser"]
74
+ offset = param_def.get("offset", 0)
75
+ parsed_data = parser_func(payload, offset)
76
+ result.update(parsed_data)
77
+ else:
78
+ # Unknown parameter - try different parsing strategies
79
+ result.update(_parse_unknown_parameter(payload, param_id))
80
+
81
+ # Extract footer/status bytes (last 6 bytes typically)
82
+ if len(payload) >= 46:
83
+ result["type ? (3:5)"] = payload[3:5]
84
+ result["footer ? (-6)"] = payload[-6:]
85
+ result["status_flag ?(19)"] = payload[38:40] # Byte 19
86
+
87
+ except (ValueError, IndexError) as err:
88
+ _LOGGER.error(f"Error parsing 2411 payload for param {param_id}: {err}")
89
+ result["error"] = str(err)
90
+ result["raw_data"] = payload[6:]
91
+ return result
92
+
93
+
94
+ def _parse_unknown_parameter(payload: str, param_id: str) -> dict[str, Any]:
95
+ """
96
+ Try different parsing strategies for unknown 2411 parameters.
97
+
98
+ :param payload: Hex string payload
99
+ :param param_id: Parameter ID
100
+ :return: Dictionary with parsed data from different strategies
101
+ """
102
+ result = {}
103
+
104
+ # Strategy 1: Try 4-byte blocks from position 6 onwards
105
+ result["strategy_4byte"] = _try_4byte_blocks(payload)
106
+
107
+ # Strategy 2: Try 6-byte blocks from position 6 onwards
108
+ result["strategy_6byte"] = _try_6byte_blocks(payload)
109
+
110
+ # Strategy 3: Try 8-byte blocks from position 6 onwards
111
+ result["strategy_8byte"] = _try_8byte_blocks(payload)
112
+
113
+ return result
114
+
115
+
116
+ def _parse_hex_value(hex_str: str) -> dict[str, Any]:
117
+ """
118
+ Parse a hex string into multiple useful representations.
119
+
120
+ :param hex_str: Hex string to parse
121
+ :return: Dictionary with parsed representations
122
+ """
123
+ result: dict[str, Any] = {"raw": hex_str, "hex": f"0x{hex_str.upper()}"}
124
+
125
+ try:
126
+ # Basic decimal value
127
+ dec = int(hex_str, 16)
128
+ result["dec"] = dec
129
+
130
+ # Byte-swapped version (big-endian to little-endian)
131
+ if len(hex_str) % 2 == 0: # Only if even number of hex digits
132
+ # Swap byte order (e.g., "A1B2" -> "B2A1")
133
+ swapped = "".join(
134
+ reversed([hex_str[i : i + 2] for i in range(0, len(hex_str), 2)])
135
+ )
136
+ result["swapped_hex"] = f"0x{swapped.upper()}"
137
+ result["swapped_dec"] = int(swapped, 16)
138
+
139
+ # Little-endian interpretation
140
+ le_bytes = bytes.fromhex(hex_str)
141
+ le_value = int.from_bytes(le_bytes, byteorder="little", signed=False)
142
+ result["le_dec"] = le_value
143
+ result["le_hex"] = f"0x{le_value:X}"
144
+
145
+ # Signed integer interpretation
146
+ if len(hex_str) in [4, 8]: # 16-bit or 32-bit
147
+ result["signed_dec"] = int.from_bytes(
148
+ le_bytes, byteorder="big", signed=True
149
+ )
150
+
151
+ # Binary representation
152
+ result["bin"] = f"0b{dec:0{len(hex_str) * 4}b}"
153
+
154
+ # ASCII interpretation if possible (for 2 or 4 character hex)
155
+ if len(hex_str) in [2, 4, 6, 8]:
156
+ try:
157
+ ascii_str = bytes.fromhex(hex_str).decode("ascii", errors="replace")
158
+ if all(32 <= ord(c) <= 126 for c in ascii_str):
159
+ result["ascii"] = ascii_str
160
+ except (UnicodeDecodeError, ValueError):
161
+ pass
162
+
163
+ except ValueError as e:
164
+ result["error"] = str(e)
165
+
166
+ return result
167
+
168
+
169
+ def _try_4byte_blocks(payload: str) -> dict[str, Any]:
170
+ """
171
+ Try parsing as 4-byte (8 hex character) blocks.
172
+
173
+ For each 4-byte block, provides:
174
+ - raw: Original hex string
175
+ - hex: Formatted hex with 0x prefix
176
+ - dec: Unsigned decimal value
177
+ - swapped_hex: Bytes in reverse order
178
+ - swapped_dec: Decimal of swapped bytes
179
+ - le_dec: Little-endian decimal
180
+ - le_hex: Little-endian hex
181
+ - signed_dec: Signed decimal (if applicable)
182
+ - bin: Binary representation
183
+ - ascii: ASCII interpretation (if possible)
184
+ - offset: Position in the original payload
185
+
186
+ :param payload: Hex string payload
187
+ :return: Dictionary with parsed 4-byte blocks
188
+ """
189
+ blocks = {}
190
+ data_section = payload[6:] # Skip parameter ID
191
+
192
+ for i in range(0, min(len(data_section), 32), 4): # Up to 8 blocks
193
+ if i + 4 <= len(data_section):
194
+ block = data_section[i : i + 4]
195
+ block_info = _parse_hex_value(block)
196
+ block_info["offset"] = 6 + i # Add offset to the original payload
197
+ blocks[f"block_{i // 4 + 1}"] = block_info
198
+
199
+ return blocks
200
+
201
+
202
+ def _try_6byte_blocks(payload: str) -> dict[str, Any]:
203
+ """
204
+ Try parsing as 6-byte (12 hex character) blocks.
205
+
206
+ For each 6-byte block, provides:
207
+ - raw: Original hex string
208
+ - hex: Formatted hex with 0x prefix
209
+ - dec: Unsigned decimal value
210
+ - swapped_hex: Bytes in reverse order
211
+ - swapped_dec: Decimal of swapped bytes
212
+ - le_dec: Little-endian decimal
213
+ - le_hex: Little-endian hex
214
+ - signed_dec: Signed decimal (if applicable)
215
+ - bin: Binary representation
216
+ - ascii: ASCII interpretation (if possible)
217
+ - offset: Position in the original payload
218
+
219
+ :param payload: Hex string payload
220
+ :return: Dictionary with parsed 6-byte blocks
221
+ """
222
+ blocks = {}
223
+ data_section = payload[6:] # Skip parameter ID
224
+
225
+ for i in range(0, min(len(data_section), 30), 6): # Up to 5 blocks
226
+ if i + 6 <= len(data_section):
227
+ block = data_section[i : i + 6]
228
+ block_info = _parse_hex_value(block)
229
+ block_info["offset"] = 6 + i
230
+ blocks[f"block_{i // 6 + 1}"] = block_info
231
+
232
+ return blocks
233
+
234
+
235
+ def _try_8byte_blocks(payload: str) -> dict[str, Any]:
236
+ """
237
+ Try parsing as 8-byte (16 hex character) blocks.
238
+
239
+ For each 8-byte block, provides:
240
+ - raw: Original hex string
241
+ - hex: Formatted hex with 0x prefix
242
+ - dec: Unsigned decimal value
243
+ - swapped_hex: Bytes in reverse order
244
+ - swapped_dec: Decimal of swapped bytes
245
+ - le_dec: Little-endian decimal
246
+ - le_hex: Little-endian hex
247
+ - signed_dec: Signed decimal (if applicable)
248
+ - bin: Binary representation
249
+ - ascii: ASCII interpretation (if possible)
250
+ - offset: Position in the original payload
251
+
252
+ :param payload: Hex string payload
253
+ :return: Dictionary with parsed 8-byte blocks
254
+ """
255
+ blocks = {}
256
+ data_section = payload[6:] # Skip parameter ID
257
+
258
+ for i in range(0, min(len(data_section), 32), 8): # Up to 4 blocks
259
+ if i + 8 <= len(data_section):
260
+ block = data_section[i : i + 8]
261
+ block_info = _parse_hex_value(block)
262
+ block_info["offset"] = 6 + i
263
+ blocks[f"block_{i // 8 + 1}"] = block_info
264
+
265
+ return blocks
266
+
267
+
268
+ def format_field(value: Any, width: int, align: str = "left") -> str:
269
+ """
270
+ Format a value to a specific width with alignment.
271
+
272
+ :param value: The value to format (will be converted to string)
273
+ :param width: The desired total width
274
+ :param align: 'left', 'right', or 'center'
275
+ :return: Formatted string padded with spaces to the specified width
276
+ """
277
+ if value is None:
278
+ value = "N/A"
279
+
280
+ text = str(value)
281
+
282
+ # Truncate if too long
283
+ if len(text) > width:
284
+ text = text[: width - 3] + "..." if width > 3 else text[:width]
285
+
286
+ # Apply alignment
287
+ if align == "right":
288
+ return f"{text:>{width}}"
289
+ elif align == "center":
290
+ return f"{text:^{width}}"
291
+ else: # left align
292
+ return f"{text:<{width}}"
293
+
294
+
295
+ def format_block_table(blocks: dict[str, Any], title: str) -> str:
296
+ """
297
+ Format a dictionary of blocks as a table.
298
+
299
+ :param blocks: Dictionary of parsed blocks
300
+ :param title: Title for the table
301
+ :return: Formatted table string
302
+ """
303
+ if not blocks:
304
+ return f"{title}: No blocks found\n"
305
+
306
+ # Get all unique keys from all blocks
307
+ all_keys = set()
308
+ for block_info in blocks.values():
309
+ all_keys.update(block_info.keys())
310
+
311
+ # Remove keys that shouldn't be in the table
312
+ exclude_keys = {"raw", "offset"}
313
+ all_keys_set = set()
314
+ for block_info in blocks.values():
315
+ all_keys_set.update(block_info.keys())
316
+
317
+ # Custom ordering: put bin at the end, keep others in order
318
+ display_keys = []
319
+ for key in sorted(all_keys_set):
320
+ if key not in exclude_keys:
321
+ if key == "bin":
322
+ continue # Save for last
323
+ display_keys.append(key)
324
+ display_keys.append("bin") # Put bin at the end
325
+
326
+ if not display_keys:
327
+ return f"{title}: No displayable data\n"
328
+
329
+ # Define column specifications: (width, align)
330
+ column_specs = [
331
+ (12, "left"), # Block (+1)
332
+ (8, "left"), # Raw (-2)
333
+ ]
334
+
335
+ # Add specs for each display key
336
+ for key in display_keys:
337
+ if key == "dec":
338
+ column_specs.append((9, "right")) # Increased for large decimal numbers
339
+ elif key in ["swapped_dec", "le_dec", "signed_dec"]:
340
+ column_specs.append((11, "right")) # Increased for swapped_dec
341
+ elif key == "hex":
342
+ column_specs.append(
343
+ (10, "left")
344
+ ) # Increased for hex (10 chars for 0x12345678)
345
+ elif key == "le_hex":
346
+ column_specs.append((9, "left")) # Increased for le_hex (8 digits + 0x)
347
+ elif key == "swapped_hex":
348
+ column_specs.append((11, "left")) # Increased for swapped_hex
349
+ elif key == "bin":
350
+ column_specs.append(
351
+ (50, "left")
352
+ ) # Very large width for full binary display
353
+ else:
354
+ column_specs.append((8, "left"))
355
+
356
+ # Create header
357
+ header = f"{title} ({len(blocks)} blocks):\n"
358
+ header_parts = []
359
+ header_names = ["Block", "Raw"] + display_keys
360
+ for i, (width, align) in enumerate(column_specs):
361
+ header_parts.append(format_field(header_names[i], width, align))
362
+ header += " ".join(header_parts) + "\n"
363
+ # Calculate separator length based on header with spaces
364
+ header_with_spaces = " ".join(header_parts)
365
+ header += "-" * len(header_with_spaces) + "\n"
366
+
367
+ # Create rows
368
+ rows = []
369
+ for block_name, block_info in blocks.items():
370
+ offset = block_info.get("offset", "N/A")
371
+ block_display = f"{block_name} ({offset})"
372
+ raw_value = block_info.get("raw", "N/A")
373
+
374
+ row_parts = []
375
+ # Format Block and Raw columns
376
+ row_parts.append(format_field(block_display, 12, "left")) # Block (+1)
377
+ row_parts.append(format_field(raw_value, 8, "left")) # Raw (-2)
378
+
379
+ # Format each data column
380
+ for key in display_keys:
381
+ value = block_info.get(key, "N/A")
382
+ if key == "dec":
383
+ row_parts.append(
384
+ format_field(value, 9, "right")
385
+ ) # Increased for large decimal numbers
386
+ elif key in ["swapped_dec", "le_dec", "signed_dec"]:
387
+ row_parts.append(format_field(value, 11, "right"))
388
+ elif key == "hex":
389
+ row_parts.append(format_field(value, 10, "left"))
390
+ elif key == "le_hex":
391
+ row_parts.append(format_field(value, 9, "left"))
392
+ elif key == "swapped_hex":
393
+ row_parts.append(format_field(value, 11, "left"))
394
+ elif key == "bin":
395
+ # No truncation for binary - let it be as long as needed
396
+ row_parts.append(format_field(value, 50, "left"))
397
+ else:
398
+ row_parts.append(format_field(value, 8, "left"))
399
+
400
+ row = " ".join(row_parts) # Join with spaces between columns
401
+ rows.append(row)
402
+
403
+ return header + "\n".join(rows) + "\n"
404
+
405
+
406
+ def format_result_table(result: dict[str, Any], description: str) -> str:
407
+ """
408
+ Format a complete result as tables.
409
+
410
+ :param result: Parsed result dictionary
411
+ :param description: Description for the result
412
+ :return: Formatted result string with tables
413
+ """
414
+ output = []
415
+ output.append(f"\n{description}")
416
+ output.append("=" * 60)
417
+ output.append(f"Parameter: {result['parameter_name']} ({result['parameter_id']})")
418
+ output.append(f"Verb: {result.get('verb', 'N/A')}")
419
+ output.append(f"Description: {result['description']}")
420
+ output.append(f"Payload: {result.get('payload', 'N/A')}")
421
+
422
+ # Print strategy tables
423
+ for key, value in result.items():
424
+ if key not in [
425
+ "parameter_id",
426
+ "parameter_name",
427
+ "description",
428
+ "payload",
429
+ "verb",
430
+ ] and isinstance(value, dict):
431
+ output.append(format_block_table(value, key))
432
+
433
+ # Print simple values
434
+ simple_values = []
435
+ for key, value in result.items():
436
+ if key not in [
437
+ "parameter_id",
438
+ "parameter_name",
439
+ "description",
440
+ "payload",
441
+ "verb",
442
+ ] and not isinstance(value, dict):
443
+ simple_values.append(f"{key}: {value}")
444
+
445
+ if simple_values:
446
+ output.append("Other values:")
447
+ for value in simple_values:
448
+ output.append(f" {value}")
449
+
450
+ output.append("-" * 60)
451
+ return "\n".join(output)
452
+
453
+
454
+ def decode_2411_message(raw_message: str, verb: str = "RP") -> dict[str, Any]:
455
+ """
456
+ Convenience function to decode a raw 2411 message.
457
+
458
+ :param raw_message: Raw 2411 message string
459
+ :param verb: Message verb (default: "RP")
460
+ :return: Decoded message dictionary
461
+ """
462
+
463
+ class MockMessage:
464
+ def __init__(self, verb):
465
+ self.verb = verb
466
+
467
+ result = parser_2411(raw_message, MockMessage(verb))
468
+ result["verb"] = verb # Add verb to result for display
469
+ return result
470
+
471
+
472
+ # Example usage and testing
473
+ if __name__ == "__main__":
474
+ # Test messages from your logs
475
+ # Example:
476
+ # ("0000070000000000010000000000000001000000018A00", "RP", "Base vent is ON")
477
+ test_messages = [
478
+ ("00000700000000000000000000000000000000000000", "W", "Base vent set to OFF"),
479
+ ("00000700000000000100000000000000000000000000", "W", "Base vent set to ON"),
480
+ ("0000070000000000010000000000000001000000018A00", " I", "Base vent is ON"),
481
+ ("0000070000000000000000000000000001000000018A00", "RP", "Base vent is OFF"),
482
+ ("0000070000000000010000000000000001000000018A00", "RP", "Base vent is ON"),
483
+ # ("0000871400000000000000000000000002000000018A00", "RP", "Parameter 0x87"),
484
+ # ("0000DA7F00000000000000000000000003000000018A00", "RP", "Parameter 0xDA"),
485
+ # ("0000881510000002BC000001900000076C000000018A33", "RP", "Timer configuration"),
486
+ ]
487
+
488
+ print("2411 Message Parser Test\n" + "=" * 50)
489
+
490
+ for payload, verb, description in test_messages:
491
+ result = decode_2411_message(payload, verb)
492
+ print(format_result_table(result, description))
@@ -438,17 +438,29 @@ def print_summary(gwy: Gateway, **kwargs: Any) -> None:
438
438
 
439
439
  if kwargs.get("show_crazys"):
440
440
  for device in [d for d in gwy.devices if d.type == DEV_TYPE_MAP.CTL]:
441
- for code, verbs in device._msgz.items():
442
- if code in (Code._0005, Code._000C):
443
- for verb in verbs.values():
444
- for pkt in verb.values():
445
- print(f"{pkt}")
441
+ if gwy.msg_db:
442
+ for msg in gwy.msg_db.get(device=device.id, code=Code._0005):
443
+ print(f"{msg._pkt}")
444
+ for msg in gwy.msg_db.get(device=device.id, code=Code._000C):
445
+ print(f"{msg._pkt}")
446
+ else: # TODO(eb): replace next block by
447
+ # raise NotImplementedError
448
+ for code, verbs in device._msgz.items():
449
+ if code in (Code._0005, Code._000C):
450
+ for verb in verbs.values():
451
+ for pkt in verb.values():
452
+ print(f"{pkt}")
446
453
  print()
447
454
  for device in [d for d in gwy.devices if d.type == DEV_TYPE_MAP.UFC]:
448
- for code in device._msgz.values():
449
- for verb in code.values():
450
- for pkt in verb.values():
451
- print(f"{pkt}")
455
+ if gwy.msg_db:
456
+ for msg in gwy.msg_db.get(device=device.id):
457
+ print(f"{msg._pkt}")
458
+ else: # TODO(eb): replace next block by
459
+ # raise NotImplementedError
460
+ for code in device._msgz.values():
461
+ for verb in code.values():
462
+ for pkt in verb.values():
463
+ print(f"{pkt}")
452
464
  print()
453
465
 
454
466
 
@@ -394,7 +394,7 @@ async def script_scan_otb_ramses(
394
394
  Code._3223,
395
395
  Code._3EF0, # rel. modulation level / RelativeModulationLevel (also, below)
396
396
  Code._3EF1, # rel. modulation level / RelativeModulationLevel
397
- ) # excl. 3220
397
+ ) # excl. 3150, 3220
398
398
 
399
399
  for c in _CODES:
400
400
  gwy.send_cmd(Command.from_attrs(RQ, dev_id, c, "00"), priority=Priority.LOW)