conson-xp 1.3.0__tar.gz → 1.4.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.3.0 → conson_xp-1.4.0}/PKG-INFO +1 -1
- {conson_xp-1.3.0 → conson_xp-1.4.0}/pyproject.toml +1 -1
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/__init__.py +1 -1
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_discover.py +19 -3
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/system_telegram.py +4 -4
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_discover_service.py +120 -2
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_scan_service.py +1 -1
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/protocol/telegram_protocol.py +4 -4
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/server/base_server_service.py +9 -4
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/server/cp20_server_service.py +2 -1
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/server/server_service.py +75 -4
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/server/xp130_server_service.py +2 -1
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/server/xp20_server_service.py +2 -1
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/server/xp230_server_service.py +2 -1
- conson_xp-1.4.0/src/xp/services/server/xp24_server_service.py +192 -0
- conson_xp-1.4.0/src/xp/services/server/xp33_server_service.py +306 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_conbus_discover.py +28 -2
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_base_server_service.py +4 -3
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_xp_server_services.py +7 -7
- conson_xp-1.3.0/src/xp/services/server/xp24_server_service.py +0 -119
- conson_xp-1.3.0/src/xp/services/server/xp33_server_service.py +0 -176
- {conson_xp-1.3.0 → conson_xp-1.4.0}/LICENSE +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/README.md +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/__main__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/file_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/module_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/server/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/server/server_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/main.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/click_tree.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/decorators.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/error_handlers.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/formatters.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/serial_number_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/system_function_choice.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/cli/utils/xp_module_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/connection/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/connection/exceptions.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/actiontable/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/actiontable/actiontable.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/actiontable/msactiontable_xp24.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_blink.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_custom.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_output.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_raw.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_receive.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/homekit/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/homekit/homekit_config.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/homekit/homekit_conson_config.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/log_entry.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/protocol/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/response.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/action_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/datapoint_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/event_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/event_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/input_action_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/input_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/module_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/module_type_code.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/output_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/reply_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/system_function.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/telegram_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/telegram/timeparam_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/models/write_config_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/actiontable/actiontable_serializer.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/actiontable/actiontable_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/actiontable/msactiontable_xp20_serializer.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/actiontable/msactiontable_xp24_serializer.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/actiontable/msactiontable_xp33_serializer.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/conbus/write_config_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/homekit/homekit_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/log_file_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/module_type_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/protocol/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/protocol/protocol_factory.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/reverse_proxy_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/server/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/utils/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/utils/checksum.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/utils/dependencies.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/utils/event_helper.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/utils/serialization.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/src/xp/utils/time_utils.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/.coverage +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/conftest.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/.coverage +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/telegram_test_data.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_actiontable_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_api/.coverage +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_api/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_blink_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_checksum_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_conbus_blink_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_conbus_raw_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_conbus_receive_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_discovery_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_event_telegram_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_homekit_config_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_link_number_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_module_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_output_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_version_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/integration/test_xp24_action_table_integration.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_api/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_click_tree.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_decorators.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_formatters.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_connection/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_connection/test_connection_init.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_connection/test_exceptions.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_encoding/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_conbus.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_event_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_log_entry.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_module_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_system_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_version_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_write_config_type.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_xp24_action_table.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_actiontable_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_blink_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_checksum_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_discovery_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_homekit_services.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_log_file_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_module_type_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_protocol.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_server_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_telegram_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_version_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_xp24_action_table_service.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_utils/__init__.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_utils/test_checksum.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_utils/test_event_helper.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_utils/test_serialization.py +0 -0
- {conson_xp-1.3.0 → conson_xp-1.4.0}/tests/unit/test_utils/test_time_utils.py +0 -0
|
@@ -2,7 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from datetime import datetime
|
|
5
|
-
from typing import Any, Dict, Optional
|
|
5
|
+
from typing import Any, Dict, Optional, TypedDict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DiscoveredDevice(TypedDict):
|
|
9
|
+
"""Discovered device information.
|
|
10
|
+
|
|
11
|
+
Attributes:
|
|
12
|
+
serial_number: Serial number of the device.
|
|
13
|
+
module_type: Module type name (e.g., "XP24", "XP230"), None if not yet retrieved.
|
|
14
|
+
module_type_code: Module type code (e.g., "13", "10"), None if not yet retrieved.
|
|
15
|
+
module_type_name: Module type name converted from module_type_code, None if not yet retrieved.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
serial_number: str
|
|
19
|
+
module_type: Optional[str]
|
|
20
|
+
module_type_code: Optional[int]
|
|
21
|
+
module_type_name: Optional[str]
|
|
6
22
|
|
|
7
23
|
|
|
8
24
|
@dataclass
|
|
@@ -13,7 +29,7 @@ class ConbusDiscoverResponse:
|
|
|
13
29
|
success: Whether the operation was successful.
|
|
14
30
|
sent_telegram: Telegram sent to discover devices.
|
|
15
31
|
received_telegrams: List of telegrams received.
|
|
16
|
-
discovered_devices: List of discovered
|
|
32
|
+
discovered_devices: List of discovered devices with their module types.
|
|
17
33
|
error: Error message if operation failed.
|
|
18
34
|
timestamp: Timestamp of the response.
|
|
19
35
|
"""
|
|
@@ -21,7 +37,7 @@ class ConbusDiscoverResponse:
|
|
|
21
37
|
success: bool
|
|
22
38
|
sent_telegram: Optional[str] = None
|
|
23
39
|
received_telegrams: Optional[list[str]] = None
|
|
24
|
-
discovered_devices: Optional[list[
|
|
40
|
+
discovered_devices: Optional[list[DiscoveredDevice]] = None
|
|
25
41
|
error: Optional[str] = None
|
|
26
42
|
timestamp: Optional[datetime] = None
|
|
27
43
|
|
|
@@ -22,10 +22,10 @@ class SystemTelegram(Telegram):
|
|
|
22
22
|
Examples: <S0020012521F02D18FN>
|
|
23
23
|
|
|
24
24
|
Attributes:
|
|
25
|
-
serial_number: Serial number of the device
|
|
26
|
-
system_function: System function code.
|
|
27
|
-
data: Data payload
|
|
28
|
-
datapoint_type: Type of datapoint.
|
|
25
|
+
serial_number: Serial number of the device (0020012521)
|
|
26
|
+
system_function: System function code (02).
|
|
27
|
+
data: Data payload (18)
|
|
28
|
+
datapoint_type: Type of datapoint (18).
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
31
|
serial_number: str = ""
|
|
@@ -10,7 +10,10 @@ from typing import Callable, Optional
|
|
|
10
10
|
from twisted.internet.posixbase import PosixReactorBase
|
|
11
11
|
|
|
12
12
|
from xp.models import ConbusClientConfig, ConbusDiscoverResponse
|
|
13
|
+
from xp.models.conbus.conbus_discover import DiscoveredDevice
|
|
13
14
|
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
15
|
+
from xp.models.telegram.datapoint_type import DataPointType
|
|
16
|
+
from xp.models.telegram.module_type_code import MODULE_TYPE_REGISTRY
|
|
14
17
|
from xp.models.telegram.system_function import SystemFunction
|
|
15
18
|
from xp.models.telegram.telegram_type import TelegramType
|
|
16
19
|
from xp.services.protocol.conbus_protocol import ConbusProtocol
|
|
@@ -73,6 +76,7 @@ class ConbusDiscoverService(ConbusProtocol):
|
|
|
73
76
|
self.discovered_device_result.received_telegrams = []
|
|
74
77
|
self.discovered_device_result.received_telegrams.append(telegram_received.frame)
|
|
75
78
|
|
|
79
|
+
# Check for discovery response
|
|
76
80
|
if (
|
|
77
81
|
telegram_received.checksum_valid
|
|
78
82
|
and telegram_received.telegram_type == TelegramType.REPLY.value
|
|
@@ -80,8 +84,30 @@ class ConbusDiscoverService(ConbusProtocol):
|
|
|
80
84
|
and len(telegram_received.payload) == 15
|
|
81
85
|
):
|
|
82
86
|
self.discovered_device(telegram_received.serial_number)
|
|
87
|
+
|
|
88
|
+
# Check for module type response (F02D07)
|
|
89
|
+
elif (
|
|
90
|
+
telegram_received.checksum_valid
|
|
91
|
+
and telegram_received.telegram_type == TelegramType.REPLY.value
|
|
92
|
+
and telegram_received.payload[11:17] == "F02D07"
|
|
93
|
+
and len(telegram_received.payload) >= 19
|
|
94
|
+
):
|
|
95
|
+
self.handle_module_type_code_response(
|
|
96
|
+
telegram_received.serial_number, telegram_received.payload[17:19]
|
|
97
|
+
)
|
|
98
|
+
# Check for module type response (F02D00)
|
|
99
|
+
elif (
|
|
100
|
+
telegram_received.checksum_valid
|
|
101
|
+
and telegram_received.telegram_type == TelegramType.REPLY.value
|
|
102
|
+
and telegram_received.payload[11:17] == "F02D00"
|
|
103
|
+
and len(telegram_received.payload) >= 19
|
|
104
|
+
):
|
|
105
|
+
self.handle_module_type_response(
|
|
106
|
+
telegram_received.serial_number, telegram_received.payload[17:19]
|
|
107
|
+
)
|
|
108
|
+
|
|
83
109
|
else:
|
|
84
|
-
self.logger.debug("Not a discover response")
|
|
110
|
+
self.logger.debug("Not a discover or module type response")
|
|
85
111
|
|
|
86
112
|
def discovered_device(self, serial_number: str) -> None:
|
|
87
113
|
"""Handle discovered device event.
|
|
@@ -92,10 +118,102 @@ class ConbusDiscoverService(ConbusProtocol):
|
|
|
92
118
|
self.logger.info("discovered_device: %s", serial_number)
|
|
93
119
|
if not self.discovered_device_result.discovered_devices:
|
|
94
120
|
self.discovered_device_result.discovered_devices = []
|
|
95
|
-
|
|
121
|
+
|
|
122
|
+
# Add device with module_type as None initially
|
|
123
|
+
device: DiscoveredDevice = {
|
|
124
|
+
"serial_number": serial_number,
|
|
125
|
+
"module_type": None,
|
|
126
|
+
"module_type_code": None,
|
|
127
|
+
"module_type_name": None,
|
|
128
|
+
}
|
|
129
|
+
self.discovered_device_result.discovered_devices.append(device)
|
|
130
|
+
|
|
131
|
+
# Send READ_DATAPOINT telegram to query module type
|
|
132
|
+
self.logger.debug(f"Sending module type query for {serial_number}")
|
|
133
|
+
self.send_telegram(
|
|
134
|
+
telegram_type=TelegramType.SYSTEM,
|
|
135
|
+
serial_number=serial_number,
|
|
136
|
+
system_function=SystemFunction.READ_DATAPOINT,
|
|
137
|
+
data_value=DataPointType.MODULE_TYPE.value,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
self.send_telegram(
|
|
141
|
+
telegram_type=TelegramType.SYSTEM,
|
|
142
|
+
serial_number=serial_number,
|
|
143
|
+
system_function=SystemFunction.READ_DATAPOINT,
|
|
144
|
+
data_value=DataPointType.MODULE_TYPE_CODE.value,
|
|
145
|
+
)
|
|
146
|
+
|
|
96
147
|
if self.progress_callback:
|
|
97
148
|
self.progress_callback(serial_number)
|
|
98
149
|
|
|
150
|
+
def handle_module_type_code_response(
|
|
151
|
+
self, serial_number: str, module_type_code: str
|
|
152
|
+
) -> None:
|
|
153
|
+
"""Handle module type code response and update discovered device.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
serial_number: Serial number of the device.
|
|
157
|
+
module_type_code: Module type code from telegram (e.g., "07", "24").
|
|
158
|
+
"""
|
|
159
|
+
self.logger.info(
|
|
160
|
+
f"Received module type code {module_type_code} for {serial_number}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Convert module type code to name
|
|
164
|
+
code = 0
|
|
165
|
+
try:
|
|
166
|
+
# The telegram format uses decimal values represented as strings
|
|
167
|
+
code = int(module_type_code)
|
|
168
|
+
module_info = MODULE_TYPE_REGISTRY.get(code)
|
|
169
|
+
|
|
170
|
+
if module_info:
|
|
171
|
+
module_type_name = module_info["name"]
|
|
172
|
+
self.logger.debug(
|
|
173
|
+
f"Module type code {module_type_code} ({code}) = {module_type_name}"
|
|
174
|
+
)
|
|
175
|
+
else:
|
|
176
|
+
module_type_name = f"UNKNOWN_{module_type_code}"
|
|
177
|
+
self.logger.warning(
|
|
178
|
+
f"Unknown module type code {module_type_code} ({code})"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
except ValueError:
|
|
182
|
+
self.logger.error(
|
|
183
|
+
f"Invalid module type code format: {module_type_code} for {serial_number}"
|
|
184
|
+
)
|
|
185
|
+
module_type_name = f"INVALID_{module_type_code}"
|
|
186
|
+
|
|
187
|
+
# Find and update the device in discovered_devices
|
|
188
|
+
if self.discovered_device_result.discovered_devices:
|
|
189
|
+
for device in self.discovered_device_result.discovered_devices:
|
|
190
|
+
if device["serial_number"] == serial_number:
|
|
191
|
+
device["module_type_code"] = code
|
|
192
|
+
device["module_type_name"] = module_type_name
|
|
193
|
+
self.logger.debug(
|
|
194
|
+
f"Updated device {serial_number} with module_type {module_type_name}"
|
|
195
|
+
)
|
|
196
|
+
break
|
|
197
|
+
|
|
198
|
+
def handle_module_type_response(self, serial_number: str, module_type: str) -> None:
|
|
199
|
+
"""Handle module type response and update discovered device.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
serial_number: Serial number of the device.
|
|
203
|
+
module_type: Module type code from telegram (e.g., "XP33", "XP24").
|
|
204
|
+
"""
|
|
205
|
+
self.logger.info(f"Received module type {module_type} for {serial_number}")
|
|
206
|
+
|
|
207
|
+
# Find and update the device in discovered_devices
|
|
208
|
+
if self.discovered_device_result.discovered_devices:
|
|
209
|
+
for device in self.discovered_device_result.discovered_devices:
|
|
210
|
+
if device["serial_number"] == serial_number:
|
|
211
|
+
device["module_type"] = module_type
|
|
212
|
+
self.logger.debug(
|
|
213
|
+
f"Updated device {serial_number} with module_type {module_type}"
|
|
214
|
+
)
|
|
215
|
+
break
|
|
216
|
+
|
|
99
217
|
def timeout(self) -> bool:
|
|
100
218
|
"""Handle timeout event to stop discovery.
|
|
101
219
|
|
|
@@ -128,7 +128,7 @@ class ConbusScanService(ConbusProtocol):
|
|
|
128
128
|
function_code: str,
|
|
129
129
|
progress_callback: Callable[[str], None],
|
|
130
130
|
finish_callback: Callable[[ConbusResponse], None],
|
|
131
|
-
timeout_seconds:
|
|
131
|
+
timeout_seconds: float = 0.25,
|
|
132
132
|
) -> None:
|
|
133
133
|
"""Scan a module for all datapoints by function code.
|
|
134
134
|
|
|
@@ -124,7 +124,7 @@ class TelegramProtocol(protocol.Protocol):
|
|
|
124
124
|
payload = telegram[:-2] # S0123450001F02D12
|
|
125
125
|
checksum = telegram[-2:].decode() # FK
|
|
126
126
|
serial_number = (
|
|
127
|
-
telegram[1:11] if telegram_type in "S" else b""
|
|
127
|
+
telegram[1:11] if telegram_type in ("S", "R") else b""
|
|
128
128
|
) # 0123450001
|
|
129
129
|
calculated_checksum = calculate_checksum(payload.decode(encoding="latin-1"))
|
|
130
130
|
|
|
@@ -151,9 +151,9 @@ class TelegramProtocol(protocol.Protocol):
|
|
|
151
151
|
await self.event_bus.dispatch(
|
|
152
152
|
TelegramReceivedEvent(
|
|
153
153
|
protocol=self,
|
|
154
|
-
frame=frame.decode(),
|
|
155
|
-
telegram=telegram.decode(),
|
|
156
|
-
payload=payload.decode(),
|
|
154
|
+
frame=frame.decode("latin-1"),
|
|
155
|
+
telegram=telegram.decode("latin-1"),
|
|
156
|
+
payload=payload.decode("latin-1"),
|
|
157
157
|
telegram_type=telegram_type,
|
|
158
158
|
serial_number=serial_number,
|
|
159
159
|
checksum=checksum,
|
|
@@ -8,6 +8,7 @@ import logging
|
|
|
8
8
|
from abc import ABC
|
|
9
9
|
from typing import Optional
|
|
10
10
|
|
|
11
|
+
from xp.models import ModuleTypeCode
|
|
11
12
|
from xp.models.telegram.datapoint_type import DataPointType
|
|
12
13
|
from xp.models.telegram.system_function import SystemFunction
|
|
13
14
|
from xp.models.telegram.system_telegram import SystemTelegram
|
|
@@ -33,7 +34,7 @@ class BaseServerService(ABC):
|
|
|
33
34
|
|
|
34
35
|
# Must be set by subclasses
|
|
35
36
|
self.device_type: str = ""
|
|
36
|
-
self.module_type_code:
|
|
37
|
+
self.module_type_code: ModuleTypeCode = ModuleTypeCode.NOMOD
|
|
37
38
|
self.hardware_version: str = ""
|
|
38
39
|
self.software_version: str = ""
|
|
39
40
|
self.device_status: str = "OK"
|
|
@@ -54,11 +55,11 @@ class BaseServerService(ABC):
|
|
|
54
55
|
"""
|
|
55
56
|
datapoint_values = {
|
|
56
57
|
DataPointType.TEMPERATURE: self.temperature,
|
|
57
|
-
DataPointType.MODULE_TYPE_CODE: f"{self.module_type_code:
|
|
58
|
+
DataPointType.MODULE_TYPE_CODE: f"{self.module_type_code.value:02}",
|
|
58
59
|
DataPointType.SW_VERSION: self.software_version,
|
|
59
60
|
DataPointType.MODULE_STATE: self.device_status,
|
|
60
61
|
DataPointType.MODULE_TYPE: self.device_type,
|
|
61
|
-
DataPointType.LINK_NUMBER: f"{self.link_number:
|
|
62
|
+
DataPointType.LINK_NUMBER: f"{self.link_number:02}",
|
|
62
63
|
DataPointType.VOLTAGE: self.voltage,
|
|
63
64
|
DataPointType.HW_VERSION: self.hardware_version,
|
|
64
65
|
DataPointType.MODULE_ERROR_CODE: "00",
|
|
@@ -187,11 +188,15 @@ class BaseServerService(ABC):
|
|
|
187
188
|
self.logger.debug(
|
|
188
189
|
f"_handle_return_data_request {self.device_type} request: {request}"
|
|
189
190
|
)
|
|
191
|
+
module_specific = self._handle_device_specific_data_request(request)
|
|
192
|
+
if module_specific:
|
|
193
|
+
return module_specific
|
|
194
|
+
|
|
190
195
|
if request.datapoint_type:
|
|
191
196
|
return self.generate_datapoint_type_response(request.datapoint_type)
|
|
192
197
|
|
|
193
198
|
# Allow device-specific handlers
|
|
194
|
-
return
|
|
199
|
+
return None
|
|
195
200
|
|
|
196
201
|
def _handle_device_specific_data_request(
|
|
197
202
|
self, request: SystemTelegram
|
|
@@ -6,6 +6,7 @@ including response generation and device configuration handling.
|
|
|
6
6
|
|
|
7
7
|
from typing import Dict, Optional
|
|
8
8
|
|
|
9
|
+
from xp.models import ModuleTypeCode
|
|
9
10
|
from xp.models.telegram.system_telegram import SystemTelegram
|
|
10
11
|
from xp.services.server.base_server_service import BaseServerService
|
|
11
12
|
|
|
@@ -32,7 +33,7 @@ class CP20ServerService(BaseServerService):
|
|
|
32
33
|
"""
|
|
33
34
|
super().__init__(serial_number)
|
|
34
35
|
self.device_type = "CP20"
|
|
35
|
-
self.module_type_code =
|
|
36
|
+
self.module_type_code = ModuleTypeCode.CP20 # CP20 module type from registry
|
|
36
37
|
self.firmware_version = "CP20_V0.01.05"
|
|
37
38
|
|
|
38
39
|
def _handle_device_specific_data_request(
|
|
@@ -253,15 +253,86 @@ class ServerService:
|
|
|
253
253
|
self.logger.error(f"Error closing client socket: {e}")
|
|
254
254
|
|
|
255
255
|
def _process_request(self, message: str) -> List[str]:
|
|
256
|
-
"""Process incoming request and generate responses.
|
|
256
|
+
"""Process incoming request and generate responses.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
message: Message potentially containing multiple telegrams in format <TELEGRAM><TELEGRAM2>...
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
List of responses for all processed telegrams.
|
|
263
|
+
"""
|
|
264
|
+
responses: list[str] = []
|
|
265
|
+
|
|
266
|
+
try:
|
|
267
|
+
# Split message into individual telegrams (enclosed in angle brackets)
|
|
268
|
+
telegrams = self._split_telegrams(message)
|
|
269
|
+
|
|
270
|
+
if not telegrams:
|
|
271
|
+
self.logger.warning(f"No valid telegrams found in message: {message}")
|
|
272
|
+
return responses
|
|
273
|
+
|
|
274
|
+
# Process each telegram
|
|
275
|
+
for telegram in telegrams:
|
|
276
|
+
telegram_responses = self._process_single_telegram(telegram)
|
|
277
|
+
responses.extend(telegram_responses)
|
|
278
|
+
|
|
279
|
+
except Exception as e:
|
|
280
|
+
self.logger.error(f"Error processing request: {e}")
|
|
281
|
+
|
|
282
|
+
return responses
|
|
283
|
+
|
|
284
|
+
def _split_telegrams(self, message: str) -> List[str]:
|
|
285
|
+
"""Split message into individual telegrams.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
message: Raw message containing one or more telegrams in format <TELEGRAM><TELEGRAM2>...
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
List of individual telegram strings including angle brackets.
|
|
292
|
+
"""
|
|
293
|
+
telegrams = []
|
|
294
|
+
start = 0
|
|
295
|
+
|
|
296
|
+
while True:
|
|
297
|
+
# Find the start of a telegram
|
|
298
|
+
start_idx = message.find("<", start)
|
|
299
|
+
if start_idx == -1:
|
|
300
|
+
break
|
|
301
|
+
|
|
302
|
+
# Find the end of the telegram
|
|
303
|
+
end_idx = message.find(">", start_idx)
|
|
304
|
+
if end_idx == -1:
|
|
305
|
+
self.logger.warning(
|
|
306
|
+
f"Incomplete telegram found starting at position {start_idx}"
|
|
307
|
+
)
|
|
308
|
+
break
|
|
309
|
+
|
|
310
|
+
# Extract telegram including angle brackets
|
|
311
|
+
telegram = message[start_idx : end_idx + 1]
|
|
312
|
+
telegrams.append(telegram)
|
|
313
|
+
|
|
314
|
+
# Move to the next position
|
|
315
|
+
start = end_idx + 1
|
|
316
|
+
|
|
317
|
+
return telegrams
|
|
318
|
+
|
|
319
|
+
def _process_single_telegram(self, telegram: str) -> List[str]:
|
|
320
|
+
"""Process a single telegram and generate responses.
|
|
321
|
+
|
|
322
|
+
Args:
|
|
323
|
+
telegram: A single telegram string.
|
|
324
|
+
|
|
325
|
+
Returns:
|
|
326
|
+
List of response strings for this telegram.
|
|
327
|
+
"""
|
|
257
328
|
responses: list[str] = []
|
|
258
329
|
|
|
259
330
|
try:
|
|
260
331
|
# Parse the telegram
|
|
261
|
-
parsed_telegram = self.telegram_service.parse_system_telegram(
|
|
332
|
+
parsed_telegram = self.telegram_service.parse_system_telegram(telegram)
|
|
262
333
|
|
|
263
334
|
if not parsed_telegram:
|
|
264
|
-
self.logger.warning(f"Failed to parse telegram: {
|
|
335
|
+
self.logger.warning(f"Failed to parse telegram: {telegram}")
|
|
265
336
|
return responses
|
|
266
337
|
|
|
267
338
|
# Handle discover requests
|
|
@@ -296,7 +367,7 @@ class ServerService:
|
|
|
296
367
|
)
|
|
297
368
|
|
|
298
369
|
except Exception as e:
|
|
299
|
-
self.logger.error(f"Error processing
|
|
370
|
+
self.logger.error(f"Error processing telegram: {e}")
|
|
300
371
|
|
|
301
372
|
return responses
|
|
302
373
|
|
|
@@ -7,6 +7,7 @@ XP130 is an Ethernet/TCPIP interface module.
|
|
|
7
7
|
|
|
8
8
|
from typing import Dict
|
|
9
9
|
|
|
10
|
+
from xp.models import ModuleTypeCode
|
|
10
11
|
from xp.services.server.base_server_service import BaseServerService
|
|
11
12
|
|
|
12
13
|
|
|
@@ -32,7 +33,7 @@ class XP130ServerService(BaseServerService):
|
|
|
32
33
|
"""
|
|
33
34
|
super().__init__(serial_number)
|
|
34
35
|
self.device_type = "XP130"
|
|
35
|
-
self.module_type_code =
|
|
36
|
+
self.module_type_code = ModuleTypeCode.XP130 # XP130 module type from registry
|
|
36
37
|
self.firmware_version = "XP130_V1.02.15"
|
|
37
38
|
|
|
38
39
|
# XP130-specific network configuration
|
|
@@ -6,6 +6,7 @@ including response generation and device configuration handling.
|
|
|
6
6
|
|
|
7
7
|
from typing import Dict
|
|
8
8
|
|
|
9
|
+
from xp.models import ModuleTypeCode
|
|
9
10
|
from xp.services.server.base_server_service import BaseServerService
|
|
10
11
|
|
|
11
12
|
|
|
@@ -31,7 +32,7 @@ class XP20ServerService(BaseServerService):
|
|
|
31
32
|
"""
|
|
32
33
|
super().__init__(serial_number)
|
|
33
34
|
self.device_type = "XP20"
|
|
34
|
-
self.module_type_code =
|
|
35
|
+
self.module_type_code = ModuleTypeCode.XP20 # XP20 module type from registry
|
|
35
36
|
self.firmware_version = "XP20_V0.01.05"
|
|
36
37
|
|
|
37
38
|
def get_device_info(self) -> Dict:
|
|
@@ -6,6 +6,7 @@ including response generation and device configuration handling.
|
|
|
6
6
|
|
|
7
7
|
from typing import Dict
|
|
8
8
|
|
|
9
|
+
from xp.models import ModuleTypeCode
|
|
9
10
|
from xp.services.server.base_server_service import BaseServerService
|
|
10
11
|
|
|
11
12
|
|
|
@@ -31,7 +32,7 @@ class XP230ServerService(BaseServerService):
|
|
|
31
32
|
"""
|
|
32
33
|
super().__init__(serial_number)
|
|
33
34
|
self.device_type = "XP230"
|
|
34
|
-
self.module_type_code =
|
|
35
|
+
self.module_type_code = ModuleTypeCode.XP230 # XP230 module type from registry
|
|
35
36
|
self.firmware_version = "XP230_V1.00.04"
|
|
36
37
|
|
|
37
38
|
def get_device_info(self) -> Dict:
|