conson-xp 1.35.0__tar.gz → 1.36.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 (316) hide show
  1. {conson_xp-1.35.0 → conson_xp-1.36.0}/PKG-INFO +1 -1
  2. {conson_xp-1.35.0 → conson_xp-1.36.0}/pyproject.toml +1 -1
  3. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/__init__.py +1 -1
  4. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/term/state_monitor_service.py +35 -15
  5. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/widgets/modules_list.py +4 -2
  6. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_state_monitor_service.py +150 -1
  7. {conson_xp-1.35.0 → conson_xp-1.36.0}/LICENSE +0 -0
  8. {conson_xp-1.35.0 → conson_xp-1.36.0}/README.md +0 -0
  9. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/__init__.py +0 -0
  10. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/__main__.py +0 -0
  11. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/__init__.py +0 -0
  12. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
  13. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
  14. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
  15. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
  16. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
  17. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
  18. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
  19. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
  20. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
  21. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_event_commands.py +0 -0
  22. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_export_commands.py +0 -0
  23. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
  24. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
  25. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
  26. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
  27. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
  28. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
  29. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
  30. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
  31. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/file_commands.py +0 -0
  32. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
  33. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
  34. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
  35. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/module_commands.py +0 -0
  36. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
  37. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/server/__init__.py +0 -0
  38. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/server/server_commands.py +0 -0
  39. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
  40. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
  41. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
  42. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
  43. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
  44. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
  45. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
  46. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
  47. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/term/__init__.py +0 -0
  48. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/term/term.py +0 -0
  49. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/commands/term/term_commands.py +0 -0
  50. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/main.py +0 -0
  51. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/__init__.py +0 -0
  52. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/click_tree.py +0 -0
  53. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
  54. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/decorators.py +0 -0
  55. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/error_handlers.py +0 -0
  56. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/formatters.py +0 -0
  57. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/module_type_choice.py +0 -0
  58. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/serial_number_type.py +0 -0
  59. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/system_function_choice.py +0 -0
  60. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/cli/utils/xp_module_type.py +0 -0
  61. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/connection/__init__.py +0 -0
  62. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/connection/exceptions.py +0 -0
  63. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/__init__.py +0 -0
  64. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/actiontable/__init__.py +0 -0
  65. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/actiontable/actiontable.py +0 -0
  66. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
  67. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
  68. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
  69. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/__init__.py +0 -0
  70. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus.py +0 -0
  71. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
  72. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_blink.py +0 -0
  73. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
  74. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
  75. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_custom.py +0 -0
  76. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
  77. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_discover.py +0 -0
  78. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_event_list.py +0 -0
  79. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_event_raw.py +0 -0
  80. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_export.py +0 -0
  81. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
  82. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
  83. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_logger_config.py +0 -0
  84. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_output.py +0 -0
  85. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_raw.py +0 -0
  86. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_receive.py +0 -0
  87. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
  88. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/homekit/__init__.py +0 -0
  89. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
  90. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/homekit/homekit_config.py +0 -0
  91. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
  92. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/log_entry.py +0 -0
  93. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/protocol/__init__.py +0 -0
  94. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
  95. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/response.py +0 -0
  96. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/__init__.py +0 -0
  97. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/action_type.py +0 -0
  98. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/datapoint_type.py +0 -0
  99. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/event_telegram.py +0 -0
  100. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/event_type.py +0 -0
  101. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/input_action_type.py +0 -0
  102. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/input_type.py +0 -0
  103. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/module_type.py +0 -0
  104. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/module_type_code.py +0 -0
  105. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/output_telegram.py +0 -0
  106. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/reply_telegram.py +0 -0
  107. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/system_function.py +0 -0
  108. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/system_telegram.py +0 -0
  109. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/telegram.py +0 -0
  110. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/telegram_type.py +0 -0
  111. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/telegram/timeparam_type.py +0 -0
  112. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/term/__init__.py +0 -0
  113. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/term/connection_state.py +0 -0
  114. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/term/module_state.py +0 -0
  115. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/term/protocol_keys_config.py +0 -0
  116. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/term/status_message.py +0 -0
  117. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/term/telegram_display.py +0 -0
  118. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/models/write_config_type.py +0 -0
  119. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/__init__.py +0 -0
  120. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/actiontable/__init__.py +0 -0
  121. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
  122. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
  123. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
  124. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
  125. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
  126. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/__init__.py +0 -0
  127. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
  128. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
  129. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
  130. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
  131. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
  132. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
  133. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
  134. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
  135. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
  136. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
  137. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
  138. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_discover_service.py +0 -0
  139. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_event_list_service.py +0 -0
  140. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_event_raw_service.py +0 -0
  141. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_export_service.py +0 -0
  142. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
  143. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
  144. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
  145. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
  146. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/conbus/write_config_service.py +0 -0
  147. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/__init__.py +0 -0
  148. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
  149. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
  150. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
  151. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
  152. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
  153. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
  154. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
  155. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
  156. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
  157. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
  158. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
  159. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
  160. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/homekit/homekit_service.py +0 -0
  161. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/log_file_service.py +0 -0
  162. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/module_type_service.py +0 -0
  163. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/protocol/__init__.py +0 -0
  164. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/protocol/conbus_event_protocol.py +0 -0
  165. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
  166. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/protocol/protocol_factory.py +0 -0
  167. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
  168. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/reverse_proxy_service.py +0 -0
  169. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/__init__.py +0 -0
  170. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/base_server_service.py +0 -0
  171. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/client_buffer_manager.py +0 -0
  172. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/cp20_server_service.py +0 -0
  173. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/device_service_factory.py +0 -0
  174. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/server_service.py +0 -0
  175. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/xp130_server_service.py +0 -0
  176. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/xp20_server_service.py +0 -0
  177. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/xp230_server_service.py +0 -0
  178. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/xp24_server_service.py +0 -0
  179. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/server/xp33_server_service.py +0 -0
  180. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/__init__.py +0 -0
  181. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
  182. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
  183. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
  184. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
  185. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
  186. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
  187. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_service.py +0 -0
  188. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
  189. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/term/__init__.py +0 -0
  190. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/services/term/protocol_monitor_service.py +0 -0
  191. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/__init__.py +0 -0
  192. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/protocol.py +0 -0
  193. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/protocol.tcss +0 -0
  194. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/state.py +0 -0
  195. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/state.tcss +0 -0
  196. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/widgets/__init__.py +0 -0
  197. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/widgets/help_menu.py +0 -0
  198. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/widgets/protocol_log.py +0 -0
  199. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/term/widgets/status_footer.py +0 -0
  200. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/__init__.py +0 -0
  201. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/checksum.py +0 -0
  202. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/dependencies.py +0 -0
  203. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/event_helper.py +0 -0
  204. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/logging.py +0 -0
  205. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/serialization.py +0 -0
  206. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/state_machine.py +0 -0
  207. {conson_xp-1.35.0 → conson_xp-1.36.0}/src/xp/utils/time_utils.py +0 -0
  208. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/.coverage +0 -0
  209. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/__init__.py +0 -0
  210. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/conftest.py +0 -0
  211. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/.coverage +0 -0
  212. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/__init__.py +0 -0
  213. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/telegram_test_data.py +0 -0
  214. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_actiontable_integration.py +0 -0
  215. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_api/.coverage +0 -0
  216. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_api/__init__.py +0 -0
  217. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_blink_integration.py +0 -0
  218. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_checksum_integration.py +0 -0
  219. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_conbus_blink_integration.py +0 -0
  220. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
  221. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_conbus_raw_integration.py +0 -0
  222. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_conbus_receive_integration.py +0 -0
  223. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_discovery_integration.py +0 -0
  224. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_event_telegram_integration.py +0 -0
  225. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_homekit_config_integration.py +0 -0
  226. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_link_number_integration.py +0 -0
  227. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_module_integration.py +0 -0
  228. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_output_integration.py +0 -0
  229. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
  230. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
  231. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_term_logging_integration.py +0 -0
  232. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_version_integration.py +0 -0
  233. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
  234. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
  235. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/__init__.py +0 -0
  236. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_api/__init__.py +0 -0
  237. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/__init__.py +0 -0
  238. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_click_tree.py +0 -0
  239. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
  240. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
  241. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
  242. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_decorators.py +0 -0
  243. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
  244. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_formatters.py +0 -0
  245. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
  246. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
  247. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_cli/test_term_commands.py +0 -0
  248. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_connection/__init__.py +0 -0
  249. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_connection/test_connection_init.py +0 -0
  250. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_connection/test_exceptions.py +0 -0
  251. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_encoding/__init__.py +0 -0
  252. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
  253. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/__init__.py +0 -0
  254. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_conbus.py +0 -0
  255. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
  256. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
  257. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
  258. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_event_telegram.py +0 -0
  259. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_log_entry.py +0 -0
  260. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_logger_config.py +0 -0
  261. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_module_type.py +0 -0
  262. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
  263. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_system_telegram.py +0 -0
  264. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
  265. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_version_telegram.py +0 -0
  266. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_write_config_type.py +0 -0
  267. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
  268. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
  269. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
  270. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/__init__.py +0 -0
  271. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
  272. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
  273. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
  274. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_base_server_service.py +0 -0
  275. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_blink_service.py +0 -0
  276. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_checksum_service.py +0 -0
  277. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_client_buffer_manager.py +0 -0
  278. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
  279. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_event_list_service.py +0 -0
  280. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_event_protocol.py +0 -0
  281. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_event_raw_service.py +0 -0
  282. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_output_service.py +0 -0
  283. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
  284. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_receive_service.py +0 -0
  285. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
  286. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_conbus_scan_service.py +0 -0
  287. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
  288. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_discovery_service.py +0 -0
  289. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
  290. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
  291. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
  292. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_homekit_services.py +0 -0
  293. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_log_file_service.py +0 -0
  294. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_module_type_service.py +0 -0
  295. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_protocol.py +0 -0
  296. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_protocol_monitor_service.py +0 -0
  297. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_server_service.py +0 -0
  298. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
  299. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_telegram_output_service.py +0 -0
  300. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
  301. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_telegram_service.py +0 -0
  302. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_version_service.py +0 -0
  303. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
  304. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
  305. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
  306. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
  307. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
  308. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
  309. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_tui/__init__.py +0 -0
  310. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_tui/test_protocol_log.py +0 -0
  311. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_utils/__init__.py +0 -0
  312. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_utils/test_checksum.py +0 -0
  313. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_utils/test_event_helper.py +0 -0
  314. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_utils/test_logging.py +0 -0
  315. {conson_xp-1.35.0 → conson_xp-1.36.0}/tests/unit/test_utils/test_serialization.py +0 -0
  316. {conson_xp-1.35.0 → conson_xp-1.36.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.35.0
3
+ Version: 1.36.0
4
4
  Summary: XP Protocol Communication Tools
5
5
  Author-Email: ldvchosal <ldvchosal@github.com>
6
6
  License: MIT License
@@ -22,7 +22,7 @@ dependencies = [
22
22
  ]
23
23
  requires-python = ">=3.11"
24
24
  readme = "README.md"
25
- version = "1.35.0"
25
+ version = "1.36.0"
26
26
 
27
27
  [project.license]
28
28
  file = "LICENSE"
@@ -3,7 +3,7 @@
3
3
  conson-xp package.
4
4
  """
5
5
 
6
- __version__ = "1.35.0"
6
+ __version__ = "1.36.0"
7
7
  __manufacturer__ = "salchichon"
8
8
  __model__ = "xp.cli"
9
9
  __serial__ = "2025.09.23.000"
@@ -321,7 +321,7 @@ class StateMonitorService:
321
321
 
322
322
  Args:
323
323
  module_state: Module state to update.
324
- output_number: Output number (0-3 for XP24).
324
+ output_number: Output number (0-3 for XP24, 0-2 for XP33 modules).
325
325
  output_state: True for ON, False for OFF.
326
326
  """
327
327
  # Parse existing outputs string "0 1 0 0" → [0, 1, 0, 0]
@@ -340,8 +340,9 @@ class StateMonitorService:
340
340
  def _handle_event_telegram(self, event: TelegramReceivedEvent) -> None:
341
341
  """Handle event telegram for output state changes.
342
342
 
343
- Processes XP24 output event telegrams to update module state in real-time.
344
- Output events use input_number field with values 80-83 to represent outputs 0-3.
343
+ Processes XP24 and XP33 output event telegrams to update module state in real-time.
344
+ - XP24 output events use input_number 80-83 to represent outputs 0-3.
345
+ - XP33 output events use input_number 0-2 to represent channels 0-2.
345
346
 
346
347
  Args:
347
348
  event: Telegram received event containing event telegram.
@@ -352,17 +353,37 @@ class StateMonitorService:
352
353
  self.logger.debug("Failed to parse event telegram")
353
354
  return
354
355
 
355
- # Only process XP24 output events
356
- if event_telegram.module_type != ModuleTypeCode.XP24.value:
357
- self.logger.debug(
358
- f"Ignoring event from module type {event_telegram.module_type}"
359
- )
360
- return
356
+ # Determine output number based on module type
357
+ output_number = None
358
+
359
+ if event_telegram.module_type == ModuleTypeCode.XP24.value:
360
+ # XP24 uses input_number 80-83 for outputs 0-3
361
+ if 80 <= event_telegram.input_number <= 83:
362
+ output_number = event_telegram.input_number - 80
363
+ else:
364
+ self.logger.debug(
365
+ f"Ignoring XP24 input event I{event_telegram.input_number:02d}"
366
+ )
367
+ return
361
368
 
362
- # Validate output number range (80-83 for XP24 outputs 0-3)
363
- if not (80 <= event_telegram.input_number <= 83):
369
+ elif event_telegram.module_type in (
370
+ ModuleTypeCode.XP33.value,
371
+ ModuleTypeCode.XP33LR.value,
372
+ ModuleTypeCode.XP33LED.value,
373
+ ):
374
+ # XP33 modules use input_number 0-2 for channels 0-2
375
+ if 80 <= event_telegram.input_number <= 82:
376
+ output_number = event_telegram.input_number - 80
377
+ else:
378
+ self.logger.debug(
379
+ f"Ignoring XP33 input event I{event_telegram.input_number:02d}"
380
+ )
381
+ return
382
+
383
+ else:
384
+ # Ignore events from other module types
364
385
  self.logger.debug(
365
- f"Ignoring input event I{event_telegram.input_number:02d}"
386
+ f"Ignoring event from module type {event_telegram.module_type}"
366
387
  )
367
388
  return
368
389
 
@@ -374,9 +395,8 @@ class StateMonitorService:
374
395
  )
375
396
  return
376
397
 
377
- # Convert input_number to output_number (80→0, 81→1, 82→2, 83→3)
378
- output_number = event_telegram.input_number - 80
379
- output_state = event_telegram.is_button_press # M=True, B=False
398
+ # Determine output state (M=True/ON, B=False/OFF)
399
+ output_state = event_telegram.is_button_press
380
400
 
381
401
  # Update output state
382
402
  self._update_output_bit(module_state, output_number, output_state)
@@ -111,7 +111,9 @@ class ModulesListWidget(Static):
111
111
  # Update existing row
112
112
  row_key = self._row_keys[serial_number]
113
113
  self.table.update_cell(
114
- row_key, "outputs", self._format_outputs(module_state.outputs)
114
+ row_key,
115
+ "outputs",
116
+ Text(self._format_outputs(module_state.outputs), justify="right"),
115
117
  )
116
118
  self.table.update_cell(
117
119
  row_key,
@@ -144,7 +146,7 @@ class ModulesListWidget(Static):
144
146
  Text(str(module_state.link_number), justify="right"),
145
147
  module_state.serial_number,
146
148
  module_state.module_type,
147
- self._format_outputs(module_state.outputs),
149
+ Text(self._format_outputs(module_state.outputs), justify="right"),
148
150
  Text(self._format_report(module_state.auto_report), justify="center"),
149
151
  module_state.error_status,
150
152
  Text(self._format_last_update(module_state.last_update), justify="center"),
@@ -84,6 +84,22 @@ class TestStateMonitorService:
84
84
  link_number=5,
85
85
  auto_report_status="NN",
86
86
  ),
87
+ ConsonModuleConfig(
88
+ name="A03",
89
+ serial_number="1111111111",
90
+ module_type="XP33LR",
91
+ module_type_code=30,
92
+ link_number=3,
93
+ auto_report_status="PP",
94
+ ),
95
+ ConsonModuleConfig(
96
+ name="A04",
97
+ serial_number="2222222222",
98
+ module_type="XP33LED",
99
+ module_type_code=35,
100
+ link_number=4,
101
+ auto_report_status="PP",
102
+ ),
87
103
  ]
88
104
  )
89
105
 
@@ -107,7 +123,7 @@ class TestStateMonitorService:
107
123
 
108
124
  def test_initialization(self, service):
109
125
  """Test service initializes module states from config."""
110
- assert len(service.module_states) == 2
126
+ assert len(service.module_states) == 4
111
127
 
112
128
  # Check first module (XP24)
113
129
  xp24_state = next(m for m in service.module_states if m.name == "A01")
@@ -123,6 +139,20 @@ class TestStateMonitorService:
123
139
  assert xp130_state.link_number == 5
124
140
  assert xp130_state.auto_report is False
125
141
 
142
+ # Check third module (XP33LR)
143
+ xp33lr_state = next(m for m in service.module_states if m.name == "A03")
144
+ assert xp33lr_state.serial_number == "1111111111"
145
+ assert xp33lr_state.module_type == "XP33LR"
146
+ assert xp33lr_state.link_number == 3
147
+ assert xp33lr_state.auto_report is True
148
+
149
+ # Check fourth module (XP33LED)
150
+ xp33led_state = next(m for m in service.module_states if m.name == "A04")
151
+ assert xp33led_state.serial_number == "2222222222"
152
+ assert xp33led_state.module_type == "XP33LED"
153
+ assert xp33led_state.link_number == 4
154
+ assert xp33led_state.auto_report is True
155
+
126
156
  def test_find_module_by_link_found(self, service):
127
157
  """Test _find_module_by_link returns module when found."""
128
158
  module = service._find_module_by_link(9)
@@ -362,3 +392,122 @@ class TestStateMonitorService:
362
392
 
363
393
  # Verify parse_reply_telegram was called
364
394
  mock_telegram_service.parse_reply_telegram.assert_called_once()
395
+
396
+ def test_handle_event_telegram_xp33lr_channel_on(
397
+ self, service, mock_telegram_service, mock_protocol
398
+ ):
399
+ """Test _handle_event_telegram processes XP33LR channel ON event."""
400
+ # Mock event telegram for XP33LR L03 channel 0 ON
401
+ event_telegram = EventTelegram(
402
+ raw_telegram="<E30L03I80MAE>",
403
+ checksum="AE",
404
+ checksum_validated=True,
405
+ event_telegram_type="E",
406
+ module_type=30, # XP33LR
407
+ link_number=3,
408
+ input_number=80, # Channel 0 (I80)
409
+ event_type=EventType.BUTTON_PRESS,
410
+ )
411
+ mock_telegram_service.parse_event_telegram.return_value = event_telegram
412
+
413
+ # Setup module initial state
414
+ module = service._find_module_by_link(3)
415
+ module.outputs = "0 0 0"
416
+
417
+ # Mock signal to verify emission
418
+ signal_handler = Mock()
419
+ service.on_module_state_changed.connect(signal_handler)
420
+
421
+ # Create event
422
+ event = self._make_event(mock_protocol, "<E30L03I80MAE>", "E")
423
+
424
+ # Process event
425
+ service._handle_event_telegram(event)
426
+
427
+ # Verify output updated
428
+ assert module.outputs == "1 0 0"
429
+ assert module.last_update is not None
430
+ signal_handler.assert_called_once()
431
+
432
+ def test_handle_event_telegram_xp33lr_channel_off(
433
+ self, service, mock_telegram_service, mock_protocol
434
+ ):
435
+ """Test _handle_event_telegram processes XP33LR channel OFF event."""
436
+ # Mock event telegram for XP33LR L03 channel 1 OFF
437
+ event_telegram = EventTelegram(
438
+ raw_telegram="<E30L03I81BAE>",
439
+ checksum="AE",
440
+ checksum_validated=True,
441
+ event_telegram_type="E",
442
+ module_type=30, # XP33LR
443
+ link_number=3,
444
+ input_number=81, # Channel 1 (I81)
445
+ event_type=EventType.BUTTON_RELEASE,
446
+ )
447
+ mock_telegram_service.parse_event_telegram.return_value = event_telegram
448
+
449
+ module = service._find_module_by_link(3)
450
+ module.outputs = "1 1 1"
451
+
452
+ event = self._make_event(mock_protocol, "<E30L03I81BAE>", "E")
453
+
454
+ service._handle_event_telegram(event)
455
+ assert module.outputs == "1 0 1"
456
+
457
+ def test_handle_event_telegram_xp33led_channel_on(
458
+ self, service, mock_telegram_service, mock_protocol
459
+ ):
460
+ """Test _handle_event_telegram processes XP33LED channel ON event."""
461
+ # Mock event telegram for XP33LED L04 channel 2 ON
462
+ event_telegram = EventTelegram(
463
+ raw_telegram="<E35L04I82MAE>",
464
+ checksum="AE",
465
+ checksum_validated=True,
466
+ event_telegram_type="E",
467
+ module_type=35, # XP33LED
468
+ link_number=4,
469
+ input_number=82, # Channel 2 (I82)
470
+ event_type=EventType.BUTTON_PRESS,
471
+ )
472
+ mock_telegram_service.parse_event_telegram.return_value = event_telegram
473
+
474
+ # Setup module initial state
475
+ module = service._find_module_by_link(4)
476
+ module.outputs = "0 0 0"
477
+
478
+ # Create event
479
+ event = self._make_event(mock_protocol, "<E35L04I82MAE>", "E")
480
+
481
+ # Process event
482
+ service._handle_event_telegram(event)
483
+
484
+ # Verify output updated
485
+ assert module.outputs == "0 0 1"
486
+ assert module.last_update is not None
487
+
488
+ def test_handle_event_telegram_xp33_ignores_invalid_channel(
489
+ self, service, mock_telegram_service, mock_protocol
490
+ ):
491
+ """Test _handle_event_telegram ignores XP33 events for invalid channels."""
492
+ # Mock event telegram for XP33LR with invalid channel number
493
+ event_telegram = EventTelegram(
494
+ raw_telegram="<E30L03I05MAE>",
495
+ checksum="AE",
496
+ checksum_validated=True,
497
+ event_telegram_type="E",
498
+ module_type=30, # XP33LR
499
+ link_number=3,
500
+ input_number=5, # Invalid channel (only 0-2 valid)
501
+ event_type=EventType.BUTTON_PRESS,
502
+ )
503
+ mock_telegram_service.parse_event_telegram.return_value = event_telegram
504
+
505
+ module = service._find_module_by_link(3)
506
+ module.outputs = "0 0 0"
507
+
508
+ event = self._make_event(mock_protocol, "<E30L03I05MAE>", "E")
509
+
510
+ service._handle_event_telegram(event)
511
+
512
+ # Output should not change
513
+ assert module.outputs == "0 0 0"
File without changes
File without changes