conson-xp 1.15.0__tar.gz → 1.17.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 (269) hide show
  1. {conson_xp-1.15.0 → conson_xp-1.17.0}/PKG-INFO +6 -1
  2. {conson_xp-1.15.0 → conson_xp-1.17.0}/README.md +4 -0
  3. {conson_xp-1.15.0 → conson_xp-1.17.0}/pyproject.toml +2 -1
  4. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/__init__.py +1 -1
  5. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/__init__.py +3 -0
  6. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +11 -2
  7. conson_xp-1.17.0/src/xp/cli/commands/conbus/conbus_event_commands.py +115 -0
  8. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/main.py +1 -1
  9. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/__init__.py +2 -0
  10. conson_xp-1.17.0/src/xp/models/conbus/conbus_event_raw.py +47 -0
  11. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/protocol/conbus_protocol.py +2 -1
  12. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_datapoint_service.py +1 -0
  13. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_discover_service.py +91 -38
  14. conson_xp-1.17.0/src/xp/services/conbus/conbus_event_raw_service.py +185 -0
  15. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_outlet.py +11 -12
  16. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/protocol/__init__.py +2 -1
  17. conson_xp-1.17.0/src/xp/services/protocol/conbus_event_protocol.py +342 -0
  18. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/utils/dependencies.py +20 -2
  19. conson_xp-1.17.0/tests/unit/test_services/test_conbus_event_raw_service.py +169 -0
  20. {conson_xp-1.15.0 → conson_xp-1.17.0}/LICENSE +0 -0
  21. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/__init__.py +0 -0
  22. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/__main__.py +0 -0
  23. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
  24. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
  25. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
  26. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
  27. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
  28. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
  29. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
  30. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
  31. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
  32. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
  33. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
  34. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
  35. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
  36. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
  37. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
  38. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
  39. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/file_commands.py +0 -0
  40. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
  41. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
  42. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
  43. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/module_commands.py +0 -0
  44. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
  45. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/server/__init__.py +0 -0
  46. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/server/server_commands.py +0 -0
  47. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
  48. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
  49. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
  50. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
  51. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
  52. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
  53. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
  54. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
  55. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/__init__.py +0 -0
  56. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/click_tree.py +0 -0
  57. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
  58. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/decorators.py +0 -0
  59. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/error_handlers.py +0 -0
  60. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/formatters.py +0 -0
  61. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/serial_number_type.py +0 -0
  62. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/system_function_choice.py +0 -0
  63. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/cli/utils/xp_module_type.py +0 -0
  64. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/connection/__init__.py +0 -0
  65. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/connection/exceptions.py +0 -0
  66. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/actiontable/__init__.py +0 -0
  67. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/actiontable/actiontable.py +0 -0
  68. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
  69. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
  70. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
  71. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/__init__.py +0 -0
  72. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus.py +0 -0
  73. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
  74. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_blink.py +0 -0
  75. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
  76. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
  77. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_custom.py +0 -0
  78. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
  79. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_discover.py +0 -0
  80. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
  81. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
  82. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_output.py +0 -0
  83. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_raw.py +0 -0
  84. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_receive.py +0 -0
  85. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
  86. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/homekit/__init__.py +0 -0
  87. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
  88. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/homekit/homekit_config.py +0 -0
  89. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
  90. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/log_entry.py +0 -0
  91. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/protocol/__init__.py +0 -0
  92. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/response.py +0 -0
  93. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/__init__.py +0 -0
  94. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/action_type.py +0 -0
  95. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/datapoint_type.py +0 -0
  96. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/event_telegram.py +0 -0
  97. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/event_type.py +0 -0
  98. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/input_action_type.py +0 -0
  99. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/input_type.py +0 -0
  100. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/module_type.py +0 -0
  101. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/module_type_code.py +0 -0
  102. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/output_telegram.py +0 -0
  103. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/reply_telegram.py +0 -0
  104. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/system_function.py +0 -0
  105. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/system_telegram.py +0 -0
  106. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/telegram.py +0 -0
  107. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/telegram_type.py +0 -0
  108. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/telegram/timeparam_type.py +0 -0
  109. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/models/write_config_type.py +0 -0
  110. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/__init__.py +0 -0
  111. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/actiontable/__init__.py +0 -0
  112. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
  113. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
  114. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
  115. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
  116. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
  117. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/__init__.py +0 -0
  118. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
  119. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
  120. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
  121. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
  122. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
  123. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
  124. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
  125. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
  126. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
  127. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
  128. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
  129. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
  130. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
  131. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
  132. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/conbus/write_config_service.py +0 -0
  133. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/__init__.py +0 -0
  134. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
  135. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
  136. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
  137. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
  138. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
  139. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
  140. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
  141. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
  142. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
  143. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
  144. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
  145. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/homekit/homekit_service.py +0 -0
  146. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/log_file_service.py +0 -0
  147. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/module_type_service.py +0 -0
  148. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
  149. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/protocol/protocol_factory.py +0 -0
  150. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
  151. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/reverse_proxy_service.py +0 -0
  152. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/__init__.py +0 -0
  153. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/base_server_service.py +0 -0
  154. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/cp20_server_service.py +0 -0
  155. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/device_service_factory.py +0 -0
  156. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/server_service.py +0 -0
  157. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/xp130_server_service.py +0 -0
  158. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/xp20_server_service.py +0 -0
  159. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/xp230_server_service.py +0 -0
  160. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/xp24_server_service.py +0 -0
  161. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/server/xp33_server_service.py +0 -0
  162. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/__init__.py +0 -0
  163. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
  164. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
  165. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
  166. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
  167. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
  168. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
  169. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_service.py +0 -0
  170. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
  171. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/utils/__init__.py +0 -0
  172. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/utils/checksum.py +0 -0
  173. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/utils/event_helper.py +0 -0
  174. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/utils/serialization.py +0 -0
  175. {conson_xp-1.15.0 → conson_xp-1.17.0}/src/xp/utils/time_utils.py +0 -0
  176. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/.coverage +0 -0
  177. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/__init__.py +0 -0
  178. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/conftest.py +0 -0
  179. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/.coverage +0 -0
  180. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/__init__.py +0 -0
  181. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/telegram_test_data.py +0 -0
  182. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_actiontable_integration.py +0 -0
  183. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_api/.coverage +0 -0
  184. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_api/__init__.py +0 -0
  185. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_blink_integration.py +0 -0
  186. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_checksum_integration.py +0 -0
  187. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_conbus_blink_integration.py +0 -0
  188. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
  189. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_conbus_raw_integration.py +0 -0
  190. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_conbus_receive_integration.py +0 -0
  191. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_discovery_integration.py +0 -0
  192. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_event_telegram_integration.py +0 -0
  193. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_homekit_config_integration.py +0 -0
  194. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_link_number_integration.py +0 -0
  195. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_module_integration.py +0 -0
  196. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_output_integration.py +0 -0
  197. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
  198. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
  199. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_version_integration.py +0 -0
  200. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
  201. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
  202. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/__init__.py +0 -0
  203. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_api/__init__.py +0 -0
  204. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/__init__.py +0 -0
  205. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_click_tree.py +0 -0
  206. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
  207. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
  208. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
  209. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_decorators.py +0 -0
  210. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
  211. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_formatters.py +0 -0
  212. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
  213. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
  214. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_connection/__init__.py +0 -0
  215. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_connection/test_connection_init.py +0 -0
  216. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_connection/test_exceptions.py +0 -0
  217. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_encoding/__init__.py +0 -0
  218. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
  219. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/__init__.py +0 -0
  220. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_conbus.py +0 -0
  221. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
  222. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
  223. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
  224. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_event_telegram.py +0 -0
  225. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_log_entry.py +0 -0
  226. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_module_type.py +0 -0
  227. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
  228. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_system_telegram.py +0 -0
  229. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
  230. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_version_telegram.py +0 -0
  231. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_write_config_type.py +0 -0
  232. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
  233. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
  234. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
  235. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/__init__.py +0 -0
  236. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
  237. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
  238. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
  239. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_base_server_service.py +0 -0
  240. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_blink_service.py +0 -0
  241. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_checksum_service.py +0 -0
  242. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
  243. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
  244. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
  245. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
  246. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_discovery_service.py +0 -0
  247. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
  248. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
  249. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
  250. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_homekit_services.py +0 -0
  251. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_log_file_service.py +0 -0
  252. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_module_type_service.py +0 -0
  253. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_protocol.py +0 -0
  254. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_server_service.py +0 -0
  255. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
  256. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
  257. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_telegram_service.py +0 -0
  258. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_version_service.py +0 -0
  259. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
  260. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
  261. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
  262. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
  263. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
  264. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
  265. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_utils/__init__.py +0 -0
  266. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_utils/test_checksum.py +0 -0
  267. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_utils/test_event_helper.py +0 -0
  268. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_utils/test_serialization.py +0 -0
  269. {conson_xp-1.15.0 → conson_xp-1.17.0}/tests/unit/test_utils/test_time_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: conson-xp
