conson-xp 1.20.0__tar.gz → 1.22.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.20.0 → conson_xp-1.22.0}/PKG-INFO +32 -17
  2. {conson_xp-1.20.0 → conson_xp-1.22.0}/README.md +31 -16
  3. {conson_xp-1.20.0 → conson_xp-1.22.0}/pyproject.toml +2 -2
  4. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/__init__.py +1 -1
  5. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/term/term_commands.py +1 -1
  6. conson_xp-1.22.0/src/xp/models/term/__init__.py +11 -0
  7. conson_xp-1.22.0/src/xp/models/term/protocol_keys_config.py +45 -0
  8. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/conbus_event_protocol.py +8 -0
  9. conson_xp-1.22.0/src/xp/term/protocol.py +127 -0
  10. conson_xp-1.22.0/src/xp/term/protocol.tcss +135 -0
  11. conson_xp-1.22.0/src/xp/term/protocol.yml +139 -0
  12. conson_xp-1.22.0/src/xp/term/widgets/__init__.py +7 -0
  13. conson_xp-1.22.0/src/xp/term/widgets/help_menu.py +55 -0
  14. {conson_xp-1.20.0/src/xp/tui → conson_xp-1.22.0/src/xp/term}/widgets/protocol_log.py +157 -76
  15. conson_xp-1.22.0/src/xp/term/widgets/status_footer.py +53 -0
  16. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/logging.py +16 -5
  17. conson_xp-1.22.0/src/xp/utils/state_machine.py +81 -0
  18. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_tui/test_protocol_log.py +17 -18
  19. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_logging.py +12 -20
  20. conson_xp-1.20.0/src/xp/tui/app.py +0 -72
  21. conson_xp-1.20.0/src/xp/tui/protocol.tcss +0 -50
  22. conson_xp-1.20.0/src/xp/tui/widgets/__init__.py +0 -1
  23. {conson_xp-1.20.0 → conson_xp-1.22.0}/LICENSE +0 -0
  24. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/__init__.py +0 -0
  25. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/__main__.py +0 -0
  26. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/__init__.py +0 -0
  27. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
  28. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
  29. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
  30. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
  31. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
  32. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
  33. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
  34. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
  35. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
  36. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_event_commands.py +0 -0
  37. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
  38. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
  39. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
  40. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
  41. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
  42. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
  43. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
  44. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
  45. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/file_commands.py +0 -0
  46. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
  47. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
  48. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
  49. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/module_commands.py +0 -0
  50. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
  51. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/server/__init__.py +0 -0
  52. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/server/server_commands.py +0 -0
  53. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
  54. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
  55. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
  56. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
  57. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
  58. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
  59. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
  60. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
  61. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/term/__init__.py +0 -0
  62. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/term/term.py +0 -0
  63. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/main.py +0 -0
  64. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/__init__.py +0 -0
  65. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/click_tree.py +0 -0
  66. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
  67. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/decorators.py +0 -0
  68. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/error_handlers.py +0 -0
  69. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/formatters.py +0 -0
  70. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/module_type_choice.py +0 -0
  71. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/serial_number_type.py +0 -0
  72. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/system_function_choice.py +0 -0
  73. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/xp_module_type.py +0 -0
  74. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/connection/__init__.py +0 -0
  75. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/connection/exceptions.py +0 -0
  76. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/__init__.py +0 -0
  77. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/__init__.py +0 -0
  78. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/actiontable.py +0 -0
  79. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
  80. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
  81. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
  82. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/__init__.py +0 -0
  83. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus.py +0 -0
  84. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
  85. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_blink.py +0 -0
  86. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
  87. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
  88. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_custom.py +0 -0
  89. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
  90. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_discover.py +0 -0
  91. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_event_list.py +0 -0
  92. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_event_raw.py +0 -0
  93. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
  94. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
  95. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_logger_config.py +0 -0
  96. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_output.py +0 -0
  97. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_raw.py +0 -0
  98. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_receive.py +0 -0
  99. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
  100. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/__init__.py +0 -0
  101. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
  102. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/homekit_config.py +0 -0
  103. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
  104. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/log_entry.py +0 -0
  105. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/protocol/__init__.py +0 -0
  106. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
  107. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/response.py +0 -0
  108. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/__init__.py +0 -0
  109. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/action_type.py +0 -0
  110. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/datapoint_type.py +0 -0
  111. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/event_telegram.py +0 -0
  112. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/event_type.py +0 -0
  113. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/input_action_type.py +0 -0
  114. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/input_type.py +0 -0
  115. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/module_type.py +0 -0
  116. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/module_type_code.py +0 -0
  117. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/output_telegram.py +0 -0
  118. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/reply_telegram.py +0 -0
  119. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/system_function.py +0 -0
  120. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/system_telegram.py +0 -0
  121. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/telegram.py +0 -0
  122. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/telegram_type.py +0 -0
  123. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/timeparam_type.py +0 -0
  124. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/write_config_type.py +0 -0
  125. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/__init__.py +0 -0
  126. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/__init__.py +0 -0
  127. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
  128. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
  129. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
  130. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
  131. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
  132. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/__init__.py +0 -0
  133. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
  134. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
  135. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
  136. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
  137. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
  138. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
  139. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
  140. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
  141. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
  142. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
  143. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
  144. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_discover_service.py +0 -0
  145. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_event_list_service.py +0 -0
  146. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_event_raw_service.py +0 -0
  147. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
  148. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
  149. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
  150. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
  151. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/write_config_service.py +0 -0
  152. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/__init__.py +0 -0
  153. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
  154. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
  155. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
  156. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
  157. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
  158. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
  159. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
  160. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
  161. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
  162. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
  163. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
  164. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
  165. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_service.py +0 -0
  166. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/log_file_service.py +0 -0
  167. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/module_type_service.py +0 -0
  168. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/__init__.py +0 -0
  169. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
  170. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/protocol_factory.py +0 -0
  171. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
  172. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/reverse_proxy_service.py +0 -0
  173. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/__init__.py +0 -0
  174. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/base_server_service.py +0 -0
  175. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/cp20_server_service.py +0 -0
  176. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/device_service_factory.py +0 -0
  177. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/server_service.py +0 -0
  178. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp130_server_service.py +0 -0
  179. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp20_server_service.py +0 -0
  180. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp230_server_service.py +0 -0
  181. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp24_server_service.py +0 -0
  182. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp33_server_service.py +0 -0
  183. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/__init__.py +0 -0
  184. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
  185. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
  186. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
  187. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
  188. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
  189. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
  190. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_service.py +0 -0
  191. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
  192. {conson_xp-1.20.0/src/xp/tui → conson_xp-1.22.0/src/xp/term}/__init__.py +0 -0
  193. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/__init__.py +0 -0
  194. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/checksum.py +0 -0
  195. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/dependencies.py +0 -0
  196. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/event_helper.py +0 -0
  197. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/serialization.py +0 -0
  198. {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/time_utils.py +0 -0
  199. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/.coverage +0 -0
  200. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/__init__.py +0 -0
  201. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/conftest.py +0 -0
  202. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/.coverage +0 -0
  203. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/__init__.py +0 -0
  204. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/telegram_test_data.py +0 -0
  205. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_actiontable_integration.py +0 -0
  206. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_api/.coverage +0 -0
  207. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_api/__init__.py +0 -0
  208. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_blink_integration.py +0 -0
  209. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_checksum_integration.py +0 -0
  210. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_blink_integration.py +0 -0
  211. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
  212. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_raw_integration.py +0 -0
  213. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_receive_integration.py +0 -0
  214. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_discovery_integration.py +0 -0
  215. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_event_telegram_integration.py +0 -0
  216. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_homekit_config_integration.py +0 -0
  217. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_link_number_integration.py +0 -0
  218. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_module_integration.py +0 -0
  219. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_output_integration.py +0 -0
  220. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
  221. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
  222. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_term_logging_integration.py +0 -0
  223. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_version_integration.py +0 -0
  224. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
  225. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
  226. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/__init__.py +0 -0
  227. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_api/__init__.py +0 -0
  228. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/__init__.py +0 -0
  229. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_click_tree.py +0 -0
  230. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
  231. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
  232. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
  233. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_decorators.py +0 -0
  234. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
  235. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_formatters.py +0 -0
  236. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
  237. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
  238. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_term_commands.py +0 -0
  239. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_connection/__init__.py +0 -0
  240. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_connection/test_connection_init.py +0 -0
  241. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_connection/test_exceptions.py +0 -0
  242. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_encoding/__init__.py +0 -0
  243. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
  244. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/__init__.py +0 -0
  245. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus.py +0 -0
  246. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
  247. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
  248. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
  249. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_event_telegram.py +0 -0
  250. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_log_entry.py +0 -0
  251. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_logger_config.py +0 -0
  252. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_module_type.py +0 -0
  253. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
  254. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_system_telegram.py +0 -0
  255. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
  256. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_version_telegram.py +0 -0
  257. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_write_config_type.py +0 -0
  258. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
  259. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
  260. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
  261. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/__init__.py +0 -0
  262. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
  263. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
  264. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
  265. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_base_server_service.py +0 -0
  266. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_blink_service.py +0 -0
  267. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_checksum_service.py +0 -0
  268. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
  269. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_event_list_service.py +0 -0
  270. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_event_raw_service.py +0 -0
  271. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
  272. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_receive_service.py +0 -0
  273. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
  274. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
  275. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_discovery_service.py +0 -0
  276. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
  277. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
  278. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
  279. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_services.py +0 -0
  280. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_log_file_service.py +0 -0
  281. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_module_type_service.py +0 -0
  282. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_protocol.py +0 -0
  283. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_server_service.py +0 -0
  284. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
  285. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
  286. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_telegram_service.py +0 -0
  287. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_version_service.py +0 -0
  288. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
  289. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
  290. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
  291. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
  292. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
  293. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
  294. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_tui/__init__.py +0 -0
  295. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/__init__.py +0 -0
  296. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_checksum.py +0 -0
  297. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_event_helper.py +0 -0
  298. {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_serialization.py +0 -0
  299. {conson_xp-1.20.0 → conson_xp-1.22.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.20.0
3
+ Version: 1.22.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.20.0"
25
+ version = "1.22.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.20.0"
6
+ __version__ = "1.22.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.tui.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,11 @@
1
+ """Terminal UI models."""
2
+
3
+ from xp.models.term.protocol_keys_config import (
4
+ ProtocolKeyConfig,
5
+ ProtocolKeysConfig,
6
+ )
7
+
8
+ __all__ = [
9
+ "ProtocolKeyConfig",
10
+ "ProtocolKeysConfig",
11
+ ]
@@ -0,0 +1,45 @@
1
+ """Protocol keys configuration model."""
2
+
3
+ from pathlib import Path
4
+ from typing import Dict
5
+
6
+ import yaml
7
+ from pydantic import BaseModel, Field
8
+
9
+
10
+ class ProtocolKeyConfig(BaseModel):
11
+ """Configuration for a single protocol key.
12
+
13
+ Attributes:
14
+ name: Human-readable command name.
15
+ telegrams: List of raw telegram strings to send (without angle brackets).
16
+ """
17
+
18
+ name: str = Field(..., description="Human-readable command name")
19
+ telegrams: list[str] = Field(..., description="List of raw telegram strings")
20
+
21
+
22
+ class ProtocolKeysConfig(BaseModel):
23
+ """Protocol keys configuration.
24
+
25
+ Attributes:
26
+ protocol: Dictionary mapping key to protocol configuration.
27
+ """
28
+
29
+ protocol: Dict[str, ProtocolKeyConfig] = Field(
30
+ default_factory=dict, description="Protocol key mappings"
31
+ )
32
+
33
+ @classmethod
34
+ def from_yaml(cls, config_path: Path) -> "ProtocolKeysConfig":
35
+ """Load protocol keys from YAML file.
36
+
37
+ Args:
38
+ config_path: Path to YAML configuration file.
39
+
40
+ Returns:
41
+ ProtocolKeysConfig instance.
42
+ """
43
+ with config_path.open("r") as f:
44
+ data = yaml.safe_load(f)
45
+ return cls(**data)
@@ -209,6 +209,14 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
209
209
  f"F{system_function.value}"
210
210
  f"D{data_value}"
211
211
  )
212
+ self.send_raw_telegram(payload)
213
+
214
+ def send_raw_telegram(self, payload: str) -> None:
215
+ """Send telegram with specified parameters.
216
+
217
+ Args:
218
+ payload: Telegram to send.
219
+ """
212
220
  self.telegram_queue.put_nowait(payload.encode())
213
221
  self.call_later(0.0, self.start_queue_manager)
214
222
 
@@ -0,0 +1,127 @@
1
+ """Protocol Monitor TUI Application."""
2
+
3
+ from pathlib import Path
4
+ from typing import Any, Optional
5
+
6
+ from textual.app import App, ComposeResult
7
+ from textual.containers import Horizontal
8
+
9
+ from xp.models.term import ProtocolKeysConfig
10
+ from xp.term.widgets.help_menu import HelpMenuWidget
11
+ from xp.term.widgets.protocol_log import ProtocolLogWidget
12
+ from xp.term.widgets.status_footer import StatusFooterWidget
13
+
14
+
15
+ class ProtocolMonitorApp(App[None]):
16
+ """Textual app for real-time protocol monitoring.
17
+
18
+ Displays live RX/TX telegram stream from Conbus server in an interactive
19
+ terminal interface with keyboard shortcuts for control.
20
+
21
+ Attributes:
22
+ container: ServiceContainer for dependency injection.
23
+ CSS_PATH: Path to CSS stylesheet file.
24
+ BINDINGS: Keyboard bindings for app actions.
25
+ TITLE: Application title displayed in header.
26
+ ENABLE_COMMAND_PALETTE: Disable Textual's command palette feature.
27
+ """
28
+
29
+ CSS_PATH = Path(__file__).parent / "protocol.tcss"
30
+ TITLE = "Protocol Monitor"
31
+ ENABLE_COMMAND_PALETTE = False
32
+
33
+ BINDINGS = [
34
+ ("Q", "quit", "Quit"),
35
+ ("C", "toggle_connection", "Connect"),
36
+ ("R", "reset", "Reset"),
37
+ ("0-9,a-q", "protocol_keys", "Keys"),
38
+ ]
39
+
40
+ def __init__(self, container: Any) -> None:
41
+ """Initialize the Protocol Monitor app.
42
+
43
+ Args:
44
+ container: ServiceContainer for resolving services.
45
+ """
46
+ super().__init__()
47
+ self.container = container
48
+ self.protocol_widget: Optional[ProtocolLogWidget] = None
49
+ self.help_menu: Optional[HelpMenuWidget] = None
50
+ self.footer_widget: Optional[StatusFooterWidget] = None
51
+ self.protocol_keys = self._load_protocol_keys()
52
+
53
+ def _load_protocol_keys(self) -> ProtocolKeysConfig:
54
+ """Load protocol keys from YAML config file.
55
+
56
+ Returns:
57
+ ProtocolKeysConfig instance.
58
+ """
59
+ config_path = Path(__file__).parent / "protocol.yml"
60
+ return ProtocolKeysConfig.from_yaml(config_path)
61
+
62
+ def compose(self) -> ComposeResult:
63
+ """Compose the app layout with widgets.
64
+
65
+ Yields:
66
+ ProtocolLogWidget and Footer widgets.
67
+ """
68
+ with Horizontal(id="main-container"):
69
+ self.protocol_widget = ProtocolLogWidget(container=self.container)
70
+ yield self.protocol_widget
71
+
72
+ # Help menu (hidden by default)
73
+ self.help_menu = HelpMenuWidget(
74
+ protocol_keys=self.protocol_keys, id="help-menu"
75
+ )
76
+ yield self.help_menu
77
+
78
+ self.footer_widget = StatusFooterWidget(id="footer-container")
79
+ yield self.footer_widget
80
+
81
+ def action_toggle_connection(self) -> None:
82
+ """Toggle connection on 'c' key press.
83
+
84
+ Connects if disconnected/failed, disconnects if connected/connecting.
85
+ """
86
+ if self.protocol_widget:
87
+ from xp.term.widgets.protocol_log import ConnectionState
88
+
89
+ state = self.protocol_widget.connection_state
90
+ if state in (ConnectionState.CONNECTED, ConnectionState.CONNECTING):
91
+ self.protocol_widget.disconnect()
92
+ else:
93
+ self.protocol_widget.connect()
94
+
95
+ def action_reset(self) -> None:
96
+ """Reset and clear protocol widget on 'r' key press."""
97
+ if self.protocol_widget:
98
+ self.protocol_widget.clear_log()
99
+
100
+ def on_key(self, event: Any) -> None:
101
+ """Handle key press events for protocol keys.
102
+
103
+ Args:
104
+ event: Key press event from Textual.
105
+ """
106
+ if event.key in self.protocol_keys.protocol and self.protocol_widget:
107
+ key_config = self.protocol_keys.protocol[event.key]
108
+ for telegram in key_config.telegrams:
109
+ self.protocol_widget.send_telegram(key_config.name, telegram)
110
+
111
+ def on_mount(self) -> None:
112
+ """Set up status line updates when app mounts."""
113
+ if self.protocol_widget:
114
+ self.protocol_widget.watch(
115
+ self.protocol_widget,
116
+ "connection_state",
117
+ self._update_status,
118
+ )
119
+
120
+ def _update_status(self, state: Any) -> None:
121
+ """Update status line with connection state.
122
+
123
+ Args:
124
+ state: Current connection state.
125
+ """
126
+ if self.footer_widget:
127
+ self.footer_widget.update_status(state)
@@ -0,0 +1,135 @@
1
+ /* Protocol Monitor TUI Styling */
2
+
3
+ /* App-level styling */
4
+ Screen {
5
+ background: $background;
6
+ }
7
+
8
+ /* Protocol Log Widget */
9
+ ProtocolLogWidget {
10
+ border: solid $success;
11
+ width: 1fr;
12
+ height: 1fr;
13
+ background: $background;
14
+ padding: 1;
15
+ }
16
+
17
+ ProtocolLogWidget > RichLog {
18
+ background: $background !important;
19
+ scrollbar-background: $background;
20
+ }
21
+
22
+ ProtocolLogWidget > RichLog:focus {
23
+ background: $background !important;
24
+ background-tint: transparent;
25
+ }
26
+
27
+ ProtocolLogWidget > .connection-status {
28
+ color: $text;
29
+ text-align: center;
30
+ padding: 1;
31
+ }
32
+
33
+ ProtocolLogWidget > .connection-status.connecting {
34
+ color: $warning;
35
+ }
36
+
37
+ ProtocolLogWidget > .connection-status.connected {
38
+ color: $success;
39
+ }
40
+
41
+ ProtocolLogWidget > .connection-status.failed {
42
+ color: $error;
43
+ }
44
+
45
+ /* Message display styling */
46
+ .message-tx {
47
+ color: $success;
48
+ }
49
+
50
+ .message-rx {
51
+ color: $success;
52
+ }
53
+
54
+ .message-frame {
55
+ color: $text-muted;
56
+ }
57
+
58
+ /* Main container */
59
+ #main-container {
60
+ height: 1fr;
61
+ }
62
+
63
+ /* Help menu styling */
64
+ #help-menu {
65
+ width: 35;
66
+ height: 1fr;
67
+ background: $background;
68
+ border: solid $success;
69
+ padding: 1;
70
+ }
71
+
72
+ #help-menu:focus {
73
+ border: solid $success;
74
+ }
75
+
76
+ #help-title {
77
+ color: $success;
78
+ text-align: center;
79
+ text-style: bold;
80
+ margin-bottom: 1;
81
+ }
82
+
83
+ #help-table {
84
+ background: $background;
85
+ height: auto;
86
+ color: $success;
87
+ }
88
+
89
+ DataTable {
90
+ background: $background;
91
+ }
92
+
93
+ DataTable > .datatable--header {
94
+ background: $background;
95
+ color: $success;
96
+ }
97
+
98
+ DataTable > .datatable--cursor {
99
+ background: $background;
100
+ }
101
+
102
+ DataTable:focus > .datatable--cursor {
103
+ background: $background;
104
+ }
105
+
106
+ /* Footer styling */
107
+ #footer-container {
108
+ dock: bottom;
109
+ height: 1;
110
+ background: $background;
111
+ }
112
+
113
+ Footer {
114
+ width: auto;
115
+ background: $background;
116
+ color: $text;
117
+ }
118
+
119
+ #status-text {
120
+ dock: right;
121
+ width: auto;
122
+ padding: 0 1;
123
+ background: $background;
124
+ color: $text;
125
+ text-align: right;
126
+ }
127
+
128
+ #status-line {
129
+ dock: right;
130
+ width: auto;
131
+ padding: 0 1;
132
+ background: $background;
133
+ color: $text;
134
+ text-align: right;
135
+ }