ramses-rf 0.53.5__tar.gz → 0.53.6__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 (391) hide show
  1. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.github/workflows/check-lint.yml +2 -0
  2. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.github/workflows/check-test.yml +2 -0
  3. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.github/workflows/check-type.yml +2 -0
  4. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/PKG-INFO +3 -3
  5. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/README.md +2 -2
  6. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/dispatcher.py +5 -1
  7. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/schemas.py +2 -0
  8. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/version.py +1 -1
  9. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/protocol_fsm.py +11 -4
  10. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/schemas.py +2 -0
  11. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/transport.py +24 -11
  12. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/version.py +1 -1
  13. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/requirements/requirements_dev.txt +1 -1
  14. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_dispatcher.py +61 -1
  15. ramses_rf-0.53.6/tests/tests_tx/test_transport.py +194 -0
  16. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  17. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.github/dependabot.yml +0 -0
  18. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.github/workflows/check-cov.yml +0 -0
  19. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.github/workflows/publish-hatch.yml +0 -0
  20. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.gitignore +0 -0
  21. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/.pre-commit-config.yaml +0 -0
  22. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/LICENSE +0 -0
  23. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/README-developers.md +0 -0
  24. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/client.py +0 -0
  25. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/Makefile +0 -0
  26. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/make.bat +0 -0
  27. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/_static/CC-BY-NC-SA-4.0.txt +0 -0
  28. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/_static/ramses_rf_logo.png +0 -0
  29. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/binding_process.md +0 -0
  30. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/conf.py +0 -0
  31. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/glossary.rst +0 -0
  32. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/index.rst +0 -0
  33. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/modules.rst +0 -0
  34. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/ramses_cli.rst +0 -0
  35. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/ramses_rf.device.rst +0 -0
  36. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/ramses_rf.rst +0 -0
  37. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/ramses_rf.system.rst +0 -0
  38. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/ramses_tx.rst +0 -0
  39. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/docs/source/usage.md +0 -0
  40. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/misc/2411_parser.py +0 -0
  41. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/misc/fingerprints.log +0 -0
  42. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/misc/ser2net.yaml +0 -0
  43. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/misc/ti_3410/notes.sh +0 -0
  44. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/misc/ti_3410/ti_3410.fw +0 -0
  45. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/pyproject.toml +0 -0
  46. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_cli/__init__.py +0 -0
  47. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_cli/client.py +0 -0
  48. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_cli/debug.py +0 -0
  49. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_cli/discovery.py +0 -0
  50. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_cli/py.typed +0 -0
  51. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_cli/utils/cat_slow.py +0 -0
  52. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_cli/utils/convert.py +0 -0
  53. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/__init__.py +0 -0
  54. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/binding_fsm.py +0 -0
  55. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/const.py +0 -0
  56. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/database.py +0 -0
  57. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/device/__init__.py +0 -0
  58. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/device/base.py +0 -0
  59. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/device/heat.py +0 -0
  60. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/device/hvac.py +0 -0
  61. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/entity_base.py +0 -0
  62. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/exceptions.py +0 -0
  63. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/gateway.py +0 -0
  64. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/helpers.py +0 -0
  65. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/py.typed +0 -0
  66. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/storage.py +0 -0
  67. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/system/__init__.py +0 -0
  68. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/system/faultlog.py +0 -0
  69. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/system/heat.py +0 -0
  70. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/system/schedule.py +0 -0
  71. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_rf/system/zones.py +0 -0
  72. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/__init__.py +0 -0
  73. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/address.py +0 -0
  74. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/command.py +0 -0
  75. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/const.py +0 -0
  76. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/exceptions.py +0 -0
  77. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/fingerprints.py +0 -0
  78. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/frame.py +0 -0
  79. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/gateway.py +0 -0
  80. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/helpers.py +0 -0
  81. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/logger.py +0 -0
  82. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/message.py +0 -0
  83. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/opentherm.py +0 -0
  84. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/packet.py +0 -0
  85. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/parsers.py +0 -0
  86. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/protocol.py +0 -0
  87. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/py.typed +0 -0
  88. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/ramses.py +0 -0
  89. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/typed_dicts.py +0 -0
  90. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/ramses_tx/typing.py +0 -0
  91. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/requirements/requirements.txt +0 -0
  92. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/requirements/requirements_docs.txt +0 -0
  93. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/_test_apis_mock.py +0 -0
  94. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/_test_mock_faultlog.py +0 -0
  95. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/_test_mock_schedule.py +0 -0
  96. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/_test_packets_bad.py +0 -0
  97. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/_test_performance_WIP.py +0 -0
  98. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/_test_state_mgt.py +0 -0
  99. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/common.py +0 -0
  100. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/mocked_devices/__init__.py +0 -0
  101. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/mocked_devices/command.py +0 -0
  102. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/mocked_devices/const.py +0 -0
  103. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/mocked_devices/device_heat.py +0 -0
  104. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/mocked_devices/device_hvac.py +0 -0
  105. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/deprecated/mocked_devices/transport.py +0 -0
  106. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/test_HA_MQTT/test_transport_callback.py +0 -0
  107. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/__init__.py +0 -0
  108. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/heat/ctl_bdr_91t.log +0 -0
  109. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/heat/dts_ctl_sensor.log +0 -0
  110. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/heat/hcw_ctl_sensor.log +0 -0
  111. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/heat/rnd_ctl_sensor.log +0 -0
  112. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/heat/rnd_ctl_sensor.yaml +0 -0
  113. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/heat/trv_ctl.log +0 -0
  114. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/co2_fan_itho.json +0 -0
  115. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/co2_fan_itho.log +0 -0
  116. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/co2_fan_itho.yaml +0 -0
  117. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/dis_fan_orcon.json +0 -0
  118. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/dis_fan_orcon.log +0 -0
  119. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/rem_fan_climarad.log +0 -0
  120. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/rem_fan_nuaire.json +0 -0
  121. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/rem_fan_nuaire.log +0 -0
  122. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/rem_fan_nuaire.yaml +0 -0
  123. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/rem_fan_vasco.log +0 -0
  124. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/bindings/hvac/rem_fan_ventura.log +0 -0
  125. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/devices/device_02.log +0 -0
  126. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/devices/device_04.log +0 -0
  127. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/devices/device_10.log +0 -0
  128. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/devices/device_13.log +0 -0
  129. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/devices/device_22.log +0 -0
  130. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_off.json +0 -0
  131. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_dev_class/hvac/known_list_eavesdrop_on.json +0 -0
  132. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_dev_class/hvac/packet.log +0 -0
  133. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_trv_actuator_long/packet.log +0 -0
  134. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_off.json +0 -0
  135. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_trv_actuator_long/schema_eavesdrop_on.json +0 -0
  136. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/packet.log +0 -0
  137. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_off.json +0 -0
  138. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_trv_actuator_mixed/schema_eavesdrop_on.json +0 -0
  139. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_ufh_circuits/packet.log +0 -0
  140. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_off.json +0 -0
  141. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/_ufh_circuits/schema_eavesdrop_on.json +0 -0
  142. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/app_cntrl/packet.log +0 -0
  143. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_off.json +0 -0
  144. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/app_cntrl/schema_eavesdrop_on.json +0 -0
  145. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/trv_actuators/packet.log +0 -0
  146. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_off.json +0 -0
  147. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/trv_actuators/schema_eavesdrop_on.json +0 -0
  148. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_000/packet.log +0 -0
  149. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_off.json +0 -0
  150. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_000/schema_eavesdrop_on.json +0 -0
  151. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_001/packet.log +0 -0
  152. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_off.json +0 -0
  153. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_001/schema_eavesdrop_on.json +0 -0
  154. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_002/packet.log +0 -0
  155. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_off.json +0 -0
  156. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_002/schema_eavesdrop_on.json +0 -0
  157. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_003/packet.log +0 -0
  158. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_off.json +0 -0
  159. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_003/schema_eavesdrop_on.json +0 -0
  160. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_004/packet.log +0 -0
  161. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_off.json +0 -0
  162. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/eavesdrop_schema/zone_sensors_004/schema_eavesdrop_on.json +0 -0
  163. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/10e0_xxxx.log +0 -0
  164. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/_gather.sh +0 -0
  165. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/01_EvoTouch_Colour.log +0 -0
  166. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/01_Evo_Color.log +0 -0
  167. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/01_IONA_RAI_Prototype.log +0 -0
  168. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/02_HCE80_V3.10_061117..log +0 -0
  169. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/04_HR92 Radiator Ctrl_.log +0 -0
  170. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/08_Jasper_EIM.log +0 -0
  171. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/10_R8810A_Bridge.log +0 -0
  172. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/10_R8820.log +0 -0
  173. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/30_Internet_Gateway.log +0 -0
  174. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/31_Jasper_Stat_TXXX.log +0 -0
  175. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/heat/34_T87RF2025.log +0 -0
  176. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/18_BRDG-02A55.log +0 -0
  177. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/18_HRA82.log +0 -0
  178. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/20.log +0 -0
  179. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/21_CCU-12T20.log +0 -0
  180. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMC-07RP01.log +0 -0
  181. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMC-15RP01.log +0 -0
  182. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMC-17RP01.log +0 -0
  183. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMN-07LM01.log +0 -0
  184. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMN-15LF01.log +0 -0
  185. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMN-17LMP01.log +0 -0
  186. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMS-15C16.log +0 -0
  187. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/29_VMS-17HB01.log +0 -0
  188. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/30_BRDG-02EM23.log +0 -0
  189. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/30_BRDG-02JAS01.log +0 -0
  190. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMC-15RPS34.log +0 -0
  191. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMD-15RMS64.log +0 -0
  192. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMD-15RMS86.log +0 -0
  193. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMD-17RPS01.log +0 -0
  194. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMN-23LM33.log +0 -0
  195. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMN-23LMH23.log +0 -0
  196. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMS-15CM17.log +0 -0
  197. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMS-23C33.log +0 -0
  198. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMS-23HB33.log +0 -0
  199. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/32_VMZ-15V13.log +0 -0
  200. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/37_VMD-07RPS13.log +0 -0
  201. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/37_VMI-15MC01log +0 -0
  202. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/37_VMI-15WSJ53.log +0 -0
  203. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/37_VMS-02J52.log +0 -0
  204. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/37_VMS-12C39.log +0 -0
  205. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/99_CVE-RF.log +0 -0
  206. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/fingerprints/hvac/99_VMS-17C01.log +0 -0
  207. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/helpers.py +0 -0
  208. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/logger/packet_in.log +0 -0
  209. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/logger/packet_out.log +0 -0
  210. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/logs/pkts_bad_000.log +0 -0
  211. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/logs/pkts_tba_000.log +0 -0
  212. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/logs/system_cache.json +0 -0
  213. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parser_helpers/pkt_addr_set.log +0 -0
  214. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parser_helpers/pkt_dev_class.log +0 -0
  215. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0001_wip.log +0 -0
  216. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0002.log +0 -0
  217. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0004_wip.log +0 -0
  218. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0005.log +0 -0
  219. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0006.log +0 -0
  220. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0008.log +0 -0
  221. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0009.log +0 -0
  222. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_000a.log +0 -0
  223. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_000c.log +0 -0
  224. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_000e.log +0 -0
  225. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_01ff_wip.log +0 -0
  226. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_0418.log +0 -0
  227. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_042f.log +0 -0
  228. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1030.log +0 -0
  229. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1060.log +0 -0
  230. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_10d0.log +0 -0
  231. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_10e0.log +0 -0
  232. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1260.log +0 -0
  233. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1298.log +0 -0
  234. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_12a0.log +0 -0
  235. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_12c0.log +0 -0
  236. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1300.log +0 -0
  237. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1f09.log +0 -0
  238. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1fc9.log +0 -0
  239. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_1fd4.log +0 -0
  240. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_2210.log +0 -0
  241. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22c9.log +0 -0
  242. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22d0.log +0 -0
  243. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22d9.log +0 -0
  244. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22e0.log +0 -0
  245. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22e5.log +0 -0
  246. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22e9.log +0 -0
  247. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22f1.log +0 -0
  248. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22f2.log +0 -0
  249. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22f3.log +0 -0
  250. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22f4.log +0 -0
  251. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_22f7.log +0 -0
  252. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_2309.log +0 -0
  253. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_2349.log +0 -0
  254. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_2411_wip.log +0 -0
  255. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_2e04.log +0 -0
  256. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_2e10_wip.log +0 -0
  257. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_30c9.log +0 -0
  258. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3110_wip.log +0 -0
  259. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3120.log +0 -0
  260. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_313e_wip.log +0 -0
  261. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3150.log +0 -0
  262. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_31d9.log +0 -0
  263. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_31da.log +0 -0
  264. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3200.log +0 -0
  265. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3210.log +0 -0
  266. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3220.log +0 -0
  267. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3222.log +0 -0
  268. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3ef0_wip.log +0 -0
  269. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_3ef1_wip.log +0 -0
  270. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_4e01.log +0 -0
  271. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_4e02.log +0 -0
  272. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_4e04.log +0 -0
  273. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/parsers/code_4e15.log +0 -0
  274. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schedules/_sched_002/packet.log +0 -0
  275. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schedules/_sched_002/schedule.json +0 -0
  276. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schedules/sched_001/packet.log +0 -0
  277. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schedules/sched_001/schedule.json +0 -0
  278. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schedules/sched_dhw/packet.log +0 -0
  279. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schedules/sched_dhw/schedule.json +0 -0
  280. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/jsn_files/schema_100.json +0 -0
  281. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/jsn_files/schema_101.json +0 -0
  282. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/jsn_files/schema_102.json +0 -0
  283. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/jsn_files/schema_103.json +0 -0
  284. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/jsn_files/schema_104.json +0 -0
  285. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/jsn_files/schema_105.json +0 -0
  286. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/jsn_files/schema_108.json +0 -0
  287. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_000.json +0 -0
  288. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_000.log +0 -0
  289. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_001.json +0 -0
  290. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_001.log +0 -0
  291. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_002.json +0 -0
  292. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_002.log +0 -0
  293. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_010.json +0 -0
  294. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_010.log +0 -0
  295. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_011.json +0 -0
  296. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_011.log +0 -0
  297. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_012.json +0 -0
  298. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_012.log +0 -0
  299. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_013.json +0 -0
  300. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_013.log +0 -0
  301. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_014.json +0 -0
  302. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_014.log +0 -0
  303. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_300.json +0 -0
  304. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_300.log +0 -0
  305. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_301.json +0 -0
  306. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_301.log +0 -0
  307. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_302.json +0 -0
  308. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_302.log +0 -0
  309. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_303.json +0 -0
  310. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_303.log +0 -0
  311. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_304.json +0 -0
  312. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_304.log +0 -0
  313. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_310.json +0 -0
  314. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/schemas/log_files/schema_310.log +0 -0
  315. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_heat_trv_00/config.json +0 -0
  316. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_heat_trv_00/packet.log +0 -0
  317. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_heat_trv_00/schema.json +0 -0
  318. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_hvac_nuaire/config.json +0 -0
  319. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_hvac_nuaire/known_list.json +0 -0
  320. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_hvac_nuaire/packet.log +0 -0
  321. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_hvac_nuaire/schema.json +0 -0
  322. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/_hvac_nuaire/status.json +0 -0
  323. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_otb_00/config.json +0 -0
  324. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_otb_00/packet.log +0 -0
  325. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_otb_00/schema.json +0 -0
  326. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_simple/packet.log +0 -0
  327. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_simple/schema.json +0 -0
  328. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_ufc_00/config.json +0 -0
  329. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_ufc_00/packet.log +0 -0
  330. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_ufc_01/packet.log +0 -0
  331. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_zxdavb/config.json +0 -0
  332. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_zxdavb/known_list.json +0 -0
  333. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_zxdavb/packet.log +0 -0
  334. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/systems/heat_zxdavb/schema.json +0 -0
  335. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_api_faultlog.py +0 -0
  336. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_api_schedule.py +0 -0
  337. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_apis_binding.py +0 -0
  338. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_apis_common.py +0 -0
  339. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_apis_heat.py +0 -0
  340. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_apis_hvac.py +0 -0
  341. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_cli_transport_factory.py +0 -0
  342. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_devices.py +0 -0
  343. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_eavesdrop_dev_class.py +0 -0
  344. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_eavesdrop_schema.py +0 -0
  345. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_helpers.py +0 -0
  346. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_hgi_id.py +0 -0
  347. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_parser_helpers.py +0 -0
  348. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_parsers.py +0 -0
  349. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_ramses_schema.py +0 -0
  350. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_schema_bits.py +0 -0
  351. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_schemas.py +0 -0
  352. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_storage.py +0 -0
  353. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_systems.py +0 -0
  354. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests/test_vol_schemas.py +0 -0
  355. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_cli/test_cli_utility.py +0 -0
  356. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_cli/test_client.py +0 -0
  357. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_cli/test_debug.py +0 -0
  358. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_cli/test_discovery.py +0 -0
  359. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/__init__.py +0 -0
  360. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/configs/config_heat.json +0 -0
  361. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/configs/config_hvac.json +0 -0
  362. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/conftest.py +0 -0
  363. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/device/__init__.py +0 -0
  364. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/device/test_hvac_ventilator.py +0 -0
  365. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/logs/test_api_faultlog.log +0 -0
  366. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_api_faultlog.py +0 -0
  367. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_api_schedule.py +0 -0
  368. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_binding_fsm.py +0 -0
  369. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_create_stack.py +0 -0
  370. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_database.py +0 -0
  371. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_entity_base.py +0 -0
  372. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_hgi_behaviors.py +0 -0
  373. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_protocol_fsm.py +0 -0
  374. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_system_heat.py +0 -0
  375. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_use_regex.py +0 -0
  376. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_virt_network.py +0 -0
  377. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/test_virtual_rf.py +0 -0
  378. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/virtual_rf/__init__.py +0 -0
  379. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/virtual_rf/const.py +0 -0
  380. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/virtual_rf/helpers.py +0 -0
  381. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_rf/virtual_rf/virtual_rf.py +0 -0
  382. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_tx/__init__.py +0 -0
  383. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_tx/test_command.py +0 -0
  384. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_tx/test_const.py +0 -0
  385. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/tests_tx/test_logger.py +0 -0
  386. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/wip/_test_eavesdrop_dhw_sensor.py +0 -0
  387. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/wip/_test_eavesdrop_htg_control.py +0 -0
  388. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/wip/_test_eavesdrop_ufc_circuits.py +0 -0
  389. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/wip/_test_eavesdrop_zone_sensors.py +0 -0
  390. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/wip/_test_eavesdrop_zone_type.py +0 -0
  391. {ramses_rf-0.53.5 → ramses_rf-0.53.6}/tests/wip/test_wip_cli.sh +0 -0
