conson-xp 1.21.0__tar.gz → 1.23.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 (299) hide show
  1. {conson_xp-1.21.0 → conson_xp-1.23.0}/PKG-INFO +32 -17
  2. {conson_xp-1.21.0 → conson_xp-1.23.0}/README.md +31 -16
  3. {conson_xp-1.21.0 → conson_xp-1.23.0}/pyproject.toml +2 -2
  4. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/__init__.py +1 -1
  5. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/term/term_commands.py +1 -1
  6. conson_xp-1.23.0/src/xp/models/term/connection_state.py +58 -0
  7. conson_xp-1.23.0/src/xp/models/term/status_message.py +16 -0
  8. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/protocol/conbus_event_protocol.py +19 -6
  9. conson_xp-1.21.0/src/xp/term/app.py → conson_xp-1.23.0/src/xp/term/protocol.py +19 -40
  10. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/term/protocol.tcss +1 -1
  11. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/term/protocol.yml +14 -14
  12. conson_xp-1.23.0/src/xp/term/widgets/__init__.py +7 -0
  13. conson_xp-1.23.0/src/xp/term/widgets/help_menu.py +55 -0
  14. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/term/widgets/protocol_log.py +37 -84
  15. conson_xp-1.23.0/src/xp/term/widgets/status_footer.py +63 -0
  16. conson_xp-1.21.0/src/xp/term/widgets/__init__.py +0 -1
  17. {conson_xp-1.21.0 → conson_xp-1.23.0}/LICENSE +0 -0
  18. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/__init__.py +0 -0
  19. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/__main__.py +0 -0
  20. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/__init__.py +0 -0
  21. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
  22. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
  23. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
  24. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
  25. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
  26. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
  27. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
  28. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
  29. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
  30. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_event_commands.py +0 -0
  31. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
  32. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
  33. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
  34. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
  35. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
  36. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
  37. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
  38. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
  39. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/file_commands.py +0 -0
  40. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
  41. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
  42. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
  43. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/module_commands.py +0 -0
  44. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
  45. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/server/__init__.py +0 -0
  46. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/server/server_commands.py +0 -0
  47. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
  48. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
  49. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
  50. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
  51. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
  52. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
  53. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
  54. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
  55. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/term/__init__.py +0 -0
  56. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/commands/term/term.py +0 -0
  57. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/main.py +0 -0
  58. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/__init__.py +0 -0
  59. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/click_tree.py +0 -0
  60. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
  61. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/decorators.py +0 -0
  62. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/error_handlers.py +0 -0
  63. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/formatters.py +0 -0
  64. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/module_type_choice.py +0 -0
  65. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/serial_number_type.py +0 -0
  66. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/system_function_choice.py +0 -0
  67. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/cli/utils/xp_module_type.py +0 -0
  68. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/connection/__init__.py +0 -0
  69. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/connection/exceptions.py +0 -0
  70. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/__init__.py +0 -0
  71. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/actiontable/__init__.py +0 -0
  72. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/actiontable/actiontable.py +0 -0
  73. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
  74. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
  75. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
  76. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/__init__.py +0 -0
  77. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus.py +0 -0
  78. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
  79. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_blink.py +0 -0
  80. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
  81. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
  82. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_custom.py +0 -0
  83. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
  84. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_discover.py +0 -0
  85. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_event_list.py +0 -0
  86. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_event_raw.py +0 -0
  87. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
  88. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
  89. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_logger_config.py +0 -0
  90. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_output.py +0 -0
  91. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_raw.py +0 -0
  92. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_receive.py +0 -0
  93. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
  94. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/homekit/__init__.py +0 -0
  95. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
  96. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/homekit/homekit_config.py +0 -0
  97. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
  98. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/log_entry.py +0 -0
  99. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/protocol/__init__.py +0 -0
  100. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
  101. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/response.py +0 -0
  102. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/__init__.py +0 -0
  103. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/action_type.py +0 -0
  104. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/datapoint_type.py +0 -0
  105. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/event_telegram.py +0 -0
  106. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/event_type.py +0 -0
  107. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/input_action_type.py +0 -0
  108. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/input_type.py +0 -0
  109. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/module_type.py +0 -0
  110. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/module_type_code.py +0 -0
  111. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/output_telegram.py +0 -0
  112. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/reply_telegram.py +0 -0
  113. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/system_function.py +0 -0
  114. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/system_telegram.py +0 -0
  115. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/telegram.py +0 -0
  116. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/telegram_type.py +0 -0
  117. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/telegram/timeparam_type.py +0 -0
  118. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/term/__init__.py +0 -0
  119. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/term/protocol_keys_config.py +0 -0
  120. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/models/write_config_type.py +0 -0
  121. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/__init__.py +0 -0
  122. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/actiontable/__init__.py +0 -0
  123. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
  124. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
  125. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
  126. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
  127. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
  128. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/__init__.py +0 -0
  129. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
  130. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
  131. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
  132. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
  133. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
  134. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
  135. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
  136. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
  137. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
  138. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
  139. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
  140. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_discover_service.py +0 -0
  141. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_event_list_service.py +0 -0
  142. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_event_raw_service.py +0 -0
  143. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
  144. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
  145. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
  146. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
  147. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/conbus/write_config_service.py +0 -0
  148. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/__init__.py +0 -0
  149. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
  150. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
  151. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
  152. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
  153. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
  154. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
  155. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
  156. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
  157. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
  158. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
  159. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
  160. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
  161. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/homekit/homekit_service.py +0 -0
  162. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/log_file_service.py +0 -0
  163. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/module_type_service.py +0 -0
  164. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/protocol/__init__.py +0 -0
  165. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
  166. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/protocol/protocol_factory.py +0 -0
  167. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
  168. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/reverse_proxy_service.py +0 -0
  169. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/__init__.py +0 -0
  170. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/base_server_service.py +0 -0
  171. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/cp20_server_service.py +0 -0
  172. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/device_service_factory.py +0 -0
  173. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/server_service.py +0 -0
  174. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/xp130_server_service.py +0 -0
  175. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/xp20_server_service.py +0 -0
  176. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/xp230_server_service.py +0 -0
  177. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/xp24_server_service.py +0 -0
  178. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/server/xp33_server_service.py +0 -0
  179. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/__init__.py +0 -0
  180. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
  181. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
  182. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
  183. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
  184. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
  185. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
  186. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_service.py +0 -0
  187. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
  188. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/term/__init__.py +0 -0
  189. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/__init__.py +0 -0
  190. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/checksum.py +0 -0
  191. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/dependencies.py +0 -0
  192. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/event_helper.py +0 -0
  193. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/logging.py +0 -0
  194. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/serialization.py +0 -0
  195. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/state_machine.py +0 -0
  196. {conson_xp-1.21.0 → conson_xp-1.23.0}/src/xp/utils/time_utils.py +0 -0
  197. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/.coverage +0 -0
  198. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/__init__.py +0 -0
  199. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/conftest.py +0 -0
  200. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/.coverage +0 -0
  201. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/__init__.py +0 -0
  202. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/telegram_test_data.py +0 -0
  203. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_actiontable_integration.py +0 -0
  204. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_api/.coverage +0 -0
  205. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_api/__init__.py +0 -0
  206. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_blink_integration.py +0 -0
  207. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_checksum_integration.py +0 -0
  208. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_conbus_blink_integration.py +0 -0
  209. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
  210. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_conbus_raw_integration.py +0 -0
  211. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_conbus_receive_integration.py +0 -0
  212. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_discovery_integration.py +0 -0
  213. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_event_telegram_integration.py +0 -0
  214. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_homekit_config_integration.py +0 -0
  215. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_link_number_integration.py +0 -0
  216. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_module_integration.py +0 -0
  217. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_output_integration.py +0 -0
  218. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
  219. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
  220. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_term_logging_integration.py +0 -0
  221. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_version_integration.py +0 -0
  222. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
  223. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
  224. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/__init__.py +0 -0
  225. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_api/__init__.py +0 -0
  226. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/__init__.py +0 -0
  227. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_click_tree.py +0 -0
  228. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
  229. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
  230. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
  231. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_decorators.py +0 -0
  232. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
  233. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_formatters.py +0 -0
  234. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
  235. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
  236. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_cli/test_term_commands.py +0 -0
  237. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_connection/__init__.py +0 -0
  238. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_connection/test_connection_init.py +0 -0
  239. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_connection/test_exceptions.py +0 -0
  240. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_encoding/__init__.py +0 -0
  241. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
  242. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/__init__.py +0 -0
  243. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_conbus.py +0 -0
  244. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
  245. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
  246. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
  247. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_event_telegram.py +0 -0
  248. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_log_entry.py +0 -0
  249. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_logger_config.py +0 -0
  250. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_module_type.py +0 -0
  251. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
  252. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_system_telegram.py +0 -0
  253. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
  254. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_version_telegram.py +0 -0
  255. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_write_config_type.py +0 -0
  256. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
  257. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
  258. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
  259. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/__init__.py +0 -0
  260. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
  261. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
  262. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
  263. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_base_server_service.py +0 -0
  264. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_blink_service.py +0 -0
  265. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_checksum_service.py +0 -0
  266. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
  267. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_conbus_event_list_service.py +0 -0
  268. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_conbus_event_raw_service.py +0 -0
  269. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
  270. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_conbus_receive_service.py +0 -0
  271. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
  272. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
  273. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_discovery_service.py +0 -0
  274. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
  275. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
  276. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
  277. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_homekit_services.py +0 -0
  278. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_log_file_service.py +0 -0
  279. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_module_type_service.py +0 -0
  280. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_protocol.py +0 -0
  281. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_server_service.py +0 -0
  282. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
  283. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
  284. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_telegram_service.py +0 -0
  285. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_version_service.py +0 -0
  286. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
  287. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
  288. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
  289. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
  290. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
  291. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
  292. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_tui/__init__.py +0 -0
  293. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_tui/test_protocol_log.py +0 -0
  294. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_utils/__init__.py +0 -0
  295. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_utils/test_checksum.py +0 -0
  296. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_utils/test_event_helper.py +0 -0
  297. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_utils/test_logging.py +0 -0
  298. {conson_xp-1.21.0 → conson_xp-1.23.0}/tests/unit/test_utils/test_serialization.py +0 -0
  299. {conson_xp-1.21.0 → conson_xp-1.23.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.21.0
3
+ Version: 1.23.0
4
4
  Summary: XP Protocol Communication Tools
5
5
  Author-Email: ldvchosal <ldvchosal@github.com>
6
6
  License: MIT License
@@ -60,7 +60,7 @@ Description-Content-Type: text/markdown
60
60
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
61
61
  [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
62
62
 
63
- > **A powerful Python CLI and API toolkit for CONSON XP Protocol operations**
63
+ > **A powerful Python CLI toolkit for CONSON XP Protocol operations**
64
64
 
65
65
  Control and communicate with XP devices through console bus (Conbus), parse telegrams in real-time, and integrate with smart home systems like Apple HomeKit.
66
66
 
@@ -81,7 +81,7 @@ Bridge XP devices to Apple HomeKit for seamless smart home control
81
81
  Automatically discover XP servers and scan connected modules on your network
82
82
 
83
83
  ⚡ **Modern Architecture**
84
- FastAPI REST endpoints and comprehensive type safety
84
+ Comprehensive type safety and robust error handling
85
85
 
86
86
  ---
87
87
 
@@ -96,9 +96,6 @@ xp telegram parse "<E14L00I02MAK>"
96
96
 
97
97
  # Discover XP servers on your network
98
98
  xp conbus discover
99
-
100
- # Start the REST API server
101
- xp api start
102
99
  ```
103
100
 
104
101
  ## 📦 Installation
@@ -167,7 +164,32 @@ xp module search "push button"
167
164
  xp module list --group-by-category
168
165
  ```
169
166
 
167
+ ### 🖥️ Terminal UI (TUI)
168
+
169
+ **Real-time Protocol Monitor**
170
+
171
+ Launch an interactive terminal interface for live protocol monitoring and control:
170
172
 
173
+ ```bash
174
+ # Start the protocol monitor TUI
175
+ xp term protocol
176
+ ```
177
+
178
+ **Features:**
179
+ - 📊 **Live Telegram Stream**: Real-time RX/TX telegram monitoring from Conbus server
180
+ - ⌨️ **Keyboard Shortcuts**: Quick access controls for common operations
181
+ - `Q` - Quit application
182
+ - `C` - Toggle connection (connect/disconnect)
183
+ - `R` - Reset and clear log
184
+ - `0-9, a-q` - Send predefined protocol telegrams
185
+ - 🎨 **Visual Status Indicators**: Color-coded connection states
186
+ - 🟢 Green - Connected
187
+ - 🟡 Yellow - Connecting/Disconnecting
188
+ - 🔴 Red - Failed
189
+ - ⚪ White - Disconnected
190
+ - 📝 **Interactive Display**: Scrollable telegram log with detailed parsing information
191
+
192
+ The TUI provides a convenient way to monitor and interact with XP devices without juggling multiple terminal commands.
171
193
 
172
194
  ### 🔧 Advanced Features
173
195
 
@@ -201,13 +223,7 @@ xp checksum calculate "E14L00I02M" --algorithm crc32
201
223
  ```
202
224
  </details>
203
225
 
204
- ### 🌐 API & Integration
205
-
206
- **REST API Server**
207
- ```bash
208
- # Start API server with interactive docs at /docs
209
- xp api start
210
- ```
226
+ ### 🌐 Integration
211
227
 
212
228
  **HomeKit Smart Home Bridge**
213
229
  ```bash
@@ -232,7 +248,7 @@ xp reverse-proxy start
232
248
 
233
249
  **Layered Design**
234
250
  ```
235
- CLI Layer → API Layer → Services → Models → Connection Layer
251
+ CLI Layer → Services → Models → Connection Layer
236
252
  ```
237
253
 
238
254
  **Key Components**: Telegram processing • Real-time Conbus communication • HomeKit bridge • Multiple XP server support • Configuration management
@@ -256,9 +272,8 @@ pdm run check
256
272
  <details>
257
273
  <summary><b>Project Structure</b></summary>
258
274
 
259
- ```
275
+ ```
260
276
  src/xp/
261
- ├── api/ # FastAPI REST endpoints
262
277
  ├── cli/ # Command-line interface
263
278
  ├── models/ # Core data models
264
279
  ├── services/ # Business logic
@@ -407,7 +422,7 @@ xp term protocol
407
422
  ```
408
423
  </details>
409
424
 
410
- **Requirements**: Python 3.10+ • FastAPI • Pydantic • Click • HAP-python
425
+ **Requirements**: Python 3.10+ • Pydantic • Click • HAP-python
411
426
 
412
427
  ## License
413
428
 
@@ -7,7 +7,7 @@
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
8
  [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
9
9
 
10
- > **A powerful Python CLI and API toolkit for CONSON XP Protocol operations**
10
+ > **A powerful Python CLI toolkit for CONSON XP Protocol operations**
11
11
 
12
12
  Control and communicate with XP devices through console bus (Conbus), parse telegrams in real-time, and integrate with smart home systems like Apple HomeKit.
13
13
 
@@ -28,7 +28,7 @@ Bridge XP devices to Apple HomeKit for seamless smart home control
28
28
  Automatically discover XP servers and scan connected modules on your network
29
29
 
30
30
  ⚡ **Modern Architecture**
31
- FastAPI REST endpoints and comprehensive type safety
31
+ Comprehensive type safety and robust error handling
32
32
 
33
33
  ---
34
34
 
@@ -43,9 +43,6 @@ xp telegram parse "<E14L00I02MAK>"
43
43
 
44
44
  # Discover XP servers on your network
45
45
  xp conbus discover
46
-
47
- # Start the REST API server
48
- xp api start
49
46
  ```
50
47
 
51
48
  ## 📦 Installation
@@ -114,7 +111,32 @@ xp module search "push button"
114
111
  xp module list --group-by-category
115
112
  ```
116
113
 
114
+ ### 🖥️ Terminal UI (TUI)
115
+
116
+ **Real-time Protocol Monitor**
117
+
118
+ Launch an interactive terminal interface for live protocol monitoring and control:
117
119
 
120
+ ```bash
121
+ # Start the protocol monitor TUI
122
+ xp term protocol
123
+ ```
124
+
125
+ **Features:**
126
+ - 📊 **Live Telegram Stream**: Real-time RX/TX telegram monitoring from Conbus server
127
+ - ⌨️ **Keyboard Shortcuts**: Quick access controls for common operations
128
+ - `Q` - Quit application
129
+ - `C` - Toggle connection (connect/disconnect)
130
+ - `R` - Reset and clear log
131
+ - `0-9, a-q` - Send predefined protocol telegrams
132
+ - 🎨 **Visual Status Indicators**: Color-coded connection states
133
+ - 🟢 Green - Connected
134
+ - 🟡 Yellow - Connecting/Disconnecting
135
+ - 🔴 Red - Failed
136
+ - ⚪ White - Disconnected
137
+ - 📝 **Interactive Display**: Scrollable telegram log with detailed parsing information
138
+
139
+ The TUI provides a convenient way to monitor and interact with XP devices without juggling multiple terminal commands.
118
140
 
119
141
  ### 🔧 Advanced Features
120
142
 
@@ -148,13 +170,7 @@ xp checksum calculate "E14L00I02M" --algorithm crc32
148
170
  ```
149
171
  </details>
150
172
 
151
- ### 🌐 API & Integration
152
-
153
- **REST API Server**
154
- ```bash
155
- # Start API server with interactive docs at /docs
156
- xp api start
157
- ```
173
+ ### 🌐 Integration
158
174
 
159
175
  **HomeKit Smart Home Bridge**
160
176
  ```bash
@@ -179,7 +195,7 @@ xp reverse-proxy start
179
195
 
180
196
  **Layered Design**
181
197
  ```
182
- CLI Layer → API Layer → Services → Models → Connection Layer
198
+ CLI Layer → Services → Models → Connection Layer
183
199
  ```
184
200
 
185
201
  **Key Components**: Telegram processing • Real-time Conbus communication • HomeKit bridge • Multiple XP server support • Configuration management
@@ -203,9 +219,8 @@ pdm run check
203
219
  <details>
204
220
  <summary><b>Project Structure</b></summary>
205
221
 
206
- ```
222
+ ```
207
223
  src/xp/
208
- ├── api/ # FastAPI REST endpoints
209
224
  ├── cli/ # Command-line interface
210
225
  ├── models/ # Core data models
211
226
  ├── services/ # Business logic
@@ -354,7 +369,7 @@ xp term protocol
354
369
  ```
355
370
  </details>
356
371
 
357
- **Requirements**: Python 3.10+ • FastAPI • Pydantic • Click • HAP-python
372
+ **Requirements**: Python 3.10+ • Pydantic • Click • HAP-python
358
373
 
359
374
  ## License
360
375
 
@@ -22,7 +22,7 @@ dependencies = [
22
22
  ]
23
23
  requires-python = ">=3.11"
24
24
  readme = "README.md"
25
- version = "1.21.0"
25
+ version = "1.23.0"
26
26
 
27
27
  [project.license]
28
28
  file = "LICENSE"
@@ -209,7 +209,7 @@ composite = [
209
209
  ]
210
210
 
211
211
  [tool.pdm.scripts.clean]
212
- shell = "rm -rf .coverage coverage.xml htmlcov/ .pytest_cache/ && find . -type d -name '__pycache__' -exec rm -rf {} +"
212
+ shell = "rm -rf .coverage coverage.xml htmlcov/ .pytest_cache/ conbus.log.* && find . -type d -name '__pycache__' -exec rm -rf {} +"
213
213
 
214
214
  [tool.vulture]
215
215
  exclude = [
@@ -3,7 +3,7 @@
3
3
  conson-xp package.
4
4
  """
5
5
 
6
- __version__ = "1.21.0"
6
+ __version__ = "1.23.0"
7
7
  __manufacturer__ = "salchichon"
8
8
  __model__ = "xp.cli"
9
9
  __serial__ = "2025.09.23.000"
@@ -21,7 +21,7 @@ def protocol_monitor(ctx: Context) -> None:
21
21
  \b
22
22
  xp term protocol
23
23
  """
24
- from xp.term.app import ProtocolMonitorApp
24
+ from xp.term.protocol import ProtocolMonitorApp
25
25
 
26
26
  # Resolve ServiceContainer from context
27
27
  container = ctx.obj.get("container").get_container()
@@ -0,0 +1,58 @@
1
+ """Connection state management module."""
2
+
3
+ from enum import Enum
4
+
5
+ from xp.utils.state_machine import StateMachine
6
+
7
+
8
+ class ConnectionState(str, Enum):
9
+ """Connection state enumeration.
10
+
11
+ Attributes:
12
+ DISCONNECTING: Disconnecting to server.
13
+ DISCONNECTED: Not connected to server.
14
+ CONNECTING: Connection in progress.
15
+ CONNECTED: Successfully connected.
16
+ FAILED: Connection failed.
17
+ """
18
+
19
+ DISCONNECTING = "DISCONNECTING"
20
+ DISCONNECTED = "DISCONNECTED"
21
+ CONNECTING = "CONNECTING"
22
+ CONNECTED = "CONNECTED"
23
+ FAILED = "FAILED"
24
+
25
+ @staticmethod
26
+ def create_state_machine() -> StateMachine:
27
+ """Create and configure state machine for connection management.
28
+
29
+ Returns:
30
+ Configured StateMachine with connection state transitions.
31
+ """
32
+ sm = StateMachine(ConnectionState.DISCONNECTED)
33
+
34
+ # Define valid transitions
35
+ sm.define_transition(
36
+ "connect", {ConnectionState.DISCONNECTED, ConnectionState.FAILED}
37
+ )
38
+ sm.define_transition(
39
+ "disconnect", {ConnectionState.CONNECTED, ConnectionState.CONNECTING}
40
+ )
41
+ sm.define_transition(
42
+ "connecting", {ConnectionState.DISCONNECTED, ConnectionState.FAILED}
43
+ )
44
+ sm.define_transition("connected", {ConnectionState.CONNECTING})
45
+ sm.define_transition(
46
+ "disconnecting", {ConnectionState.CONNECTED, ConnectionState.CONNECTING}
47
+ )
48
+ sm.define_transition("disconnected", {ConnectionState.DISCONNECTING})
49
+ sm.define_transition(
50
+ "failed",
51
+ {
52
+ ConnectionState.CONNECTING,
53
+ ConnectionState.CONNECTED,
54
+ ConnectionState.DISCONNECTING,
55
+ },
56
+ )
57
+
58
+ return sm
@@ -0,0 +1,16 @@
1
+ """Status message models for terminal UI."""
2
+
3
+ from textual.message import Message
4
+
5
+
6
+ class StatusMessageChanged(Message):
7
+ """Message posted when status message changes."""
8
+
9
+ def __init__(self, message: str) -> None:
10
+ """Initialize the message.
11
+
12
+ Args:
13
+ message: The status message to display.
14
+ """
15
+ super().__init__()
16
+ self.message = message
@@ -17,7 +17,7 @@ from twisted.internet.interfaces import IAddress, IConnector
17
17
  from twisted.internet.posixbase import PosixReactorBase
18
18
  from twisted.python.failure import Failure
19
19
 
20
- from xp.models import ConbusClientConfig
20
+ from xp.models import ConbusClientConfig, ModuleTypeCode
21
21
  from xp.models.protocol.conbus_protocol import (
22
22
  TelegramReceivedEvent,
23
23
  )
@@ -168,9 +168,6 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
168
168
 
169
169
  Args:
170
170
  data: Raw telegram payload (without checksum/framing).
171
-
172
- Raises:
173
- IOError: If transport is not open.
174
171
  """
175
172
  self.on_send_frame.emit(data)
176
173
 
@@ -180,8 +177,9 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
180
177
  frame = b"<" + frame_data.encode() + b">"
181
178
 
182
179
  if not self.transport:
183
- self.logger.info("Invalid transport")
184
- raise IOError("Transport is not open")
180
+ self.logger.info("Invalid transport, connection closed.")
181
+ self.on_connection_failed.emit(Failure("Invalid transport."))
182
+ return
185
183
 
186
184
  self.logger.debug(f"Sending frame: {frame.decode()}")
187
185
  self.transport.write(frame) # type: ignore
@@ -211,6 +209,21 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
211
209
  )
212
210
  self.send_raw_telegram(payload)
213
211
 
212
+ def send_event_telegram(
213
+ self, module_type_code: ModuleTypeCode, link_number: int, input_number: int
214
+ ) -> None:
215
+ """Send telegram with specified parameters.
216
+
217
+ Args:
218
+ module_type_code: Type code of module.
219
+ link_number: Link number.
220
+ input_number: Input number.
221
+ """
222
+ payload = (
223
+ f"E" f"{module_type_code}" f"L{link_number:02d}" f"I{input_number:02d}"
224
+ )
225
+ self.send_raw_telegram(payload)
226
+
214
227
  def send_raw_telegram(self, payload: str) -> None:
215
228
  """Send telegram with specified parameters.
216
229
 
@@ -4,11 +4,13 @@ from pathlib import Path
4
4
  from typing import Any, Optional
5
5
 
6
6
  from textual.app import App, ComposeResult
7
- from textual.containers import Horizontal, Vertical
8
- from textual.widgets import DataTable, Footer, Static
7
+ from textual.containers import Horizontal
9
8
 
10
9
  from xp.models.term import ProtocolKeysConfig
10
+ from xp.models.term.status_message import StatusMessageChanged
11
+ from xp.term.widgets.help_menu import HelpMenuWidget
11
12
  from xp.term.widgets.protocol_log import ProtocolLogWidget
13
+ from xp.term.widgets.status_footer import StatusFooterWidget
12
14
 
13
15
 
14
16
  class ProtocolMonitorApp(App[None]):
@@ -45,9 +47,8 @@ class ProtocolMonitorApp(App[None]):
45
47
  super().__init__()
46
48
  self.container = container
47
49
  self.protocol_widget: Optional[ProtocolLogWidget] = None
48
- self.status_widget: Optional[Static] = None
49
- self.status_text_widget: Optional[Static] = None
50
- self.help_table: Optional[DataTable] = None
50
+ self.help_menu: Optional[HelpMenuWidget] = None
51
+ self.footer_widget: Optional[StatusFooterWidget] = None
51
52
  self.protocol_keys = self._load_protocol_keys()
52
53
 
53
54
  def _load_protocol_keys(self) -> ProtocolKeysConfig:
@@ -70,18 +71,13 @@ class ProtocolMonitorApp(App[None]):
70
71
  yield self.protocol_widget
71
72
 
72
73
  # Help menu (hidden by default)
73
- help_container = Vertical(id="help-menu")
74
- help_container.border_title = "Help menu"
75
- help_container.can_focus = False
76
- with help_container:
77
- self.help_table = DataTable(id="help-table", show_header=False)
78
- self.help_table.can_focus = False
79
- yield self.help_table
80
-
81
- with Horizontal(id="footer-container"):
82
- yield Footer()
83
- self.status_widget = Static("○", id="status-line")
84
- yield self.status_widget
74
+ self.help_menu = HelpMenuWidget(
75
+ protocol_keys=self.protocol_keys, id="help-menu"
76
+ )
77
+ yield self.help_menu
78
+
79
+ self.footer_widget = StatusFooterWidget(id="footer-container")
80
+ yield self.footer_widget
85
81
 
86
82
  def action_toggle_connection(self) -> None:
87
83
  """Toggle connection on 'c' key press.
@@ -122,37 +118,20 @@ class ProtocolMonitorApp(App[None]):
122
118
  self._update_status,
123
119
  )
124
120
 
125
- # Initialize help table
126
- if self.help_table:
127
- self.help_table.add_columns("Key", "Command")
128
- for key, config in self.protocol_keys.protocol.items():
129
- self.help_table.add_row(key, config.name)
130
-
131
121
  def _update_status(self, state: Any) -> None:
132
122
  """Update status line with connection state.
133
123
 
134
124
  Args:
135
125
  state: Current connection state.
136
126
  """
137
- if self.status_widget:
138
- # Map states to colored dots
139
- status_map = {
140
- "CONNECTED": "[green]●[/green]",
141
- "CONNECTING": "[yellow]●[/yellow]",
142
- "DISCONNECTING": "[yellow]●[/yellow]",
143
- "FAILED": "[red]●[/red]",
144
- "DISCONNECTED": "○",
145
- }
146
- dot = status_map.get(state.value, "○")
147
- self.status_widget.update(dot)
148
-
149
- def on_protocol_log_widget_status_message_changed(
150
- self, message: ProtocolLogWidget.StatusMessageChanged
151
- ) -> None:
127
+ if self.footer_widget:
128
+ self.footer_widget.update_status(state)
129
+
130
+ def on_status_message_changed(self, message: StatusMessageChanged) -> None:
152
131
  """Handle status message changes from protocol widget.
153
132
 
154
133
  Args:
155
134
  message: Message containing the status text.
156
135
  """
157
- if self.status_text_widget:
158
- self.status_text_widget.update(message.message)
136
+ if self.footer_widget:
137
+ self.footer_widget.update_message(message.message)
@@ -119,7 +119,7 @@ Footer {
119
119
  #status-text {
120
120
  dock: right;
121
121
  width: auto;
122
- padding: 0 1;
122
+ padding: 0 3;
123
123
  background: $background;
124
124
  color: $text;
125
125
  text-align: right;
@@ -55,85 +55,85 @@ protocol:
55
55
  - E02L00I08B
56
56
 
57
57
  "d":
58
- name: "All 1 On"
58
+ name: "Link 1 On"
59
59
  telegrams:
60
60
  - E02L01I08M
61
61
  - E02L01I08B
62
62
 
63
63
  "e":
64
- name: "All 1 Off"
64
+ name: "Link 1 Off"
65
65
  telegrams:
66
66
  - E02L01I00M
67
67
  - E02L01I00B
68
68
 
69
69
  "f":
70
- name: "All 2 On"
70
+ name: "Link 2 On"
71
71
  telegrams:
72
72
  - E02L02I08M
73
73
  - E02L02I08B
74
74
 
75
75
  "g":
76
- name: "All 2 Off"
76
+ name: "Link 2 Off"
77
77
  telegrams:
78
78
  - E02L02I00M
79
79
  - E02L02I00B
80
80
 
81
81
  "h":
82
- name: "All 3 On"
82
+ name: "Link 3 On"
83
83
  telegrams:
84
84
  - E02L03I08M
85
85
  - E02L03I08B
86
86
 
87
87
  "i":
88
- name: "All 3 Off"
88
+ name: "Link 3 Off"
89
89
  telegrams:
90
90
  - E02L03I00M
91
91
  - E02L03I00B
92
92
 
93
93
  "j":
94
- name: "All 4 On"
94
+ name: "Link 4 On"
95
95
  telegrams:
96
96
  - E02L04I08M
97
97
  - E02L04I08B
98
98
 
99
99
  "k":
100
- name: "All 4 Off"
100
+ name: "Link 4 Off"
101
101
  telegrams:
102
102
  - E02L04I00M
103
103
  - E02L04I00B
104
104
 
105
105
  "l":
106
- name: "All 5 On"
106
+ name: "Link 5 On"
107
107
  telegrams:
108
108
  - E02L05I08M
109
109
  - E02L05I08B
110
110
 
111
111
  "m":
112
- name: "All 5 Off"
112
+ name: "Link 5 Off"
113
113
  telegrams:
114
114
  - E02L05I00M
115
115
  - E02L05I00B
116
116
 
117
117
  "n":
118
- name: "All 6 On"
118
+ name: "Link 6 On"
119
119
  telegrams:
120
120
  - E02L06I08M
121
121
  - E02L06I08B
122
122
 
123
123
  "o":
124
- name: "All 6 Off"
124
+ name: "Link 6 Off"
125
125
  telegrams:
126
126
  - E02L06I00M
127
127
  - E02L06I00B
128
128
 
129
129
  "p":
130
- name: "All 7 On"
130
+ name: "Link 7 On"
131
131
  telegrams:
132
132
  - E02L07I08M
133
133
  - E02L07I08B
134
134
 
135
135
  "q":
136
- name: "All 7 Off"
136
+ name: "Link 7 Off"
137
137
  telegrams:
138
138
  - E02L07I00M
139
139
  - E02L07I00B
@@ -0,0 +1,7 @@
1
+ """TUI widgets package."""
2
+
3
+ from xp.term.widgets.help_menu import HelpMenuWidget
4
+ from xp.term.widgets.protocol_log import ProtocolLogWidget
5
+ from xp.term.widgets.status_footer import StatusFooterWidget
6
+
7
+ __all__ = ["HelpMenuWidget", "ProtocolLogWidget", "StatusFooterWidget"]
@@ -0,0 +1,55 @@
1
+ """Help Menu Widget for displaying keyboard shortcuts and protocol keys."""
2
+
3
+ from typing import Any
4
+
5
+ from textual.app import ComposeResult
6
+ from textual.containers import Vertical
7
+ from textual.widgets import DataTable
8
+
9
+ from xp.models.term import ProtocolKeysConfig
10
+
11
+
12
+ class HelpMenuWidget(Vertical):
13
+ """Help menu widget displaying keyboard shortcuts and protocol keys.
14
+
15
+ Displays a table of available keyboard shortcuts mapped to their
16
+ corresponding protocol commands.
17
+
18
+ Attributes:
19
+ protocol_keys: Configuration of protocol keys and their telegrams.
20
+ help_table: DataTable widget for displaying key mappings.
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ protocol_keys: ProtocolKeysConfig,
26
+ *args: Any,
27
+ **kwargs: Any,
28
+ ) -> None:
29
+ """Initialize the Help Menu widget.
30
+
31
+ Args:
32
+ protocol_keys: Configuration containing protocol key mappings.
33
+ args: Additional positional arguments for Vertical.
34
+ kwargs: Additional keyword arguments for Vertical.
35
+ """
36
+ super().__init__(*args, **kwargs)
37
+ self.protocol_keys = protocol_keys
38
+ self.help_table: DataTable = DataTable(id="help-table", show_header=False)
39
+ self.help_table.can_focus = False
40
+ self.border_title = "Help menu"
41
+ self.can_focus = False
42
+
43
+ def compose(self) -> ComposeResult:
44
+ """Compose the help menu layout.
45
+
46
+ Yields:
47
+ DataTable widget with key mappings.
48
+ """
49
+ yield self.help_table
50
+
51
+ def on_mount(self) -> None:
52
+ """Populate help table when widget mounts."""
53
+ self.help_table.add_columns("Key", "Command")
54
+ for key, config in self.protocol_keys.protocol.items():
55
+ self.help_table.add_row(key, config.name)