3
- Version: 1.15.0
3
+ Version: 1.17.0
4
4
  Summary: XP Protocol Communication Tools
5
5
  Author-Email: ldvchosal <ldvchosal@github.com>
6
6
  License: MIT License
@@ -47,6 +47,7 @@ Requires-Dist: HAP-python[QRCode]>=5.0.0
47
47
  Requires-Dist: punq>=0.7.0
48
48
  Requires-Dist: twisted>=25.5.0
49
49
  Requires-Dist: bubus>=1.5.6
50
+ Requires-Dist: psygnal>=0.15.0
50
51
  Description-Content-Type: text/markdown
51
52
 
52
53
  # 🔌 XP Protocol Communication Tool
@@ -304,6 +305,10 @@ xp conbus datapoint query
304
305
 
305
306
  xp conbus discover
306
307
 
308
+ xp conbus event
309
+ xp conbus event raw
310
+
311
+
307
312
  xp conbus lightlevel
308
313
  xp conbus lightlevel get
309
314
  xp conbus lightlevel off
@@ -253,6 +253,10 @@ xp conbus datapoint query
253
253
 
254
254
  xp conbus discover
255
255
 
256
+ xp conbus event
257
+ xp conbus event raw
258
+
259
+
256
260
  xp conbus lightlevel
