conson-xp 1.1.0__py3-none-any.whl → 1.3.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.3.0.dist-info}/METADATA +1 -5
- conson_xp-1.3.0.dist-info/RECORD +164 -0
- xp/__init__.py +4 -3
- xp/cli/__init__.py +1 -1
- xp/cli/commands/__init__.py +1 -2
- xp/cli/commands/conbus/conbus.py +9 -37
- xp/cli/commands/conbus/conbus_actiontable_commands.py +26 -4
- xp/cli/commands/conbus/conbus_autoreport_commands.py +58 -30
- xp/cli/commands/conbus/conbus_blink_commands.py +61 -29
- xp/cli/commands/conbus/conbus_config_commands.py +10 -5
- xp/cli/commands/conbus/conbus_custom_commands.py +16 -5
- xp/cli/commands/conbus/conbus_datapoint_commands.py +32 -10
- xp/cli/commands/conbus/conbus_discover_commands.py +20 -7
- xp/cli/commands/conbus/conbus_lightlevel_commands.py +114 -39
- xp/cli/commands/conbus/conbus_linknumber_commands.py +50 -25
- xp/cli/commands/conbus/conbus_msactiontable_commands.py +36 -5
- xp/cli/commands/conbus/conbus_output_commands.py +52 -14
- xp/cli/commands/conbus/conbus_raw_commands.py +17 -6
- xp/cli/commands/conbus/conbus_receive_commands.py +20 -10
- xp/cli/commands/conbus/conbus_scan_commands.py +17 -4
- xp/cli/commands/file_commands.py +35 -18
- xp/cli/commands/homekit/homekit.py +14 -8
- xp/cli/commands/homekit/homekit_start_commands.py +8 -6
- xp/cli/commands/module_commands.py +38 -23
- xp/cli/commands/reverse_proxy_commands.py +27 -19
- 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 -3
- 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 +25 -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/conbus/conbus_writeconfig.py +60 -0
- 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_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 +42 -18
- xp/services/conbus/conbus_discover_service.py +43 -7
- 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/conbus/write_config_service.py +193 -0
- 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_datapoint_service.py +70 -0
- 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 +4 -47
- xp/utils/serialization.py +6 -0
- xp/utils/time_utils.py +6 -11
- conson_xp-1.1.0.dist-info/RECORD +0 -181
- xp/api/__init__.py +0 -1
- xp/api/main.py +0 -110
- xp/api/models/__init__.py +0 -1
- xp/api/models/api.py +0 -20
- xp/api/models/discover.py +0 -21
- xp/api/routers/__init__.py +0 -17
- xp/api/routers/conbus.py +0 -5
- xp/api/routers/conbus_blink.py +0 -105
- xp/api/routers/conbus_custom.py +0 -63
- xp/api/routers/conbus_datapoint.py +0 -67
- xp/api/routers/conbus_output.py +0 -147
- xp/api/routers/errors.py +0 -37
- xp/cli/commands/api.py +0 -16
- xp/cli/commands/api_start_commands.py +0 -126
- xp/services/conbus/conbus_autoreport_get_service.py +0 -85
- xp/services/conbus/conbus_autoreport_set_service.py +0 -128
- xp/services/conbus/conbus_lightlevel_get_service.py +0 -101
- xp/services/conbus/conbus_lightlevel_set_service.py +0 -205
- xp/services/conbus/conbus_linknumber_get_service.py +0 -86
- xp/services/conbus/conbus_linknumber_set_service.py +0 -155
- {conson_xp-1.1.0.dist-info → conson_xp-1.3.0.dist-info}/WHEEL +0 -0
- {conson_xp-1.1.0.dist-info → conson_xp-1.3.0.dist-info}/entry_points.txt +0 -0
- {conson_xp-1.1.0.dist-info → conson_xp-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -17,9 +17,7 @@ from xp.services.module_type_service import ModuleTypeNotFoundError, ModuleTypeS
|
|
|
17
17
|
cls=HelpColorsGroup, help_headers_color="yellow", help_options_color="green"
|
|
18
18
|
)
|
|
19
19
|
def module() -> None:
|
|
20
|
-
"""
|
|
21
|
-
Module type operations
|
|
22
|
-
"""
|
|
20
|
+
"""Perform module type operations."""
|
|
23
21
|
pass
|
|
24
22
|
|
|
25
23
|
|
|
@@ -28,16 +26,20 @@ def module() -> None:
|
|
|
28
26
|
@click.pass_context
|
|
29
27
|
@list_command(ModuleTypeNotFoundError)
|
|
30
28
|
def module_info(ctx: Context, identifier: str) -> None:
|
|
31
|
-
"""
|
|
32
|
-
Get information about a module type by code or name.
|
|
29
|
+
r"""Get information about a module type by code or name.
|
|
33
30
|
|
|
34
|
-
|
|
31
|
+
Args:
|
|
32
|
+
ctx: Click context object.
|
|
33
|
+
identifier: Module code or name.
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
Examples:
|
|
36
|
+
\b
|
|
37
37
|
xp module info 14
|
|
38
38
|
xp module info XP2606
|
|
39
39
|
"""
|
|
40
|
-
service =
|
|
40
|
+
service: ModuleTypeService = (
|
|
41
|
+
ctx.obj.get("container").get_container().resolve(ModuleTypeService)
|
|
42
|
+
)
|
|
41
43
|
OutputFormatter(True)
|
|
42
44
|
|
|
43
45
|
try:
|
|
@@ -63,17 +65,22 @@ def module_info(ctx: Context, identifier: str) -> None:
|
|
|
63
65
|
@click.pass_context
|
|
64
66
|
@list_command(Exception)
|
|
65
67
|
def module_list(ctx: Context, category: str, group_by_category: bool) -> None:
|
|
66
|
-
"""
|
|
67
|
-
List module types, optionally filtered by category.
|
|
68
|
+
r"""List module types, optionally filtered by category.
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
Args:
|
|
71
|
+
ctx: Click context object.
|
|
72
|
+
category: Filter by category.
|
|
73
|
+
group_by_category: Group modules by category.
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
Examples:
|
|
76
|
+
\b
|
|
72
77
|
xp module list
|
|
73
78
|
xp module list --category "Interface Panels"
|
|
74
79
|
xp module list --group-by-category
|
|
75
80
|
"""
|
|
76
|
-
service =
|
|
81
|
+
service: ModuleTypeService = (
|
|
82
|
+
ctx.obj.get("container").get_container().resolve(ModuleTypeService)
|
|
83
|
+
)
|
|
77
84
|
ListFormatter(True)
|
|
78
85
|
|
|
79
86
|
try:
|
|
@@ -115,16 +122,21 @@ def module_list(ctx: Context, category: str, group_by_category: bool) -> None:
|
|
|
115
122
|
@click.pass_context
|
|
116
123
|
@list_command(Exception)
|
|
117
124
|
def module_search(ctx: Context, query: str, field: tuple) -> None:
|
|
118
|
-
"""
|
|
119
|
-
Search for module types by name or description.
|
|
125
|
+
r"""Search for module types by name or description.
|
|
120
126
|
|
|
121
|
-
|
|
127
|
+
Args:
|
|
128
|
+
ctx: Click context object.
|
|
129
|
+
query: Search query.
|
|
130
|
+
field: Fields to search in.
|
|
122
131
|
|
|
123
|
-
|
|
132
|
+
Examples:
|
|
133
|
+
\b
|
|
124
134
|
xp module search "push button"
|
|
125
135
|
xp module search --field name "XP"
|
|
126
136
|
"""
|
|
127
|
-
service =
|
|
137
|
+
service: ModuleTypeService = (
|
|
138
|
+
ctx.obj.get("container").get_container().resolve(ModuleTypeService)
|
|
139
|
+
)
|
|
128
140
|
ListFormatter(True)
|
|
129
141
|
|
|
130
142
|
try:
|
|
@@ -147,15 +159,18 @@ def module_search(ctx: Context, query: str, field: tuple) -> None:
|
|
|
147
159
|
@click.pass_context
|
|
148
160
|
@list_command(Exception)
|
|
149
161
|
def module_categories(ctx: Context) -> None:
|
|
150
|
-
"""
|
|
151
|
-
List all available module categories.
|
|
162
|
+
r"""List all available module categories.
|
|
152
163
|
|
|
153
|
-
|
|
164
|
+
Args:
|
|
165
|
+
ctx: Click context object.
|
|
154
166
|
|
|
155
|
-
|
|
167
|
+
Examples:
|
|
168
|
+
\b
|
|
156
169
|
xp module categories
|
|
157
170
|
"""
|
|
158
|
-
service =
|
|
171
|
+
service: ModuleTypeService = (
|
|
172
|
+
ctx.obj.get("container").get_container().resolve(ModuleTypeService)
|
|
173
|
+
)
|
|
159
174
|
OutputFormatter(True)
|
|
160
175
|
|
|
161
176
|
try:
|
|
@@ -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
|
|
|
@@ -69,11 +73,19 @@ def start_proxy(ctx: Context, port: int, config: str) -> None:
|
|
|
69
73
|
raise SystemExit(1)
|
|
70
74
|
|
|
71
75
|
# Load configuration and create proxy instance
|
|
72
|
-
service =
|
|
76
|
+
service: ReverseProxyService = (
|
|
77
|
+
ctx.obj.get("container").get_container().resolve(ReverseProxyService)
|
|
78
|
+
)
|
|
73
79
|
global_proxy_instance = service
|
|
74
80
|
|
|
75
81
|
# Handle graceful shutdown on SIGINT
|
|
76
82
|
def signal_handler(signum: int, frame: Optional[FrameType]) -> None:
|
|
83
|
+
"""Handle shutdown signals for graceful proxy termination.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
signum: Signal number received.
|
|
87
|
+
frame: Current stack frame (may be None).
|
|
88
|
+
"""
|
|
77
89
|
if global_proxy_instance and global_proxy_instance.is_running:
|
|
78
90
|
timestamp = global_proxy_instance.timestamp()
|
|
79
91
|
print(f"\n{timestamp} [SHUTDOWN] Received interrupt signal ({signum})")
|
|
@@ -104,16 +116,15 @@ def start_proxy(ctx: Context, port: int, config: str) -> None:
|
|
|
104
116
|
@reverse_proxy.command("stop")
|
|
105
117
|
@handle_service_errors(ReverseProxyError)
|
|
106
118
|
def stop_proxy() -> None:
|
|
107
|
-
"""
|
|
108
|
-
Stop the running Conbus reverse proxy server.
|
|
119
|
+
r"""Stop the running Conbus reverse proxy server.
|
|
109
120
|
|
|
110
121
|
Examples:
|
|
111
|
-
|
|
112
|
-
\b
|
|
122
|
+
\b
|
|
113
123
|
xp rp stop
|
|
114
|
-
"""
|
|
115
|
-
global global_proxy_instance
|
|
116
124
|
|
|
125
|
+
Raises:
|
|
126
|
+
SystemExit: If proxy is not running.
|
|
127
|
+
"""
|
|
117
128
|
try:
|
|
118
129
|
if global_proxy_instance is None or not global_proxy_instance.is_running:
|
|
119
130
|
error_response = {
|
|
@@ -135,18 +146,15 @@ def stop_proxy() -> None:
|
|
|
135
146
|
@reverse_proxy.command("status")
|
|
136
147
|
@handle_service_errors(Exception)
|
|
137
148
|
def proxy_status() -> None:
|
|
138
|
-
"""
|
|
139
|
-
Get status of the Conbus reverse proxy server.
|
|
149
|
+
r"""Get status of the Conbus reverse proxy server.
|
|
140
150
|
|
|
141
151
|
Shows current running state, listen port, target server,
|
|
142
152
|
and active connection details.
|
|
143
153
|
|
|
144
154
|
Examples:
|
|
145
|
-
|
|
146
|
-
\b
|
|
155
|
+
\b
|
|
147
156
|
xp rp status
|
|
148
157
|
"""
|
|
149
|
-
global global_proxy_instance
|
|
150
158
|
OutputFormatter(True)
|
|
151
159
|
|
|
152
160
|
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
|
@@ -6,7 +6,6 @@ import click
|
|
|
6
6
|
from click_help_colors import HelpColorsGroup
|
|
7
7
|
|
|
8
8
|
from xp.cli.commands import homekit
|
|
9
|
-
from xp.cli.commands.api import api
|
|
10
9
|
from xp.cli.commands.conbus.conbus import conbus
|
|
11
10
|
from xp.cli.commands.file_commands import file
|
|
12
11
|
from xp.cli.commands.module_commands import module
|
|
@@ -27,7 +26,11 @@ from xp.utils.dependencies import ServiceContainer
|
|
|
27
26
|
@click.version_option()
|
|
28
27
|
@click.pass_context
|
|
29
28
|
def cli(ctx: click.Context) -> None:
|
|
30
|
-
"""XP CLI tool for remote console bus operations
|
|
29
|
+
"""XP CLI tool for remote console bus operations.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
ctx: Click context object for passing state between commands.
|
|
33
|
+
"""
|
|
31
34
|
# Configure logging with thread information
|
|
32
35
|
log_format = "%(asctime)s - [%(threadName)s-%(thread)d] - %(levelname)s - %(name)s - %(message)s"
|
|
33
36
|
date_format = "%H:%M:%S"
|
|
@@ -75,7 +78,6 @@ cli.add_command(telegram)
|
|
|
75
78
|
cli.add_command(module)
|
|
76
79
|
cli.add_command(file)
|
|
77
80
|
cli.add_command(server)
|
|
78
|
-
cli.add_command(api)
|
|
79
81
|
cli.add_command(reverse_proxy)
|
|
80
82
|
|
|
81
83
|
# Add the tree command
|
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
|
|