conson-xp 1.22.0__tar.gz → 1.24.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.22.0 → conson_xp-1.24.0}/PKG-INFO +1 -1
- {conson_xp-1.22.0 → conson_xp-1.24.0}/pyproject.toml +1 -1
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/__init__.py +1 -1
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +7 -2
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +5 -2
- conson_xp-1.24.0/src/xp/models/term/connection_state.py +58 -0
- conson_xp-1.24.0/src/xp/models/term/status_message.py +16 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_discover_service.py +61 -53
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_receive_service.py +30 -25
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/protocol/conbus_event_protocol.py +19 -6
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/protocol.py +10 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/protocol.tcss +1 -1
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/protocol.yml +14 -14
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/widgets/protocol_log.py +39 -123
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/widgets/status_footer.py +10 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_receive_service.py +22 -43
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_tui/test_protocol_log.py +0 -1
- {conson_xp-1.22.0 → conson_xp-1.24.0}/LICENSE +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/README.md +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/__main__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_event_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/file_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/module_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/server/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/server/server_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/term/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/term/term.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/term/term_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/main.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/click_tree.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/decorators.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/error_handlers.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/formatters.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/module_type_choice.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/serial_number_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/system_function_choice.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/utils/xp_module_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/connection/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/connection/exceptions.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/actiontable/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/actiontable/actiontable.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_blink.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_custom.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_discover.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_event_list.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_event_raw.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_logger_config.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_output.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_raw.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_receive.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/homekit/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/homekit/homekit_config.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/log_entry.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/protocol/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/response.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/action_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/datapoint_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/event_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/event_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/input_action_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/input_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/module_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/module_type_code.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/output_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/reply_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/system_function.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/system_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/telegram_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/telegram/timeparam_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/term/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/term/protocol_keys_config.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/models/write_config_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/actiontable/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_event_list_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_event_raw_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/conbus/write_config_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/log_file_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/module_type_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/protocol/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/protocol/protocol_factory.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/reverse_proxy_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/base_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/cp20_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/device_service_factory.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/xp130_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/xp20_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/xp230_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/xp24_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/server/xp33_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/widgets/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/term/widgets/help_menu.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/checksum.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/dependencies.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/event_helper.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/logging.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/serialization.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/state_machine.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/utils/time_utils.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/.coverage +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/conftest.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/.coverage +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/telegram_test_data.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_actiontable_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_api/.coverage +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_api/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_blink_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_checksum_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_conbus_blink_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_conbus_raw_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_conbus_receive_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_discovery_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_event_telegram_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_homekit_config_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_link_number_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_module_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_output_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_term_logging_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_version_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_api/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_click_tree.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_decorators.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_formatters.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_term_commands.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_connection/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_connection/test_connection_init.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_connection/test_exceptions.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_encoding/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_event_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_log_entry.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_logger_config.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_module_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_system_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_version_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_write_config_type.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_base_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_blink_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_checksum_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_event_list_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_event_raw_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_discovery_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_services.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_log_file_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_module_type_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_protocol.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_server_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_telegram_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_version_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_tui/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_utils/__init__.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_checksum.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_event_helper.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_logging.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_serialization.py +0 -0
- {conson_xp-1.22.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_time_utils.py +0 -0
{conson_xp-1.22.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py
RENAMED
|
@@ -36,6 +36,7 @@ def send_discover_telegram(ctx: click.Context) -> None:
|
|
|
36
36
|
discovered_devices: Discover response with all found devices.
|
|
37
37
|
"""
|
|
38
38
|
click.echo(json.dumps(discovered_devices.to_dict(), indent=2))
|
|
39
|
+
service.stop_reactor()
|
|
39
40
|
|
|
40
41
|
def on_device_discovered(discovered_device: DiscoveredDevice) -> None:
|
|
41
42
|
"""Handle discovery of sa single module.
|
|
@@ -57,5 +58,9 @@ def send_discover_telegram(ctx: click.Context) -> None:
|
|
|
57
58
|
service: ConbusDiscoverService = (
|
|
58
59
|
ctx.obj.get("container").get_container().resolve(ConbusDiscoverService)
|
|
59
60
|
)
|
|
60
|
-
service
|
|
61
|
-
|
|
61
|
+
with service:
|
|
62
|
+
service.on_progress.connect(progress)
|
|
63
|
+
service.on_device_discovered.connect(on_device_discovered)
|
|
64
|
+
service.on_finish.connect(on_finish)
|
|
65
|
+
service.set_timeout(5)
|
|
66
|
+
service.start_reactor()
|
|
@@ -43,8 +43,9 @@ def receive_telegrams(ctx: Context, timeout: float) -> None:
|
|
|
43
43
|
response_received: Receive response object with telegrams.
|
|
44
44
|
"""
|
|
45
45
|
click.echo(json.dumps(response_received.to_dict(), indent=2))
|
|
46
|
+
service.stop_reactor()
|
|
46
47
|
|
|
47
|
-
def
|
|
48
|
+
def on_progress(telegram_received: str) -> None:
|
|
48
49
|
"""Handle progress updates during telegram receive operation.
|
|
49
50
|
|
|
50
51
|
Args:
|
|
@@ -56,5 +57,7 @@ def receive_telegrams(ctx: Context, timeout: float) -> None:
|
|
|
56
57
|
ctx.obj.get("container").get_container().resolve(ConbusReceiveService)
|
|
57
58
|
)
|
|
58
59
|
with service:
|
|
59
|
-
service.
|
|
60
|
+
service.on_progress.connect(on_progress)
|
|
61
|
+
service.on_finish.connect(on_finish)
|
|
62
|
+
service.set_timeout(timeout)
|
|
60
63
|
service.start_reactor()
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Connection state management module."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
from xp.utils.state_machine import StateMachine
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ConnectionState(str, Enum):
|
|
9
|
+
"""Connection state enumeration.
|
|
10
|
+
|
|
11
|
+
Attributes:
|
|
12
|
+
DISCONNECTING: Disconnecting to server.
|
|
13
|
+
DISCONNECTED: Not connected to server.
|
|
14
|
+
CONNECTING: Connection in progress.
|
|
15
|
+
CONNECTED: Successfully connected.
|
|
16
|
+
FAILED: Connection failed.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
DISCONNECTING = "DISCONNECTING"
|
|
20
|
+
DISCONNECTED = "DISCONNECTED"
|
|
21
|
+
CONNECTING = "CONNECTING"
|
|
22
|
+
CONNECTED = "CONNECTED"
|
|
23
|
+
FAILED = "FAILED"
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def create_state_machine() -> StateMachine:
|
|
27
|
+
"""Create and configure state machine for connection management.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
Configured StateMachine with connection state transitions.
|
|
31
|
+
"""
|
|
32
|
+
sm = StateMachine(ConnectionState.DISCONNECTED)
|
|
33
|
+
|
|
34
|
+
# Define valid transitions
|
|
35
|
+
sm.define_transition(
|
|
36
|
+
"connect", {ConnectionState.DISCONNECTED, ConnectionState.FAILED}
|
|
37
|
+
)
|
|
38
|
+
sm.define_transition(
|
|
39
|
+
"disconnect", {ConnectionState.CONNECTED, ConnectionState.CONNECTING}
|
|
40
|
+
)
|
|
41
|
+
sm.define_transition(
|
|
42
|
+
"connecting", {ConnectionState.DISCONNECTED, ConnectionState.FAILED}
|
|
43
|
+
)
|
|
44
|
+
sm.define_transition("connected", {ConnectionState.CONNECTING})
|
|
45
|
+
sm.define_transition(
|
|
46
|
+
"disconnecting", {ConnectionState.CONNECTED, ConnectionState.CONNECTING}
|
|
47
|
+
)
|
|
48
|
+
sm.define_transition("disconnected", {ConnectionState.DISCONNECTING})
|
|
49
|
+
sm.define_transition(
|
|
50
|
+
"failed",
|
|
51
|
+
{
|
|
52
|
+
ConnectionState.CONNECTING,
|
|
53
|
+
ConnectionState.CONNECTED,
|
|
54
|
+
ConnectionState.DISCONNECTING,
|
|
55
|
+
},
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return sm
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Status message models for terminal UI."""
|
|
2
|
+
|
|
3
|
+
from textual.message import Message
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class StatusMessageChanged(Message):
|
|
7
|
+
"""Message posted when status message changes."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, message: str) -> None:
|
|
10
|
+
"""Initialize the message.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
message: The status message to display.
|
|
14
|
+
"""
|
|
15
|
+
super().__init__()
|
|
16
|
+
self.message = message
|
|
@@ -4,8 +4,11 @@ This service implements a TCP client that connects to Conbus servers and sends
|
|
|
4
4
|
discover telegrams to find modules on the network.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import asyncio
|
|
7
8
|
import logging
|
|
8
|
-
from typing import
|
|
9
|
+
from typing import Any, Optional
|
|
10
|
+
|
|
11
|
+
from psygnal import Signal
|
|
9
12
|
|
|
10
13
|
from xp.models import ConbusDiscoverResponse
|
|
11
14
|
from xp.models.conbus.conbus_discover import DiscoveredDevice
|
|
@@ -26,9 +29,15 @@ class ConbusDiscoverService:
|
|
|
26
29
|
|
|
27
30
|
Attributes:
|
|
28
31
|
conbus_protocol: Protocol instance for Conbus communication.
|
|
32
|
+
on_progress: Signal emitted when discovery progress is made (with serial number).
|
|
33
|
+
on_finish: Signal emitted when discovery finishes (with result).
|
|
34
|
+
on_device_discovered: Signal emitted when a device is discovered (with device info).
|
|
29
35
|
"""
|
|
30
36
|
|
|
31
37
|
conbus_protocol: ConbusEventProtocol
|
|
38
|
+
on_progress: Signal = Signal(str)
|
|
39
|
+
on_finish: Signal = Signal(DiscoveredDevice)
|
|
40
|
+
on_device_discovered: Signal = Signal(ConbusDiscoverResponse)
|
|
32
41
|
|
|
33
42
|
def __init__(self, conbus_protocol: ConbusEventProtocol) -> None:
|
|
34
43
|
"""Initialize the Conbus discover service.
|
|
@@ -36,12 +45,6 @@ class ConbusDiscoverService:
|
|
|
36
45
|
Args:
|
|
37
46
|
conbus_protocol: ConbusProtocol.
|
|
38
47
|
"""
|
|
39
|
-
self.progress_callback: Optional[Callable[[str], None]] = None
|
|
40
|
-
self.device_discover_callback: Optional[Callable[[DiscoveredDevice], None]] = (
|
|
41
|
-
None
|
|
42
|
-
)
|
|
43
|
-
self.finish_callback: Optional[Callable[[ConbusDiscoverResponse], None]] = None
|
|
44
|
-
|
|
45
48
|
self.conbus_protocol: ConbusEventProtocol = conbus_protocol
|
|
46
49
|
self.conbus_protocol.on_connection_made.connect(self.connection_made)
|
|
47
50
|
self.conbus_protocol.on_telegram_sent.connect(self.telegram_sent)
|
|
@@ -135,9 +138,7 @@ class ConbusDiscoverService:
|
|
|
135
138
|
"module_type_name": None,
|
|
136
139
|
}
|
|
137
140
|
self.discovered_device_result.discovered_devices.append(device)
|
|
138
|
-
|
|
139
|
-
if self.device_discover_callback:
|
|
140
|
-
self.device_discover_callback(device)
|
|
141
|
+
self.on_device_discovered.emit(device)
|
|
141
142
|
|
|
142
143
|
# Send READ_DATAPOINT telegram to query module type
|
|
143
144
|
self.logger.debug(f"Sending module type query for {serial_number}")
|
|
@@ -147,8 +148,7 @@ class ConbusDiscoverService:
|
|
|
147
148
|
system_function=SystemFunction.READ_DATAPOINT,
|
|
148
149
|
data_value=DataPointType.MODULE_TYPE.value,
|
|
149
150
|
)
|
|
150
|
-
|
|
151
|
-
self.progress_callback(serial_number)
|
|
151
|
+
self.on_progress.emit(serial_number)
|
|
152
152
|
|
|
153
153
|
def handle_module_type_code_response(
|
|
154
154
|
self, serial_number: str, module_type_code: str
|
|
@@ -194,8 +194,7 @@ class ConbusDiscoverService:
|
|
|
194
194
|
device["module_type_code"] = code
|
|
195
195
|
device["module_type_name"] = module_type_name
|
|
196
196
|
|
|
197
|
-
|
|
198
|
-
self.device_discover_callback(device)
|
|
197
|
+
self.on_device_discovered.emit(device)
|
|
199
198
|
|
|
200
199
|
self.logger.debug(
|
|
201
200
|
f"Updated device {serial_number} with module_type {module_type_name}"
|
|
@@ -231,9 +230,7 @@ class ConbusDiscoverService:
|
|
|
231
230
|
self.logger.debug(
|
|
232
231
|
f"Updated device {serial_number} with module_type {module_type}"
|
|
233
232
|
)
|
|
234
|
-
|
|
235
|
-
self.device_discover_callback(device)
|
|
236
|
-
|
|
233
|
+
self.on_device_discovered.emit(device)
|
|
237
234
|
break
|
|
238
235
|
|
|
239
236
|
self.conbus_protocol.send_telegram(
|
|
@@ -249,10 +246,7 @@ class ConbusDiscoverService:
|
|
|
249
246
|
self.logger.info("Discovery stopped after: %ss", timeout)
|
|
250
247
|
self.discovered_device_result.success = False
|
|
251
248
|
self.discovered_device_result.error = "Discovered device timeout"
|
|
252
|
-
|
|
253
|
-
self.finish_callback(self.discovered_device_result)
|
|
254
|
-
|
|
255
|
-
self.stop_reactor()
|
|
249
|
+
self.on_finish.emit(self.discovered_device_result)
|
|
256
250
|
|
|
257
251
|
def failed(self, message: str) -> None:
|
|
258
252
|
"""Handle failed connection event.
|
|
@@ -263,50 +257,64 @@ class ConbusDiscoverService:
|
|
|
263
257
|
self.logger.debug(f"Failed: {message}")
|
|
264
258
|
self.discovered_device_result.success = False
|
|
265
259
|
self.discovered_device_result.error = message
|
|
266
|
-
|
|
267
|
-
self.finish_callback(self.discovered_device_result)
|
|
268
|
-
|
|
269
|
-
self.stop_reactor()
|
|
260
|
+
self.on_finish.emit(self.discovered_device_result)
|
|
270
261
|
|
|
271
262
|
def succeed(self) -> None:
|
|
272
263
|
"""Handle discovered device success event."""
|
|
273
264
|
self.logger.debug("Succeed")
|
|
274
265
|
self.discovered_device_result.success = True
|
|
275
266
|
self.discovered_device_result.error = None
|
|
276
|
-
|
|
277
|
-
self.finish_callback(self.discovered_device_result)
|
|
267
|
+
self.on_finish.emit(self.discovered_device_result)
|
|
278
268
|
|
|
279
|
-
|
|
269
|
+
def set_timeout(self, timeout_seconds: float) -> None:
|
|
270
|
+
"""Setup callbacks and timeout for receiving telegrams.
|
|
280
271
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
self.
|
|
285
|
-
|
|
286
|
-
def start_reactor(self) -> None:
|
|
287
|
-
"""Start reactor."""
|
|
288
|
-
self.logger.info("Starting reactor")
|
|
289
|
-
self.conbus_protocol.start_reactor()
|
|
272
|
+
Args:
|
|
273
|
+
timeout_seconds: Optional timeout in seconds.
|
|
274
|
+
"""
|
|
275
|
+
self.logger.debug("Set timeout")
|
|
276
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
290
277
|
|
|
291
|
-
def
|
|
278
|
+
def set_event_loop(
|
|
292
279
|
self,
|
|
293
|
-
|
|
294
|
-
device_discover_callback: Callable[[DiscoveredDevice], None],
|
|
295
|
-
finish_callback: Callable[[ConbusDiscoverResponse], None],
|
|
296
|
-
timeout_seconds: Optional[float] = None,
|
|
280
|
+
event_loop: asyncio.AbstractEventLoop,
|
|
297
281
|
) -> None:
|
|
298
|
-
"""
|
|
282
|
+
"""Setup callbacks and timeout for receiving telegrams.
|
|
299
283
|
|
|
300
284
|
Args:
|
|
301
|
-
|
|
302
|
-
device_discover_callback: Callback for each discovered device.
|
|
303
|
-
finish_callback: Callback when discovery completes.
|
|
304
|
-
timeout_seconds: Optional timeout in seconds.
|
|
285
|
+
event_loop: Optional event loop to use for async operations.
|
|
305
286
|
"""
|
|
306
|
-
self.logger.
|
|
287
|
+
self.logger.debug("Set eventloop")
|
|
288
|
+
self.conbus_protocol.set_event_loop(event_loop)
|
|
307
289
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
self.
|
|
311
|
-
|
|
312
|
-
|
|
290
|
+
def start_reactor(self) -> None:
|
|
291
|
+
"""Start the reactor."""
|
|
292
|
+
self.conbus_protocol.start_reactor()
|
|
293
|
+
|
|
294
|
+
def stop_reactor(self) -> None:
|
|
295
|
+
"""Start the reactor."""
|
|
296
|
+
self.conbus_protocol.stop_reactor()
|
|
297
|
+
|
|
298
|
+
def __enter__(self) -> "ConbusDiscoverService":
|
|
299
|
+
"""Enter context manager.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Self for context manager protocol.
|
|
303
|
+
"""
|
|
304
|
+
# Reset state for singleton reuse
|
|
305
|
+
self.receive_response = ConbusDiscoverResponse(success=True)
|
|
306
|
+
return self
|
|
307
|
+
|
|
308
|
+
def __exit__(
|
|
309
|
+
self, _exc_type: Optional[type], _exc_val: Optional[Exception], _exc_tb: Any
|
|
310
|
+
) -> None:
|
|
311
|
+
"""Exit context manager and disconnect signals."""
|
|
312
|
+
self.conbus_protocol.on_connection_made.disconnect(self.connection_made)
|
|
313
|
+
self.conbus_protocol.on_telegram_sent.disconnect(self.telegram_sent)
|
|
314
|
+
self.conbus_protocol.on_telegram_received.disconnect(self.telegram_received)
|
|
315
|
+
self.conbus_protocol.on_timeout.disconnect(self.timeout)
|
|
316
|
+
self.conbus_protocol.on_failed.disconnect(self.failed)
|
|
317
|
+
self.on_device_discovered.disconnect()
|
|
318
|
+
self.on_progress.disconnect()
|
|
319
|
+
self.on_finish.disconnect()
|
|
320
|
+
self.stop_reactor()
|
|
@@ -6,7 +6,9 @@ allowing clients to receive waiting event telegrams using empty telegram sends.
|
|
|
6
6
|
|
|
7
7
|
import asyncio
|
|
8
8
|
import logging
|
|
9
|
-
from typing import Any,
|
|
9
|
+
from typing import Any, Optional
|
|
10
|
+
|
|
11
|
+
from psygnal import Signal
|
|
10
12
|
|
|
11
13
|
from xp.models.conbus.conbus_receive import ConbusReceiveResponse
|
|
12
14
|
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
@@ -22,9 +24,13 @@ class ConbusReceiveService:
|
|
|
22
24
|
|
|
23
25
|
Attributes:
|
|
24
26
|
conbus_protocol: Protocol instance for Conbus communication.
|
|
27
|
+
on_progress: Signal emitted when a telegram is received (with telegram frame).
|
|
28
|
+
on_finish: Signal emitted when receiving finishes (with result).
|
|
25
29
|
"""
|
|
26
30
|
|
|
27
31
|
conbus_protocol: ConbusEventProtocol
|
|
32
|
+
on_progress: Signal = Signal(str)
|
|
33
|
+
on_finish: Signal = Signal(ConbusReceiveResponse)
|
|
28
34
|
|
|
29
35
|
def __init__(self, conbus_protocol: ConbusEventProtocol) -> None:
|
|
30
36
|
"""Initialize the Conbus receive service.
|
|
@@ -32,8 +38,6 @@ class ConbusReceiveService:
|
|
|
32
38
|
Args:
|
|
33
39
|
conbus_protocol: ConbusEventProtocol instance.
|
|
34
40
|
"""
|
|
35
|
-
self.progress_callback: Optional[Callable[[str], None]] = None
|
|
36
|
-
self.finish_callback: Optional[Callable[[ConbusReceiveResponse], None]] = None
|
|
37
41
|
self.receive_response: ConbusReceiveResponse = ConbusReceiveResponse(
|
|
38
42
|
success=True
|
|
39
43
|
)
|
|
@@ -67,8 +71,7 @@ class ConbusReceiveService:
|
|
|
67
71
|
telegram_received: The telegram received event.
|
|
68
72
|
"""
|
|
69
73
|
self.logger.debug(f"Telegram received: {telegram_received}")
|
|
70
|
-
|
|
71
|
-
self.progress_callback(telegram_received.frame)
|
|
74
|
+
self.on_progress.emit(telegram_received.frame)
|
|
72
75
|
|
|
73
76
|
if not self.receive_response.received_telegrams:
|
|
74
77
|
self.receive_response.received_telegrams = []
|
|
@@ -79,8 +82,7 @@ class ConbusReceiveService:
|
|
|
79
82
|
timeout = self.conbus_protocol.timeout_seconds
|
|
80
83
|
self.logger.info("Receive stopped after: %ss", timeout)
|
|
81
84
|
self.receive_response.success = True
|
|
82
|
-
|
|
83
|
-
self.finish_callback(self.receive_response)
|
|
85
|
+
self.on_finish.emit(self.receive_response)
|
|
84
86
|
|
|
85
87
|
def failed(self, message: str) -> None:
|
|
86
88
|
"""Handle failed connection event.
|
|
@@ -91,37 +93,37 @@ class ConbusReceiveService:
|
|
|
91
93
|
self.logger.debug("Failed %s:", message)
|
|
92
94
|
self.receive_response.success = False
|
|
93
95
|
self.receive_response.error = message
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
self.on_finish.emit(self.receive_response)
|
|
97
|
+
|
|
98
|
+
def set_timeout(self, timeout_seconds: float) -> None:
|
|
99
|
+
"""Setup callbacks and timeout for receiving telegrams.
|
|
96
100
|
|
|
97
|
-
|
|
101
|
+
Args:
|
|
102
|
+
timeout_seconds: Optional timeout in seconds.
|
|
103
|
+
"""
|
|
104
|
+
self.logger.debug("Set timeout")
|
|
105
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
106
|
+
|
|
107
|
+
def set_event_loop(
|
|
98
108
|
self,
|
|
99
|
-
|
|
100
|
-
finish_callback: Callable[[ConbusReceiveResponse], None],
|
|
101
|
-
timeout_seconds: Optional[float] = None,
|
|
102
|
-
event_loop: Optional[asyncio.AbstractEventLoop] = None,
|
|
109
|
+
event_loop: asyncio.AbstractEventLoop,
|
|
103
110
|
) -> None:
|
|
104
111
|
"""Setup callbacks and timeout for receiving telegrams.
|
|
105
112
|
|
|
106
113
|
Args:
|
|
107
|
-
progress_callback: Callback for each received telegram.
|
|
108
|
-
finish_callback: Callback when receiving completes.
|
|
109
|
-
timeout_seconds: Optional timeout in seconds.
|
|
110
114
|
event_loop: Optional event loop to use for async operations.
|
|
111
115
|
"""
|
|
112
|
-
self.logger.
|
|
113
|
-
|
|
114
|
-
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
115
|
-
self.progress_callback = progress_callback
|
|
116
|
-
self.finish_callback = finish_callback
|
|
117
|
-
|
|
118
|
-
if event_loop:
|
|
119
|
-
self.conbus_protocol.set_event_loop(event_loop)
|
|
116
|
+
self.logger.debug("Set eventloop")
|
|
117
|
+
self.conbus_protocol.set_event_loop(event_loop)
|
|
120
118
|
|
|
121
119
|
def start_reactor(self) -> None:
|
|
122
120
|
"""Start the reactor."""
|
|
123
121
|
self.conbus_protocol.start_reactor()
|
|
124
122
|
|
|
123
|
+
def stop_reactor(self) -> None:
|
|
124
|
+
"""Start the reactor."""
|
|
125
|
+
self.conbus_protocol.stop_reactor()
|
|
126
|
+
|
|
125
127
|
def __enter__(self) -> "ConbusReceiveService":
|
|
126
128
|
"""Enter context manager.
|
|
127
129
|
|
|
@@ -141,3 +143,6 @@ class ConbusReceiveService:
|
|
|
141
143
|
self.conbus_protocol.on_telegram_received.disconnect(self.telegram_received)
|
|
142
144
|
self.conbus_protocol.on_timeout.disconnect(self.timeout)
|
|
143
145
|
self.conbus_protocol.on_failed.disconnect(self.failed)
|
|
146
|
+
self.on_progress.disconnect()
|
|
147
|
+
self.on_finish.disconnect()
|
|
148
|
+
self.stop_reactor()
|
|
@@ -17,7 +17,7 @@ from twisted.internet.interfaces import IAddress, IConnector
|
|
|
17
17
|
from twisted.internet.posixbase import PosixReactorBase
|
|
18
18
|
from twisted.python.failure import Failure
|
|
19
19
|
|
|
20
|
-
from xp.models import ConbusClientConfig
|
|
20
|
+
from xp.models import ConbusClientConfig, ModuleTypeCode
|
|
21
21
|
from xp.models.protocol.conbus_protocol import (
|
|
22
22
|
TelegramReceivedEvent,
|
|
23
23
|
)
|
|
@@ -168,9 +168,6 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
168
168
|
|
|
169
169
|
Args:
|
|
170
170
|
data: Raw telegram payload (without checksum/framing).
|
|
171
|
-
|
|
172
|
-
Raises:
|
|
173
|
-
IOError: If transport is not open.
|
|
174
171
|
"""
|
|
175
172
|
self.on_send_frame.emit(data)
|
|
176
173
|
|
|
@@ -180,8 +177,9 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
180
177
|
frame = b"<" + frame_data.encode() + b">"
|
|
181
178
|
|
|
182
179
|
if not self.transport:
|
|
183
|
-
self.logger.info("Invalid transport")
|
|
184
|
-
|
|
180
|
+
self.logger.info("Invalid transport, connection closed.")
|
|
181
|
+
self.on_connection_failed.emit(Failure("Invalid transport."))
|
|
182
|
+
return
|
|
185
183
|
|
|
186
184
|
self.logger.debug(f"Sending frame: {frame.decode()}")
|
|
187
185
|
self.transport.write(frame) # type: ignore
|
|
@@ -211,6 +209,21 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
211
209
|
)
|
|
212
210
|
self.send_raw_telegram(payload)
|
|
213
211
|
|
|
212
|
+
def send_event_telegram(
|
|
213
|
+
self, module_type_code: ModuleTypeCode, link_number: int, input_number: int
|
|
214
|
+
) -> None:
|
|
215
|
+
"""Send telegram with specified parameters.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
module_type_code: Type code of module.
|
|
219
|
+
link_number: Link number.
|
|
220
|
+
input_number: Input number.
|
|
221
|
+
"""
|
|
222
|
+
payload = (
|
|
223
|
+
f"E" f"{module_type_code}" f"L{link_number:02d}" f"I{input_number:02d}"
|
|
224
|
+
)
|
|
225
|
+
self.send_raw_telegram(payload)
|
|
226
|
+
|
|
214
227
|
def send_raw_telegram(self, payload: str) -> None:
|
|
215
228
|
"""Send telegram with specified parameters.
|
|
216
229
|
|
|
@@ -7,6 +7,7 @@ from textual.app import App, ComposeResult
|
|
|
7
7
|
from textual.containers import Horizontal
|
|
8
8
|
|
|
9
9
|
from xp.models.term import ProtocolKeysConfig
|
|
10
|
+
from xp.models.term.status_message import StatusMessageChanged
|
|
10
11
|
from xp.term.widgets.help_menu import HelpMenuWidget
|
|
11
12
|
from xp.term.widgets.protocol_log import ProtocolLogWidget
|
|
12
13
|
from xp.term.widgets.status_footer import StatusFooterWidget
|
|
@@ -125,3 +126,12 @@ class ProtocolMonitorApp(App[None]):
|
|
|
125
126
|
"""
|
|
126
127
|
if self.footer_widget:
|
|
127
128
|
self.footer_widget.update_status(state)
|
|
129
|
+
|
|
130
|
+
def on_status_message_changed(self, message: StatusMessageChanged) -> None:
|
|
131
|
+
"""Handle status message changes from protocol widget.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
message: Message containing the status text.
|
|
135
|
+
"""
|
|
136
|
+
if self.footer_widget:
|
|
137
|
+
self.footer_widget.update_message(message.message)
|
|
@@ -63,8 +63,8 @@ protocol:
|
|
|
63
63
|
"e":
|
|
64
64
|
name: "Link 1 Off"
|
|
65
65
|
telegrams:
|
|
66
|
-
-
|
|
67
|
-
-
|
|
66
|
+
- E02L01I09M
|
|
67
|
+
- E02L01I09B
|
|
68
68
|
|
|
69
69
|
"f":
|
|
70
70
|
name: "Link 2 On"
|
|
@@ -75,8 +75,8 @@ protocol:
|
|
|
75
75
|
"g":
|
|
76
76
|
name: "Link 2 Off"
|
|
77
77
|
telegrams:
|
|
78
|
-
-
|
|
79
|
-
-
|
|
78
|
+
- E02L02I09M
|
|
79
|
+
- E02L02I09B
|
|
80
80
|
|
|
81
81
|
"h":
|
|
82
82
|
name: "Link 3 On"
|
|
@@ -87,8 +87,8 @@ protocol:
|
|
|
87
87
|
"i":
|
|
88
88
|
name: "Link 3 Off"
|
|
89
89
|
telegrams:
|
|
90
|
-
-
|
|
91
|
-
-
|
|
90
|
+
- E02L03I09M
|
|
91
|
+
- E02L03I09B
|
|
92
92
|
|
|
93
93
|
"j":
|
|
94
94
|
name: "Link 4 On"
|
|
@@ -99,8 +99,8 @@ protocol:
|
|
|
99
99
|
"k":
|
|
100
100
|
name: "Link 4 Off"
|
|
101
101
|
telegrams:
|
|
102
|
-
-
|
|
103
|
-
-
|
|
102
|
+
- E02L04I09M
|
|
103
|
+
- E02L04I09B
|
|
104
104
|
|
|
105
105
|
"l":
|
|
106
106
|
name: "Link 5 On"
|
|
@@ -111,8 +111,8 @@ protocol:
|
|
|
111
111
|
"m":
|
|
112
112
|
name: "Link 5 Off"
|
|
113
113
|
telegrams:
|
|
114
|
-
-
|
|
115
|
-
-
|
|
114
|
+
- E02L05I09M
|
|
115
|
+
- E02L05I09B
|
|
116
116
|
|
|
117
117
|
"n":
|
|
118
118
|
name: "Link 6 On"
|
|
@@ -123,8 +123,8 @@ protocol:
|
|
|
123
123
|
"o":
|
|
124
124
|
name: "Link 6 Off"
|
|
125
125
|
telegrams:
|
|
126
|
-
-
|
|
127
|
-
-
|
|
126
|
+
- E02L06I09M
|
|
127
|
+
- E02L06I09B
|
|
128
128
|
|
|
129
129
|
"p":
|
|
130
130
|
name: "Link 7 On"
|
|
@@ -135,5 +135,5 @@ protocol:
|
|
|
135
135
|
"q":
|
|
136
136
|
name: "Link 7 Off"
|
|
137
137
|
telegrams:
|
|
138
|
-
-
|
|
139
|
-
-
|
|
138
|
+
- E02L07I09M
|
|
139
|
+
- E02L07I09B
|