257
261
  xp conbus lightlevel get
258
262
  xp conbus lightlevel off
@@ -17,10 +17,11 @@ dependencies = [
17
17
  "punq>=0.7.0",
18
18
  "twisted>=25.5.0",
19
19
  "bubus>=1.5.6",
20
+ "psygnal>=0.15.0",
20
21
  ]
21
22
  requires-python = ">=3.11"
22
23
  readme = "README.md"
23
- version = "1.15.0"
24
+ version = "1.17.0"
24
25
 
25
26
  [project.license]
26
27
  file = "LICENSE"
@@ -3,7 +3,7 @@
3
3
  conson-xp package.
4
4
  """
5
5
 
6
- __version__ = "1.15.0"
6
+ __version__ = "1.17.0"
7
7
  __manufacturer__ = "salchichon"
8
8
  __model__ = "xp.cli"
9
9
  __serial__ = "2025.09.23.000"
@@ -37,6 +37,7 @@ from xp.cli.commands.conbus.conbus_datapoint_commands import (
37
37
  query_datapoint,
38
38
  )
39
39
  from xp.cli.commands.conbus.conbus_discover_commands import send_discover_telegram
40
+ from xp.cli.commands.conbus.conbus_event_commands import conbus_event, send_event_raw
40
41
  from xp.cli.commands.conbus.conbus_lightlevel_commands import (
41
42
  xp_lightlevel_get,
42
43
  xp_lightlevel_off,
@@ -97,6 +98,7 @@ __all__ = [
97
98
  "conbus_lightlevel",
98
99
  "conbus_msactiontable",
99
100
  "conbus_actiontable",
101
+ "conbus_event",
100
102
  "file",
101
103
  "module",
102
104
  "reverse_proxy",
@@ -118,6 +120,7 @@ __all__ = [
118
120
  "show_config",
119
121
  "send_custom_telegram",
120
122
  "send_discover_telegram",
123
+ "send_event_raw",
121
124
  "xp_output_on",
122
125
  "xp_output_off",
123
126
  "xp_output_status",
@@ -9,6 +9,7 @@ from xp.cli.utils.decorators import (
9
9
  connection_command,
10
10
  )
11
11
  from xp.models import ConbusDiscoverResponse
12
+ from xp.models.conbus.conbus_discover import DiscoveredDevice
12
13
  from xp.services.conbus.conbus_discover_service import (
13
14
  ConbusDiscoverService,
14
15
  )
@@ -36,6 +37,14 @@ def send_discover_telegram(ctx: click.Context) -> None:
36
37
  """
