conson-xp 1.40.0__tar.gz → 1.41.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.40.0 → conson_xp-1.41.0}/PKG-INFO +2 -1
- {conson_xp-1.40.0 → conson_xp-1.41.0}/README.md +1 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/pyproject.toml +1 -1
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/__init__.py +1 -1
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +62 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/actiontable/msactiontable_xp24.py +4 -4
- conson_xp-1.41.0/src/xp/services/conbus/msactiontable/msactiontable_upload_service.py +324 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/dependencies.py +16 -0
- conson_xp-1.41.0/tests/unit/test_cli/test_conbus_msactiontable_upload_commands.py +376 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_xp24_action_table_short_format.py +12 -14
- conson_xp-1.41.0/tests/unit/test_services/test_msactiontable_upload_service.py +503 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/LICENSE +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/__main__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_event_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_export_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/file_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/module_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/server/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/server/server_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/term/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/term/term.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/term/term_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/main.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/click_tree.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/decorators.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/error_handlers.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/formatters.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/module_type_choice.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/serial_number_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/system_function_choice.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/utils/xp_module_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/actiontable/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/actiontable/actiontable.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_blink.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_custom.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_discover.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_event_list.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_event_raw.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_export.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_logger_config.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_output.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_raw.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_receive.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/config/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/config/conson_module_config.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/homekit/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/homekit/homekit_config.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/log_entry.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/protocol/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/response.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/action_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/datapoint_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/event_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/event_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/input_action_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/input_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/module_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/module_type_code.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/output_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/reply_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/system_function.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/system_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/telegram_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/telegram/timeparam_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/term/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/term/connection_state.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/term/module_state.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/term/protocol_keys_config.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/term/status_message.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/term/telegram_display.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/models/write_config_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/actiontable/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_discover_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_event_list_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_event_raw_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_export_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/msactiontable/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/msactiontable/msactiontable_download_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/msactiontable/msactiontable_list_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/msactiontable/msactiontable_show_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/conbus/write_config_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/homekit/homekit_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/log_file_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/module_type_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/protocol/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/protocol/conbus_event_protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/protocol/protocol_factory.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/reverse_proxy_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/base_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/client_buffer_manager.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/cp20_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/device_service_factory.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/xp130_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/xp20_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/xp230_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/xp24_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/server/xp33_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/term/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/term/protocol_monitor_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/services/term/state_monitor_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/protocol.tcss +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/state.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/state.tcss +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/widgets/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/widgets/help_menu.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/widgets/modules_list.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/widgets/protocol_log.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/term/widgets/status_footer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/checksum.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/event_helper.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/logging.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/serialization.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/state_machine.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/utils/time_utils.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/.coverage +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/conftest.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/.coverage +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/telegram_test_data.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_actiontable_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_api/.coverage +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_api/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_blink_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_checksum_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_conbus_blink_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_conbus_raw_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_conbus_receive_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_discovery_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_event_telegram_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_homekit_config_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_link_number_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_module_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_output_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_term_logging_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_version_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_api/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_click_tree.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_decorators.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_formatters.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_cli/test_term_commands.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_encoding/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_conbus.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_event_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_log_entry.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_logger_config.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_module_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_system_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_version_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_write_config_type.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_base_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_blink_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_checksum_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_client_buffer_manager.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_event_list_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_event_protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_event_raw_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_output_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_receive_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_conbus_scan_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_discovery_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_homekit_services.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_log_file_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_module_type_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_protocol_monitor_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_server_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_state_monitor_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_telegram_output_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_telegram_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_version_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_xp33_short_format.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_tui/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_tui/test_protocol_log.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_utils/__init__.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_utils/test_checksum.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_utils/test_event_helper.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_utils/test_logging.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_utils/test_serialization.py +0 -0
- {conson_xp-1.40.0 → conson_xp-1.41.0}/tests/unit/test_utils/test_time_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: conson-xp
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.41.0
|
|
4
4
|
Summary: XP Protocol Communication Tools
|
|
5
5
|
Author-Email: ldvchosal <ldvchosal@github.com>
|
|
6
6
|
License: MIT License
|
|
@@ -376,6 +376,7 @@ xp conbus msactiontable
|
|
|
376
376
|
xp conbus msactiontable download
|
|
377
377
|
xp conbus msactiontable list
|
|
378
378
|
xp conbus msactiontable show
|
|
379
|
+
xp conbus msactiontable upload
|
|
379
380
|
|
|
380
381
|
|
|
381
382
|
xp conbus output
|
{conson_xp-1.40.0 → conson_xp-1.41.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py
RENAMED
|
@@ -25,6 +25,9 @@ from xp.services.conbus.msactiontable.msactiontable_list_service import (
|
|
|
25
25
|
from xp.services.conbus.msactiontable.msactiontable_show_service import (
|
|
26
26
|
MsActionTableShowService,
|
|
27
27
|
)
|
|
28
|
+
from xp.services.conbus.msactiontable.msactiontable_upload_service import (
|
|
29
|
+
MsActionTableUploadService,
|
|
30
|
+
)
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
@conbus_msactiontable.command("download", short_help="Download MSActionTable")
|
|
@@ -206,6 +209,65 @@ def conbus_show_msactiontable(ctx: Context, serial_number: str) -> None:
|
|
|
206
209
|
)
|
|
207
210
|
|
|
208
211
|
|
|
212
|
+
@conbus_msactiontable.command("upload", short_help="Upload MSActionTable")
|
|
213
|
+
@click.argument("serial_number", type=SERIAL)
|
|
214
|
+
@click.argument("xpmoduletype", type=XP_MODULE_TYPE)
|
|
215
|
+
@click.pass_context
|
|
216
|
+
@connection_command()
|
|
217
|
+
def conbus_upload_msactiontable(
|
|
218
|
+
ctx: Context, serial_number: str, xpmoduletype: str
|
|
219
|
+
) -> None:
|
|
220
|
+
"""Upload MS action table from conson.yml to XP module.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
ctx: Click context object.
|
|
224
|
+
serial_number: 10-digit module serial number.
|
|
225
|
+
xpmoduletype: XP module type.
|
|
226
|
+
"""
|
|
227
|
+
service: MsActionTableUploadService = (
|
|
228
|
+
ctx.obj.get("container").get_container().resolve(MsActionTableUploadService)
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
def on_progress(progress: str) -> None:
|
|
232
|
+
"""Handle progress updates during MS action table upload.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
progress: Progress message string.
|
|
236
|
+
"""
|
|
237
|
+
click.echo(progress, nl=False)
|
|
238
|
+
|
|
239
|
+
def on_finish(success: bool) -> None:
|
|
240
|
+
"""Handle successful completion of MS action table upload.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
success: Whether upload was successful.
|
|
244
|
+
"""
|
|
245
|
+
service.stop_reactor()
|
|
246
|
+
if success:
|
|
247
|
+
click.echo("\nMsactiontable uploaded successfully")
|
|
248
|
+
|
|
249
|
+
def on_error(error: str) -> None:
|
|
250
|
+
"""Handle errors during MS action table upload.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
error: Error message string.
|
|
254
|
+
"""
|
|
255
|
+
service.stop_reactor()
|
|
256
|
+
click.echo(f"\nError: {error}")
|
|
257
|
+
|
|
258
|
+
click.echo(f"Uploading msactiontable to {serial_number}...")
|
|
259
|
+
|
|
260
|
+
with service:
|
|
261
|
+
service.on_progress.connect(on_progress)
|
|
262
|
+
service.on_error.connect(on_error)
|
|
263
|
+
service.on_finish.connect(on_finish)
|
|
264
|
+
service.start(
|
|
265
|
+
serial_number=serial_number,
|
|
266
|
+
xpmoduletype=xpmoduletype,
|
|
267
|
+
)
|
|
268
|
+
service.start_reactor()
|
|
269
|
+
|
|
270
|
+
|
|
209
271
|
def _format_yaml(data: dict, indent: int = 0) -> str:
|
|
210
272
|
"""Format a dictionary as YAML-like output.
|
|
211
273
|
|
|
@@ -178,7 +178,7 @@ class Xp24MsActionTable(BaseModel):
|
|
|
178
178
|
param_value = action.param.value
|
|
179
179
|
action_parts.append(f"{short_code}:{param_value}")
|
|
180
180
|
|
|
181
|
-
result =
|
|
181
|
+
result = " ".join(action_parts)
|
|
182
182
|
|
|
183
183
|
# Add settings
|
|
184
184
|
settings = (
|
|
@@ -212,14 +212,14 @@ class Xp24MsActionTable(BaseModel):
|
|
|
212
212
|
|
|
213
213
|
# Parse action part
|
|
214
214
|
tokens = action_part.split()
|
|
215
|
-
if len(tokens) !=
|
|
215
|
+
if len(tokens) != 4:
|
|
216
216
|
raise ValueError(
|
|
217
|
-
f"Invalid short format: expected '
|
|
217
|
+
f"Invalid short format: expected '<a1> <a2> <a3> <a4>', got '{action_part}'"
|
|
218
218
|
)
|
|
219
219
|
|
|
220
220
|
# Parse input actions
|
|
221
221
|
input_actions = []
|
|
222
|
-
for i, token in enumerate(tokens[
|
|
222
|
+
for i, token in enumerate(tokens[0:4], 1):
|
|
223
223
|
if ":" not in token:
|
|
224
224
|
raise ValueError(f"Invalid action format at position {i}: '{token}'")
|
|
225
225
|
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"""Service for uploading MS action tables via Conbus protocol."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Any, Optional, Union
|
|
5
|
+
|
|
6
|
+
from psygnal import Signal
|
|
7
|
+
|
|
8
|
+
from xp.models.config.conson_module_config import ConsonModuleListConfig
|
|
9
|
+
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
10
|
+
from xp.models.telegram.system_function import SystemFunction
|
|
11
|
+
from xp.models.telegram.telegram_type import TelegramType
|
|
12
|
+
from xp.services.actiontable.msactiontable_xp20_serializer import (
|
|
13
|
+
Xp20MsActionTableSerializer,
|
|
14
|
+
)
|
|
15
|
+
from xp.services.actiontable.msactiontable_xp24_serializer import (
|
|
16
|
+
Xp24MsActionTableSerializer,
|
|
17
|
+
)
|
|
18
|
+
from xp.services.actiontable.msactiontable_xp33_serializer import (
|
|
19
|
+
Xp33MsActionTableSerializer,
|
|
20
|
+
)
|
|
21
|
+
from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
|
|
22
|
+
from xp.services.telegram.telegram_service import TelegramService
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MsActionTableUploadError(Exception):
|
|
26
|
+
"""Raised when MS action table upload operations fail."""
|
|
27
|
+
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class MsActionTableUploadService:
|
|
32
|
+
"""TCP client service for uploading MS action tables to Conbus modules.
|
|
33
|
+
|
|
34
|
+
Manages TCP socket connections, handles telegram generation and transmission,
|
|
35
|
+
and processes server responses for MS action table uploads.
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
on_progress: Signal emitted with telegram frame when progress is made.
|
|
39
|
+
on_error: Signal emitted with error message string when an error occurs.
|
|
40
|
+
on_finish: Signal emitted with bool (True on success) when upload completes.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
on_progress: Signal = Signal(str)
|
|
44
|
+
on_error: Signal = Signal(str)
|
|
45
|
+
on_finish: Signal = Signal(bool) # True on success
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
conbus_protocol: ConbusEventProtocol,
|
|
50
|
+
xp20ms_serializer: Xp20MsActionTableSerializer,
|
|
51
|
+
xp24ms_serializer: Xp24MsActionTableSerializer,
|
|
52
|
+
xp33ms_serializer: Xp33MsActionTableSerializer,
|
|
53
|
+
telegram_service: TelegramService,
|
|
54
|
+
conson_config: ConsonModuleListConfig,
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Initialize the MS action table upload service.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
conbus_protocol: ConbusEventProtocol for communication.
|
|
60
|
+
xp20ms_serializer: XP20 MS action table serializer.
|
|
61
|
+
xp24ms_serializer: XP24 MS action table serializer.
|
|
62
|
+
xp33ms_serializer: XP33 MS action table serializer.
|
|
63
|
+
telegram_service: Telegram service for parsing.
|
|
64
|
+
conson_config: Conson module list configuration.
|
|
65
|
+
"""
|
|
66
|
+
self.conbus_protocol = conbus_protocol
|
|
67
|
+
self.xp20ms_serializer = xp20ms_serializer
|
|
68
|
+
self.xp24ms_serializer = xp24ms_serializer
|
|
69
|
+
self.xp33ms_serializer = xp33ms_serializer
|
|
70
|
+
self.serializer: Union[
|
|
71
|
+
Xp20MsActionTableSerializer,
|
|
72
|
+
Xp24MsActionTableSerializer,
|
|
73
|
+
Xp33MsActionTableSerializer,
|
|
74
|
+
] = xp20ms_serializer
|
|
75
|
+
self.telegram_service = telegram_service
|
|
76
|
+
self.conson_config = conson_config
|
|
77
|
+
self.serial_number: str = ""
|
|
78
|
+
self.xpmoduletype: str = ""
|
|
79
|
+
|
|
80
|
+
# Upload state
|
|
81
|
+
self.upload_data: str = ""
|
|
82
|
+
self.upload_initiated: bool = False
|
|
83
|
+
|
|
84
|
+
# Set up logging
|
|
85
|
+
self.logger = logging.getLogger(__name__)
|
|
86
|
+
|
|
87
|
+
# Connect protocol signals
|
|
88
|
+
self.conbus_protocol.on_connection_made.connect(self.connection_made)
|
|
89
|
+
self.conbus_protocol.on_telegram_sent.connect(self.telegram_sent)
|
|
90
|
+
self.conbus_protocol.on_telegram_received.connect(self.telegram_received)
|
|
91
|
+
self.conbus_protocol.on_timeout.connect(self.timeout)
|
|
92
|
+
self.conbus_protocol.on_failed.connect(self.failed)
|
|
93
|
+
|
|
94
|
+
def connection_made(self) -> None:
|
|
95
|
+
"""Handle connection established event."""
|
|
96
|
+
self.logger.debug(
|
|
97
|
+
"Connection established, sending upload msactiontable telegram"
|
|
98
|
+
)
|
|
99
|
+
self.conbus_protocol.send_telegram(
|
|
100
|
+
telegram_type=TelegramType.SYSTEM,
|
|
101
|
+
serial_number=self.serial_number,
|
|
102
|
+
system_function=SystemFunction.UPLOAD_MSACTIONTABLE,
|
|
103
|
+
data_value="00",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def telegram_sent(self, telegram_sent: str) -> None:
|
|
107
|
+
"""Handle telegram sent event.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
telegram_sent: The telegram that was sent.
|
|
111
|
+
"""
|
|
112
|
+
self.logger.debug(f"Telegram sent: {telegram_sent}")
|
|
113
|
+
|
|
114
|
+
def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
|
|
115
|
+
"""Handle telegram received event.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
telegram_received: The telegram received event.
|
|
119
|
+
"""
|
|
120
|
+
self.logger.debug(f"Telegram received: {telegram_received}")
|
|
121
|
+
if (
|
|
122
|
+
not telegram_received.checksum_valid
|
|
123
|
+
or telegram_received.telegram_type != TelegramType.REPLY.value
|
|
124
|
+
or telegram_received.serial_number != self.serial_number
|
|
125
|
+
):
|
|
126
|
+
self.logger.debug("Not a reply response")
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
reply_telegram = self.telegram_service.parse_reply_telegram(
|
|
130
|
+
telegram_received.frame
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
self._handle_upload_response(reply_telegram)
|
|
134
|
+
|
|
135
|
+
def _handle_upload_response(self, reply_telegram: Any) -> None:
|
|
136
|
+
"""Handle telegram responses during upload.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
reply_telegram: Parsed reply telegram.
|
|
140
|
+
"""
|
|
141
|
+
if reply_telegram.system_function == SystemFunction.ACK:
|
|
142
|
+
self.logger.debug("Received ACK for upload")
|
|
143
|
+
|
|
144
|
+
if not self.upload_initiated:
|
|
145
|
+
# First ACK - send data chunk
|
|
146
|
+
self.logger.debug("Sending msactiontable data")
|
|
147
|
+
self.conbus_protocol.send_telegram(
|
|
148
|
+
telegram_type=TelegramType.SYSTEM,
|
|
149
|
+
serial_number=self.serial_number,
|
|
150
|
+
system_function=SystemFunction.MSACTIONTABLE,
|
|
151
|
+
data_value=self.upload_data,
|
|
152
|
+
)
|
|
153
|
+
self.upload_initiated = True
|
|
154
|
+
self.on_progress.emit(".")
|
|
155
|
+
else:
|
|
156
|
+
# Second ACK - send EOF
|
|
157
|
+
self.logger.debug("Data sent, sending EOF")
|
|
158
|
+
self.conbus_protocol.send_telegram(
|
|
159
|
+
telegram_type=TelegramType.SYSTEM,
|
|
160
|
+
serial_number=self.serial_number,
|
|
161
|
+
system_function=SystemFunction.EOF,
|
|
162
|
+
data_value="00",
|
|
163
|
+
)
|
|
164
|
+
self.on_finish.emit(True)
|
|
165
|
+
elif reply_telegram.system_function == SystemFunction.NAK:
|
|
166
|
+
self.logger.debug("Received NAK during upload")
|
|
167
|
+
self.failed("Upload failed: NAK received")
|
|
168
|
+
else:
|
|
169
|
+
self.logger.debug(f"Unexpected response during upload: {reply_telegram}")
|
|
170
|
+
|
|
171
|
+
def timeout(self) -> None:
|
|
172
|
+
"""Handle timeout event."""
|
|
173
|
+
self.logger.debug("Upload timeout")
|
|
174
|
+
self.failed("Upload timeout")
|
|
175
|
+
|
|
176
|
+
def failed(self, message: str) -> None:
|
|
177
|
+
"""Handle failed connection event.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
message: Failure message.
|
|
181
|
+
"""
|
|
182
|
+
self.logger.debug(f"Failed: {message}")
|
|
183
|
+
self.on_error.emit(message)
|
|
184
|
+
|
|
185
|
+
def start(
|
|
186
|
+
self,
|
|
187
|
+
serial_number: str,
|
|
188
|
+
xpmoduletype: str,
|
|
189
|
+
timeout_seconds: Optional[float] = None,
|
|
190
|
+
) -> None:
|
|
191
|
+
"""Upload MS action table to module.
|
|
192
|
+
|
|
193
|
+
Uploads the MS action table configuration to the specified module.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
serial_number: Module serial number.
|
|
197
|
+
xpmoduletype: XP module type (xp20, xp24, xp33).
|
|
198
|
+
timeout_seconds: Optional timeout in seconds.
|
|
199
|
+
|
|
200
|
+
Raises:
|
|
201
|
+
MsActionTableUploadError: If configuration or validation errors occur.
|
|
202
|
+
"""
|
|
203
|
+
self.logger.info("Starting msactiontable upload")
|
|
204
|
+
self.serial_number = serial_number
|
|
205
|
+
self.xpmoduletype = xpmoduletype
|
|
206
|
+
|
|
207
|
+
# Select serializer based on module type
|
|
208
|
+
if xpmoduletype == "xp20":
|
|
209
|
+
self.serializer = self.xp20ms_serializer
|
|
210
|
+
config_field = "xp20_msaction_table"
|
|
211
|
+
elif xpmoduletype == "xp24":
|
|
212
|
+
self.serializer = self.xp24ms_serializer
|
|
213
|
+
config_field = "xp24_msaction_table"
|
|
214
|
+
elif xpmoduletype == "xp33":
|
|
215
|
+
self.serializer = self.xp33ms_serializer
|
|
216
|
+
config_field = "xp33_msaction_table"
|
|
217
|
+
else:
|
|
218
|
+
raise MsActionTableUploadError(f"Unsupported module type: {xpmoduletype}")
|
|
219
|
+
|
|
220
|
+
if timeout_seconds:
|
|
221
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
222
|
+
|
|
223
|
+
# Find module
|
|
224
|
+
module = self.conson_config.find_module(serial_number)
|
|
225
|
+
if not module:
|
|
226
|
+
self.failed(f"Module {serial_number} not found in conson.yml")
|
|
227
|
+
return
|
|
228
|
+
|
|
229
|
+
# Validate module type matches
|
|
230
|
+
if module.module_type.lower() != xpmoduletype.lower():
|
|
231
|
+
self.failed(
|
|
232
|
+
f"Module type mismatch: module has type {module.module_type}, "
|
|
233
|
+
f"but {xpmoduletype} was specified"
|
|
234
|
+
)
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
# Get msactiontable config for the module type
|
|
238
|
+
msactiontable_config = getattr(module, config_field, None)
|
|
239
|
+
|
|
240
|
+
if not msactiontable_config:
|
|
241
|
+
self.failed(
|
|
242
|
+
f"Module {serial_number} does not have {config_field} configured in conson.yml"
|
|
243
|
+
)
|
|
244
|
+
return
|
|
245
|
+
|
|
246
|
+
if not isinstance(msactiontable_config, list) or len(msactiontable_config) == 0:
|
|
247
|
+
self.failed(
|
|
248
|
+
f"Module {serial_number} has empty {config_field} list in conson.yml"
|
|
249
|
+
)
|
|
250
|
+
return
|
|
251
|
+
|
|
252
|
+
# Parse MS action table from short format (first element)
|
|
253
|
+
try:
|
|
254
|
+
short_format = msactiontable_config
|
|
255
|
+
msactiontable: Union[
|
|
256
|
+
"Xp20MsActionTable", "Xp24MsActionTable", "Xp33MsActionTable"
|
|
257
|
+
]
|
|
258
|
+
if xpmoduletype == "xp20":
|
|
259
|
+
from xp.models.actiontable.msactiontable_xp20 import Xp20MsActionTable
|
|
260
|
+
|
|
261
|
+
msactiontable = Xp20MsActionTable.from_short_format(short_format)
|
|
262
|
+
elif xpmoduletype == "xp24":
|
|
263
|
+
from xp.models.actiontable.msactiontable_xp24 import Xp24MsActionTable
|
|
264
|
+
|
|
265
|
+
msactiontable = Xp24MsActionTable.from_short_format(short_format)
|
|
266
|
+
elif xpmoduletype == "xp33":
|
|
267
|
+
from xp.models.actiontable.msactiontable_xp33 import Xp33MsActionTable
|
|
268
|
+
|
|
269
|
+
msactiontable = Xp33MsActionTable.from_short_format(short_format)
|
|
270
|
+
except (ValueError, AttributeError) as e:
|
|
271
|
+
self.logger.error(f"Invalid msactiontable format: {e}")
|
|
272
|
+
self.failed(f"Invalid msactiontable format: {e}")
|
|
273
|
+
return
|
|
274
|
+
|
|
275
|
+
# Serialize to telegram data (68 characters: AAAA + 64 data chars)
|
|
276
|
+
self.upload_data = self.serializer.to_data(msactiontable) # type: ignore[arg-type]
|
|
277
|
+
|
|
278
|
+
self.logger.debug(
|
|
279
|
+
f"Upload data encoded: {len(self.upload_data)} chars (single chunk)"
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
def set_timeout(self, timeout_seconds: float) -> None:
|
|
283
|
+
"""Set operation timeout.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
timeout_seconds: Timeout in seconds.
|
|
287
|
+
"""
|
|
288
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
289
|
+
|
|
290
|
+
def start_reactor(self) -> None:
|
|
291
|
+
"""Start the reactor."""
|
|
292
|
+
self.conbus_protocol.start_reactor()
|
|
293
|
+
|
|
294
|
+
def stop_reactor(self) -> None:
|
|
295
|
+
"""Stop the reactor."""
|
|
296
|
+
self.conbus_protocol.stop_reactor()
|
|
297
|
+
|
|
298
|
+
def __enter__(self) -> "MsActionTableUploadService":
|
|
299
|
+
"""Enter context manager - reset state for singleton reuse.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Self for context manager protocol.
|
|
303
|
+
"""
|
|
304
|
+
# Reset state
|
|
305
|
+
self.upload_data = ""
|
|
306
|
+
self.upload_initiated = False
|
|
307
|
+
self.serial_number = ""
|
|
308
|
+
self.xpmoduletype = ""
|
|
309
|
+
return self
|
|
310
|
+
|
|
311
|
+
def __exit__(self, _exc_type: Any, _exc_val: Any, _exc_tb: Any) -> None:
|
|
312
|
+
"""Exit context manager - cleanup signals and reactor."""
|
|
313
|
+
# Disconnect protocol signals
|
|
314
|
+
self.conbus_protocol.on_connection_made.disconnect(self.connection_made)
|
|
315
|
+
self.conbus_protocol.on_telegram_sent.disconnect(self.telegram_sent)
|
|
316
|
+
self.conbus_protocol.on_telegram_received.disconnect(self.telegram_received)
|
|
317
|
+
self.conbus_protocol.on_timeout.disconnect(self.timeout)
|
|
318
|
+
self.conbus_protocol.on_failed.disconnect(self.failed)
|
|
319
|
+
# Disconnect service signals
|
|
320
|
+
self.on_progress.disconnect()
|
|
321
|
+
self.on_error.disconnect()
|
|
322
|
+
self.on_finish.disconnect()
|
|
323
|
+
# Stop reactor
|
|
324
|
+
self.stop_reactor()
|
|
@@ -60,6 +60,9 @@ from xp.services.conbus.msactiontable.msactiontable_list_service import (
|
|
|
60
60
|
from xp.services.conbus.msactiontable.msactiontable_show_service import (
|
|
61
61
|
MsActionTableShowService,
|
|
62
62
|
)
|
|
63
|
+
from xp.services.conbus.msactiontable.msactiontable_upload_service import (
|
|
64
|
+
MsActionTableUploadService,
|
|
65
|
+
)
|
|
63
66
|
from xp.services.conbus.write_config_service import WriteConfigService
|
|
64
67
|
from xp.services.homekit.homekit_cache_service import HomeKitCacheService
|
|
65
68
|
from xp.services.homekit.homekit_conbus_service import HomeKitConbusService
|
|
@@ -381,6 +384,19 @@ class ServiceContainer:
|
|
|
381
384
|
scope=punq.Scope.singleton,
|
|
382
385
|
)
|
|
383
386
|
|
|
387
|
+
self.container.register(
|
|
388
|
+
MsActionTableUploadService,
|
|
389
|
+
factory=lambda: MsActionTableUploadService(
|
|
390
|
+
conbus_protocol=self.container.resolve(ConbusEventProtocol),
|
|
391
|
+
xp20ms_serializer=self.container.resolve(Xp20MsActionTableSerializer),
|
|
392
|
+
xp24ms_serializer=self.container.resolve(Xp24MsActionTableSerializer),
|
|
393
|
+
xp33ms_serializer=self.container.resolve(Xp33MsActionTableSerializer),
|
|
394
|
+
telegram_service=self.container.resolve(TelegramService),
|
|
395
|
+
conson_config=self.container.resolve(ConsonModuleListConfig),
|
|
396
|
+
),
|
|
397
|
+
scope=punq.Scope.singleton,
|
|
398
|
+
)
|
|
399
|
+
|
|
384
400
|
self.container.register(
|
|
385
401
|
ConbusCustomService,
|
|
386
402
|
factory=lambda: ConbusCustomService(
|