conson-xp 1.23.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.23.0 → conson_xp-1.24.0}/PKG-INFO +1 -1
- {conson_xp-1.23.0 → conson_xp-1.24.0}/pyproject.toml +1 -1
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/__init__.py +1 -1
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +7 -2
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +5 -2
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_discover_service.py +61 -53
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_receive_service.py +30 -25
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/protocol.yml +14 -14
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/widgets/protocol_log.py +2 -39
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_receive_service.py +22 -43
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_tui/test_protocol_log.py +0 -1
- {conson_xp-1.23.0 → conson_xp-1.24.0}/LICENSE +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/README.md +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/__main__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_event_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/file_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/module_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/server/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/server/server_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/term/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/term/term.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/commands/term/term_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/main.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/click_tree.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/decorators.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/error_handlers.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/formatters.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/module_type_choice.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/serial_number_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/system_function_choice.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/cli/utils/xp_module_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/connection/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/connection/exceptions.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/actiontable/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/actiontable/actiontable.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_blink.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_custom.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_discover.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_event_list.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_event_raw.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_logger_config.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_output.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_raw.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_receive.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/homekit/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/homekit/homekit_config.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/log_entry.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/protocol/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/response.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/action_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/datapoint_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/event_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/event_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/input_action_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/input_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/module_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/module_type_code.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/output_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/reply_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/system_function.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/system_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/telegram_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/telegram/timeparam_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/term/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/term/connection_state.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/term/protocol_keys_config.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/term/status_message.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/models/write_config_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/actiontable/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_event_list_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_event_raw_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/conbus/write_config_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/homekit/homekit_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/log_file_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/module_type_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/protocol/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/protocol/conbus_event_protocol.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/protocol/protocol_factory.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/reverse_proxy_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/base_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/cp20_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/device_service_factory.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/xp130_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/xp20_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/xp230_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/xp24_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/server/xp33_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/protocol.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/protocol.tcss +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/widgets/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/widgets/help_menu.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/term/widgets/status_footer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/checksum.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/dependencies.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/event_helper.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/logging.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/serialization.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/state_machine.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/src/xp/utils/time_utils.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/.coverage +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/conftest.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/.coverage +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/telegram_test_data.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_actiontable_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_api/.coverage +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_api/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_blink_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_checksum_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_conbus_blink_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_conbus_raw_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_conbus_receive_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_discovery_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_event_telegram_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_homekit_config_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_link_number_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_module_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_output_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_term_logging_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_version_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_api/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_click_tree.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_decorators.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_formatters.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_cli/test_term_commands.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_connection/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_connection/test_connection_init.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_connection/test_exceptions.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_encoding/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_event_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_log_entry.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_logger_config.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_module_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_system_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_version_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_write_config_type.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_base_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_blink_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_checksum_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_event_list_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_event_raw_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_discovery_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_homekit_services.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_log_file_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_module_type_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_protocol.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_server_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_telegram_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_version_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_tui/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_utils/__init__.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_checksum.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_event_helper.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_logging.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_serialization.py +0 -0
- {conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_utils/test_time_utils.py +0 -0
{conson_xp-1.23.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()
|
|
@@ -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()
|
|
@@ -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
|
|
@@ -12,7 +12,6 @@ from twisted.python.failure import Failure
|
|
|
12
12
|
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
13
13
|
from xp.models.term.connection_state import ConnectionState
|
|
14
14
|
from xp.models.term.status_message import StatusMessageChanged
|
|
15
|
-
from xp.services.conbus.conbus_receive_service import ConbusReceiveService
|
|
16
15
|
from xp.services.protocol import ConbusEventProtocol
|
|
17
16
|
|
|
18
17
|
|
|
@@ -26,7 +25,6 @@ class ProtocolLogWidget(Widget):
|
|
|
26
25
|
container: ServiceContainer for dependency injection.
|
|
27
26
|
connection_state: Current connection state (reactive).
|
|
28
27
|
protocol: Reference to ConbusEventProtocol (prevents duplicate connections).
|
|
29
|
-
service: ConbusReceiveService instance.
|
|
30
28
|
logger: Logger instance for this widget.
|
|
31
29
|
log_widget: RichLog widget for displaying messages.
|
|
32
30
|
"""
|
|
@@ -43,7 +41,6 @@ class ProtocolLogWidget(Widget):
|
|
|
43
41
|
self.border_title = "Protocol"
|
|
44
42
|
self.container = container
|
|
45
43
|
self.protocol: Optional[ConbusEventProtocol] = None
|
|
46
|
-
self.service: Optional[ConbusReceiveService] = None
|
|
47
44
|
self.logger = logging.getLogger(__name__)
|
|
48
45
|
self.log_widget: Optional[RichLog] = None
|
|
49
46
|
self._state_machine = ConnectionState.create_state_machine()
|
|
@@ -64,8 +61,7 @@ class ProtocolLogWidget(Widget):
|
|
|
64
61
|
Resolves ConbusReceiveService and connects signals.
|
|
65
62
|
"""
|
|
66
63
|
# Resolve service from container (singleton)
|
|
67
|
-
self.
|
|
68
|
-
self.protocol = self.service.conbus_protocol
|
|
64
|
+
self.protocol = self.container.resolve(ConbusEventProtocol)
|
|
69
65
|
|
|
70
66
|
# Connect psygnal signals
|
|
71
67
|
self.protocol.on_connection_made.connect(self._on_connection_made)
|
|
@@ -86,10 +82,6 @@ class ProtocolLogWidget(Widget):
|
|
|
86
82
|
Integrates Twisted reactor with Textual's asyncio loop cleanly.
|
|
87
83
|
"""
|
|
88
84
|
# Guard against duplicate connections (race condition)
|
|
89
|
-
if self.service is None:
|
|
90
|
-
self.logger.error("Service not initialized")
|
|
91
|
-
return
|
|
92
|
-
|
|
93
85
|
if self.protocol is None:
|
|
94
86
|
self.logger.error("Protocol not initialized")
|
|
95
87
|
return
|
|
@@ -114,41 +106,12 @@ class ProtocolLogWidget(Widget):
|
|
|
114
106
|
self.logger.info(f"Reactor object: {self.protocol._reactor}")
|
|
115
107
|
self.logger.info(f"Reactor running: {self.protocol._reactor.running}")
|
|
116
108
|
|
|
117
|
-
# Setup service callbacks
|
|
118
|
-
def progress_callback(telegram: str) -> None:
|
|
119
|
-
"""Handle progress updates for telegram reception.
|
|
120
|
-
|
|
121
|
-
Args:
|
|
122
|
-
telegram: Received telegram string.
|
|
123
|
-
"""
|
|
124
|
-
pass
|
|
125
|
-
|
|
126
|
-
def finish_callback(response: Any) -> None:
|
|
127
|
-
"""Handle completion of telegram reception.
|
|
128
|
-
|
|
129
|
-
Args:
|
|
130
|
-
response: Response object from telegram reception.
|
|
131
|
-
"""
|
|
132
|
-
pass
|
|
133
|
-
|
|
134
109
|
# Get the currently running asyncio event loop (Textual's loop)
|
|
135
110
|
event_loop = asyncio.get_running_loop()
|
|
136
111
|
self.logger.info(f"Current running loop: {event_loop}")
|
|
137
112
|
self.logger.info(f"Loop is running: {event_loop.is_running()}")
|
|
138
113
|
|
|
139
|
-
self.
|
|
140
|
-
progress_callback=progress_callback,
|
|
141
|
-
finish_callback=finish_callback,
|
|
142
|
-
timeout_seconds=None, # Continuous monitoring
|
|
143
|
-
event_loop=event_loop,
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
reactor = self.service.conbus_protocol._reactor
|
|
147
|
-
reactor.connectTCP(
|
|
148
|
-
self.protocol.cli_config.ip,
|
|
149
|
-
self.protocol.cli_config.port,
|
|
150
|
-
self.protocol,
|
|
151
|
-
)
|
|
114
|
+
self.protocol.connect()
|
|
152
115
|
|
|
153
116
|
# Wait for connection to establish
|
|
154
117
|
await asyncio.sleep(1.0)
|
{conson_xp-1.23.0 → conson_xp-1.24.0}/tests/unit/test_services/test_conbus_receive_service.py
RENAMED
|
@@ -43,8 +43,6 @@ class TestConbusReceiveService:
|
|
|
43
43
|
|
|
44
44
|
def test_service_initialization(self, service, mock_protocol):
|
|
45
45
|
"""Test service can be initialized with required dependencies."""
|
|
46
|
-
assert service.progress_callback is None
|
|
47
|
-
assert service.finish_callback is None
|
|
48
46
|
assert service.receive_response.success is True
|
|
49
47
|
assert service.receive_response.received_telegrams == []
|
|
50
48
|
|
|
@@ -117,9 +115,9 @@ class TestConbusReceiveService:
|
|
|
117
115
|
]
|
|
118
116
|
|
|
119
117
|
def test_telegram_received_with_progress_callback(self, service, mock_protocol):
|
|
120
|
-
"""Test telegram_received
|
|
118
|
+
"""Test telegram_received emits progress signal."""
|
|
121
119
|
progress_mock = Mock()
|
|
122
|
-
service.
|
|
120
|
+
service.on_progress.connect(progress_mock)
|
|
123
121
|
|
|
124
122
|
telegram_event = TelegramReceivedEvent(
|
|
125
123
|
protocol=mock_protocol,
|
|
@@ -137,9 +135,7 @@ class TestConbusReceiveService:
|
|
|
137
135
|
progress_mock.assert_called_once_with("<T123456789012D0AK>")
|
|
138
136
|
|
|
139
137
|
def test_telegram_received_without_progress_callback(self, service, mock_protocol):
|
|
140
|
-
"""Test telegram_received doesn't crash when
|
|
141
|
-
service.progress_callback = None
|
|
142
|
-
|
|
138
|
+
"""Test telegram_received doesn't crash when no signal handlers connected."""
|
|
143
139
|
telegram_event = TelegramReceivedEvent(
|
|
144
140
|
protocol=mock_protocol,
|
|
145
141
|
frame="<T123456789012D0AK>",
|
|
@@ -157,7 +153,7 @@ class TestConbusReceiveService:
|
|
|
157
153
|
def test_timeout(self, service, mock_protocol):
|
|
158
154
|
"""Test timeout callback marks operation as successful."""
|
|
159
155
|
finish_mock = Mock()
|
|
160
|
-
service.
|
|
156
|
+
service.on_finish.connect(finish_mock)
|
|
161
157
|
|
|
162
158
|
service.timeout()
|
|
163
159
|
|
|
@@ -165,16 +161,14 @@ class TestConbusReceiveService:
|
|
|
165
161
|
finish_mock.assert_called_once_with(service.receive_response)
|
|
166
162
|
|
|
167
163
|
def test_timeout_without_finish_callback(self, service):
|
|
168
|
-
"""Test timeout doesn't crash when
|
|
169
|
-
service.finish_callback = None
|
|
170
|
-
|
|
164
|
+
"""Test timeout doesn't crash when no signal handlers connected."""
|
|
171
165
|
# Should not raise any errors
|
|
172
166
|
service.timeout()
|
|
173
167
|
|
|
174
168
|
def test_failed(self, service):
|
|
175
169
|
"""Test failed callback updates service response."""
|
|
176
170
|
finish_mock = Mock()
|
|
177
|
-
service.
|
|
171
|
+
service.on_finish.connect(finish_mock)
|
|
178
172
|
|
|
179
173
|
service.failed("Connection timeout")
|
|
180
174
|
|
|
@@ -183,43 +177,32 @@ class TestConbusReceiveService:
|
|
|
183
177
|
finish_mock.assert_called_once_with(service.receive_response)
|
|
184
178
|
|
|
185
179
|
def test_failed_without_finish_callback(self, service):
|
|
186
|
-
"""Test failed doesn't crash when
|
|
187
|
-
service.finish_callback = None
|
|
188
|
-
|
|
180
|
+
"""Test failed doesn't crash when no signal handlers connected."""
|
|
189
181
|
# Should not raise any errors
|
|
190
182
|
service.failed("Connection timeout")
|
|
191
183
|
|
|
192
|
-
def
|
|
193
|
-
"""Test
|
|
194
|
-
|
|
195
|
-
progress_mock = Mock()
|
|
196
|
-
|
|
197
|
-
service.init(
|
|
198
|
-
progress_callback=progress_mock,
|
|
199
|
-
finish_callback=finish_mock,
|
|
200
|
-
timeout_seconds=10,
|
|
201
|
-
)
|
|
184
|
+
def test_set_timeout(self, service, mock_protocol):
|
|
185
|
+
"""Test set_timeout method sets timeout on protocol."""
|
|
186
|
+
service.set_timeout(timeout_seconds=10)
|
|
202
187
|
|
|
203
|
-
assert service.progress_callback == progress_mock
|
|
204
|
-
assert service.finish_callback == finish_mock
|
|
205
188
|
assert mock_protocol.timeout_seconds == 10
|
|
206
189
|
|
|
207
|
-
def
|
|
208
|
-
"""Test
|
|
190
|
+
def test_signal_connections(self, service):
|
|
191
|
+
"""Test signals can be connected and emit correctly."""
|
|
209
192
|
finish_mock = Mock()
|
|
210
193
|
progress_mock = Mock()
|
|
211
|
-
original_timeout = mock_protocol.timeout_seconds
|
|
212
194
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
195
|
+
# Connect signals
|
|
196
|
+
service.on_progress.connect(progress_mock)
|
|
197
|
+
service.on_finish.connect(finish_mock)
|
|
198
|
+
|
|
199
|
+
# Emit signals
|
|
200
|
+
service.on_progress.emit("test_telegram")
|
|
201
|
+
service.on_finish.emit(service.receive_response)
|
|
218
202
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
assert mock_protocol.timeout_seconds == original_timeout
|
|
203
|
+
# Verify callbacks were called
|
|
204
|
+
progress_mock.assert_called_once_with("test_telegram")
|
|
205
|
+
finish_mock.assert_called_once_with(service.receive_response)
|
|
223
206
|
|
|
224
207
|
def test_start_reactor(self, service, mock_protocol):
|
|
225
208
|
"""Test start_reactor delegates to protocol."""
|
|
@@ -256,12 +239,8 @@ class TestConbusReceiveService:
|
|
|
256
239
|
|
|
257
240
|
def test_context_manager_full_lifecycle(self, service, mock_protocol):
|
|
258
241
|
"""Test full context manager lifecycle with singleton reuse."""
|
|
259
|
-
finish_mock = Mock()
|
|
260
|
-
progress_mock = Mock()
|
|
261
|
-
|
|
262
242
|
# First use
|
|
263
243
|
with service:
|
|
264
|
-
service.init(progress_mock, finish_mock, 5.0)
|
|
265
244
|
# Simulate receiving a telegram
|
|
266
245
|
service.receive_response.received_telegrams = ["<T123456789012D0AK>"]
|
|
267
246
|
|