37
38
  click.echo(json.dumps(discovered_devices.to_dict(), indent=2))
38
39
 
40
+ def on_device_discovered(discovered_device: DiscoveredDevice) -> None:
41
+ """Handle discovery of sa single module.
42
+
43
+ Args:
44
+ discovered_device: Discover device.
45
+ """
46
+ click.echo(json.dumps(discovered_device, indent=2))
47
+
39
48
  def progress(_serial_number: str) -> None:
40
49
  """Handle progress updates during device discovery.
41
50
 
@@ -48,5 +57,5 @@ def send_discover_telegram(ctx: click.Context) -> None:
48
57
  service: ConbusDiscoverService = (
49
58
  ctx.obj.get("container").get_container().resolve(ConbusDiscoverService)
50
59
  )
51
- with service:
52
- service.start(progress, on_finish, 0.5)
60
+ service.run(progress, on_device_discovered, on_finish, 5)
61
+ service.start_reactor()
@@ -0,0 +1,115 @@
1
+ """Conbus event operations CLI commands."""
2
+
3
+ import json
4
+
5
+ import click
6
+
7
+ from xp.cli.commands.conbus.conbus import conbus
8
+ from xp.cli.utils.decorators import connection_command
9
+ from xp.models import ConbusEventRawResponse
10
+ from xp.models.telegram.module_type_code import ModuleTypeCode
11
+ from xp.services.conbus.conbus_event_raw_service import ConbusEventRawService
12
+
13
+
14
+ @click.group(name="event")
15
+ def conbus_event() -> None:
16
+ """Send event telegrams to Conbus modules."""
17
+ pass
18
+
19
+
20
+ @conbus_event.command("raw")
21
+ @click.argument("module_type", type=str)
22
+ @click.argument("link_number", type=int)
23
+ @click.argument("input_number", type=int)
24
+ @click.argument("time_ms", type=int, default=1000)
25
+ @click.pass_context
26
+ @connection_command()
27
+ def send_event_raw(
28
+ ctx: click.Context,
29
+ module_type: str,
30
+ link_number: int,
31
+ input_number: int,
32
+ time_ms: int,
33
+ ) -> None:
34
+ r"""Send raw event telegrams to simulate button presses.
35
+
36
+ Args:
37
+ ctx: Click context object.
38
+ module_type: Module type code (e.g., CP20, XP33).
39
+ link_number: Link number (0-99).
40
+ input_number: Input number (0-9).
41
+ time_ms: Delay between MAKE/BREAK events in milliseconds (default: 1000).
42
+
43
+ Examples:
44
+ \b
45
+ xp conbus event raw CP20 00 00
46
+ xp conbus event raw XP33 00 00 500
47
+ """
48
+ # Validate parameters
49
+ if link_number < 0 or link_number > 99:
50
+ click.echo(
51
+ json.dumps({"error": "Link number must be between 0 and 99"}, indent=2)
52
+ )
53
+ return
54
+
55
+ if input_number < 0 or input_number > 9:
56
+ click.echo(
57
+ json.dumps({"error": "Input number must be between 0 and 9"}, indent=2)
58
+ )
59
+ return
60
+
61
+ if time_ms <= 0:
62
+ click.echo(json.dumps({"error": "Time must be greater than 0"}, indent=2))
63
+ return
64
+
65
+ # Resolve module type to numeric code
66
+ module_type_code: int = 0
67
+ try:
68
+ # Try to get the enum value by name
69
+ module_type_enum = ModuleTypeCode[module_type.upper()]
70
+ module_type_code = module_type_enum.value
71
+ except KeyError:
72
+ # Module type not found
73
+ click.echo(
74
+ json.dumps(
75
+ {
76
+ "error": f"Unknown module type: {module_type}. Use module types like CP20, XP33, XP24, etc."
77
+ },
78
+ indent=2,
79
+ )
80
+ )
81
+ return
82
+
83
+ def on_finish(response: ConbusEventRawResponse) -> None:
84
+ """Handle successful completion of event raw operation.
85
+
86
+ Args:
87
+ response: Event raw response with sent and received telegrams.
88
+ """
89
+ click.echo(json.dumps(response.to_dict(), indent=2))
90
+
91
+ def on_progress(telegram: str) -> None:
92
+ """Handle progress updates during event operation.
93
+
94
+ Args:
95
+ telegram: Received telegram.
96
+ """
97
+ click.echo(json.dumps({"telegram": telegram}))
98
+
99
+ service: ConbusEventRawService = (
100
+ ctx.obj.get("container").get_container().resolve(ConbusEventRawService)
101
+ )
102
+ service.run(
103
+ module_type_code=module_type_code,
104
+ link_number=link_number,
105
+ input_number=input_number,
106
+ time_ms=time_ms,
107
+ progress_callback=on_progress,
108
+ finish_callback=on_finish,
109
+ timeout_seconds=5,
110
+ )
111
+ service.start_reactor()
112
+
113
+
114
+ # Register the event command group with conbus
115
+ conbus.add_command(conbus_event)
@@ -56,7 +56,7 @@ def cli(ctx: click.Context) -> None:
56
56
 
57
57
  # xp
58
58
  logging.getLogger("xp").setLevel(logging.DEBUG)
59
- logging.getLogger("xp.services.homekit").setLevel(logging.WARNING)
59
+ logging.getLogger("xp.services.homekit").setLevel(logging.DEBUG)
60
60
 
61
61
  # pyhap
62
62
  logging.getLogger("pyhap").setLevel(logging.WARNING)
@@ -5,6 +5,7 @@ from xp.models.conbus.conbus_client_config import ConbusClientConfig
5
5
  from xp.models.conbus.conbus_connection_status import ConbusConnectionStatus
6
6
  from xp.models.conbus.conbus_datapoint import ConbusDatapointResponse
7
7
  from xp.models.conbus.conbus_discover import ConbusDiscoverResponse
8
+ from xp.models.conbus.conbus_event_raw import ConbusEventRawResponse
8
9
  from xp.models.log_entry import LogEntry
9
10
  from xp.models.telegram.event_telegram import EventTelegram
10
11
  from xp.models.telegram.event_type import EventType
@@ -30,5 +31,6 @@ __all__ = [
30
31
  "ConbusResponse",
31
32
  "ConbusDatapointResponse",
32
33
  "ConbusDiscoverResponse",
34
+ "ConbusEventRawResponse",
33
35
  "ConbusConnectionStatus",
34
36
  ]
@@ -0,0 +1,47 @@
1
+ """Conbus event raw response model."""
2
+
3
+ from dataclasses import dataclass
4
+ from datetime import datetime
5
+ from typing import Any, Dict, Optional
6
+
7
+
8
+ @dataclass
9
+ class ConbusEventRawResponse:
10
+ """Represents a response from Conbus event raw operation.
11
+
12
+ Attributes:
13
+ success: Whether the operation was successful.
14
+ sent_telegrams: List of event telegrams sent (MAKE and BREAK).
15
+ received_telegrams: List of all telegrams received.
16
+ error: Error message if operation failed.
17
+ timestamp: Timestamp of the response.
18
+ """
19
+
20
+ success: bool
21
+ sent_telegrams: Optional[list[str]] = None
22
+ received_telegrams: Optional[list[str]] = None
23
+ error: Optional[str] = None
24
+ timestamp: Optional[datetime] = None
25
+
26
+ def __post_init__(self) -> None:
27
+ """Initialize timestamp and telegram lists if not provided."""
28
+ if self.timestamp is None:
29
+ self.timestamp = datetime.now()
30
+ if self.sent_telegrams is None:
31
+ self.sent_telegrams = []
32
+ if self.received_telegrams is None:
33
+ self.received_telegrams = []
34
+
35
+ def to_dict(self) -> Dict[str, Any]:
36
+ """Convert to dictionary for JSON serialization.
37
+
38
+ Returns:
39
+ Dictionary representation of the response.
40
+ """
41
+ return {
42
+ "success": self.success,
43
+ "sent_telegrams": self.sent_telegrams,
44
+ "received_telegrams": self.received_telegrams,
45
+ "error": self.error,
46
+ "timestamp": self.timestamp.isoformat() if self.timestamp else None,
47
+ }
@@ -12,6 +12,7 @@ from xp.models.homekit.homekit_conson_config import ConsonModuleConfig
12
12
  from xp.models.telegram.datapoint_type import DataPointType
13
13
 
14
14
  if TYPE_CHECKING:
15
+ from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
15
16
  from xp.services.protocol.conbus_protocol import ConbusProtocol
16
17
  from xp.services.protocol.telegram_protocol import TelegramProtocol
17
18
 
@@ -249,7 +250,7 @@ class TelegramEvent(BaseEvent):
249
250
  checksum_valid: Checksum valid true or false.
250
251
  """
