conson-xp 1.16.0__tar.gz → 1.18.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.16.0 → conson_xp-1.18.0}/PKG-INFO +5 -1
- {conson_xp-1.16.0 → conson_xp-1.18.0}/README.md +4 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/pyproject.toml +1 -1
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/__init__.py +1 -1
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/__init__.py +3 -0
- conson_xp-1.18.0/src/xp/cli/commands/conbus/conbus_event_commands.py +81 -0
- conson_xp-1.18.0/src/xp/cli/utils/module_type_choice.py +56 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/__init__.py +2 -0
- conson_xp-1.18.0/src/xp/models/conbus/conbus_event_raw.py +47 -0
- conson_xp-1.18.0/src/xp/services/conbus/conbus_event_raw_service.py +181 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/protocol/conbus_event_protocol.py +24 -6
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/utils/dependencies.py +9 -0
- conson_xp-1.18.0/tests/unit/test_services/test_conbus_event_raw_service.py +171 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/LICENSE +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/__main__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_modulenumber_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/file_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/module_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/server/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/server/server_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/main.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/click_tree.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/decorators.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/error_handlers.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/formatters.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/serial_number_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/system_function_choice.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/cli/utils/xp_module_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/connection/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/connection/exceptions.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/actiontable/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/actiontable/actiontable.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_blink.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_custom.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_discover.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_output.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_raw.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_receive.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/homekit/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/homekit/homekit_config.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/log_entry.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/protocol/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/response.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/action_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/datapoint_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/event_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/event_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/input_action_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/input_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/module_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/module_type_code.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/output_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/reply_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/system_function.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/system_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/telegram_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/telegram/timeparam_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/models/write_config_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/actiontable/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/actiontable/actiontable_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/actiontable/actiontable_download_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/actiontable/actiontable_list_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/actiontable/actiontable_show_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/actiontable/actiontable_upload_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_discover_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/conbus/write_config_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/homekit/homekit_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/log_file_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/module_type_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/protocol/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/protocol/protocol_factory.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/reverse_proxy_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/base_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/cp20_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/device_service_factory.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/xp130_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/xp20_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/xp230_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/xp24_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/server/xp33_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/utils/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/utils/checksum.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/utils/event_helper.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/utils/serialization.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/src/xp/utils/time_utils.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/.coverage +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/conftest.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/.coverage +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/telegram_test_data.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_actiontable_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_api/.coverage +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_api/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_blink_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_checksum_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_conbus_blink_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_conbus_raw_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_conbus_receive_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_discovery_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_event_telegram_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_homekit_config_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_link_number_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_module_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_output_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_version_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_api/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_click_tree.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_decorators.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_formatters.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_connection/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_connection/test_connection_init.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_connection/test_exceptions.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_encoding/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_conbus.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_event_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_log_entry.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_module_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_system_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_version_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_write_config_type.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_actiontable_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_actiontable_upload_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_base_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_blink_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_checksum_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_discovery_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_homekit_services.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_log_file_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_module_type_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_protocol.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_server_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_telegram_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_version_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_utils/__init__.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_utils/test_checksum.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_utils/test_event_helper.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.0}/tests/unit/test_utils/test_serialization.py +0 -0
- {conson_xp-1.16.0 → conson_xp-1.18.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.18.0
|
|
4
4
|
Summary: XP Protocol Communication Tools
|
|
5
5
|
Author-Email: ldvchosal <ldvchosal@github.com>
|
|
6
6
|
License: MIT License
|
|
@@ -305,6 +305,10 @@ xp conbus datapoint query
|
|
|
305
305
|
|
|
306
306
|
xp conbus discover
|
|
307
307
|
|
|
308
|
+
xp conbus event
|
|
309
|
+
xp conbus event raw
|
|
310
|
+
|
|
311
|
+
|
|
308
312
|
xp conbus lightlevel
|
|
309
313
|
xp conbus lightlevel get
|
|
310
314
|
xp conbus lightlevel off
|
|
@@ -37,6 +37,7 @@ from xp.cli.commands.conbus.conbus_datapoint_commands import (
|
|
|
37
37
|
query_datapoint,
|
|
38
38
|
)
|
|
39
39
|
from xp.cli.commands.conbus.conbus_discover_commands import send_discover_telegram
|
|
40
|
+
from xp.cli.commands.conbus.conbus_event_commands import conbus_event, send_event_raw
|
|
40
41
|
from xp.cli.commands.conbus.conbus_lightlevel_commands import (
|
|
41
42
|
xp_lightlevel_get,
|
|
42
43
|
xp_lightlevel_off,
|
|
@@ -97,6 +98,7 @@ __all__ = [
|
|
|
97
98
|
"conbus_lightlevel",
|
|
98
99
|
"conbus_msactiontable",
|
|
99
100
|
"conbus_actiontable",
|
|
101
|
+
"conbus_event",
|
|
100
102
|
"file",
|
|
101
103
|
"module",
|
|
102
104
|
"reverse_proxy",
|
|
@@ -118,6 +120,7 @@ __all__ = [
|
|
|
118
120
|
"show_config",
|
|
119
121
|
"send_custom_telegram",
|
|
120
122
|
"send_discover_telegram",
|
|
123
|
+
"send_event_raw",
|
|
121
124
|
"xp_output_on",
|
|
122
125
|
"xp_output_off",
|
|
123
126
|
"xp_output_status",
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Conbus event operations CLI commands."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from xp.cli.commands.conbus.conbus import conbus
|
|
8
|
+
from xp.cli.utils.decorators import connection_command
|
|
9
|
+
from xp.cli.utils.module_type_choice import MODULE_TYPE
|
|
10
|
+
from xp.models import ConbusEventRawResponse
|
|
11
|
+
from xp.services.conbus.conbus_event_raw_service import ConbusEventRawService
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.group(name="event")
|
|
15
|
+
def conbus_event() -> None:
|
|
16
|
+
"""Send event telegrams to Conbus modules."""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@conbus_event.command("raw")
|
|
21
|
+
@click.argument("module_type", type=MODULE_TYPE)
|
|
22
|
+
@click.argument("link_number", type=click.IntRange(0, 99))
|
|
23
|
+
@click.argument("input_number", type=click.IntRange(0, 9))
|
|
24
|
+
@click.argument("time_ms", type=click.IntRange(min=1), default=1000)
|
|
25
|
+
@click.pass_context
|
|
26
|
+
@connection_command()
|
|
27
|
+
def send_event_raw(
|
|
28
|
+
ctx: click.Context,
|
|
29
|
+
module_type: int,
|
|
30
|
+
link_number: int,
|
|
31
|
+
input_number: int,
|
|
32
|
+
time_ms: int,
|
|
33
|
+
) -> None:
|
|
34
|
+
r"""Send raw event telegrams to simulate button presses.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
ctx: Click context object.
|
|
38
|
+
module_type: Module type code (e.g., CP20, XP33).
|
|
39
|
+
link_number: Link number (0-99).
|
|
40
|
+
input_number: Input number (0-9).
|
|
41
|
+
time_ms: Delay between MAKE/BREAK events in milliseconds (default: 1000).
|
|
42
|
+
|
|
43
|
+
Examples:
|
|
44
|
+
\b
|
|
45
|
+
xp conbus event raw CP20 00 00
|
|
46
|
+
xp conbus event raw XP33 00 00 500
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def on_finish(response: ConbusEventRawResponse) -> None:
|
|
50
|
+
"""Handle successful completion of event raw operation.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
response: Event raw response with sent and received telegrams.
|
|
54
|
+
"""
|
|
55
|
+
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
56
|
+
|
|
57
|
+
def on_progress(telegram: str) -> None:
|
|
58
|
+
"""Handle progress updates during event operation.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
telegram: Received telegram.
|
|
62
|
+
"""
|
|
63
|
+
click.echo(json.dumps({"telegram": telegram}))
|
|
64
|
+
|
|
65
|
+
service: ConbusEventRawService = (
|
|
66
|
+
ctx.obj.get("container").get_container().resolve(ConbusEventRawService)
|
|
67
|
+
)
|
|
68
|
+
service.run(
|
|
69
|
+
module_type_code=module_type,
|
|
70
|
+
link_number=link_number,
|
|
71
|
+
input_number=input_number,
|
|
72
|
+
time_ms=time_ms,
|
|
73
|
+
progress_callback=on_progress,
|
|
74
|
+
finish_callback=on_finish,
|
|
75
|
+
timeout_seconds=5,
|
|
76
|
+
)
|
|
77
|
+
service.start_reactor()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# Register the event command group with conbus
|
|
81
|
+
conbus.add_command(conbus_event)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Click parameter type for ModuleTypeCode enum validation."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from xp.models.telegram.module_type_code import ModuleTypeCode
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ModuleTypeChoice(click.ParamType):
|
|
11
|
+
"""Click parameter type for validating ModuleTypeCode enum values.
|
|
12
|
+
|
|
13
|
+
Attributes:
|
|
14
|
+
name: The parameter type name.
|
|
15
|
+
choices: List of valid choice strings.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
name = "module_type"
|
|
19
|
+
|
|
20
|
+
def __init__(self) -> None:
|
|
21
|
+
"""Initialize the ModuleTypeChoice parameter type."""
|
|
22
|
+
self.choices = [key for key in ModuleTypeCode.__members__.keys()]
|
|
23
|
+
|
|
24
|
+
def convert(
|
|
25
|
+
self, value: Any, param: Optional[click.Parameter], ctx: Optional[click.Context]
|
|
26
|
+
) -> int:
|
|
27
|
+
"""Convert and validate input to ModuleTypeCode value.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
value: The input value to convert.
|
|
31
|
+
param: The Click parameter.
|
|
32
|
+
ctx: The Click context.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Module type code integer value if valid.
|
|
36
|
+
"""
|
|
37
|
+
if value is None:
|
|
38
|
+
self.fail("Module type is required", param, ctx)
|
|
39
|
+
|
|
40
|
+
# Convert to upper for comparison
|
|
41
|
+
normalized_value = value.upper()
|
|
42
|
+
|
|
43
|
+
if normalized_value in self.choices:
|
|
44
|
+
# Return the actual enum value (integer)
|
|
45
|
+
return ModuleTypeCode[normalized_value].value
|
|
46
|
+
|
|
47
|
+
# If not found, show error with available choices
|
|
48
|
+
choices_list = "\n".join(f" - {choice}" for choice in sorted(self.choices))
|
|
49
|
+
self.fail(
|
|
50
|
+
f"{value!r} is not a valid module type. " f"Choose from:\n{choices_list}",
|
|
51
|
+
param,
|
|
52
|
+
ctx,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
MODULE_TYPE = ModuleTypeChoice()
|
|
@@ -5,6 +5,7 @@ from xp.models.conbus.conbus_client_config import ConbusClientConfig
|
|
|
5
5
|
from xp.models.conbus.conbus_connection_status import ConbusConnectionStatus
|
|
6
6
|
from xp.models.conbus.conbus_datapoint import ConbusDatapointResponse
|
|
7
7
|
from xp.models.conbus.conbus_discover import ConbusDiscoverResponse
|
|
8
|
+
from xp.models.conbus.conbus_event_raw import ConbusEventRawResponse
|
|
8
9
|
from xp.models.log_entry import LogEntry
|
|
9
10
|
from xp.models.telegram.event_telegram import EventTelegram
|
|
10
11
|
from xp.models.telegram.event_type import EventType
|
|
@@ -30,5 +31,6 @@ __all__ = [
|
|
|
30
31
|
"ConbusResponse",
|
|
31
32
|
"ConbusDatapointResponse",
|
|
32
33
|
"ConbusDiscoverResponse",
|
|
34
|
+
"ConbusEventRawResponse",
|
|
33
35
|
"ConbusConnectionStatus",
|
|
34
36
|
]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Conbus event raw response model."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any, Dict, Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class ConbusEventRawResponse:
|
|
10
|
+
"""Represents a response from Conbus event raw operation.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
success: Whether the operation was successful.
|
|
14
|
+
sent_telegrams: List of event telegrams sent (MAKE and BREAK).
|
|
15
|
+
received_telegrams: List of all telegrams received.
|
|
16
|
+
error: Error message if operation failed.
|
|
17
|
+
timestamp: Timestamp of the response.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
success: bool
|
|
21
|
+
sent_telegrams: Optional[list[str]] = None
|
|
22
|
+
received_telegrams: Optional[list[str]] = None
|
|
23
|
+
error: Optional[str] = None
|
|
24
|
+
timestamp: Optional[datetime] = None
|
|
25
|
+
|
|
26
|
+
def __post_init__(self) -> None:
|
|
27
|
+
"""Initialize timestamp and telegram lists if not provided."""
|
|
28
|
+
if self.timestamp is None:
|
|
29
|
+
self.timestamp = datetime.now()
|
|
30
|
+
if self.sent_telegrams is None:
|
|
31
|
+
self.sent_telegrams = []
|
|
32
|
+
if self.received_telegrams is None:
|
|
33
|
+
self.received_telegrams = []
|
|
34
|
+
|
|
35
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
36
|
+
"""Convert to dictionary for JSON serialization.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Dictionary representation of the response.
|
|
40
|
+
"""
|
|
41
|
+
return {
|
|
42
|
+
"success": self.success,
|
|
43
|
+
"sent_telegrams": self.sent_telegrams,
|
|
44
|
+
"received_telegrams": self.received_telegrams,
|
|
45
|
+
"error": self.error,
|
|
46
|
+
"timestamp": self.timestamp.isoformat() if self.timestamp else None,
|
|
47
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""Conbus Event Raw Service for sending raw event telegrams.
|
|
2
|
+
|
|
3
|
+
This service implements a TCP client that connects to Conbus servers and sends
|
|
4
|
+
raw event telegrams to simulate button presses on Conbus modules.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from typing import Callable, Optional
|
|
9
|
+
|
|
10
|
+
from twisted.internet.base import DelayedCall
|
|
11
|
+
|
|
12
|
+
from xp.models import ConbusEventRawResponse
|
|
13
|
+
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
14
|
+
from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ConbusEventRawService:
|
|
18
|
+
"""Service for sending raw event telegrams to Conbus servers.
|
|
19
|
+
|
|
20
|
+
Uses ConbusEventProtocol to send MAKE/BREAK event sequences to
|
|
21
|
+
simulate button presses on Conbus modules.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
conbus_protocol: Protocol instance for Conbus communication.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
conbus_protocol: ConbusEventProtocol
|
|
28
|
+
|
|
29
|
+
def __init__(self, conbus_protocol: ConbusEventProtocol) -> None:
|
|
30
|
+
"""Initialize the Conbus event raw service.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
conbus_protocol: ConbusEventProtocol instance.
|
|
34
|
+
"""
|
|
35
|
+
self.progress_callback: Optional[Callable[[str], None]] = None
|
|
36
|
+
self.finish_callback: Optional[Callable[[ConbusEventRawResponse], None]] = None
|
|
37
|
+
|
|
38
|
+
self.conbus_protocol: ConbusEventProtocol = conbus_protocol
|
|
39
|
+
self.conbus_protocol.on_connection_made.connect(self.connection_made)
|
|
40
|
+
self.conbus_protocol.on_telegram_sent.connect(self.telegram_sent)
|
|
41
|
+
self.conbus_protocol.on_telegram_received.connect(self.telegram_received)
|
|
42
|
+
self.conbus_protocol.on_timeout.connect(self.timeout)
|
|
43
|
+
self.conbus_protocol.on_failed.connect(self.failed)
|
|
44
|
+
|
|
45
|
+
self.event_result = ConbusEventRawResponse(success=False)
|
|
46
|
+
self.logger = logging.getLogger(__name__)
|
|
47
|
+
|
|
48
|
+
# Event parameters
|
|
49
|
+
self.module_type_code: int = 0
|
|
50
|
+
self.link_number: int = 0
|
|
51
|
+
self.input_number: int = 0
|
|
52
|
+
self.time_ms: int = 1000
|
|
53
|
+
self.break_event_call: Optional[DelayedCall] = None
|
|
54
|
+
|
|
55
|
+
def connection_made(self) -> None:
|
|
56
|
+
"""Handle connection established event."""
|
|
57
|
+
self.logger.debug("Connection established")
|
|
58
|
+
self.logger.debug("Sending MAKE event telegram")
|
|
59
|
+
self._send_make_event()
|
|
60
|
+
|
|
61
|
+
def _send_make_event(self) -> None:
|
|
62
|
+
"""Send MAKE event telegram."""
|
|
63
|
+
payload = f"E{self.module_type_code:02d}L{self.link_number:02d}I{self.input_number:02d}M"
|
|
64
|
+
self.logger.debug(f"Sending MAKE event: {payload}")
|
|
65
|
+
self.conbus_protocol.telegram_queue.put_nowait(payload.encode())
|
|
66
|
+
self.conbus_protocol.call_later(0.0, self.conbus_protocol.start_queue_manager)
|
|
67
|
+
|
|
68
|
+
# Schedule BREAK event after delay
|
|
69
|
+
delay_seconds = self.time_ms / 1000.0
|
|
70
|
+
self.break_event_call = self.conbus_protocol.call_later(
|
|
71
|
+
delay_seconds, self._send_break_event
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def _send_break_event(self) -> None:
|
|
75
|
+
"""Send BREAK event telegram."""
|
|
76
|
+
payload = f"E{self.module_type_code:02d}L{self.link_number:02d}I{self.input_number:02d}B"
|
|
77
|
+
self.logger.debug(f"Sending BREAK event: {payload}")
|
|
78
|
+
self.conbus_protocol.telegram_queue.put_nowait(payload.encode())
|
|
79
|
+
self.conbus_protocol.call_later(0.0, self.conbus_protocol.start_queue_manager)
|
|
80
|
+
|
|
81
|
+
def telegram_sent(self, telegram_sent: str) -> None:
|
|
82
|
+
"""Handle telegram sent event.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
telegram_sent: The telegram that was sent.
|
|
86
|
+
"""
|
|
87
|
+
self.logger.debug(f"Telegram sent: {telegram_sent}")
|
|
88
|
+
if self.event_result.sent_telegrams is None:
|
|
89
|
+
self.event_result.sent_telegrams = []
|
|
90
|
+
self.event_result.sent_telegrams.append(telegram_sent)
|
|
91
|
+
|
|
92
|
+
def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
|
|
93
|
+
"""Handle telegram received event.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
telegram_received: The telegram received event.
|
|
97
|
+
"""
|
|
98
|
+
self.logger.debug(f"Telegram received: {telegram_received.frame}")
|
|
99
|
+
if self.event_result.received_telegrams is None:
|
|
100
|
+
self.event_result.received_telegrams = []
|
|
101
|
+
self.event_result.received_telegrams.append(telegram_received.frame)
|
|
102
|
+
|
|
103
|
+
# Display progress - show ALL received telegrams
|
|
104
|
+
if self.progress_callback:
|
|
105
|
+
self.progress_callback(telegram_received.frame)
|
|
106
|
+
|
|
107
|
+
def timeout(self) -> None:
|
|
108
|
+
"""Handle timeout event.
|
|
109
|
+
|
|
110
|
+
Timeout is the normal/expected way to finish this service.
|
|
111
|
+
"""
|
|
112
|
+
timeout_seconds = self.conbus_protocol.timeout_seconds
|
|
113
|
+
self.logger.info("Event raw finished after timeout: %ss", timeout_seconds)
|
|
114
|
+
self.event_result.success = True
|
|
115
|
+
self.event_result.error = None
|
|
116
|
+
if self.finish_callback:
|
|
117
|
+
self.finish_callback(self.event_result)
|
|
118
|
+
|
|
119
|
+
self.stop_reactor()
|
|
120
|
+
|
|
121
|
+
def failed(self, message: str) -> None:
|
|
122
|
+
"""Handle failed connection event.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
message: Failure message.
|
|
126
|
+
"""
|
|
127
|
+
self.logger.debug(f"Failed: {message}")
|
|
128
|
+
self.event_result.success = False
|
|
129
|
+
self.event_result.error = message
|
|
130
|
+
if self.finish_callback:
|
|
131
|
+
self.finish_callback(self.event_result)
|
|
132
|
+
|
|
133
|
+
self.stop_reactor()
|
|
134
|
+
|
|
135
|
+
def stop_reactor(self) -> None:
|
|
136
|
+
"""Stop reactor."""
|
|
137
|
+
self.logger.info("Stopping reactor")
|
|
138
|
+
# Cancel break event call if it's still pending
|
|
139
|
+
if self.break_event_call and self.break_event_call.active():
|
|
140
|
+
self.break_event_call.cancel()
|
|
141
|
+
self.conbus_protocol.stop_reactor()
|
|
142
|
+
|
|
143
|
+
def start_reactor(self) -> None:
|
|
144
|
+
"""Start reactor."""
|
|
145
|
+
self.logger.info("Starting reactor")
|
|
146
|
+
self.conbus_protocol.start_reactor()
|
|
147
|
+
|
|
148
|
+
def run(
|
|
149
|
+
self,
|
|
150
|
+
module_type_code: int,
|
|
151
|
+
link_number: int,
|
|
152
|
+
input_number: int,
|
|
153
|
+
time_ms: int,
|
|
154
|
+
progress_callback: Optional[Callable[[str], None]],
|
|
155
|
+
finish_callback: Callable[[ConbusEventRawResponse], None],
|
|
156
|
+
timeout_seconds: int = 5,
|
|
157
|
+
) -> None:
|
|
158
|
+
"""Run reactor in dedicated thread with its own event loop.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
module_type_code: Module type code (numeric, e.g., 2 for CP20, 33 for XP33).
|
|
162
|
+
link_number: Link number (0-99).
|
|
163
|
+
input_number: Input number (0-9).
|
|
164
|
+
time_ms: Delay in milliseconds between MAKE and BREAK events.
|
|
165
|
+
progress_callback: Callback for progress updates (received telegrams).
|
|
166
|
+
finish_callback: Callback when operation completes.
|
|
167
|
+
timeout_seconds: Timeout in seconds (default: 5).
|
|
168
|
+
"""
|
|
169
|
+
self.logger.info(
|
|
170
|
+
f"Starting event raw: module={module_type_code}, "
|
|
171
|
+
f"link={link_number}, input={input_number}, time={time_ms}ms"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
self.module_type_code = module_type_code
|
|
175
|
+
self.link_number = link_number
|
|
176
|
+
self.input_number = input_number
|
|
177
|
+
self.time_ms = time_ms
|
|
178
|
+
|
|
179
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
180
|
+
self.progress_callback = progress_callback
|
|
181
|
+
self.finish_callback = finish_callback
|
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
from queue import SimpleQueue
|
|
8
8
|
from random import randint
|
|
9
9
|
from threading import Lock
|
|
10
|
-
from typing import Any, Optional
|
|
10
|
+
from typing import Any, Callable, Optional
|
|
11
11
|
|
|
12
12
|
from psygnal import Signal
|
|
13
13
|
from twisted.internet import protocol
|
|
@@ -209,7 +209,27 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
209
209
|
f"D{data_value}"
|
|
210
210
|
)
|
|
211
211
|
self.telegram_queue.put_nowait(payload.encode())
|
|
212
|
-
self.
|
|
212
|
+
self.call_later(0.0, self.start_queue_manager)
|
|
213
|
+
|
|
214
|
+
def call_later(
|
|
215
|
+
self,
|
|
216
|
+
delay: float,
|
|
217
|
+
callable_action: Callable[..., Any],
|
|
218
|
+
*args: object,
|
|
219
|
+
**kw: object,
|
|
220
|
+
) -> DelayedCall:
|
|
221
|
+
"""Schedule a callable to be called later.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
delay: Delay in seconds before calling.
|
|
225
|
+
callable_action: The callable to execute.
|
|
226
|
+
args: Positional arguments to pass to callable.
|
|
227
|
+
kw: Keyword arguments to pass to callable.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
DelayedCall object that can be cancelled.
|
|
231
|
+
"""
|
|
232
|
+
return self._reactor.callLater(delay, callable_action, *args, **kw)
|
|
213
233
|
|
|
214
234
|
def buildProtocol(self, addr: IAddress) -> protocol.Protocol:
|
|
215
235
|
"""Build protocol instance for connection.
|
|
@@ -264,9 +284,7 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
264
284
|
def _reset_timeout(self) -> None:
|
|
265
285
|
"""Reset the inactivity timeout."""
|
|
266
286
|
self._cancel_timeout()
|
|
267
|
-
self.timeout_call = self.
|
|
268
|
-
self.timeout_seconds, self._on_timeout
|
|
269
|
-
)
|
|
287
|
+
self.timeout_call = self.call_later(self.timeout_seconds, self._on_timeout)
|
|
270
288
|
|
|
271
289
|
def _cancel_timeout(self) -> None:
|
|
272
290
|
"""Cancel the inactivity timeout."""
|
|
@@ -320,7 +338,7 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
|
|
|
320
338
|
telegram = self.telegram_queue.get_nowait()
|
|
321
339
|
self.sendFrame(telegram)
|
|
322
340
|
later = randint(10, 80) / 100
|
|
323
|
-
self.
|
|
341
|
+
self.call_later(later, self.process_telegram_queue)
|
|
324
342
|
|
|
325
343
|
def __enter__(self) -> "ConbusEventProtocol":
|
|
326
344
|
"""Enter context manager.
|
|
@@ -43,6 +43,7 @@ from xp.services.conbus.conbus_datapoint_service import (
|
|
|
43
43
|
ConbusDatapointService,
|
|
44
44
|
)
|
|
45
45
|
from xp.services.conbus.conbus_discover_service import ConbusDiscoverService
|
|
46
|
+
from xp.services.conbus.conbus_event_raw_service import ConbusEventRawService
|
|
46
47
|
from xp.services.conbus.conbus_output_service import ConbusOutputService
|
|
47
48
|
from xp.services.conbus.conbus_raw_service import ConbusRawService
|
|
48
49
|
from xp.services.conbus.conbus_receive_service import ConbusReceiveService
|
|
@@ -180,6 +181,14 @@ class ServiceContainer:
|
|
|
180
181
|
scope=punq.Scope.singleton,
|
|
181
182
|
)
|
|
182
183
|
|
|
184
|
+
self.container.register(
|
|
185
|
+
ConbusEventRawService,
|
|
186
|
+
factory=lambda: ConbusEventRawService(
|
|
187
|
+
conbus_protocol=self.container.resolve(ConbusEventProtocol)
|
|
188
|
+
),
|
|
189
|
+
scope=punq.Scope.singleton,
|
|
190
|
+
)
|
|
191
|
+
|
|
183
192
|
self.container.register(
|
|
184
193
|
ConbusBlinkService,
|
|
185
194
|
factory=lambda: ConbusBlinkService(
|