conson-xp 1.8.0__tar.gz → 1.11.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.8.0 → conson_xp-1.11.0}/PKG-INFO +4 -1
- {conson_xp-1.8.0 → conson_xp-1.11.0}/README.md +3 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/pyproject.toml +1 -1
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/__init__.py +1 -1
- conson_xp-1.11.0/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +233 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/actiontable/actiontable.py +1 -1
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/actiontable/msactiontable_xp24.py +1 -1
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/homekit/homekit_conson_config.py +18 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/input_action_type.py +4 -4
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/system_function.py +49 -19
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/actiontable/actiontable_serializer.py +114 -10
- conson_xp-1.8.0/src/xp/services/conbus/actiontable/actiontable_service.py → conson_xp-1.11.0/src/xp/services/conbus/actiontable/actiontable_download_service.py +13 -8
- conson_xp-1.11.0/src/xp/services/conbus/actiontable/actiontable_list_service.py +91 -0
- conson_xp-1.11.0/src/xp/services/conbus/actiontable/actiontable_show_service.py +89 -0
- conson_xp-1.11.0/src/xp/services/conbus/actiontable/actiontable_upload_service.py +211 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/utils/dependencies.py +36 -1
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_actiontable_integration.py +18 -13
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_xp24_action_table_integration.py +2 -2
- conson_xp-1.11.0/tests/unit/test_cli/test_conbus_actiontable_commands.py +643 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_xp24_action_table.py +7 -7
- conson_xp-1.11.0/tests/unit/test_services/test_actiontable_serializer.py +411 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_actiontable_service.py +17 -5
- conson_xp-1.11.0/tests/unit/test_services/test_actiontable_upload_service.py +591 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_xp24_action_table_serializer.py +2 -2
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_xp24_action_table_service.py +1 -1
- conson_xp-1.8.0/src/xp/cli/commands/conbus/conbus_actiontable_commands.py +0 -69
- conson_xp-1.8.0/tests/unit/test_cli/test_conbus_actiontable_commands.py +0 -229
- {conson_xp-1.8.0 → conson_xp-1.11.0}/LICENSE +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/__main__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_autoreport_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_blink_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_config_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_custom_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_datapoint_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_discover_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_lightlevel_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_linknumber_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_msactiontable_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_output_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_raw_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_receive_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/conbus/conbus_scan_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/file_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/homekit/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/homekit/homekit.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/homekit/homekit_start_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/module_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/reverse_proxy_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/server/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/server/server_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/telegram_blink_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/telegram_checksum_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/telegram_discover_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/telegram_linknumber_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/telegram_parse_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/commands/telegram/telegram_version_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/main.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/click_tree.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/datapoint_type_choice.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/decorators.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/error_handlers.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/formatters.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/serial_number_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/system_function_choice.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/cli/utils/xp_module_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/connection/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/connection/exceptions.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/actiontable/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/actiontable/msactiontable_xp20.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/actiontable/msactiontable_xp33.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_autoreport.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_blink.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_client_config.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_connection_status.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_custom.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_datapoint.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_discover.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_lightlevel.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_linknumber.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_output.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_raw.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_receive.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/conbus/conbus_writeconfig.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/homekit/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/homekit/homekit_accessory.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/homekit/homekit_config.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/log_entry.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/protocol/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/response.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/action_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/datapoint_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/event_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/event_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/input_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/module_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/module_type_code.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/output_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/reply_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/system_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/telegram_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/telegram/timeparam_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/models/write_config_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/actiontable/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/actiontable/msactiontable_serializer.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/actiontable/msactiontable_xp20_serializer.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/actiontable/msactiontable_xp24_serializer.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/actiontable/msactiontable_xp33_serializer.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/actiontable/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/actiontable/msactiontable_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_blink_all_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_blink_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_custom_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_datapoint_queryall_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_datapoint_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_discover_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_output_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_raw_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_receive_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/conbus_scan_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/conbus/write_config_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_cache_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_conbus_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_config_validator.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_conson_validator.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_dimminglight.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_dimminglight_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_hap_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_lightbulb.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_lightbulb_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_module_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_outlet.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_outlet_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/homekit/homekit_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/log_file_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/module_type_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/protocol/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/protocol/conbus_protocol.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/protocol/protocol_factory.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/protocol/telegram_protocol.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/reverse_proxy_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/base_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/cp20_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/device_service_factory.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/xp130_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/xp20_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/xp230_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/xp24_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/server/xp33_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_blink_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_checksum_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_datapoint_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_discover_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_link_number_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_output_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/services/telegram/telegram_version_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/utils/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/utils/checksum.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/utils/event_helper.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/utils/serialization.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/src/xp/utils/time_utils.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/.coverage +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/conftest.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/.coverage +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/telegram_test_data.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_api/.coverage +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_api/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_blink_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_checksum_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_conbus_blink_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_conbus_datapoint_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_conbus_raw_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_conbus_receive_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_discovery_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_event_telegram_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_homekit_config_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_link_number_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_module_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_output_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_reverse_proxy_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_system_reply_telegram_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_version_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/integration/test_xp20_action_table_integration.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_api/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_click_tree.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_conbus_blink_commands.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_datapoint_type_choice.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_decorators.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_error_handlers.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_formatters.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_serial_number_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_cli/test_system_function_choice.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_connection/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_connection/test_connection_init.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_connection/test_exceptions.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_encoding/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_encoding/test_latin1_edge_cases.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_conbus.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_conbus_client_send.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_conbus_discover.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_conbus_linknumber.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_event_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_log_entry.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_module_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_reply_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_system_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_system_telegram_enhancements.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_version_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_write_config_type.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_xp20_action_table.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_models/test_xp24_action_telegram.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_base_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_blink_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_checksum_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_conbus_blink_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_conbus_raw_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_conbus_reverse_proxy_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_device_service_factory.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_discovery_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_homekit_cache_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_homekit_config_validator.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_homekit_conson_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_homekit_services.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_log_file_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_module_type_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_protocol.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_server_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_telegram_input_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_telegram_protocol.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_telegram_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_version_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_xp20_action_table_serializer.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_xp24_action_service.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_xp33_action_table_serializer.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_services/test_xp_server_services.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_utils/__init__.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_utils/test_checksum.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_utils/test_event_helper.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.0}/tests/unit/test_utils/test_serialization.py +0 -0
- {conson_xp-1.8.0 → conson_xp-1.11.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.11.0
|
|
4
4
|
Summary: XP Protocol Communication Tools
|
|
5
5
|
Author-Email: ldvchosal <ldvchosal@github.com>
|
|
6
6
|
License: MIT License
|
|
@@ -276,6 +276,9 @@ xp conbus
|
|
|
276
276
|
|
|
277
277
|
xp conbus actiontable
|
|
278
278
|
xp conbus actiontable download
|
|
279
|
+
xp conbus actiontable list
|
|
280
|
+
xp conbus actiontable show
|
|
281
|
+
xp conbus actiontable upload
|
|
279
282
|
|
|
280
283
|
|
|
281
284
|
xp conbus autoreport
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"""ActionTable CLI commands."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from contextlib import suppress
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
from click import Context
|
|
10
|
+
|
|
11
|
+
from xp.cli.commands.conbus.conbus import conbus_actiontable
|
|
12
|
+
from xp.cli.utils.decorators import (
|
|
13
|
+
connection_command,
|
|
14
|
+
)
|
|
15
|
+
from xp.cli.utils.serial_number_type import SERIAL
|
|
16
|
+
from xp.models.actiontable.actiontable import ActionTable
|
|
17
|
+
from xp.models.homekit.homekit_conson_config import (
|
|
18
|
+
ConsonModuleConfig,
|
|
19
|
+
ConsonModuleListConfig,
|
|
20
|
+
)
|
|
21
|
+
from xp.services.conbus.actiontable.actiontable_download_service import (
|
|
22
|
+
ActionTableService,
|
|
23
|
+
)
|
|
24
|
+
from xp.services.conbus.actiontable.actiontable_list_service import (
|
|
25
|
+
ActionTableListService,
|
|
26
|
+
)
|
|
27
|
+
from xp.services.conbus.actiontable.actiontable_show_service import (
|
|
28
|
+
ActionTableShowService,
|
|
29
|
+
)
|
|
30
|
+
from xp.services.conbus.actiontable.actiontable_upload_service import (
|
|
31
|
+
ActionTableUploadService,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ActionTableError(Exception):
|
|
36
|
+
"""Raised when ActionTable operations fail."""
|
|
37
|
+
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@conbus_actiontable.command("download", short_help="Download ActionTable")
|
|
42
|
+
@click.argument("serial_number", type=SERIAL)
|
|
43
|
+
@click.pass_context
|
|
44
|
+
@connection_command()
|
|
45
|
+
def conbus_download_actiontable(ctx: Context, serial_number: str) -> None:
|
|
46
|
+
"""Download action table from XP module.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
ctx: Click context object.
|
|
50
|
+
serial_number: 10-digit module serial number.
|
|
51
|
+
"""
|
|
52
|
+
service: ActionTableService = (
|
|
53
|
+
ctx.obj.get("container").get_container().resolve(ActionTableService)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def progress_callback(progress: str) -> None:
|
|
57
|
+
"""Handle progress updates during action table download.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
progress: Progress message string.
|
|
61
|
+
"""
|
|
62
|
+
click.echo(progress)
|
|
63
|
+
|
|
64
|
+
def on_finish(
|
|
65
|
+
_actiontable: ActionTable,
|
|
66
|
+
actiontable_dict: dict[str, Any],
|
|
67
|
+
actiontable_short: list[str],
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Handle successful completion of action table download.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
_actiontable: Downloaded action table object.
|
|
73
|
+
actiontable_dict: Dictionary representation of action table.
|
|
74
|
+
actiontable_short: List of textual format strings.
|
|
75
|
+
"""
|
|
76
|
+
output = {
|
|
77
|
+
"serial_number": serial_number,
|
|
78
|
+
"actiontable_short": actiontable_short,
|
|
79
|
+
"actiontable": actiontable_dict,
|
|
80
|
+
}
|
|
81
|
+
click.echo(json.dumps(output, indent=2, default=str))
|
|
82
|
+
|
|
83
|
+
def error_callback(error: str) -> None:
|
|
84
|
+
"""Handle errors during action table download.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
error: Error message string.
|
|
88
|
+
"""
|
|
89
|
+
click.echo(error)
|
|
90
|
+
|
|
91
|
+
with service:
|
|
92
|
+
service.start(
|
|
93
|
+
serial_number=serial_number,
|
|
94
|
+
progress_callback=progress_callback,
|
|
95
|
+
finish_callback=on_finish,
|
|
96
|
+
error_callback=error_callback,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@conbus_actiontable.command("upload", short_help="Upload ActionTable")
|
|
101
|
+
@click.argument("serial_number", type=SERIAL)
|
|
102
|
+
@click.pass_context
|
|
103
|
+
@connection_command()
|
|
104
|
+
def conbus_upload_actiontable(ctx: Context, serial_number: str) -> None:
|
|
105
|
+
"""Upload action table from conson.yml to XP module.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
ctx: Click context object.
|
|
109
|
+
serial_number: 10-digit module serial number.
|
|
110
|
+
"""
|
|
111
|
+
service: ActionTableUploadService = (
|
|
112
|
+
ctx.obj.get("container").get_container().resolve(ActionTableUploadService)
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
click.echo(f"Uploading action table to {serial_number}...")
|
|
116
|
+
|
|
117
|
+
# Track number of entries for success message
|
|
118
|
+
entries_count = 0
|
|
119
|
+
|
|
120
|
+
def progress_callback(progress: str) -> None:
|
|
121
|
+
"""Handle progress updates during action table upload.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
progress: Progress message string.
|
|
125
|
+
"""
|
|
126
|
+
click.echo(progress, nl=False)
|
|
127
|
+
|
|
128
|
+
def success_callback() -> None:
|
|
129
|
+
"""Handle successful completion of action table upload."""
|
|
130
|
+
click.echo("\nAction table uploaded successfully")
|
|
131
|
+
if entries_count > 0:
|
|
132
|
+
click.echo(f"{entries_count} entries written")
|
|
133
|
+
|
|
134
|
+
def error_callback(error: str) -> None:
|
|
135
|
+
"""Handle errors during action table upload.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
error: Error message string.
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
ActionTableError: Always raised with upload failure message.
|
|
142
|
+
"""
|
|
143
|
+
raise ActionTableError(f"Upload failed: {error}")
|
|
144
|
+
|
|
145
|
+
with service:
|
|
146
|
+
# Load config to get entry count for success message
|
|
147
|
+
config_path = Path.cwd() / "conson.yml"
|
|
148
|
+
if config_path.exists():
|
|
149
|
+
with suppress(Exception):
|
|
150
|
+
config = ConsonModuleListConfig.from_yaml(str(config_path))
|
|
151
|
+
module = config.find_module(serial_number)
|
|
152
|
+
if module and module.action_table:
|
|
153
|
+
entries_count = len(module.action_table)
|
|
154
|
+
|
|
155
|
+
service.start(
|
|
156
|
+
serial_number=serial_number,
|
|
157
|
+
progress_callback=progress_callback,
|
|
158
|
+
success_callback=success_callback,
|
|
159
|
+
error_callback=error_callback,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@conbus_actiontable.command("list", short_help="List modules with ActionTable")
|
|
164
|
+
@click.pass_context
|
|
165
|
+
def conbus_list_actiontable(ctx: Context) -> None:
|
|
166
|
+
"""List all modules with action table configurations from conson.yml.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
ctx: Click context object.
|
|
170
|
+
"""
|
|
171
|
+
service: ActionTableListService = (
|
|
172
|
+
ctx.obj.get("container").get_container().resolve(ActionTableListService)
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
def on_finish(module_list: dict) -> None:
|
|
176
|
+
"""Handle successful completion of action table list.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
module_list: Dictionary containing modules and total count.
|
|
180
|
+
"""
|
|
181
|
+
click.echo(json.dumps(module_list, indent=2, default=str))
|
|
182
|
+
|
|
183
|
+
def error_callback(error: str) -> None:
|
|
184
|
+
"""Handle errors during action table list.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
error: Error message string.
|
|
188
|
+
"""
|
|
189
|
+
click.echo(error)
|
|
190
|
+
|
|
191
|
+
with service:
|
|
192
|
+
service.start(
|
|
193
|
+
finish_callback=on_finish,
|
|
194
|
+
error_callback=error_callback,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@conbus_actiontable.command("show", short_help="Show ActionTable configuration")
|
|
199
|
+
@click.argument("serial_number", type=SERIAL)
|
|
200
|
+
@click.pass_context
|
|
201
|
+
def conbus_show_actiontable(ctx: Context, serial_number: str) -> None:
|
|
202
|
+
"""Show action table configuration for a specific module from conson.yml.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
ctx: Click context object.
|
|
206
|
+
serial_number: 10-digit module serial number.
|
|
207
|
+
"""
|
|
208
|
+
service: ActionTableShowService = (
|
|
209
|
+
ctx.obj.get("container").get_container().resolve(ActionTableShowService)
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def on_finish(module: ConsonModuleConfig) -> None:
|
|
213
|
+
"""Handle successful completion of action table show.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
module: Dictionary containing module configuration.
|
|
217
|
+
"""
|
|
218
|
+
click.echo(json.dumps(module.model_dump(), indent=2, default=str))
|
|
219
|
+
|
|
220
|
+
def error_callback(error: str) -> None:
|
|
221
|
+
"""Handle errors during action table show.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
error: Error message string.
|
|
225
|
+
"""
|
|
226
|
+
click.echo(error)
|
|
227
|
+
|
|
228
|
+
with service:
|
|
229
|
+
service.start(
|
|
230
|
+
serial_number=serial_number,
|
|
231
|
+
finish_callback=on_finish,
|
|
232
|
+
error_callback=error_callback,
|
|
233
|
+
)
|
|
@@ -27,7 +27,7 @@ class ActionTableEntry:
|
|
|
27
27
|
link_number: int = 0
|
|
28
28
|
module_input: int = 0
|
|
29
29
|
module_output: int = 1
|
|
30
|
-
command: InputActionType = InputActionType.
|
|
30
|
+
command: InputActionType = InputActionType.OFF
|
|
31
31
|
parameter: TimeParam = TimeParam.NONE
|
|
32
32
|
inverted: bool = False
|
|
33
33
|
|
|
@@ -23,7 +23,7 @@ class InputAction:
|
|
|
23
23
|
class Xp24MsActionTable:
|
|
24
24
|
"""XP24 Action Table for managing input actions and settings.
|
|
25
25
|
|
|
26
|
-
Each input has an action type (TOGGLE,
|
|
26
|
+
Each input has an action type (TOGGLE, ON, LEVELSET, etc.)
|
|
27
27
|
with an optional parameter string.
|
|
28
28
|
|
|
29
29
|
Attributes:
|
|
@@ -22,6 +22,8 @@ class ConsonModuleConfig(BaseModel):
|
|
|
22
22
|
conbus_port: Optional Conbus port number.
|
|
23
23
|
sw_version: Optional software version.
|
|
24
24
|
hw_version: Optional hardware version.
|
|
25
|
+
action_table: Optional action table configuration.
|
|
26
|
+
auto_report_status: Optional auto report status.
|
|
25
27
|
"""
|
|
26
28
|
|
|
27
29
|
name: str
|
|
@@ -35,6 +37,8 @@ class ConsonModuleConfig(BaseModel):
|
|
|
35
37
|
conbus_port: Optional[int] = None
|
|
36
38
|
sw_version: Optional[str] = None
|
|
37
39
|
hw_version: Optional[str] = None
|
|
40
|
+
action_table: Optional[List[str]] = None
|
|
41
|
+
auto_report_status: Optional[str] = None
|
|
38
42
|
|
|
39
43
|
|
|
40
44
|
class ConsonModuleListConfig(BaseModel):
|
|
@@ -66,3 +70,17 @@ class ConsonModuleListConfig(BaseModel):
|
|
|
66
70
|
with Path(file_path).open("r") as file:
|
|
67
71
|
data = yaml.safe_load(file)
|
|
68
72
|
return cls(root=data)
|
|
73
|
+
|
|
74
|
+
def find_module(self, serial_number: str) -> Optional[ConsonModuleConfig]:
|
|
75
|
+
"""Find a module by serial number.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
serial_number: Module serial number to search for.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
ConsonModuleConfig if found, None otherwise.
|
|
82
|
+
"""
|
|
83
|
+
for module in self.root:
|
|
84
|
+
if module.serial_number == serial_number:
|
|
85
|
+
return module
|
|
86
|
+
return None
|
|
@@ -8,8 +8,8 @@ class InputActionType(Enum):
|
|
|
8
8
|
|
|
9
9
|
Attributes:
|
|
10
10
|
VOID: No action.
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
ON: Turn on action.
|
|
12
|
+
OFF: Turn off action.
|
|
13
13
|
TOGGLE: Toggle action.
|
|
14
14
|
BLOCK: Block action.
|
|
15
15
|
AUXRELAY: Auxiliary relay action.
|
|
@@ -39,8 +39,8 @@ class InputActionType(Enum):
|
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
41
|
VOID = 0
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
ON = 1
|
|
43
|
+
OFF = 2
|
|
44
44
|
TOGGLE = 3
|
|
45
45
|
BLOCK = 4
|
|
46
46
|
AUXRELAY = 5
|
|
@@ -15,35 +15,65 @@ class SystemFunction(str, Enum):
|
|
|
15
15
|
WRITE_CONFIG: Write configuration.
|
|
16
16
|
BLINK: Blink LED function.
|
|
17
17
|
UNBLINK: Unblink LED function.
|
|
18
|
-
|
|
18
|
+
UPLOAD_FIRMWARE_START: Start upload firmware.
|
|
19
|
+
UPLOAD_FIRMWARE_STOP: Stop upload firmware.
|
|
20
|
+
UPLOAD_FIRMWARE: Upload firmware.
|
|
21
|
+
UPLOAD_ACTIONTABLE: Upload ActionTable to module.
|
|
19
22
|
DOWNLOAD_ACTIONTABLE: Download ActionTable.
|
|
23
|
+
UPLOAD_MSACTIONTABLE: Upload module specific action table to module.
|
|
24
|
+
DOWNLOAD_MSACTIONTABLE: Download module specific action table.
|
|
25
|
+
TELEGRAM_WRITE_START: Start writing telegram.
|
|
26
|
+
TELEGRAM_READ_START: Start reading telegram.
|
|
20
27
|
EOF: End of msactiontable response.
|
|
28
|
+
TELEGRAM: Module specific telegram response.
|
|
21
29
|
MSACTIONTABLE: Module specific action table response.
|
|
22
30
|
ACTIONTABLE: Module specific action table response.
|
|
23
31
|
ACK: Acknowledge response.
|
|
24
32
|
NAK: Not acknowledge response.
|
|
33
|
+
UPLOAD_TOP_FIRMWARE_START: Start upload firmware (TOP).
|
|
34
|
+
UPLOAD_TOP_FIRMWARE_STOP: Stop upload firmware (TOP).
|
|
35
|
+
UPLOAD_TOP_FIRMWARE: Upload firmware (TOP).
|
|
36
|
+
ROTATE_ENABLE: Enable rotate.
|
|
37
|
+
ROTATE_DISABLE: Disable rotate.
|
|
25
38
|
UNKNOWN_26: Used after discover, unknown purpose.
|
|
26
39
|
ACTION: Action function.
|
|
27
40
|
"""
|
|
28
41
|
|
|
29
|
-
NONE = "00" # Undefined
|
|
30
|
-
DISCOVERY = "01" # Discover function
|
|
31
|
-
READ_DATAPOINT = "02" # Read datapoint
|
|
32
|
-
READ_CONFIG = "03" # Read configuration
|
|
33
|
-
WRITE_CONFIG = "04" # Write configuration
|
|
34
|
-
BLINK = "05" # Blink LED function
|
|
35
|
-
UNBLINK = "06" # Unblink LED function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
NONE = "00" # F00D Undefined
|
|
43
|
+
DISCOVERY = "01" # F01D Discover function
|
|
44
|
+
READ_DATAPOINT = "02" # F02D Read datapoint
|
|
45
|
+
READ_CONFIG = "03" # F03D Read configuration
|
|
46
|
+
WRITE_CONFIG = "04" # F04D Write configuration
|
|
47
|
+
BLINK = "05" # F05D Blink LED function
|
|
48
|
+
UNBLINK = "06" # F06D Unblink LED function
|
|
49
|
+
|
|
50
|
+
UPLOAD_FIRMWARE_START = "07" # F07D Start Upload firmware
|
|
51
|
+
UPLOAD_FIRMWARE_STOP = "08" # F08D Stop Upload firmware
|
|
52
|
+
UPLOAD_FIRMWARE = "09" # F09D Upload firmware
|
|
53
|
+
|
|
54
|
+
UPLOAD_ACTIONTABLE = "10" # F10D Upload ActionTable
|
|
55
|
+
DOWNLOAD_ACTIONTABLE = "11" # F11D Download ActionTable
|
|
56
|
+
UPLOAD_MSACTIONTABLE = "12" # F12D Upload MsActionTable to module
|
|
57
|
+
DOWNLOAD_MSACTIONTABLE = "13" # F13D Download MsActionTable
|
|
58
|
+
|
|
59
|
+
TELEGRAM_WRITE_START = "14" # F14D Start writing telegram
|
|
60
|
+
TELEGRAM_READ_START = "15" # F15D Start reading telegram
|
|
61
|
+
EOF = "16" # F16D End of msactiontable response
|
|
62
|
+
TELEGRAM = "17" # F17D module specific Telegram response
|
|
63
|
+
MSACTIONTABLE = "17" # F17D module specific ms action table (Telegram) response
|
|
64
|
+
ACTIONTABLE = "17" # F17D module specific action table (Telegram) response
|
|
65
|
+
ACK = "18" # F18D Acknowledge / continue response
|
|
66
|
+
NAK = "19" # F19D Not acknowledge response
|
|
67
|
+
|
|
68
|
+
UPLOAD_TOP_FIRMWARE_START = "20" # F20D Start Upload firmware (TOP)
|
|
69
|
+
UPLOAD_TOP_FIRMWARE_STOP = "21" # F21D Stop Upload firmware (TOP)
|
|
70
|
+
UPLOAD_TOP_FIRMWARE = "22" # F22D Upload firmware (TOP)
|
|
71
|
+
|
|
72
|
+
ROTATE_ENABLE = "23" # F23D Enable rotate
|
|
73
|
+
ROTATE_DISABLE = "24" # F24D Disable rotate
|
|
74
|
+
|
|
75
|
+
UNKNOWN_26 = "26" # F26D Used after discover, but don't know what it is
|
|
76
|
+
ACTION = "27" # F27D Action function
|
|
47
77
|
|
|
48
78
|
def get_description(self) -> str:
|
|
49
79
|
"""Get the description of the SystemFunction.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Serializer for ActionTable telegram encoding/decoding."""
|
|
2
2
|
|
|
3
|
+
import re
|
|
4
|
+
|
|
3
5
|
from xp.models import ModuleTypeCode
|
|
4
6
|
from xp.models.actiontable.actiontable import ActionTable, ActionTableEntry
|
|
5
7
|
from xp.models.telegram.input_action_type import InputActionType
|
|
@@ -18,7 +20,13 @@ from xp.utils.serialization import (
|
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
class ActionTableSerializer:
|
|
21
|
-
"""Handles serialization/deserialization of ActionTable to/from telegrams.
|
|
23
|
+
"""Handles serialization/deserialization of ActionTable to/from telegrams.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
MAX_ENTRIES: Maximum number of entries in an ActionTable (96).
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
MAX_ENTRIES = 96 # ActionTable must always contain exactly 96 entries
|
|
22
30
|
|
|
23
31
|
@staticmethod
|
|
24
32
|
def from_data(data: bytes) -> ActionTable:
|
|
@@ -57,12 +65,12 @@ class ActionTableSerializer:
|
|
|
57
65
|
try:
|
|
58
66
|
module_type = ModuleTypeCode(module_type_raw)
|
|
59
67
|
except ValueError:
|
|
60
|
-
module_type = ModuleTypeCode.
|
|
68
|
+
module_type = ModuleTypeCode.NOMOD # Default fallback
|
|
61
69
|
|
|
62
70
|
try:
|
|
63
71
|
command = InputActionType(command_raw)
|
|
64
72
|
except ValueError:
|
|
65
|
-
command = InputActionType.
|
|
73
|
+
command = InputActionType.OFF # Default fallback
|
|
66
74
|
|
|
67
75
|
try:
|
|
68
76
|
parameter = TimeParam(parameter_raw)
|
|
@@ -91,7 +99,7 @@ class ActionTableSerializer:
|
|
|
91
99
|
action_table: ActionTable to serialize
|
|
92
100
|
|
|
93
101
|
Returns:
|
|
94
|
-
Raw byte data for telegram
|
|
102
|
+
Raw byte data for telegram (always 480 bytes for 96 entries)
|
|
95
103
|
"""
|
|
96
104
|
data = bytearray()
|
|
97
105
|
|
|
@@ -112,6 +120,14 @@ class ActionTableSerializer:
|
|
|
112
120
|
[type_byte, link_byte, input_byte, output_command_byte, parameter_byte]
|
|
113
121
|
)
|
|
114
122
|
|
|
123
|
+
# Pad to 96 entries with default NOMOD entries (00 00 00 00 00)
|
|
124
|
+
current_entries = len(action_table.entries)
|
|
125
|
+
if current_entries < ActionTableSerializer.MAX_ENTRIES:
|
|
126
|
+
# Default entry: NOMOD 0 0 > 0 OFF (all zeros)
|
|
127
|
+
padding_bytes = [0x00, 0x00, 0x00, 0x00, 0x00]
|
|
128
|
+
for _ in range(ActionTableSerializer.MAX_ENTRIES - current_entries):
|
|
129
|
+
data.extend(padding_bytes)
|
|
130
|
+
|
|
115
131
|
return bytes(data)
|
|
116
132
|
|
|
117
133
|
@staticmethod
|
|
@@ -141,29 +157,117 @@ class ActionTableSerializer:
|
|
|
141
157
|
return ActionTableSerializer.from_data(data)
|
|
142
158
|
|
|
143
159
|
@staticmethod
|
|
144
|
-
def format_decoded_output(action_table: ActionTable) -> str:
|
|
160
|
+
def format_decoded_output(action_table: ActionTable) -> list[str]:
|
|
145
161
|
"""Format ActionTable as human-readable decoded output.
|
|
146
162
|
|
|
147
163
|
Args:
|
|
148
164
|
action_table: ActionTable to format
|
|
149
165
|
|
|
150
166
|
Returns:
|
|
151
|
-
|
|
167
|
+
List of human-readable string representations
|
|
152
168
|
"""
|
|
153
169
|
lines = []
|
|
154
170
|
for entry in action_table.entries:
|
|
155
|
-
# Format: CP20 0 0 > 1 OFF;
|
|
171
|
+
# Format: CP20 0 0 > 1 OFF [param];
|
|
156
172
|
module_type = entry.module_type.name
|
|
157
173
|
link = entry.link_number
|
|
158
174
|
input_num = entry.module_input
|
|
159
175
|
output = entry.module_output
|
|
160
176
|
command = entry.command.name
|
|
161
177
|
|
|
162
|
-
# Add prefix for
|
|
178
|
+
# Add prefix for inverted commands
|
|
163
179
|
if entry.inverted:
|
|
164
180
|
command = f"~{command}"
|
|
165
181
|
|
|
166
|
-
|
|
182
|
+
# Build base line
|
|
183
|
+
line = f"{module_type} {link} {input_num} > {output} {command}"
|
|
184
|
+
|
|
185
|
+
# Add parameter if present and non-zero
|
|
186
|
+
if entry.parameter is not None and entry.parameter.value != 0:
|
|
187
|
+
line += f" {entry.parameter.value}"
|
|
188
|
+
|
|
189
|
+
# Add semicolon terminator
|
|
190
|
+
line += ";"
|
|
191
|
+
|
|
167
192
|
lines.append(line)
|
|
168
193
|
|
|
169
|
-
return
|
|
194
|
+
return lines
|
|
195
|
+
|
|
196
|
+
@staticmethod
|
|
197
|
+
def parse_action_string(action_str: str) -> ActionTableEntry:
|
|
198
|
+
"""Parse action table entry from string format.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
action_str: String in format "CP20 0 0 > 1 OFF" or "CP20 0 1 > 1 ~ON"
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
Parsed ActionTableEntry
|
|
205
|
+
|
|
206
|
+
Raises:
|
|
207
|
+
ValueError: If string format is invalid
|
|
208
|
+
"""
|
|
209
|
+
# Remove trailing semicolon if present
|
|
210
|
+
action_str = action_str.strip().rstrip(";")
|
|
211
|
+
|
|
212
|
+
# Pattern: <Type> <Link> <Input> > <Output> <Command> [Parameter]
|
|
213
|
+
pattern = r"^(\w+)\s+(\d+)\s+(\d+)\s+>\s+(\d+)\s+(~?)(\w+)(?:\s+(\d+))?$"
|
|
214
|
+
match = re.match(pattern, action_str)
|
|
215
|
+
|
|
216
|
+
if not match:
|
|
217
|
+
raise ValueError(f"Invalid action table format: {action_str}")
|
|
218
|
+
|
|
219
|
+
(
|
|
220
|
+
module_type_str,
|
|
221
|
+
link_str,
|
|
222
|
+
input_str,
|
|
223
|
+
output_str,
|
|
224
|
+
inverted_str,
|
|
225
|
+
command_str,
|
|
226
|
+
parameter_str,
|
|
227
|
+
) = match.groups()
|
|
228
|
+
|
|
229
|
+
# Parse module type
|
|
230
|
+
try:
|
|
231
|
+
module_type = ModuleTypeCode[module_type_str]
|
|
232
|
+
except KeyError:
|
|
233
|
+
raise ValueError(f"Invalid module type: {module_type_str}")
|
|
234
|
+
|
|
235
|
+
# Parse command
|
|
236
|
+
try:
|
|
237
|
+
command = InputActionType[command_str]
|
|
238
|
+
except KeyError:
|
|
239
|
+
raise ValueError(f"Invalid command: {command_str}")
|
|
240
|
+
|
|
241
|
+
# Parse parameter (default to NONE)
|
|
242
|
+
parameter = TimeParam.NONE
|
|
243
|
+
if parameter_str:
|
|
244
|
+
try:
|
|
245
|
+
parameter = TimeParam(int(parameter_str))
|
|
246
|
+
except ValueError:
|
|
247
|
+
raise ValueError(f"Invalid parameter: {parameter_str}")
|
|
248
|
+
|
|
249
|
+
return ActionTableEntry(
|
|
250
|
+
module_type=module_type,
|
|
251
|
+
link_number=int(link_str),
|
|
252
|
+
module_input=int(input_str),
|
|
253
|
+
module_output=int(output_str),
|
|
254
|
+
command=command,
|
|
255
|
+
parameter=parameter,
|
|
256
|
+
inverted=bool(inverted_str),
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
@staticmethod
|
|
260
|
+
def parse_action_table(action_strings: list[str]) -> ActionTable:
|
|
261
|
+
"""Parse action table from list of string entries.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
action_strings: List of action strings from conson.yml
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Parsed ActionTable
|
|
268
|
+
"""
|
|
269
|
+
entries = [
|
|
270
|
+
ActionTableSerializer.parse_action_string(action_str)
|
|
271
|
+
for action_str in action_strings
|
|
272
|
+
]
|
|
273
|
+
return ActionTable(entries=entries)
|