conson-xp 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
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.1.0.dist-info → conson_xp-1.2.0.dist-info}/METADATA +1 -1
- conson_xp-1.2.0.dist-info/RECORD +181 -0
- xp/__init__.py +4 -3
- xp/api/main.py +18 -3
- xp/api/models/api.py +13 -2
- xp/api/models/discover.py +12 -2
- xp/api/routers/conbus_blink.py +18 -6
- xp/api/routers/conbus_custom.py +11 -3
- xp/api/routers/conbus_datapoint.py +10 -3
- xp/api/routers/conbus_output.py +29 -9
- xp/api/routers/errors.py +6 -5
- xp/cli/__init__.py +1 -1
- xp/cli/commands/__init__.py +1 -0
- xp/cli/commands/api.py +1 -5
- xp/cli/commands/api_start_commands.py +14 -8
- xp/cli/commands/conbus/conbus.py +9 -37
- xp/cli/commands/conbus/conbus_actiontable_commands.py +21 -1
- xp/cli/commands/conbus/conbus_autoreport_commands.py +21 -11
- xp/cli/commands/conbus/conbus_blink_commands.py +53 -21
- xp/cli/commands/conbus/conbus_config_commands.py +7 -4
- xp/cli/commands/conbus/conbus_custom_commands.py +13 -4
- xp/cli/commands/conbus/conbus_datapoint_commands.py +28 -8
- xp/cli/commands/conbus/conbus_discover_commands.py +15 -4
- xp/cli/commands/conbus/conbus_lightlevel_commands.py +50 -11
- xp/cli/commands/conbus/conbus_linknumber_commands.py +21 -11
- xp/cli/commands/conbus/conbus_msactiontable_commands.py +25 -1
- xp/cli/commands/conbus/conbus_output_commands.py +46 -12
- xp/cli/commands/conbus/conbus_raw_commands.py +17 -6
- xp/cli/commands/conbus/conbus_receive_commands.py +15 -7
- xp/cli/commands/conbus/conbus_scan_commands.py +17 -4
- xp/cli/commands/file_commands.py +26 -15
- xp/cli/commands/homekit/homekit.py +14 -8
- xp/cli/commands/homekit/homekit_start_commands.py +5 -5
- xp/cli/commands/module_commands.py +26 -19
- xp/cli/commands/reverse_proxy_commands.py +24 -18
- xp/cli/commands/server/server_commands.py +18 -18
- xp/cli/commands/telegram/telegram.py +4 -12
- xp/cli/commands/telegram/telegram_blink_commands.py +10 -8
- xp/cli/commands/telegram/telegram_checksum_commands.py +19 -8
- xp/cli/commands/telegram/telegram_discover_commands.py +2 -4
- xp/cli/commands/telegram/telegram_linknumber_commands.py +11 -8
- xp/cli/commands/telegram/telegram_parse_commands.py +10 -9
- xp/cli/commands/telegram/telegram_version_commands.py +8 -4
- xp/cli/main.py +5 -1
- xp/cli/utils/click_tree.py +23 -3
- xp/cli/utils/datapoint_type_choice.py +20 -0
- xp/cli/utils/decorators.py +165 -14
- xp/cli/utils/error_handlers.py +49 -18
- xp/cli/utils/formatters.py +95 -10
- xp/cli/utils/serial_number_type.py +18 -0
- xp/cli/utils/system_function_choice.py +20 -0
- xp/cli/utils/xp_module_type.py +20 -0
- xp/connection/__init__.py +1 -1
- xp/connection/exceptions.py +5 -5
- xp/models/__init__.py +1 -1
- xp/models/actiontable/__init__.py +1 -0
- xp/models/actiontable/actiontable.py +17 -1
- xp/models/actiontable/msactiontable_xp20.py +10 -0
- xp/models/actiontable/msactiontable_xp24.py +20 -3
- xp/models/actiontable/msactiontable_xp33.py +27 -4
- xp/models/conbus/__init__.py +1 -0
- xp/models/conbus/conbus.py +34 -4
- xp/models/conbus/conbus_autoreport.py +20 -2
- xp/models/conbus/conbus_blink.py +22 -2
- xp/models/conbus/conbus_client_config.py +22 -1
- xp/models/conbus/conbus_connection_status.py +16 -2
- xp/models/conbus/conbus_custom.py +21 -2
- xp/models/conbus/conbus_datapoint.py +22 -2
- xp/models/conbus/conbus_discover.py +18 -2
- xp/models/conbus/conbus_lightlevel.py +20 -2
- xp/models/conbus/conbus_linknumber.py +20 -2
- xp/models/conbus/conbus_output.py +22 -2
- xp/models/conbus/conbus_raw.py +17 -2
- xp/models/conbus/conbus_receive.py +16 -2
- xp/models/homekit/__init__.py +1 -0
- xp/models/homekit/homekit_accessory.py +15 -1
- xp/models/homekit/homekit_config.py +52 -0
- xp/models/homekit/homekit_conson_config.py +32 -0
- xp/models/log_entry.py +49 -9
- xp/models/protocol/__init__.py +1 -0
- xp/models/protocol/conbus_protocol.py +130 -21
- xp/models/telegram/__init__.py +1 -0
- xp/models/telegram/action_type.py +16 -2
- xp/models/telegram/datapoint_type.py +36 -2
- xp/models/telegram/event_telegram.py +46 -10
- xp/models/telegram/event_type.py +8 -1
- xp/models/telegram/input_action_type.py +34 -2
- xp/models/telegram/input_type.py +9 -1
- xp/models/telegram/module_type.py +69 -19
- xp/models/telegram/module_type_code.py +43 -1
- xp/models/telegram/output_telegram.py +30 -6
- xp/models/telegram/reply_telegram.py +56 -11
- xp/models/telegram/system_function.py +35 -3
- xp/models/telegram/system_telegram.py +18 -4
- xp/models/telegram/telegram.py +12 -3
- xp/models/telegram/telegram_type.py +8 -1
- xp/models/telegram/timeparam_type.py +27 -0
- xp/models/write_config_type.py +17 -2
- xp/services/__init__.py +1 -1
- xp/services/conbus/__init__.py +1 -0
- xp/services/conbus/actiontable/__init__.py +1 -0
- xp/services/conbus/actiontable/actiontable_service.py +33 -2
- xp/services/conbus/actiontable/msactiontable_service.py +40 -3
- xp/services/conbus/actiontable/msactiontable_xp24_serializer.py +36 -4
- xp/services/conbus/actiontable/msactiontable_xp33_serializer.py +45 -5
- xp/services/conbus/conbus_autoreport_get_service.py +17 -8
- xp/services/conbus/conbus_autoreport_set_service.py +29 -16
- xp/services/conbus/conbus_blink_all_service.py +40 -21
- xp/services/conbus/conbus_blink_service.py +37 -13
- xp/services/conbus/conbus_custom_service.py +29 -13
- xp/services/conbus/conbus_datapoint_queryall_service.py +40 -16
- xp/services/conbus/conbus_datapoint_service.py +33 -12
- xp/services/conbus/conbus_discover_service.py +43 -7
- xp/services/conbus/conbus_lightlevel_get_service.py +22 -14
- xp/services/conbus/conbus_lightlevel_set_service.py +40 -20
- xp/services/conbus/conbus_linknumber_get_service.py +18 -10
- xp/services/conbus/conbus_linknumber_set_service.py +34 -8
- xp/services/conbus/conbus_output_service.py +33 -13
- xp/services/conbus/conbus_raw_service.py +36 -16
- xp/services/conbus/conbus_receive_service.py +38 -6
- xp/services/conbus/conbus_scan_service.py +44 -18
- xp/services/homekit/__init__.py +1 -0
- xp/services/homekit/homekit_cache_service.py +31 -6
- xp/services/homekit/homekit_conbus_service.py +33 -2
- xp/services/homekit/homekit_config_validator.py +97 -15
- xp/services/homekit/homekit_conson_validator.py +51 -7
- xp/services/homekit/homekit_dimminglight.py +47 -1
- xp/services/homekit/homekit_dimminglight_service.py +35 -1
- xp/services/homekit/homekit_hap_service.py +71 -18
- xp/services/homekit/homekit_lightbulb.py +35 -1
- xp/services/homekit/homekit_lightbulb_service.py +30 -2
- xp/services/homekit/homekit_module_service.py +23 -1
- xp/services/homekit/homekit_outlet.py +47 -1
- xp/services/homekit/homekit_outlet_service.py +44 -2
- xp/services/homekit/homekit_service.py +113 -19
- xp/services/log_file_service.py +37 -41
- xp/services/module_type_service.py +26 -5
- xp/services/protocol/__init__.py +1 -1
- xp/services/protocol/conbus_protocol.py +110 -16
- xp/services/protocol/protocol_factory.py +40 -0
- xp/services/protocol/telegram_protocol.py +38 -7
- xp/services/reverse_proxy_service.py +79 -14
- xp/services/server/__init__.py +1 -0
- xp/services/server/base_server_service.py +102 -14
- xp/services/server/cp20_server_service.py +12 -4
- xp/services/server/server_service.py +26 -11
- xp/services/server/xp130_server_service.py +11 -3
- xp/services/server/xp20_server_service.py +11 -3
- xp/services/server/xp230_server_service.py +11 -3
- xp/services/server/xp24_server_service.py +33 -6
- xp/services/server/xp33_server_service.py +41 -8
- xp/services/telegram/__init__.py +1 -0
- xp/services/telegram/telegram_blink_service.py +19 -31
- xp/services/telegram/telegram_checksum_service.py +10 -10
- xp/services/telegram/telegram_discover_service.py +58 -29
- xp/services/telegram/telegram_link_number_service.py +27 -40
- xp/services/telegram/telegram_output_service.py +46 -49
- xp/services/telegram/telegram_service.py +41 -41
- xp/services/telegram/telegram_version_service.py +4 -2
- xp/utils/__init__.py +1 -1
- xp/utils/dependencies.py +0 -1
- xp/utils/serialization.py +6 -0
- xp/utils/time_utils.py +6 -11
- conson_xp-1.1.0.dist-info/RECORD +0 -181
- {conson_xp-1.1.0.dist-info → conson_xp-1.2.0.dist-info}/WHEEL +0 -0
- {conson_xp-1.1.0.dist-info → conson_xp-1.2.0.dist-info}/entry_points.txt +0 -0
- {conson_xp-1.1.0.dist-info → conson_xp-1.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -29,9 +29,7 @@ global_proxy_instance: Optional[ReverseProxyService] = None
|
|
|
29
29
|
help_options_color="green",
|
|
30
30
|
)
|
|
31
31
|
def reverse_proxy() -> None:
|
|
32
|
-
"""
|
|
33
|
-
Conbus reverse proxy operations
|
|
34
|
-
"""
|
|
32
|
+
"""Perform Conbus reverse proxy operations."""
|
|
35
33
|
pass
|
|
36
34
|
|
|
37
35
|
|
|
@@ -43,18 +41,24 @@ def reverse_proxy() -> None:
|
|
|
43
41
|
@handle_service_errors(ReverseProxyError)
|
|
44
42
|
@click.pass_context
|
|
45
43
|
def start_proxy(ctx: Context, port: int, config: str) -> None:
|
|
46
|
-
"""
|
|
47
|
-
Start the Conbus reverse proxy server.
|
|
44
|
+
r"""Start the Conbus reverse proxy server.
|
|
48
45
|
|
|
49
46
|
The proxy listens on the specified port and forwards all telegrams
|
|
50
47
|
to the target server configured in cli.yml. All traffic is monitored
|
|
51
48
|
and printed with timestamps.
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
Args:
|
|
51
|
+
ctx: Click context object.
|
|
52
|
+
port: Port to listen on.
|
|
53
|
+
config: Configuration file path.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Examples:
|
|
56
|
+
\b
|
|
56
57
|
xp rp start
|
|
57
58
|
xp rp start --port 10002 --config my_cli.yml
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
SystemExit: If proxy is already running.
|
|
58
62
|
"""
|
|
59
63
|
global global_proxy_instance
|
|
60
64
|
|
|
@@ -74,6 +78,12 @@ def start_proxy(ctx: Context, port: int, config: str) -> None:
|
|
|
74
78
|
|
|
75
79
|
# Handle graceful shutdown on SIGINT
|
|
76
80
|
def signal_handler(signum: int, frame: Optional[FrameType]) -> None:
|
|
81
|
+
"""Handle shutdown signals for graceful proxy termination.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
signum: Signal number received.
|
|
85
|
+
frame: Current stack frame (may be None).
|
|
86
|
+
"""
|
|
77
87
|
if global_proxy_instance and global_proxy_instance.is_running:
|
|
78
88
|
timestamp = global_proxy_instance.timestamp()
|
|
79
89
|
print(f"\n{timestamp} [SHUTDOWN] Received interrupt signal ({signum})")
|
|
@@ -104,16 +114,15 @@ def start_proxy(ctx: Context, port: int, config: str) -> None:
|
|
|
104
114
|
@reverse_proxy.command("stop")
|
|
105
115
|
@handle_service_errors(ReverseProxyError)
|
|
106
116
|
def stop_proxy() -> None:
|
|
107
|
-
"""
|
|
108
|
-
Stop the running Conbus reverse proxy server.
|
|
117
|
+
r"""Stop the running Conbus reverse proxy server.
|
|
109
118
|
|
|
110
119
|
Examples:
|
|
111
|
-
|
|
112
|
-
\b
|
|
120
|
+
\b
|
|
113
121
|
xp rp stop
|
|
114
|
-
"""
|
|
115
|
-
global global_proxy_instance
|
|
116
122
|
|
|
123
|
+
Raises:
|
|
124
|
+
SystemExit: If proxy is not running.
|
|
125
|
+
"""
|
|
117
126
|
try:
|
|
118
127
|
if global_proxy_instance is None or not global_proxy_instance.is_running:
|
|
119
128
|
error_response = {
|
|
@@ -135,18 +144,15 @@ def stop_proxy() -> None:
|
|
|
135
144
|
@reverse_proxy.command("status")
|
|
136
145
|
@handle_service_errors(Exception)
|
|
137
146
|
def proxy_status() -> None:
|
|
138
|
-
"""
|
|
139
|
-
Get status of the Conbus reverse proxy server.
|
|
147
|
+
r"""Get status of the Conbus reverse proxy server.
|
|
140
148
|
|
|
141
149
|
Shows current running state, listen port, target server,
|
|
142
150
|
and active connection details.
|
|
143
151
|
|
|
144
152
|
Examples:
|
|
145
|
-
|
|
146
|
-
\b
|
|
153
|
+
\b
|
|
147
154
|
xp rp status
|
|
148
155
|
"""
|
|
149
|
-
global global_proxy_instance
|
|
150
156
|
OutputFormatter(True)
|
|
151
157
|
|
|
152
158
|
try:
|
|
@@ -20,9 +20,7 @@ _server_instance: Optional[ServerService] = None
|
|
|
20
20
|
cls=HelpColorsGroup, help_headers_color="yellow", help_options_color="green"
|
|
21
21
|
)
|
|
22
22
|
def server() -> None:
|
|
23
|
-
"""
|
|
24
|
-
Conbus emulator server operations
|
|
25
|
-
"""
|
|
23
|
+
"""Perform Conbus emulator server operations."""
|
|
26
24
|
pass
|
|
27
25
|
|
|
28
26
|
|
|
@@ -34,14 +32,20 @@ def server() -> None:
|
|
|
34
32
|
@click.pass_context
|
|
35
33
|
@handle_service_errors(ServerError)
|
|
36
34
|
def start_server(ctx: Context, port: int, config: str) -> None:
|
|
37
|
-
"""
|
|
38
|
-
Start the Conbus emulator server.
|
|
35
|
+
r"""Start the Conbus emulator server.
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
Args:
|
|
38
|
+
ctx: Click context object.
|
|
39
|
+
port: Port to listen on.
|
|
40
|
+
config: Configuration file path.
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Examples:
|
|
43
|
+
\b
|
|
43
44
|
xp server start
|
|
44
45
|
xp server start --port 1001 --config my_config.yml
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
SystemExit: If server is already running.
|
|
45
49
|
"""
|
|
46
50
|
global _server_instance
|
|
47
51
|
|
|
@@ -76,16 +80,12 @@ def start_server(ctx: Context, port: int, config: str) -> None:
|
|
|
76
80
|
@server.command("stop")
|
|
77
81
|
@handle_service_errors(ServerError)
|
|
78
82
|
def stop_server() -> None:
|
|
79
|
-
"""
|
|
80
|
-
Stop the running Conbus emulator server.
|
|
83
|
+
r"""Stop the running Conbus emulator server.
|
|
81
84
|
|
|
82
85
|
Examples:
|
|
83
|
-
|
|
84
|
-
\b
|
|
86
|
+
\b
|
|
85
87
|
xp server stop
|
|
86
88
|
"""
|
|
87
|
-
global _server_instance
|
|
88
|
-
|
|
89
89
|
try:
|
|
90
90
|
if _server_instance is None or not _server_instance.is_running:
|
|
91
91
|
ServerErrorHandler.handle_server_not_running_error()
|
|
@@ -104,15 +104,15 @@ def stop_server() -> None:
|
|
|
104
104
|
@server.command("status")
|
|
105
105
|
@handle_service_errors(Exception)
|
|
106
106
|
def server_status() -> None:
|
|
107
|
-
"""
|
|
108
|
-
Get status of the Conbus emulator server.
|
|
107
|
+
r"""Get status of the Conbus emulator server.
|
|
109
108
|
|
|
110
109
|
Examples:
|
|
111
|
-
|
|
112
|
-
\b
|
|
110
|
+
\b
|
|
113
111
|
xp server status
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
SystemExit: If status cannot be retrieved.
|
|
114
115
|
"""
|
|
115
|
-
global _server_instance
|
|
116
116
|
formatter = OutputFormatter(True)
|
|
117
117
|
|
|
118
118
|
try:
|
|
@@ -8,9 +8,7 @@ from click_help_colors import HelpColorsGroup
|
|
|
8
8
|
cls=HelpColorsGroup, help_headers_color="yellow", help_options_color="green"
|
|
9
9
|
)
|
|
10
10
|
def telegram() -> None:
|
|
11
|
-
"""
|
|
12
|
-
Event telegram operations
|
|
13
|
-
"""
|
|
11
|
+
"""Perform event telegram operations."""
|
|
14
12
|
pass
|
|
15
13
|
|
|
16
14
|
|
|
@@ -18,9 +16,7 @@ def telegram() -> None:
|
|
|
18
16
|
cls=HelpColorsGroup, help_headers_color="yellow", help_options_color="green"
|
|
19
17
|
)
|
|
20
18
|
def linknumber() -> None:
|
|
21
|
-
"""
|
|
22
|
-
Link number operations for module configuration
|
|
23
|
-
"""
|
|
19
|
+
"""Perform link number operations for module configuration."""
|
|
24
20
|
pass
|
|
25
21
|
|
|
26
22
|
|
|
@@ -28,9 +24,7 @@ def linknumber() -> None:
|
|
|
28
24
|
cls=HelpColorsGroup, help_headers_color="yellow", help_options_color="green"
|
|
29
25
|
)
|
|
30
26
|
def blink() -> None:
|
|
31
|
-
"""
|
|
32
|
-
Blink operations for module LED control
|
|
33
|
-
"""
|
|
27
|
+
"""Perform blink operations for module LED control."""
|
|
34
28
|
pass
|
|
35
29
|
|
|
36
30
|
|
|
@@ -38,9 +32,7 @@ def blink() -> None:
|
|
|
38
32
|
cls=HelpColorsGroup, help_headers_color="yellow", help_options_color="green"
|
|
39
33
|
)
|
|
40
34
|
def checksum() -> None:
|
|
41
|
-
"""
|
|
42
|
-
Checksum calculation and validation operations
|
|
43
|
-
"""
|
|
35
|
+
"""Perform checksum calculation and validation operations."""
|
|
44
36
|
pass
|
|
45
37
|
|
|
46
38
|
|
|
@@ -16,12 +16,13 @@ from xp.services.telegram.telegram_blink_service import BlinkError, TelegramBlin
|
|
|
16
16
|
@click.argument("serial_number", type=SERIAL)
|
|
17
17
|
@handle_service_errors(BlinkError)
|
|
18
18
|
def blink_on(serial_number: str) -> None:
|
|
19
|
-
"""
|
|
20
|
-
Generate a telegram to start blinking module LED.
|
|
19
|
+
r"""Generate a telegram to start blinking module LED.
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
Args:
|
|
22
|
+
serial_number: 10-digit module serial number.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Examples:
|
|
25
|
+
\b
|
|
25
26
|
xp blink on 0012345008
|
|
26
27
|
xp blink on 0012345008
|
|
27
28
|
"""
|
|
@@ -49,12 +50,13 @@ def blink_on(serial_number: str) -> None:
|
|
|
49
50
|
@click.argument("serial_number", type=SERIAL)
|
|
50
51
|
@handle_service_errors(BlinkError)
|
|
51
52
|
def blink_off(serial_number: str) -> None:
|
|
52
|
-
"""
|
|
53
|
-
Generate a telegram to stop blinking module LED.
|
|
53
|
+
r"""Generate a telegram to stop blinking module LED.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Args:
|
|
56
|
+
serial_number: 10-digit module serial number.
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
Examples:
|
|
59
|
+
\b
|
|
58
60
|
xp blink off 0012345011
|
|
59
61
|
"""
|
|
60
62
|
service = TelegramBlinkService()
|
|
@@ -22,14 +22,19 @@ from xp.services.telegram.telegram_checksum_service import TelegramChecksumServi
|
|
|
22
22
|
)
|
|
23
23
|
@handle_service_errors(Exception)
|
|
24
24
|
def calculate_checksum(data: str, algorithm: str) -> None:
|
|
25
|
-
"""
|
|
26
|
-
Calculate checksum for given data string.
|
|
25
|
+
r"""Calculate checksum for given data string.
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
Args:
|
|
28
|
+
data: Data string to calculate checksum for.
|
|
29
|
+
algorithm: Checksum algorithm to use.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
Examples:
|
|
32
|
+
\b
|
|
31
33
|
xp checksum calculate "E14L00I02M"
|
|
32
34
|
xp checksum calculate "E14L00I02M" --algorithm crc32
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
SystemExit: If checksum calculation fails.
|
|
33
38
|
"""
|
|
34
39
|
service = TelegramChecksumService()
|
|
35
40
|
formatter = OutputFormatter(True)
|
|
@@ -65,14 +70,20 @@ def calculate_checksum(data: str, algorithm: str) -> None:
|
|
|
65
70
|
)
|
|
66
71
|
@handle_service_errors(Exception)
|
|
67
72
|
def validate_checksum(data: str, expected_checksum: str, algorithm: str) -> None:
|
|
68
|
-
"""
|
|
69
|
-
Validate data against expected checksum.
|
|
73
|
+
r"""Validate data against expected checksum.
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
Args:
|
|
76
|
+
data: Data string to validate.
|
|
77
|
+
expected_checksum: Expected checksum value.
|
|
78
|
+
algorithm: Checksum algorithm to use.
|
|
72
79
|
|
|
73
|
-
|
|
80
|
+
Examples:
|
|
81
|
+
\b
|
|
74
82
|
xp checksum validate "E14L00I02M" "AK"
|
|
75
83
|
xp checksum validate "E14L00I02M" "ABCDABCD" --algorithm crc32
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
SystemExit: If checksum validation fails.
|
|
76
87
|
"""
|
|
77
88
|
service = TelegramChecksumService()
|
|
78
89
|
formatter = OutputFormatter(True)
|
|
@@ -17,12 +17,10 @@ from xp.services.telegram.telegram_discover_service import (
|
|
|
17
17
|
@telegram.command("discover")
|
|
18
18
|
@handle_service_errors(DiscoverError)
|
|
19
19
|
def generate_discover() -> None:
|
|
20
|
-
"""
|
|
21
|
-
Generate a discover telegram for device enumeration.
|
|
20
|
+
r"""Generate a discover telegram for device enumeration.
|
|
22
21
|
|
|
23
22
|
Examples:
|
|
24
|
-
|
|
25
|
-
\b
|
|
23
|
+
\b
|
|
26
24
|
xp telegram discover
|
|
27
25
|
"""
|
|
28
26
|
service = TelegramDiscoverService()
|
|
@@ -20,12 +20,14 @@ from xp.services.telegram.telegram_link_number_service import (
|
|
|
20
20
|
@click.argument("link_number", type=int)
|
|
21
21
|
@handle_service_errors(LinkNumberError)
|
|
22
22
|
def generate_set_link_number(serial_number: str, link_number: int) -> None:
|
|
23
|
-
"""
|
|
24
|
-
Generate a telegram to set module link number.
|
|
23
|
+
r"""Generate a telegram to set module link number.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Args:
|
|
26
|
+
serial_number: 10-digit module serial number.
|
|
27
|
+
link_number: Link number to set.
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
Examples:
|
|
30
|
+
\b
|
|
29
31
|
xp telegram linknumber write 0012345005 25
|
|
30
32
|
"""
|
|
31
33
|
service = LinkNumberService()
|
|
@@ -55,12 +57,13 @@ def generate_set_link_number(serial_number: str, link_number: int) -> None:
|
|
|
55
57
|
@click.argument("serial_number", type=SERIAL)
|
|
56
58
|
@handle_service_errors(LinkNumberError)
|
|
57
59
|
def generate_read_link_number(serial_number: str) -> None:
|
|
58
|
-
"""
|
|
59
|
-
Generate a telegram to read module link number.
|
|
60
|
+
r"""Generate a telegram to read module link number.
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
Args:
|
|
63
|
+
serial_number: 10-digit module serial number.
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
Examples:
|
|
66
|
+
\b
|
|
64
67
|
xp telegram linknumber read 0012345005
|
|
65
68
|
"""
|
|
66
69
|
service = LinkNumberService()
|
|
@@ -17,19 +17,19 @@ from xp.services.telegram.telegram_service import TelegramParsingError, Telegram
|
|
|
17
17
|
@click.argument("telegram_string")
|
|
18
18
|
@handle_service_errors(TelegramParsingError)
|
|
19
19
|
def parse_any_telegram(telegram_string: str) -> None:
|
|
20
|
-
"""
|
|
21
|
-
Auto-detect and parse any type of telegram (event, system, reply, or discover).
|
|
20
|
+
r"""Auto-detect and parse any type of telegram (event, system, reply, or discover).
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
Args:
|
|
23
|
+
telegram_string: Telegram string to parse.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Examples:
|
|
26
|
+
\b
|
|
26
27
|
xp telegram parse "<E14L00I02MAK>"
|
|
27
28
|
xp telegram parse "<S0020012521F02D18FN>"
|
|
28
29
|
xp telegram parse "<R0020012521F02D18+26,0§CIL>"
|
|
29
30
|
xp telegram parse "<S0000000000F01D00FA>"
|
|
30
31
|
xp telegram parse "<R0012345011F01DFM>"
|
|
31
32
|
xp telegram parse "<R0012345003F18DFF>"
|
|
32
|
-
|
|
33
33
|
"""
|
|
34
34
|
service = TelegramService()
|
|
35
35
|
TelegramFormatter(True)
|
|
@@ -47,12 +47,13 @@ def parse_any_telegram(telegram_string: str) -> None:
|
|
|
47
47
|
@click.argument("telegram_string")
|
|
48
48
|
@handle_service_errors(TelegramParsingError)
|
|
49
49
|
def validate_telegram(telegram_string: str) -> None:
|
|
50
|
-
"""
|
|
51
|
-
Validate the format of an event telegram.
|
|
50
|
+
r"""Validate the format of an event telegram.
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
Args:
|
|
53
|
+
telegram_string: Telegram string to validate.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
Examples:
|
|
56
|
+
\b
|
|
56
57
|
xp telegram validate "<E14L00I02MAK>"
|
|
57
58
|
"""
|
|
58
59
|
service = TelegramService()
|
|
@@ -19,13 +19,17 @@ from xp.services.telegram.telegram_version_service import (
|
|
|
19
19
|
@click.argument("serial_number", type=SERIAL)
|
|
20
20
|
@handle_service_errors(VersionParsingError)
|
|
21
21
|
def generate_version_request(serial_number: str) -> None:
|
|
22
|
-
"""
|
|
23
|
-
Generate a telegram to request version information from a device.
|
|
22
|
+
r"""Generate a telegram to request version information from a device.
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
Args:
|
|
25
|
+
serial_number: 10-digit module serial number.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Examples:
|
|
28
|
+
\b
|
|
28
29
|
xp telegram version 0012345011
|
|
30
|
+
|
|
31
|
+
Raises:
|
|
32
|
+
SystemExit: If request cannot be generated.
|
|
29
33
|
"""
|
|
30
34
|
service = VersionService()
|
|
31
35
|
formatter = OutputFormatter(True)
|
xp/cli/main.py
CHANGED
|
@@ -27,7 +27,11 @@ from xp.utils.dependencies import ServiceContainer
|
|
|
27
27
|
@click.version_option()
|
|
28
28
|
@click.pass_context
|
|
29
29
|
def cli(ctx: click.Context) -> None:
|
|
30
|
-
"""XP CLI tool for remote console bus operations
|
|
30
|
+
"""XP CLI tool for remote console bus operations.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
ctx: Click context object for passing state between commands.
|
|
34
|
+
"""
|
|
31
35
|
# Configure logging with thread information
|
|
32
36
|
log_format = "%(asctime)s - [%(threadName)s-%(thread)d] - %(levelname)s - %(name)s - %(message)s"
|
|
33
37
|
date_format = "%H:%M:%S"
|
xp/cli/utils/click_tree.py
CHANGED
|
@@ -1,13 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
"""Utilities for displaying Click command trees."""
|
|
2
|
+
|
|
2
3
|
from typing import Any
|
|
3
4
|
|
|
4
5
|
import click
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
def add_tree_command(cli_group: click.Group, command_name: str = "help") -> Any:
|
|
8
|
-
"""Add a tree command to any Click group
|
|
9
|
+
"""Add a tree command to any Click group.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
cli_group: The Click group to add the tree command to.
|
|
13
|
+
command_name: Name of the tree command (default: "help").
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
The tree command function.
|
|
17
|
+
"""
|
|
9
18
|
|
|
10
19
|
def print_command_tree(group: click.Group, ctx: click.Context, suffix: str) -> None:
|
|
20
|
+
"""Print command tree recursively.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
group: The Click group to print.
|
|
24
|
+
ctx: The Click context.
|
|
25
|
+
suffix: Prefix string for tree display.
|
|
26
|
+
"""
|
|
11
27
|
for name in sorted(group.list_commands(ctx)):
|
|
12
28
|
cmd = group.get_command(ctx, name)
|
|
13
29
|
|
|
@@ -23,7 +39,11 @@ def add_tree_command(cli_group: click.Group, command_name: str = "help") -> Any:
|
|
|
23
39
|
@cli_group.command(command_name)
|
|
24
40
|
@click.pass_context
|
|
25
41
|
def tree_command(ctx: click.Context) -> None:
|
|
26
|
-
"""Show complete command tree
|
|
42
|
+
"""Show complete command tree.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
ctx: The Click context.
|
|
46
|
+
"""
|
|
27
47
|
root = ctx.find_root().command
|
|
28
48
|
root_ctx = ctx.find_root()
|
|
29
49
|
root_name = root_ctx.info_name or "cli"
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Click parameter type for DataPointType enum validation."""
|
|
2
|
+
|
|
1
3
|
from typing import Any, Optional
|
|
2
4
|
|
|
3
5
|
import click
|
|
@@ -7,14 +9,32 @@ from xp.models.telegram.datapoint_type import DataPointType
|
|
|
7
9
|
|
|
8
10
|
# noinspection DuplicatedCode
|
|
9
11
|
class DatapointTypeChoice(click.ParamType):
|
|
12
|
+
"""Click parameter type for validating DataPointType enum values.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
name: The parameter type name.
|
|
16
|
+
choices: List of valid choice strings.
|
|
17
|
+
"""
|
|
18
|
+
|
|
10
19
|
name = "telegram_type"
|
|
11
20
|
|
|
12
21
|
def __init__(self) -> None:
|
|
22
|
+
"""Initialize the DatapointTypeChoice parameter type."""
|
|
13
23
|
self.choices = [key.lower() for key in DataPointType.__members__.keys()]
|
|
14
24
|
|
|
15
25
|
def convert(
|
|
16
26
|
self, value: Any, param: Optional[click.Parameter], ctx: Optional[click.Context]
|
|
17
27
|
) -> Any:
|
|
28
|
+
"""Convert and validate input to DataPointType enum.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
value: The input value to convert.
|
|
32
|
+
param: The Click parameter.
|
|
33
|
+
ctx: The Click context.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
DataPointType enum member if valid, None if input is None.
|
|
37
|
+
"""
|
|
18
38
|
if value is None:
|
|
19
39
|
return value
|
|
20
40
|
|