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.
- {conson_xp-1.20.0 → conson_xp-1.22.0}/PKG-INFO +32 -17
- {conson_xp-1.20.0 → conson_xp-1.22.0}/README.md +31 -16
- {conson_xp-1.20.0 → conson_xp-1.22.0}/pyproject.toml +2 -2
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/__init__.py +1 -1
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/term/term_commands.py +1 -1
- conson_xp-1.22.0/src/xp/models/term/__init__.py +11 -0
- conson_xp-1.22.0/src/xp/models/term/protocol_keys_config.py +45 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/conbus_event_protocol.py +8 -0
- conson_xp-1.22.0/src/xp/term/protocol.py +127 -0
- conson_xp-1.22.0/src/xp/term/protocol.tcss +135 -0
- conson_xp-1.22.0/src/xp/term/protocol.yml +139 -0
- conson_xp-1.22.0/src/xp/term/widgets/__init__.py +7 -0
- conson_xp-1.22.0/src/xp/term/widgets/help_menu.py +55 -0
- {conson_xp-1.20.0/src/xp/tui → conson_xp-1.22.0/src/xp/term}/widgets/protocol_log.py +157 -76
- conson_xp-1.22.0/src/xp/term/widgets/status_footer.py +53 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/logging.py +16 -5
- conson_xp-1.22.0/src/xp/utils/state_machine.py +81 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_tui/test_protocol_log.py +17 -18
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_logging.py +12 -20
- conson_xp-1.20.0/src/xp/tui/app.py +0 -72
- conson_xp-1.20.0/src/xp/tui/protocol.tcss +0 -50
- conson_xp-1.20.0/src/xp/tui/widgets/__init__.py +0 -1
- {conson_xp-1.20.0 → conson_xp-1.22.0}/LICENSE +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/__main__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_event_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/file_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/module_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/server/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/server/server_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/term/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/commands/term/term.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/main.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/click_tree.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/decorators.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/error_handlers.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/formatters.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/module_type_choice.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/serial_number_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/system_function_choice.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/cli/utils/xp_module_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/connection/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/connection/exceptions.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/actiontable.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_blink.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_custom.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_discover.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_event_list.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_event_raw.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_logger_config.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_output.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_raw.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_receive.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/homekit_config.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/log_entry.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/protocol/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/response.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/action_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/datapoint_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/event_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/event_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/input_action_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/input_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/module_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/module_type_code.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/output_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/reply_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/system_function.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/system_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/telegram_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/telegram/timeparam_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/models/write_config_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_discover_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_event_list_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_event_raw_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/conbus/write_config_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/homekit/homekit_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/log_file_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/module_type_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/protocol_factory.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/reverse_proxy_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/base_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/cp20_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/device_service_factory.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp130_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp20_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp230_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp24_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/server/xp33_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
- {conson_xp-1.20.0/src/xp/tui → conson_xp-1.22.0/src/xp/term}/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/checksum.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/dependencies.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/event_helper.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/serialization.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/src/xp/utils/time_utils.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/.coverage +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/conftest.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/.coverage +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/telegram_test_data.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_actiontable_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_api/.coverage +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_api/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_blink_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_checksum_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_blink_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_raw_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_conbus_receive_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_discovery_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_event_telegram_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_homekit_config_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_link_number_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_module_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_output_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_term_logging_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_version_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_api/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_click_tree.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_decorators.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_formatters.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_cli/test_term_commands.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_connection/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_connection/test_connection_init.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_connection/test_exceptions.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_encoding/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_event_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_log_entry.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_logger_config.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_module_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_system_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_version_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_write_config_type.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_base_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_blink_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_checksum_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_event_list_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_event_raw_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_receive_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_discovery_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_homekit_services.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_log_file_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_module_type_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_protocol.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_server_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_telegram_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_version_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_tui/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/__init__.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_checksum.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_event_helper.py +0 -0
- {conson_xp-1.20.0 → conson_xp-1.22.0}/tests/unit/test_utils/test_serialization.py +0 -0
- {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.
|
|
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
|
[](https://opensource.org/licenses/MIT)
|
|
61
61
|
[](https://mypy-lang.org/)
|
|
62
62
|
|
|
63
|
-
> **A powerful Python CLI
|
|
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
|
-
|
|
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
|
-
### 🌐
|
|
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 →
|
|
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+ •
|
|
425
|
+
**Requirements**: Python 3.10+ • Pydantic • Click • HAP-python
|
|
411
426
|
|
|
412
427
|
## License
|
|
413
428
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
8
|
[](https://mypy-lang.org/)
|
|
9
9
|
|
|
10
|
-
> **A powerful Python CLI
|
|
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
|
-
|
|
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
|
-
### 🌐
|
|
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 →
|
|
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+ •
|
|
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.
|
|
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 = [
|
|
@@ -21,7 +21,7 @@ def protocol_monitor(ctx: Context) -> None:
|
|
|
21
21
|
\b
|
|
22
22
|
xp term protocol
|
|
23
23
|
"""
|
|
24
|
-
from xp.
|
|
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,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
|
+
}
|