251
252
 
252
- protocol: Union[TelegramProtocol, ConbusProtocol] = Field(
253
+ protocol: Union[TelegramProtocol, ConbusProtocol, ConbusEventProtocol] = Field(
253
254
  description="TelegramProtocol instance"
254
255
  )
255
256
  frame: str = Field(description="Frame <S0123450001F02D12FK>")
@@ -130,6 +130,7 @@ class ConbusDatapointService(ConbusProtocol):
130
130
  self.service_response.data_value = datapoint_telegram.data_value
131
131
  if self.datapoint_finished_callback:
132
132
  self.datapoint_finished_callback(self.service_response)
133
+ self._stop_reactor()
133
134
 
134
135
  def failed(self, message: str) -> None:
135
136
  """Handle failed connection event.
@@ -7,49 +7,57 @@ discover telegrams to find modules on the network.
7
7
  import logging
8
8
  from typing import Callable, Optional
9
9
 
10
- from twisted.internet.posixbase import PosixReactorBase
11
-
12
- from xp.models import ConbusClientConfig, ConbusDiscoverResponse
10
+ from xp.models import ConbusDiscoverResponse
13
11
  from xp.models.conbus.conbus_discover import DiscoveredDevice
14
12
  from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
15
13
  from xp.models.telegram.datapoint_type import DataPointType
16
14
  from xp.models.telegram.module_type_code import MODULE_TYPE_REGISTRY
17
15
  from xp.models.telegram.system_function import SystemFunction
18
16
  from xp.models.telegram.telegram_type import TelegramType
19
- from xp.services.protocol.conbus_protocol import ConbusProtocol
17
+ from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
20
18
 
21
19
 
22
- class ConbusDiscoverService(ConbusProtocol):
20
+ class ConbusDiscoverService:
23
21
  """
24
22
  Service for discovering modules on Conbus servers.
25
23
 
26
24
  Uses ConbusProtocol to provide discovery functionality for finding
27
25
  modules connected to the Conbus network.
26
+
27
+ Attributes:
28
+ conbus_protocol: Protocol instance for Conbus communication.
28
29
  """
29
30
 
30
- def __init__(
31
- self,
32
- cli_config: ConbusClientConfig,
33
- reactor: PosixReactorBase,
34
- ) -> None:
31
+ conbus_protocol: ConbusEventProtocol
32
+
33
+ def __init__(self, conbus_protocol: ConbusEventProtocol) -> None:
35
34
  """Initialize the Conbus discover service.
36
35
 
37
36
  Args:
38
- cli_config: Conbus client configuration.
39
- reactor: Twisted reactor instance.
37
+ conbus_protocol: ConbusProtocol.
40
38
  """
41
- super().__init__(cli_config, reactor)
42
39
  self.progress_callback: Optional[Callable[[str], None]] = None
40
+ self.device_discover_callback: Optional[Callable[[DiscoveredDevice], None]] = (
41
+ None
42
+ )
43
43
  self.finish_callback: Optional[Callable[[ConbusDiscoverResponse], None]] = None
44
44
 
45
+ self.conbus_protocol: ConbusEventProtocol = conbus_protocol
46
+ self.conbus_protocol.on_connection_made.connect(self.connection_made)
47
+ self.conbus_protocol.on_telegram_sent.connect(self.telegram_sent)
48
+ self.conbus_protocol.on_telegram_received.connect(self.telegram_received)
49
+ self.conbus_protocol.on_timeout.connect(self.timeout)
50
+ self.conbus_protocol.on_failed.connect(self.failed)
51
+
45
52
  self.discovered_device_result = ConbusDiscoverResponse(success=False)
46
53
  # Set up logging
47
54
  self.logger = logging.getLogger(__name__)
48
55
 
49
- def connection_established(self) -> None:
56
+ def connection_made(self) -> None:
50
57
  """Handle connection established event."""
51
- self.logger.debug("Connection established, sending discover telegram")
52
- self.send_telegram(
58
+ self.logger.debug("Connection established")
59
+ self.logger.debug("Sending discover telegram")
60
+ self.conbus_protocol.send_telegram(
53
61
  telegram_type=TelegramType.SYSTEM,
54
62
  serial_number="0000000000",
55
63
  system_function=SystemFunction.DISCOVERY,
@@ -83,7 +91,7 @@ class ConbusDiscoverService(ConbusProtocol):
83
91
  and telegram_received.payload[11:16] == "F01D"
84
92
  and len(telegram_received.payload) == 15
85
93
  ):
86
- self.discovered_device(telegram_received.serial_number)
94
+ self.handle_discovered_device(telegram_received.serial_number)
87
95
 
88
96
  # Check for module type response (F02D07)
89
97
  elif (
@@ -109,7 +117,7 @@ class ConbusDiscoverService(ConbusProtocol):
109
117
  else:
110
118
  self.logger.debug("Not a discover or module type response")
111
119
 
112
- def discovered_device(self, serial_number: str) -> None:
120
+ def handle_discovered_device(self, serial_number: str) -> None:
113
121
  """Handle discovered device event.
114
122
 
115
123
  Args:
@@ -128,22 +136,17 @@ class ConbusDiscoverService(ConbusProtocol):
128
136
  }