@@ -1,5 +1,7 @@
1
1
  name: Linting
2
2
 
3
+ permissions: ## security hint
4
+ contents: read
3
5
 
4
6
  on:
5
7
  push:
@@ -1,5 +1,7 @@
1
1
  name: Testing
2
2
 
3
+ permissions:
4
+ contents: read
3
5
 
4
6
  on:
5
7
  push:
@@ -1,5 +1,7 @@
1
1
  name: Typing
2
2
 
3
+ permissions:
4
+ contents: read
3
5
 
4
6
  on:
5
7
  push:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramses_rf
3
- Version: 0.53.5
3
+ Version: 0.53.6
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
@@ -62,11 +62,11 @@ To install the `ramses_rf` command line client:
62
62
  ```
63
63
  git clone https://github.com/ramses-rf/ramses_rf
64
64
  cd ramses_rf
65
- pip install -r requirements.txt
65
+ pip install -r requirements/requirements.txt
66
66
  pip install -e .
67
67
  ```
68
68
 
69
- The CLI is called ``client.py`` and is included in the code root.
69
+ The CLI is called `client.py` and is included in the code root.
70
70
  It has options to monitor and parse Ramses-II traffic to screen or a log file, and to parse a file containing Ramses-II messages to the screen.
71
71
  See the [client.py CLI wiki page](https://github.com/ramses-rf/ramses_rf/wiki/2.-The-client.py-command-line) for instructions.
72
72
 
@@ -41,11 +41,11 @@ To install the `ramses_rf` command line client:
41
41
  ```
42
42
  git clone https://github.com/ramses-rf/ramses_rf
43
43
  cd ramses_rf
44
- pip install -r requirements.txt
44
+ pip install -r requirements/requirements.txt
45
45
  pip install -e .
46
46
  ```
47
47
 
48
- The CLI is called ``client.py`` and is included in the code root.
48
+ The CLI is called `client.py` and is included in the code root.
49
49
  It has options to monitor and parse Ramses-II traffic to screen or a log file, and to parse a file containing Ramses-II messages to the screen.
50
50
  See the [client.py CLI wiki page](https://github.com/ramses-rf/ramses_rf/wiki/2.-The-client.py-command-line) for instructions.
51
51
 
@@ -270,7 +270,11 @@ def process_msg(gwy: Gateway, msg: Message) -> None:
270
270
  )
271
271
 
272
272
  except (AttributeError, LookupError, TypeError, ValueError) as err:
273
- _LOGGER.exception("%s < %s(%s)", msg._pkt, err.__class__.__name__, err)
273
+ if getattr(gwy.config, "enforce_strict_handling", False):
274
+ raise
275
+ _LOGGER.warning(
276
+ "%s < %s(%s)", msg._pkt, err.__class__.__name__, err, exc_info=True
277
+ )
274
278
 
275
279
  else:
276
280
  logger_xxxx(msg)
@@ -245,6 +245,7 @@ SCH_GLOBAL_SCHEMAS = vol.Schema(SCH_GLOBAL_SCHEMAS_DICT, extra=vol.PREVENT_EXTRA
245
245
  # 4/7: Gateway (parser/state) configuration
246
246
  SZ_DISABLE_DISCOVERY: Final = "disable_discovery"
247
247
  SZ_ENABLE_EAVESDROP: Final = "enable_eavesdrop"
248
+ SZ_ENFORCE_STRICT_HANDLING: Final = "enforce_strict_handling"
248
249
  SZ_MAX_ZONES: Final = "max_zones" # TODO: move to TCS-attr from GWY-layer
249
250
  SZ_REDUCE_PROCESSING: Final = "reduce_processing"
250
251
  SZ_USE_ALIASES: Final = "use_aliases" # use friendly device names from known_list
@@ -253,6 +254,7 @@ SZ_USE_NATIVE_OT: Final = "use_native_ot" # favour OT (3220s) over RAMSES
253
254
  SCH_GATEWAY_DICT = {
254
255
  vol.Optional(SZ_DISABLE_DISCOVERY, default=False): bool,
255
256
  vol.Optional(SZ_ENABLE_EAVESDROP, default=False): bool,
257
+ vol.Optional(SZ_ENFORCE_STRICT_HANDLING, default=False): bool,
256
258
  vol.Optional(SZ_MAX_ZONES, default=DEFAULT_MAX_ZONES): vol.All(
257
259
  int, vol.Range(min=1, max=16)
258
260
  ), # NOTE: no default
@@ -1,4 +1,4 @@
1
1
  """RAMSES RF - a RAMSES-II protocol decoder & analyser (application layer)."""
2
2
 
3
- __version__ = "0.53.5"
3
+ __version__ = "0.53.6"
4
4
  VERSION = __version__
@@ -145,13 +145,20 @@ class ProtocolContext:
145
145
  # nope, was not successful, so multiplier should be incremented...
146
146
  self._multiplier = min(3, old_val + 1)
147
147
 
148
+ if self._cmd_tx_count < 3:
149
+ level = logging.DEBUG
150
+ elif self._cmd_tx_count == 3:
151
+ level = logging.INFO
152
+ else:
153
+ level = logging.WARNING
154
+
148
155
  if isinstance(self._state, WantEcho):
149
- _LOGGER.warning(
150
- f"Timeout expired waiting for echo: {self} (delay={delay})"
156
+ _LOGGER.log(
157
+ level, f"Timeout expired waiting for echo: {self} (delay={delay})"
151
158
  )
152
159
  else: # isinstance(self._state, WantRply):
153
- _LOGGER.warning(
154
- f"Timeout expired waiting for reply: {self} (delay={delay})"
160
+ _LOGGER.log(
161
+ level, f"Timeout expired waiting for reply: {self} (delay={delay})"
155
162
  )
156
163
 
157
164
  assert isinstance(self.is_sending, bool), (
@@ -407,6 +407,7 @@ def select_device_filter_mode(
407
407
  # 5/5: Gateway (engine) configuration
408
408
 
409
409
  SZ_DISABLE_SENDING: Final = "disable_sending"
410
+ SZ_AUTOSTART: Final = "autostart"
410
411
  SZ_DISABLE_QOS: Final = "disable_qos"
411
412
  SZ_ENFORCE_KNOWN_LIST: Final[str] = f"enforce_{SZ_KNOWN_LIST}"
412
413
  SZ_EVOFW_FLAG: Final = "evofw_flag"
@@ -418,6 +419,7 @@ SZ_USE_REGEX: Final = "use_regex"
418
419
 
419
420
  SCH_ENGINE_DICT = {
420
421
  vol.Optional(SZ_DISABLE_SENDING, default=False): bool,
422
+ vol.Optional(SZ_AUTOSTART, default=False): bool,
421
423
  vol.Optional(SZ_DISABLE_QOS, default=None): vol.Any(
422
424
  None, # None is selective QoS (e.g. QoS only for bindings, schedule, etc.)
423
425
  bool,
@@ -1278,8 +1278,9 @@ class PortTransport(_RegHackMixin, _FullTransport, _PortTransportAbstractor): #
1278
1278
 
1279
1279
  super()._close(exc)
1280
1280
 
1281
- if self._init_task:
1282
- self._init_task.cancel()
1281
+ # Use getattr because _init_task may not be set if initialization failed
1282
+ if init_task := getattr(self, "_init_task", None):
1283
+ init_task.cancel()
1283
1284
 
1284
1285
  if self._leaker_task:
1285
1286
  self._leaker_task.cancel()
@@ -1810,6 +1811,7 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
1810
1811
  protocol: RamsesProtocolT,
1811
1812
  io_writer: Callable[[str], Awaitable[None]],
1812
1813
  disable_sending: bool = False,
1814
+ autostart: bool = False,
1813
1815
  **kwargs: Any,
1814
1816
  ) -> None:
1815
1817
  """Initialize the callback transport.
@@ -1820,6 +1822,8 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
1820
1822
  :type io_writer: Callable[[str], Awaitable[None]]
1821
1823
  :param disable_sending: Whether to disable sending, defaults to False.
1822
1824
  :type disable_sending: bool, optional
1825
+ :param autostart: Whether to start reading immediately, defaults to False.
1826
+ :type autostart: bool, optional
1823
1827
  """
1824
1828
  # Pass kwargs up the chain. _ReadTransport will extract 'loop' if present.
1825
1829
  # _BaseTransport will pass 'loop' to _CallbackTransportAbstractor, which consumes it.
@@ -1834,9 +1838,11 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
1834
1838
  # Section 6.1: Object Lifecycle Logging
1835
1839
  _LOGGER.info(f"CallbackTransport created with io_writer={io_writer}")
1836
1840
 
1837
- # NOTE: connection_made is NOT called here. It must be triggered
1838
- # externally (e.g. by the Bridge) via the protocol methods once
1839
- # the external connection is ready.
1841
+ # Handshake: Notify protocol immediately (Safe: idempotent)
1842
+ self._protocol.connection_made(self, ramses=True)
1843
+
1844
+ if autostart:
1845
+ self.resume_reading()
1840
1846
 
1841
1847
  async def write_frame(self, frame: str, disable_tx_limits: bool = False) -> None:
1842
1848
  """Process a frame for transmission by passing it to the external writer.
@@ -1879,19 +1885,19 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
1879
1885
  :type dtm: str | None, optional
1880
1886
  """
1881
1887
  _LOGGER.debug(
1882
- f"Received frame from external source: frame='{frame}', timestamp={dtm}"
1888
+ f"Received frame from external source: frame={repr(frame)}, timestamp={dtm}"
1883
1889
  )
1884
1890
 
1885
- # Section 4.2: Circuit Breaker implementation (Packet gating)
1891
+ # Circuit Breaker implementation (Packet gating)
1886
1892
  if not self._reading:
1887
1893
  _LOGGER.debug(f"Dropping received frame (transport paused): {repr(frame)}")
1888
1894
  return
1889
1895
 
1890
1896
  dtm = dtm or dt_now().isoformat()
1891
1897
 
1892
- # Section 6.1: Boundary Logging (Incoming)
1898
+ # Boundary Logging (Incoming)
1893
1899
  _LOGGER.debug(
1894
- f"Ingesting frame into transport: frame='{frame}', timestamp={dtm}"
1900
+ f"Ingesting frame into transport: frame={repr(frame)}, timestamp={dtm}"
1895
1901
  )
1896
1902
 
1897
1903
  # Pass to the standard processing pipeline
@@ -1949,7 +1955,7 @@ async def transport_factory(
1949
1955
  extra: dict[str, Any] | None = None,
1950
1956
  loop: asyncio.AbstractEventLoop | None = None,
1951
1957
  log_all: bool = False,
1952
- **kwargs: Any, # HACK: odd/misc params
1958
+ **kwargs: Any, # HACK: odd/misc params, inc. autostart
1953
1959
  ) -> RamsesTransportT:
1954
1960
  """Create and return a Ramses-specific async packet Transport.
1955
1961
 
@@ -1980,11 +1986,18 @@ async def transport_factory(
1980
1986
  :raises exc.TransportSourceInvalid: If the packet source is invalid or multiple sources are specified.
1981
1987
  """
1982
1988
 
1989
+ # Extract autostart (default to False if missing), used in transport_constructor only
1990
+ autostart = kwargs.pop("autostart", False)
1991
+
1983
1992
  # If a constructor is provided, delegate entirely to it.
1984
1993
  if transport_constructor:
1985
1994
  _LOGGER.debug("transport_factory: Delegating to external transport_constructor")
1986
1995
  return await transport_constructor(
1987
- protocol, disable_sending=disable_sending, extra=extra, **kwargs
1996
+ protocol,
1997
+ disable_sending=disable_sending,
1998
+ extra=extra,
1999
+ autostart=autostart, # <--- Pass it explicitly
2000
+ **kwargs,
1988
2001
  )
1989
2002
 
1990
2003
  # kwargs are specific to a transport. The above transports have:
@@ -1,4 +1,4 @@
1
1
  """RAMSES RF - a RAMSES-II protocol decoder & analyser (transport layer)."""
2
2
 
3
- __version__ = "0.53.5"
3
+ __version__ = "0.53.6"
4
4
  VERSION = __version__
@@ -10,7 +10,7 @@
10
10
  # - pip list | grep -E 'pre-commit|ruff|mypy|types-|voluptuous|pytest|hatch'
11
11
 
12
12
  # used for development (linting)
13
- prek == 0.3.0 # same as ramses_cc and HA core 2026.1.2
13
+ prek == 0.3.1 # same as ramses_cc and HA core 2026.1.2
14
14
  # pre-commit >= 4.3.0 # replaced by prek since 2026.1
15
15
  ruff >= 0.13.0 # HA uses 0.13.0 ! also in: pre-commit-config.yaml
16
16
 
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env python3
2
2
  """RAMSES RF - Unittests for dispatcher."""
3
3
 
4
+ import logging
4
5
  from collections.abc import Generator
5
6
  from datetime import datetime as dt, timedelta as td
6
- from unittest.mock import AsyncMock, MagicMock
7
+ from unittest.mock import AsyncMock, MagicMock, patch
7
8
 
8
9
  import pytest
9
10
 
@@ -25,6 +26,7 @@ def mock_gateway() -> Generator[MagicMock, None, None]:
25
26
  gateway.config = MagicMock()
26
27
  gateway.config.disable_discovery = False
27
28
  gateway.config.enable_eavesdrop = False
29
+ gateway.config.reduce_processing = 0 # Ensure processing continues by default
28
30
  gateway._loop = MagicMock()
29
31
  gateway._loop.call_soon = MagicMock()
30
32
  gateway._loop.call_later = MagicMock()
@@ -99,3 +101,61 @@ class Test_dispatcher_gateway:
99
101
  assert msg1._has_array
100
102
  assert dispatcher.detect_array_fragment(msg2, msg1)
101
103
  assert not dispatcher.detect_array_fragment(msg3, msg1)
104
+
105
+
106
+ class TestDispatcherErrorHandling:
107
+ """Test Dispatcher exception handling logic."""
108
+
109
+ def test_process_msg_strict_mode(self, mock_gateway: MagicMock) -> None:
110
+ """Test process_msg raises exception in strict mode."""
111
+ # Enable strict mode
112
+ mock_gateway.config.enforce_strict_handling = True
113
+
114
+ # Create a message with a valid payload for code 0001
115
+ msg = Message._from_pkt(
116
+ Packet(
117
+ dt.now(),
118
+ "... I --- 01:000001 --:------ 01:000001 0001 005 00FFFF0200",
119
+ )
120
+ )
121
+
122
+ # Force a ValueError within process_msg by mocking _check_msg_addrs
123
+ with (
124
+ patch(
125
+ "ramses_rf.dispatcher._check_msg_addrs",
126
+ side_effect=ValueError("Test Error"),
127
+ ),
128
+ pytest.raises(ValueError, match="Test Error"),
129
+ ):
130
+ dispatcher.process_msg(mock_gateway, msg)
131
+
132
+ def test_process_msg_safe_mode(
133
+ self, mock_gateway: MagicMock, caplog: pytest.LogCaptureFixture
134
+ ) -> None:
135
+ """Test process_msg logs warning with trace in safe mode."""
136
+ # Disable strict mode (safe mode)
137
+ mock_gateway.config.enforce_strict_handling = False
138
+
139
+ msg = Message._from_pkt(
140
+ Packet(
141
+ dt.now(),
142
+ "... I --- 01:000001 --:------ 01:000001 0001 005 00FFFF0200",
143
+ )
144
+ )
145
+
146
+ # Force a ValueError within process_msg
147
+ with (
148
+ patch(
149
+ "ramses_rf.dispatcher._check_msg_addrs",
150
+ side_effect=ValueError("Test Error"),
151
+ ),
152
+ caplog.at_level(logging.WARNING),
153
+ ):
154
+ dispatcher.process_msg(mock_gateway, msg)
155
+
156
+ # Assert exception was caught and logged
157
+ assert "Test Error" in caplog.text
158
+ # Check that it was logged as a WARNING
159
+ assert any(r.levelname == "WARNING" for r in caplog.records)
160
+ # Check that traceback information is present (exc_info=True)
161
+ assert any(r.exc_info is not None for r in caplog.records)
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env python3
2
+ """Tests for CallbackTransport initialization logic."""
3
+
4
+ import asyncio
5
+ from typing import Any
6
+ from unittest.mock import AsyncMock, Mock, patch
7
+
8
+ from ramses_tx.transport import CallbackTransport, transport_factory
9
+
10
+
11
+ async def _async_callback_factory(*args: Any, **kwargs: Any) -> CallbackTransport:
12
+ """Async wrapper for CallbackTransport to satisfy transport_factory signature."""
13
+ return CallbackTransport(*args, **kwargs)
14
+
15
+
16
+ async def test_callback_transport_handshake() -> None:
17
+ """Test that connection_made is called automatically upon initialization."""
18
+ mock_protocol = Mock()
19
+ mock_writer = AsyncMock()
20
+
21
+ transport = CallbackTransport(mock_protocol, mock_writer)
22
+
23
+ # Assert handshake called immediately
24
+ mock_protocol.connection_made.assert_called_once_with(transport, ramses=True)
25
+
26
+
27
+ async def test_callback_transport_handshake_idempotency() -> None:
28
+ """Test that manual connection_made calls are safe (idempotent at protocol level)."""
29
+ mock_protocol = Mock()
30
+ mock_writer = AsyncMock()
31
+
32
+ transport = CallbackTransport(mock_protocol, mock_writer)
33
+
34
+ # Verify initial call
35
+ mock_protocol.connection_made.assert_called_once()
36
+
37
+ # Manually call again (simulating legacy consumer behavior)
38
+ mock_protocol.connection_made(transport, ramses=True)
39
+
40
+ # Assert called twice without error (protocol impl handles idempotency logic)
41
+ assert mock_protocol.connection_made.call_count == 2
42
+
43
+
44
+ async def test_callback_transport_autostart_false() -> None:
45
+ """Test that reading is paused by default (autostart=False)."""
46
+ mock_protocol = Mock()
47
+ mock_writer = AsyncMock()
48
+
49
+ transport = CallbackTransport(mock_protocol, mock_writer, autostart=False)
50
+
51
+ assert transport.is_reading() is False
52
+
53
+
54
+ async def test_callback_transport_autostart_default() -> None:
55
+ """Test that reading is paused by default (backward compatibility)."""
56
+ mock_protocol = Mock()
57
+ mock_writer = AsyncMock()
58
+
59
+ transport = CallbackTransport(mock_protocol, mock_writer)
60
+
61
+ assert transport.is_reading() is False
62
+
63
+
64
+ async def test_callback_transport_autostart_true() -> None:
65
+ """Test that reading is resumed automatically if autostart=True."""
66
+ mock_protocol = Mock()
67
+ mock_writer = AsyncMock()
68
+
69
+ transport = CallbackTransport(mock_protocol, mock_writer, autostart=True)
70
+
71
+ assert transport.is_reading() is True
72
+
73
+
74
+ async def test_factory_routes_autostart_to_custom_constructor() -> None:
75
+ """Check that autostart is passed to a custom transport_constructor."""
76
+ mock_protocol = Mock()
77
+ mock_writer = AsyncMock()
78
+
79
+ # 1. Test with autostart=True
80
+ # NOTE: transport_factory awaits the constructor, so we must pass an async callable
81
+ transport = await transport_factory(
82
+ mock_protocol,
83
+ transport_constructor=_async_callback_factory,
84
+ io_writer=mock_writer,
85
+ autostart=True,
86
+ )
87
+ assert isinstance(transport, CallbackTransport)
88
+ assert transport.is_reading() is True
89
+
90
+ # 2. Test with autostart=False (default)
91
+ transport_paused = await transport_factory(
92
+ mock_protocol,
93
+ transport_constructor=_async_callback_factory,
94
+ io_writer=mock_writer,
95
+ autostart=False,
96
+ )
97
+ assert isinstance(transport_paused, CallbackTransport)
98
+ assert transport_paused.is_reading() is False
99
+
100
+
101
+ async def test_factory_strips_autostart_for_standard_transport() -> None:
102
+ """Check that autostart is REMOVED before calling standard transports.
103
+
104
+ If it isn't removed, the standard transports (PortTransport/MqttTransport)
105
+ would raise TypeError because they don't accept 'autostart' in __init__.
106
+ """
107
+ mock_protocol = Mock()
108
+ mock_protocol.wait_for_connection_made = AsyncMock()
109
+
110
+ # We must patch serial_for_url because transport_factory calls it via
111
+ # get_serial_instance BEFORE creating PortTransport.
112
+ with (
113
+ patch("ramses_tx.transport.PortTransport") as MockPortTransport,
114
+ patch("ramses_tx.transport.serial_for_url") as mock_serial_for_url,
115
+ ):
116
+ # Setup the mock serial object to pass validity checks
117
+ mock_serial = Mock()
118
+ mock_serial.portstr = "/dev/ttyUSB0"
119
+ mock_serial_for_url.return_value = mock_serial
120
+
121
+ # valid-looking config so factory enters the Serial branch
122
+ port_config: Any = {}
123
+
124
+ await transport_factory(
125
+ mock_protocol,
126
+ port_name="/dev/ttyUSB0",
127
+ port_config=port_config,
128
+ autostart=True, # This argument must be filtered out!
129
+ )
130
+
131
+ # Assert PortTransport was called
132
+ assert MockPortTransport.call_count == 1
133
+
134
+ # Verify 'autostart' was NOT in the call args
135
+ call_args = MockPortTransport.call_args
136
+ assert "autostart" not in call_args.kwargs
137
+ assert "autostart" not in call_args.args # just in case
138
+
139
+
140
+ async def test_factory_strips_autostart_for_mqtt_transport() -> None:
141
+ """Check that autostart is REMOVED before calling MqttTransport."""
142
+ mock_protocol = Mock()
143
+ mock_protocol.wait_for_connection_made = AsyncMock()
144
+
145
+ with patch("ramses_tx.transport.MqttTransport") as MockMqttTransport:
146
+ # valid-looking config so factory enters the MQTT branch
147
+ # We must provide port_config because transport_factory validates it
148
+ # is not None even for MQTT
149
+ port_config: Any = {}
150
+
151
+ await transport_factory(
152
+ mock_protocol,
153
+ port_name="mqtt://broker:1883",
154
+ port_config=port_config,
155
+ autostart=True, # This must be filtered out
156
+ )
157
+
158
+ assert MockMqttTransport.call_count == 1
159
+ call_args = MockMqttTransport.call_args
160
+ assert "autostart" not in call_args.kwargs
161
+
162
+
163
+ async def test_port_transport_close_robustness() -> None:
164
+ """Check that PortTransport.close() does not raise AttributeError if init failed.
165
+
166
+ This ensures that _close() checks for the existence of _init_task before
167
+ attempting to cancel it.
168
+ """
169
+ from ramses_tx.transport import PortTransport
170
+
171
+ mock_protocol = Mock()
172
+ mock_serial = Mock()
173
+
174
+ # Define a side_effect for SerialTransport.__init__ that sets required attributes
175
+ # PortTransport expects _loop to be set by the parent class
176
+ def mock_init(self: Any, loop: Any, protocol: Any, serial_instance: Any) -> None:
177
+ self._loop = loop or asyncio.get_event_loop()
178
+ self._protocol = protocol
179
+ self._serial = serial_instance # Set backing attribute directly
180
+
181
+ # Patch SerialTransport.__init__ using 'new' to replace it with the function directly.
182
+ # This ensures 'self' is passed correctly, which doesn't happen with a standard Mock side_effect.
183
+ with patch(
184
+ "ramses_tx.transport.serial_asyncio.SerialTransport.__init__",
185
+ new=mock_init,
186
+ ):
187
+ transport = PortTransport(mock_serial, mock_protocol)
188
+
189
+ # Pre-condition: _init_task is created asynchronously, so it shouldn't exist yet
190
+ # because we haven't yielded to the event loop
191
+ assert not hasattr(transport, "_init_task")
192
+
193
+ # Execute close - should not raise AttributeError
194
+ transport.close()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes