conson-xp 1.14.0__tar.gz → 1.16.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 (265) hide show
  1. {conson_xp-1.14.0 → conson_xp-1.16.0}/PKG-INFO +2 -1
  2. {conson_xp-1.14.0 → conson_xp-1.16.0}/pyproject.toml +2 -1
  3. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/__init__.py +1 -1
  4. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +11 -2
  5. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/main.py +1 -1
  6. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/homekit/homekit_config.py +4 -0
  7. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/protocol/conbus_protocol.py +6 -1
  8. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_datapoint_service.py +1 -0
  9. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_discover_service.py +91 -38
  10. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_conbus_service.py +5 -9
  11. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_lightbulb_service.py +2 -0
  12. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_outlet.py +11 -12
  13. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_outlet_service.py +2 -0
  14. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/protocol/__init__.py +2 -1
  15. conson_xp-1.16.0/src/xp/services/protocol/conbus_event_protocol.py +342 -0
  16. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/utils/dependencies.py +11 -2
  17. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_homekit_config_integration.py +12 -0
  18. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_homekit_config_validator.py +36 -0
  19. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_homekit_services.py +16 -4
  20. {conson_xp-1.14.0 → conson_xp-1.16.0}/LICENSE +0 -0
  21. {conson_xp-1.14.0 → conson_xp-1.16.0}/README.md +0 -0
  22. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/__init__.py +0 -0
  23. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/__main__.py +0 -0
  24. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/__init__.py +0 -0
  25. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
  26. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
  27. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
  28. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
  29. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
  30. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
  31. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
  32. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
  33. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
  34. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
  35. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
  36. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
  37. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
  38. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
  39. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
  40. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
  41. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/file_commands.py +0 -0
  42. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
  43. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
  44. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
  45. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/module_commands.py +0 -0
  46. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
  47. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/server/__init__.py +0 -0
  48. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/server/server_commands.py +0 -0
  49. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
  50. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
  51. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
  52. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
  53. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
  54. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
  55. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
  56. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
  57. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/__init__.py +0 -0
  58. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/click_tree.py +0 -0
  59. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
  60. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/decorators.py +0 -0
  61. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/error_handlers.py +0 -0
  62. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/formatters.py +0 -0
  63. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/serial_number_type.py +0 -0
  64. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/system_function_choice.py +0 -0
  65. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/cli/utils/xp_module_type.py +0 -0
  66. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/connection/__init__.py +0 -0
  67. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/connection/exceptions.py +0 -0
  68. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/__init__.py +0 -0
  69. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/actiontable/__init__.py +0 -0
  70. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/actiontable/actiontable.py +0 -0
  71. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
  72. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
  73. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
  74. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/__init__.py +0 -0
  75. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus.py +0 -0
  76. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
  77. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_blink.py +0 -0
  78. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
  79. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
  80. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_custom.py +0 -0
  81. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
  82. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_discover.py +0 -0
  83. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
  84. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
  85. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_output.py +0 -0
  86. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_raw.py +0 -0
  87. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_receive.py +0 -0
  88. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
  89. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/homekit/__init__.py +0 -0
  90. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
  91. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
  92. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/log_entry.py +0 -0
  93. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/protocol/__init__.py +0 -0
  94. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/response.py +0 -0
  95. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/__init__.py +0 -0
  96. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/action_type.py +0 -0
  97. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/datapoint_type.py +0 -0
  98. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/event_telegram.py +0 -0
  99. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/event_type.py +0 -0
  100. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/input_action_type.py +0 -0
  101. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/input_type.py +0 -0
  102. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/module_type.py +0 -0
  103. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/module_type_code.py +0 -0
  104. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/output_telegram.py +0 -0
  105. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/reply_telegram.py +0 -0
  106. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/system_function.py +0 -0
  107. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/system_telegram.py +0 -0
  108. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/telegram.py +0 -0
  109. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/telegram_type.py +0 -0
  110. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/telegram/timeparam_type.py +0 -0
  111. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/models/write_config_type.py +0 -0
  112. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/__init__.py +0 -0
  113. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/actiontable/__init__.py +0 -0
  114. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
  115. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
  116. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
  117. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
  118. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
  119. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/__init__.py +0 -0
  120. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
  121. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
  122. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
  123. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
  124. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
  125. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
  126. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
  127. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
  128. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
  129. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
  130. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
  131. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
  132. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
  133. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
  134. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/conbus/write_config_service.py +0 -0
  135. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/__init__.py +0 -0
  136. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
  137. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
  138. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
  139. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
  140. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
  141. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
  142. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
  143. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
  144. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/homekit/homekit_service.py +0 -0
  145. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/log_file_service.py +0 -0
  146. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/module_type_service.py +0 -0
  147. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
  148. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/protocol/protocol_factory.py +0 -0
  149. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
  150. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/reverse_proxy_service.py +0 -0
  151. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/__init__.py +0 -0
  152. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/base_server_service.py +0 -0
  153. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/cp20_server_service.py +0 -0
  154. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/device_service_factory.py +0 -0
  155. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/server_service.py +0 -0
  156. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/xp130_server_service.py +0 -0
  157. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/xp20_server_service.py +0 -0
  158. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/xp230_server_service.py +0 -0
  159. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/xp24_server_service.py +0 -0
  160. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/server/xp33_server_service.py +0 -0
  161. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/__init__.py +0 -0
  162. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
  163. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
  164. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
  165. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
  166. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
  167. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
  168. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_service.py +0 -0
  169. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
  170. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/utils/__init__.py +0 -0
  171. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/utils/checksum.py +0 -0
  172. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/utils/event_helper.py +0 -0
  173. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/utils/serialization.py +0 -0
  174. {conson_xp-1.14.0 → conson_xp-1.16.0}/src/xp/utils/time_utils.py +0 -0
  175. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/.coverage +0 -0
  176. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/__init__.py +0 -0
  177. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/conftest.py +0 -0
  178. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/.coverage +0 -0
  179. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/__init__.py +0 -0
  180. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/telegram_test_data.py +0 -0
  181. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_actiontable_integration.py +0 -0
  182. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_api/.coverage +0 -0
  183. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_api/__init__.py +0 -0
  184. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_blink_integration.py +0 -0
  185. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_checksum_integration.py +0 -0
  186. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_conbus_blink_integration.py +0 -0
  187. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
  188. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_conbus_raw_integration.py +0 -0
  189. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_conbus_receive_integration.py +0 -0
  190. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_discovery_integration.py +0 -0
  191. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_event_telegram_integration.py +0 -0
  192. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_link_number_integration.py +0 -0
  193. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_module_integration.py +0 -0
  194. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_output_integration.py +0 -0
  195. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
  196. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
  197. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_version_integration.py +0 -0
  198. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
  199. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
  200. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/__init__.py +0 -0
  201. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_api/__init__.py +0 -0
  202. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/__init__.py +0 -0
  203. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_click_tree.py +0 -0
  204. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
  205. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
  206. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
  207. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_decorators.py +0 -0
  208. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
  209. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_formatters.py +0 -0
  210. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
  211. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
  212. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_connection/__init__.py +0 -0
  213. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_connection/test_connection_init.py +0 -0
  214. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_connection/test_exceptions.py +0 -0
  215. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_encoding/__init__.py +0 -0
  216. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
  217. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/__init__.py +0 -0
  218. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_conbus.py +0 -0
  219. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
  220. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
  221. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
  222. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_event_telegram.py +0 -0
  223. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_log_entry.py +0 -0
  224. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_module_type.py +0 -0
  225. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
  226. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_system_telegram.py +0 -0
  227. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
  228. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_version_telegram.py +0 -0
  229. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_write_config_type.py +0 -0
  230. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
  231. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
  232. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
  233. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/__init__.py +0 -0
  234. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
  235. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
  236. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
  237. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_base_server_service.py +0 -0
  238. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_blink_service.py +0 -0
  239. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_checksum_service.py +0 -0
  240. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
  241. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
  242. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
  243. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
  244. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_discovery_service.py +0 -0
  245. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
  246. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
  247. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_log_file_service.py +0 -0
  248. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_module_type_service.py +0 -0
  249. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_protocol.py +0 -0
  250. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_server_service.py +0 -0
  251. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
  252. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
  253. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_telegram_service.py +0 -0
  254. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_version_service.py +0 -0
  255. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
  256. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
  257. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
  258. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
  259. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
  260. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
  261. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_utils/__init__.py +0 -0
  262. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_utils/test_checksum.py +0 -0
  263. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_utils/test_event_helper.py +0 -0
  264. {conson_xp-1.14.0 → conson_xp-1.16.0}/tests/unit/test_utils/test_serialization.py +0 -0
  265. {conson_xp-1.14.0 → conson_xp-1.16.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.14.0
3
+ Version: 1.16.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
@@ -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.14.0"
24
+ version = "1.16.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.14.0"
6
+ __version__ = "1.16.0"
7
7
  __manufacturer__ = "salchichon"
8
8
  __model__ = "xp.cli"
9
9
  __serial__ = "2025.09.23.000"
@@ -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()
@@ -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)
@@ -55,6 +55,8 @@ class HomekitAccessoryConfig(BaseModel):
55
55
  output_number: Output number for the accessory.
56
56
  description: Description of the accessory.
57
57
  service: Service type for the accessory.
58
+ on_action: on code for the accessory.
59
+ off_action: off code for the accessory.
58
60
  hap_accessory: Optional HAP accessory identifier.
59
61
  """
60
62
 
@@ -64,6 +66,8 @@ class HomekitAccessoryConfig(BaseModel):
64
66
  output_number: int
65
67
  description: str
66
68
  service: str
69
+ on_action: str
70
+ off_action: str
67
71
  hap_accessory: Optional[int] = None
68
72
 
69
73
 
@@ -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
 
@@ -61,11 +62,15 @@ class SendActionEvent(BaseEvent):
61
62
  serial_number: Serial number of the light bulb set.
62
63
  output_number: Output number of the light bulb set.
63
64
  value: Set light bulb On or Off (True/False).
65
+ on_action: On action E00L00I00.
66
+ off_action: On action E00L00I04.
64
67
  """
65
68
 
66
69
  serial_number: str = Field(description="Serial number of the light bulb set")
67
70
  output_number: int = Field(description="Output number of the light bulb set")
68
71
  value: bool = Field(description="Set light bulb On or Off (True/False)")
72
+ on_action: str = Field(description="on action")
73
+ off_action: str = Field(description="off action")
69
74
 
70
75
 
71
76
  class DatapointEvent(BaseEvent):
@@ -245,7 +250,7 @@ class TelegramEvent(BaseEvent):
245
250
  checksum_valid: Checksum valid true or false.
246
251
  """
247
252
 
248
- protocol: Union[TelegramProtocol, ConbusProtocol] = Field(
253
+ protocol: Union[TelegramProtocol, ConbusProtocol, ConbusEventProtocol] = Field(
249
254
  description="TelegramProtocol instance"
250
255
  )
251
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()
@@ -12,7 +12,6 @@ from xp.models.protocol.conbus_protocol import (
12
12
  SendActionEvent,
13
13
  SendWriteConfigEvent,
14
14
  )
15
- from xp.models.telegram.action_type import ActionType
16
15
  from xp.models.telegram.datapoint_type import DataPointType
17
16
  from xp.models.telegram.system_function import SystemFunction
18
17
  from xp.services.protocol.telegram_protocol import TelegramProtocol
@@ -87,11 +86,8 @@ class HomeKitConbusService:
87
86
  """
88
87
  self.logger.debug(f"send_action_event {event}")
89
88
 
90
- action_value = (
91
- ActionType.ON_RELEASE.value if event.value else ActionType.OFF_PRESS.value
92
- )
93
- input_action = f"{event.output_number:02d}{action_value}"
94
- telegram = (
95
- f"S{event.serial_number}F{SystemFunction.ACTION.value}D{input_action}"
96
- )
97
- self.telegram_protocol.sendFrame(telegram.encode())
89
+ telegram = event.on_action if event.value else event.off_action
90
+ telegram_make = f"{telegram}M"
91
+ telegram_break = f"{telegram}B"
92
+ self.telegram_protocol.sendFrame(telegram_make.encode())
93
+ self.telegram_protocol.sendFrame(telegram_break.encode())
@@ -77,6 +77,8 @@ class HomeKitLightbulbService:
77
77
  serial_number=event.serial_number,
78
78
  output_number=event.output_number,
79
79
  value=event.value,
80
+ on_action=event.accessory.on_action,
81
+ off_action=event.accessory.off_action,
80
82
  )
81
83
 
82
84
  self.logger.debug(f"Dispatching SendActionEvent for {event.serial_number}")
@@ -134,19 +134,18 @@ class Outlet(Accessory):
134
134
  value: True to turn on, False to turn off.
135
135
  """
136
136
  # Emit set event
137
- self.logger.debug(f"set_on {value}")
138
-
139
- if value != self.is_on:
140
- self.is_on = value
141
- self.event_bus.dispatch(
142
- OutletSetOnEvent(
143
- serial_number=self.accessory.serial_number,
144
- output_number=self.accessory.output_number,
145
- module=self.module,
146
- accessory=self.accessory,
147
- value=value,
148
- )
137
+ self.logger.debug(f"set_on {value} {self.is_on}")
138
+
139
+ self.is_on = value
140
+ self.event_bus.dispatch(
141
+ OutletSetOnEvent(
142
+ serial_number=self.accessory.serial_number,
143
+ output_number=self.accessory.output_number,
144
+ module=self.module,
145
+ accessory=self.accessory,
146
+ value=value,
149
147
  )
148
+ )
150
149
 
151
150
  def get_on(self) -> bool:
152
151
  """Get the on/off state of the outlet.
@@ -85,6 +85,8 @@ class HomeKitOutletService:
85
85
  serial_number=event.serial_number,
86
86
  output_number=event.output_number,
87
87
  value=event.value,
88
+ on_action=event.accessory.on_action,
89
+ off_action=event.accessory.off_action,
88
90
  )
89
91
 
90
92
  self.logger.debug(f"Dispatching SendActionEvent for {event.serial_number}")
@@ -7,10 +7,11 @@ from xp.models.protocol.conbus_protocol import (
7
7
  ModuleDiscoveredEvent,
8
8
  TelegramReceivedEvent,
9
9
  )
10
+ from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
10
11
  from xp.services.protocol.conbus_protocol import ConbusProtocol
11
12
  from xp.services.protocol.telegram_protocol import TelegramProtocol
12
13
 
13
- __all__ = ["TelegramProtocol", "ConbusProtocol"]
14
+ __all__ = ["TelegramProtocol", "ConbusProtocol", "ConbusEventProtocol"]
14
15
 
15
16
  # Rebuild models after TelegramProtocol and ConbusProtocol are imported to resolve forward references
16
17
  ConnectionMadeEvent.model_rebuild()