129
137
  self.discovered_device_result.discovered_devices.append(device)
130
138
 
139
+ if self.device_discover_callback:
140
+ self.device_discover_callback(device)
141
+
131
142
  # Send READ_DATAPOINT telegram to query module type
132
143
  self.logger.debug(f"Sending module type query for {serial_number}")
133
- self.send_telegram(
144
+ self.conbus_protocol.send_telegram(
134
145
  telegram_type=TelegramType.SYSTEM,
135
146
  serial_number=serial_number,
136
147
  system_function=SystemFunction.READ_DATAPOINT,
137
148
  data_value=DataPointType.MODULE_TYPE.value,
138
149
  )
139
-
140
- self.send_telegram(
141
- telegram_type=TelegramType.SYSTEM,
142
- serial_number=serial_number,
143
- system_function=SystemFunction.READ_DATAPOINT,
144
- data_value=DataPointType.MODULE_TYPE_CODE.value,
145
- )
146
-
147
150
  if self.progress_callback:
148
151
  self.progress_callback(serial_number)
149
152
 
@@ -190,11 +193,27 @@ class ConbusDiscoverService(ConbusProtocol):
190
193
  if device["serial_number"] == serial_number:
191
194
  device["module_type_code"] = code
192
195
  device["module_type_name"] = module_type_name
196
+
197
+ if self.device_discover_callback:
198
+ self.device_discover_callback(device)
199
+
193
200
  self.logger.debug(
194
201
  f"Updated device {serial_number} with module_type {module_type_name}"
195
202
  )
196
203
  break
197
204
 
205
+ if self.discovered_device_result.discovered_devices:
206
+ for device in self.discovered_device_result.discovered_devices:
207
+ if not (
208
+ device["serial_number"]
209
+ and device["module_type"]
210
+ and device["module_type_code"]
211
+ and device["module_type_name"]
212
+ ):
213
+ return
214
+
215
+ self.succeed()
216
+
198
217
  def handle_module_type_response(self, serial_number: str, module_type: str) -> None:
199
218
  """Handle module type response and update discovered device.
200
219
 
@@ -212,19 +231,28 @@ class ConbusDiscoverService(ConbusProtocol):
212
231
  self.logger.debug(
213
232
  f"Updated device {serial_number} with module_type {module_type}"
214
233
  )
234
+ if self.device_discover_callback:
235
+ self.device_discover_callback(device)
236
+
215
237
  break
216
238
 
217
- def timeout(self) -> bool:
218
- """Handle timeout event to stop discovery.
239
+ self.conbus_protocol.send_telegram(
240
+ telegram_type=TelegramType.SYSTEM,
241
+ serial_number=serial_number,
242
+ system_function=SystemFunction.READ_DATAPOINT,
243
+ data_value=DataPointType.MODULE_TYPE_CODE.value,
244
+ )
219
245
 
220
- Returns:
221
- False to stop the reactor.
222
- """
223
- self.logger.info("Discovery stopped after: %ss", self.timeout_seconds)
224
- self.discovered_device_result.success = True
246
+ def timeout(self) -> None:
247
+ """Handle timeout event to stop discovery."""
248
+ timeout = self.conbus_protocol.timeout_seconds
249
+ self.logger.info("Discovery stopped after: %ss", timeout)
250
+ self.discovered_device_result.success = False
251
+ self.discovered_device_result.error = "Discovered device timeout"
225
252
  if self.finish_callback:
226
253
  self.finish_callback(self.discovered_device_result)
227
- return False
254
+
255
+ self.stop_reactor()
228
256
 
229
257
  def failed(self, message: str) -> None:
230
258
  """Handle failed connection event.
@@ -238,9 +266,32 @@ class ConbusDiscoverService(ConbusProtocol):
238
266
  if self.finish_callback:
239
267
  self.finish_callback(self.discovered_device_result)
240
268
 
241
- def start(
269
+ self.stop_reactor()
270
+
271
+ def succeed(self) -> None:
272
+ """Handle discovered device success event."""
273
+ self.logger.debug("Succeed")
274
+ self.discovered_device_result.success = True
275
+ self.discovered_device_result.error = None
276
+ if self.finish_callback:
277
+ self.finish_callback(self.discovered_device_result)
278
+
279
+ self.stop_reactor()
280
+
281
+ def stop_reactor(self) -> None:
282
+ """Stop reactor."""
283
+ self.logger.info("Stopping reactor")
284
+ self.conbus_protocol.stop_reactor()
285
+
286
+ def start_reactor(self) -> None:
287
+ """Start reactor."""
288
+ self.logger.info("Starting reactor")
289
+ self.conbus_protocol.start_reactor()
290
+
291
+ def run(
242
292
  self,
243
293
  progress_callback: Callable[[str], None],
294
+ device_discover_callback: Callable[[DiscoveredDevice], None],
244
295
  finish_callback: Callable[[ConbusDiscoverResponse], None],
245
296
  timeout_seconds: Optional[float] = None,
246
297
  ) -> None:
@@ -248,12 +299,14 @@ class ConbusDiscoverService(ConbusProtocol):
248
299
 
249
300
  Args:
250
301
  progress_callback: Callback for each discovered device.
302
+ device_discover_callback: Callback for each discovered device.
251
303
  finish_callback: Callback when discovery completes.
252
304
  timeout_seconds: Optional timeout in seconds.
253
305
  """
254
306
  self.logger.info("Starting discovery")
307
+
255
308
  if timeout_seconds:
256
- self.timeout_seconds = timeout_seconds
309
+ self.conbus_protocol.timeout_seconds = timeout_seconds
257
310
  self.progress_callback = progress_callback
311
+ self.device_discover_callback = device_discover_callback
258
312
  self.finish_callback = finish_callback
259
- self.start_reactor()