conson-xp 1.2.0__py3-none-any.whl → 1.4.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.2.0.dist-info → conson_xp-1.4.0.dist-info}/METADATA +1 -5
- {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/RECORD +43 -60
- xp/__init__.py +1 -1
- xp/cli/commands/__init__.py +0 -2
- xp/cli/commands/conbus/conbus_actiontable_commands.py +5 -3
- xp/cli/commands/conbus/conbus_autoreport_commands.py +39 -21
- xp/cli/commands/conbus/conbus_blink_commands.py +8 -8
- xp/cli/commands/conbus/conbus_config_commands.py +3 -1
- xp/cli/commands/conbus/conbus_custom_commands.py +3 -1
- xp/cli/commands/conbus/conbus_datapoint_commands.py +4 -2
- xp/cli/commands/conbus/conbus_discover_commands.py +5 -3
- xp/cli/commands/conbus/conbus_lightlevel_commands.py +68 -32
- xp/cli/commands/conbus/conbus_linknumber_commands.py +32 -17
- xp/cli/commands/conbus/conbus_msactiontable_commands.py +11 -4
- xp/cli/commands/conbus/conbus_output_commands.py +6 -2
- xp/cli/commands/conbus/conbus_receive_commands.py +5 -3
- xp/cli/commands/file_commands.py +9 -3
- xp/cli/commands/homekit/homekit_start_commands.py +3 -1
- xp/cli/commands/module_commands.py +12 -4
- xp/cli/commands/reverse_proxy_commands.py +3 -1
- xp/cli/main.py +0 -2
- xp/models/conbus/conbus_datapoint.py +3 -0
- xp/models/conbus/conbus_discover.py +19 -3
- xp/models/conbus/conbus_writeconfig.py +60 -0
- xp/models/telegram/system_telegram.py +4 -4
- xp/services/conbus/conbus_datapoint_service.py +9 -6
- xp/services/conbus/conbus_discover_service.py +120 -2
- xp/services/conbus/conbus_scan_service.py +1 -1
- xp/services/conbus/{conbus_linknumber_set_service.py → write_config_service.py} +78 -66
- xp/services/protocol/telegram_protocol.py +4 -4
- xp/services/server/base_server_service.py +9 -4
- xp/services/server/cp20_server_service.py +2 -1
- xp/services/server/server_service.py +75 -4
- xp/services/server/xp130_server_service.py +2 -1
- xp/services/server/xp20_server_service.py +2 -1
- xp/services/server/xp230_server_service.py +2 -1
- xp/services/server/xp24_server_service.py +123 -50
- xp/services/server/xp33_server_service.py +150 -20
- xp/services/telegram/telegram_datapoint_service.py +70 -0
- xp/utils/dependencies.py +4 -46
- xp/api/__init__.py +0 -1
- xp/api/main.py +0 -125
- xp/api/models/__init__.py +0 -1
- xp/api/models/api.py +0 -31
- xp/api/models/discover.py +0 -31
- xp/api/routers/__init__.py +0 -17
- xp/api/routers/conbus.py +0 -5
- xp/api/routers/conbus_blink.py +0 -117
- xp/api/routers/conbus_custom.py +0 -71
- xp/api/routers/conbus_datapoint.py +0 -74
- xp/api/routers/conbus_output.py +0 -167
- xp/api/routers/errors.py +0 -38
- xp/cli/commands/api.py +0 -12
- xp/cli/commands/api_start_commands.py +0 -132
- xp/services/conbus/conbus_autoreport_get_service.py +0 -94
- xp/services/conbus/conbus_autoreport_set_service.py +0 -141
- xp/services/conbus/conbus_lightlevel_get_service.py +0 -109
- xp/services/conbus/conbus_lightlevel_set_service.py +0 -225
- xp/services/conbus/conbus_linknumber_get_service.py +0 -94
- {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/WHEEL +0 -0
- {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/entry_points.txt +0 -0
- {conson_xp-1.2.0.dist-info → conson_xp-1.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,14 +7,14 @@ import click
|
|
|
7
7
|
from xp.cli.commands.conbus.conbus import conbus_lightlevel
|
|
8
8
|
from xp.cli.utils.decorators import (
|
|
9
9
|
connection_command,
|
|
10
|
-
handle_service_errors,
|
|
11
10
|
)
|
|
12
11
|
from xp.cli.utils.serial_number_type import SERIAL
|
|
13
|
-
from xp.models
|
|
14
|
-
from xp.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
from xp.models import ConbusDatapointResponse
|
|
13
|
+
from xp.models.conbus.conbus_writeconfig import ConbusWriteConfigResponse
|
|
14
|
+
from xp.models.telegram.datapoint_type import DataPointType
|
|
15
|
+
from xp.services.conbus.conbus_datapoint_service import ConbusDatapointService
|
|
16
|
+
from xp.services.conbus.write_config_service import WriteConfigService
|
|
17
|
+
from xp.services.telegram.telegram_datapoint_service import TelegramDatapointService
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
@conbus_lightlevel.command("set")
|
|
@@ -23,7 +23,6 @@ from xp.services.conbus.conbus_lightlevel_set_service import (
|
|
|
23
23
|
@click.argument("level", type=click.IntRange(0, 100))
|
|
24
24
|
@click.pass_context
|
|
25
25
|
@connection_command()
|
|
26
|
-
@handle_service_errors(ConbusLightlevelError)
|
|
27
26
|
def xp_lightlevel_set(
|
|
28
27
|
ctx: click.Context, serial_number: str, output_number: int, level: int
|
|
29
28
|
) -> None:
|
|
@@ -41,20 +40,28 @@ def xp_lightlevel_set(
|
|
|
41
40
|
xp conbus lightlevel set 0011223344 0 100 # Set output 0 to 100%
|
|
42
41
|
"""
|
|
43
42
|
|
|
44
|
-
def
|
|
45
|
-
"""Handle successful completion of light level
|
|
43
|
+
def on_finish(response: "ConbusWriteConfigResponse") -> None:
|
|
44
|
+
"""Handle successful completion of light level on command.
|
|
46
45
|
|
|
47
46
|
Args:
|
|
48
47
|
response: Light level response object.
|
|
49
48
|
"""
|
|
50
49
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
51
50
|
|
|
52
|
-
service = (
|
|
53
|
-
ctx.obj.get("container").get_container().resolve(
|
|
51
|
+
service: WriteConfigService = (
|
|
52
|
+
ctx.obj.get("container").get_container().resolve(WriteConfigService)
|
|
54
53
|
)
|
|
55
54
|
|
|
55
|
+
data_value = f"{output_number:02d}:{level:03d}"
|
|
56
|
+
|
|
56
57
|
with service:
|
|
57
|
-
service.
|
|
58
|
+
service.write_config(
|
|
59
|
+
serial_number=serial_number,
|
|
60
|
+
datapoint_type=DataPointType.MODULE_LIGHT_LEVEL,
|
|
61
|
+
data_value=data_value,
|
|
62
|
+
finish_callback=on_finish,
|
|
63
|
+
timeout_seconds=0.5,
|
|
64
|
+
)
|
|
58
65
|
|
|
59
66
|
|
|
60
67
|
@conbus_lightlevel.command("off")
|
|
@@ -62,7 +69,6 @@ def xp_lightlevel_set(
|
|
|
62
69
|
@click.argument("output_number", type=click.IntRange(0, 8))
|
|
63
70
|
@click.pass_context
|
|
64
71
|
@connection_command()
|
|
65
|
-
@handle_service_errors(ConbusLightlevelError)
|
|
66
72
|
def xp_lightlevel_off(
|
|
67
73
|
ctx: click.Context, serial_number: str, output_number: int
|
|
68
74
|
) -> None:
|
|
@@ -79,20 +85,29 @@ def xp_lightlevel_off(
|
|
|
79
85
|
xp conbus lightlevel off 0011223344 0 # Turn off output 0
|
|
80
86
|
"""
|
|
81
87
|
|
|
82
|
-
def
|
|
83
|
-
"""Handle successful completion of light level
|
|
88
|
+
def on_finish(response: "ConbusWriteConfigResponse") -> None:
|
|
89
|
+
"""Handle successful completion of light level on command.
|
|
84
90
|
|
|
85
91
|
Args:
|
|
86
92
|
response: Light level response object.
|
|
87
93
|
"""
|
|
88
94
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
89
95
|
|
|
90
|
-
service = (
|
|
91
|
-
ctx.obj.get("container").get_container().resolve(
|
|
96
|
+
service: WriteConfigService = (
|
|
97
|
+
ctx.obj.get("container").get_container().resolve(WriteConfigService)
|
|
92
98
|
)
|
|
93
99
|
|
|
100
|
+
level = 0
|
|
101
|
+
data_value = f"{output_number:02d}:{level:03d}"
|
|
102
|
+
|
|
94
103
|
with service:
|
|
95
|
-
service.
|
|
104
|
+
service.write_config(
|
|
105
|
+
serial_number=serial_number,
|
|
106
|
+
datapoint_type=DataPointType.MODULE_LIGHT_LEVEL,
|
|
107
|
+
data_value=data_value,
|
|
108
|
+
finish_callback=on_finish,
|
|
109
|
+
timeout_seconds=0.5,
|
|
110
|
+
)
|
|
96
111
|
|
|
97
112
|
|
|
98
113
|
@conbus_lightlevel.command("on")
|
|
@@ -100,7 +115,6 @@ def xp_lightlevel_off(
|
|
|
100
115
|
@click.argument("output_number", type=click.IntRange(0, 8))
|
|
101
116
|
@click.pass_context
|
|
102
117
|
@connection_command()
|
|
103
|
-
@handle_service_errors(ConbusLightlevelError)
|
|
104
118
|
def xp_lightlevel_on(
|
|
105
119
|
ctx: click.Context, serial_number: str, output_number: int
|
|
106
120
|
) -> None:
|
|
@@ -117,7 +131,7 @@ def xp_lightlevel_on(
|
|
|
117
131
|
xp conbus lightlevel on 0011223344 0 # Turn on output 0 (80%)
|
|
118
132
|
"""
|
|
119
133
|
|
|
120
|
-
def
|
|
134
|
+
def on_finish(response: "ConbusWriteConfigResponse") -> None:
|
|
121
135
|
"""Handle successful completion of light level on command.
|
|
122
136
|
|
|
123
137
|
Args:
|
|
@@ -125,12 +139,21 @@ def xp_lightlevel_on(
|
|
|
125
139
|
"""
|
|
126
140
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
127
141
|
|
|
128
|
-
service = (
|
|
129
|
-
ctx.obj.get("container").get_container().resolve(
|
|
142
|
+
service: WriteConfigService = (
|
|
143
|
+
ctx.obj.get("container").get_container().resolve(WriteConfigService)
|
|
130
144
|
)
|
|
131
145
|
|
|
146
|
+
level = 60
|
|
147
|
+
data_value = f"{output_number:02d}:{level:03d}"
|
|
148
|
+
|
|
132
149
|
with service:
|
|
133
|
-
service.
|
|
150
|
+
service.write_config(
|
|
151
|
+
serial_number=serial_number,
|
|
152
|
+
datapoint_type=DataPointType.MODULE_LIGHT_LEVEL,
|
|
153
|
+
data_value=data_value,
|
|
154
|
+
finish_callback=on_finish,
|
|
155
|
+
timeout_seconds=0.5,
|
|
156
|
+
)
|
|
134
157
|
|
|
135
158
|
|
|
136
159
|
@conbus_lightlevel.command("get")
|
|
@@ -138,7 +161,6 @@ def xp_lightlevel_on(
|
|
|
138
161
|
@click.argument("output_number", type=click.IntRange(0, 8))
|
|
139
162
|
@click.pass_context
|
|
140
163
|
@connection_command()
|
|
141
|
-
@handle_service_errors(ConbusLightlevelError)
|
|
142
164
|
def xp_lightlevel_get(
|
|
143
165
|
ctx: click.Context, serial_number: str, output_number: int
|
|
144
166
|
) -> None:
|
|
@@ -154,18 +176,32 @@ def xp_lightlevel_get(
|
|
|
154
176
|
xp conbus lightlevel get 0123450001 2 # Get light level for output 2
|
|
155
177
|
xp conbus lightlevel get 0011223344 0 # Get light level for output 0
|
|
156
178
|
"""
|
|
179
|
+
# Get service from container
|
|
180
|
+
service: ConbusDatapointService = (
|
|
181
|
+
ctx.obj.get("container").get_container().resolve(ConbusDatapointService)
|
|
182
|
+
)
|
|
183
|
+
telegram_service: TelegramDatapointService = (
|
|
184
|
+
ctx.obj.get("container").get_container().resolve(TelegramDatapointService)
|
|
185
|
+
)
|
|
157
186
|
|
|
158
|
-
def
|
|
187
|
+
def on_finish(service_response: "ConbusDatapointResponse") -> None:
|
|
159
188
|
"""Handle successful completion of light level get command.
|
|
160
189
|
|
|
161
190
|
Args:
|
|
162
|
-
|
|
191
|
+
service_response: Light level response object.
|
|
163
192
|
"""
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
193
|
+
lightlevel_level = telegram_service.get_lightlevel(
|
|
194
|
+
service_response.data_value, output_number
|
|
195
|
+
)
|
|
196
|
+
result = service_response.to_dict()
|
|
197
|
+
result["output_number"] = output_number
|
|
198
|
+
result["lightlevel_level"] = lightlevel_level
|
|
199
|
+
click.echo(json.dumps(result, indent=2))
|
|
169
200
|
|
|
170
201
|
with service:
|
|
171
|
-
service.
|
|
202
|
+
service.query_datapoint(
|
|
203
|
+
serial_number=serial_number,
|
|
204
|
+
datapoint_type=DataPointType.MODULE_LIGHT_LEVEL,
|
|
205
|
+
finish_callback=on_finish,
|
|
206
|
+
timeout_seconds=0.5,
|
|
207
|
+
)
|
|
@@ -9,9 +9,12 @@ from xp.cli.utils.decorators import (
|
|
|
9
9
|
connection_command,
|
|
10
10
|
)
|
|
11
11
|
from xp.cli.utils.serial_number_type import SERIAL
|
|
12
|
-
from xp.models
|
|
13
|
-
from xp.
|
|
14
|
-
from xp.
|
|
12
|
+
from xp.models import ConbusDatapointResponse
|
|
13
|
+
from xp.models.conbus.conbus_writeconfig import ConbusWriteConfigResponse
|
|
14
|
+
from xp.models.telegram.datapoint_type import DataPointType
|
|
15
|
+
from xp.services.conbus.conbus_datapoint_service import ConbusDatapointService
|
|
16
|
+
from xp.services.conbus.write_config_service import WriteConfigService
|
|
17
|
+
from xp.services.telegram.telegram_datapoint_service import TelegramDatapointService
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
@conbus_linknumber.command("set", short_help="Set link number for a module")
|
|
@@ -33,23 +36,27 @@ def set_linknumber_command(
|
|
|
33
36
|
\b
|
|
34
37
|
xp conbus linknumber set 0123450001 25
|
|
35
38
|
"""
|
|
36
|
-
service = (
|
|
37
|
-
ctx.obj.get("container").get_container().resolve(ConbusLinknumberSetService)
|
|
38
|
-
)
|
|
39
39
|
|
|
40
|
-
def on_finish(response:
|
|
41
|
-
"""Handle successful completion of
|
|
40
|
+
def on_finish(response: "ConbusWriteConfigResponse") -> None:
|
|
41
|
+
"""Handle successful completion of light level on command.
|
|
42
42
|
|
|
43
43
|
Args:
|
|
44
|
-
response:
|
|
44
|
+
response: Light level response object.
|
|
45
45
|
"""
|
|
46
46
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
47
47
|
|
|
48
|
+
service: WriteConfigService = (
|
|
49
|
+
ctx.obj.get("container").get_container().resolve(WriteConfigService)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
data_value = f"{link_number: 02d}"
|
|
48
53
|
with service:
|
|
49
|
-
service.
|
|
54
|
+
service.write_config(
|
|
50
55
|
serial_number=serial_number,
|
|
51
|
-
|
|
56
|
+
datapoint_type=DataPointType.LINK_NUMBER,
|
|
57
|
+
data_value=data_value,
|
|
52
58
|
finish_callback=on_finish,
|
|
59
|
+
timeout_seconds=0.5,
|
|
53
60
|
)
|
|
54
61
|
|
|
55
62
|
|
|
@@ -68,20 +75,28 @@ def get_linknumber_command(ctx: click.Context, serial_number: str) -> None:
|
|
|
68
75
|
\b
|
|
69
76
|
xp conbus linknumber get 0123450001
|
|
70
77
|
"""
|
|
71
|
-
service = (
|
|
72
|
-
ctx.obj.get("container").get_container().resolve(
|
|
78
|
+
service: ConbusDatapointService = (
|
|
79
|
+
ctx.obj.get("container").get_container().resolve(ConbusDatapointService)
|
|
80
|
+
)
|
|
81
|
+
telegram_service: TelegramDatapointService = (
|
|
82
|
+
ctx.obj.get("container").get_container().resolve(TelegramDatapointService)
|
|
73
83
|
)
|
|
74
84
|
|
|
75
|
-
def on_finish(
|
|
85
|
+
def on_finish(service_response: ConbusDatapointResponse) -> None:
|
|
76
86
|
"""Handle successful completion of link number get command.
|
|
77
87
|
|
|
78
88
|
Args:
|
|
79
|
-
|
|
89
|
+
service_response: Link number response object.
|
|
80
90
|
"""
|
|
81
|
-
|
|
91
|
+
linknumber_value = telegram_service.get_linknumber(service_response.data_value)
|
|
92
|
+
result = service_response.to_dict()
|
|
93
|
+
result["linknumber_value"] = linknumber_value
|
|
94
|
+
click.echo(json.dumps(result, indent=2))
|
|
82
95
|
|
|
83
96
|
with service:
|
|
84
|
-
service.
|
|
97
|
+
service.query_datapoint(
|
|
85
98
|
serial_number=serial_number,
|
|
99
|
+
datapoint_type=DataPointType.LINK_NUMBER,
|
|
86
100
|
finish_callback=on_finish,
|
|
101
|
+
timeout_seconds=0.5,
|
|
87
102
|
)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
from dataclasses import asdict
|
|
5
|
+
from typing import Union
|
|
5
6
|
|
|
6
7
|
import click
|
|
7
8
|
from click import Context
|
|
@@ -12,7 +13,9 @@ from xp.cli.utils.decorators import (
|
|
|
12
13
|
)
|
|
13
14
|
from xp.cli.utils.serial_number_type import SERIAL
|
|
14
15
|
from xp.cli.utils.xp_module_type import XP_MODULE_TYPE
|
|
15
|
-
from xp.models.actiontable.
|
|
16
|
+
from xp.models.actiontable.msactiontable_xp20 import Xp20MsActionTable
|
|
17
|
+
from xp.models.actiontable.msactiontable_xp24 import Xp24MsActionTable
|
|
18
|
+
from xp.models.actiontable.msactiontable_xp33 import Xp33MsActionTable
|
|
16
19
|
from xp.services.conbus.actiontable.msactiontable_service import (
|
|
17
20
|
MsActionTableService,
|
|
18
21
|
)
|
|
@@ -33,7 +36,9 @@ def conbus_download_msactiontable(
|
|
|
33
36
|
serial_number: 10-digit module serial number.
|
|
34
37
|
xpmoduletype: XP module type.
|
|
35
38
|
"""
|
|
36
|
-
service =
|
|
39
|
+
service: MsActionTableService = (
|
|
40
|
+
ctx.obj.get("container").get_container().resolve(MsActionTableService)
|
|
41
|
+
)
|
|
37
42
|
|
|
38
43
|
def progress_callback(progress: str) -> None:
|
|
39
44
|
"""Handle progress updates during MS action table download.
|
|
@@ -43,7 +48,9 @@ def conbus_download_msactiontable(
|
|
|
43
48
|
"""
|
|
44
49
|
click.echo(progress, nl=False)
|
|
45
50
|
|
|
46
|
-
def
|
|
51
|
+
def on_finish(
|
|
52
|
+
action_table: Union[Xp20MsActionTable | Xp24MsActionTable | Xp33MsActionTable],
|
|
53
|
+
) -> None:
|
|
47
54
|
"""Handle successful completion of MS action table download.
|
|
48
55
|
|
|
49
56
|
Args:
|
|
@@ -73,6 +80,6 @@ def conbus_download_msactiontable(
|
|
|
73
80
|
serial_number=serial_number,
|
|
74
81
|
xpmoduletype=xpmoduletype,
|
|
75
82
|
progress_callback=progress_callback,
|
|
76
|
-
finish_callback=
|
|
83
|
+
finish_callback=on_finish,
|
|
77
84
|
error_callback=error_callback,
|
|
78
85
|
)
|
|
@@ -34,7 +34,9 @@ def xp_output_on(ctx: click.Context, serial_number: str, output_number: int) ->
|
|
|
34
34
|
\b
|
|
35
35
|
xp conbus output on 0011223344 0 # Turn on output 0
|
|
36
36
|
"""
|
|
37
|
-
service =
|
|
37
|
+
service: ConbusOutputService = (
|
|
38
|
+
ctx.obj.get("container").get_container().resolve(ConbusOutputService)
|
|
39
|
+
)
|
|
38
40
|
|
|
39
41
|
def on_finish(response: ConbusOutputResponse) -> None:
|
|
40
42
|
"""Handle successful completion of output on command.
|
|
@@ -70,7 +72,9 @@ def xp_output_off(ctx: click.Context, serial_number: str, output_number: int) ->
|
|
|
70
72
|
\b
|
|
71
73
|
xp conbus output off 0011223344 1 # Turn off output 1
|
|
72
74
|
"""
|
|
73
|
-
service =
|
|
75
|
+
service: ConbusOutputService = (
|
|
76
|
+
ctx.obj.get("container").get_container().resolve(ConbusOutputService)
|
|
77
|
+
)
|
|
74
78
|
|
|
75
79
|
def on_finish(response: ConbusOutputResponse) -> None:
|
|
76
80
|
"""Handle successful completion of output off command.
|
|
@@ -36,7 +36,7 @@ def receive_telegrams(ctx: Context, timeout: float) -> None:
|
|
|
36
36
|
xp conbus receive 5.0
|
|
37
37
|
"""
|
|
38
38
|
|
|
39
|
-
def
|
|
39
|
+
def on_finish(response_received: ConbusReceiveResponse) -> None:
|
|
40
40
|
"""Handle successful completion of telegram receive operation.
|
|
41
41
|
|
|
42
42
|
Args:
|
|
@@ -52,6 +52,8 @@ def receive_telegrams(ctx: Context, timeout: float) -> None:
|
|
|
52
52
|
"""
|
|
53
53
|
click.echo(telegram_received)
|
|
54
54
|
|
|
55
|
-
service =
|
|
55
|
+
service: ConbusReceiveService = (
|
|
56
|
+
ctx.obj.get("container").get_container().resolve(ConbusReceiveService)
|
|
57
|
+
)
|
|
56
58
|
with service:
|
|
57
|
-
service.start(progress,
|
|
59
|
+
service.start(progress, on_finish, timeout)
|
xp/cli/commands/file_commands.py
CHANGED
|
@@ -56,7 +56,9 @@ def decode_log_file(
|
|
|
56
56
|
from xp.services.log_file_service import LogFileService
|
|
57
57
|
from xp.utils.time_utils import TimeParsingError, parse_time_range
|
|
58
58
|
|
|
59
|
-
service =
|
|
59
|
+
service: LogFileService = (
|
|
60
|
+
ctx.obj.get("container").get_container().resolve(LogFileService)
|
|
61
|
+
)
|
|
60
62
|
StatisticsFormatter(True)
|
|
61
63
|
|
|
62
64
|
try:
|
|
@@ -124,7 +126,9 @@ def analyze_log_file(ctx: Context, log_file_path: str) -> None:
|
|
|
124
126
|
"""
|
|
125
127
|
from xp.services.log_file_service import LogFileService
|
|
126
128
|
|
|
127
|
-
service =
|
|
129
|
+
service: LogFileService = (
|
|
130
|
+
ctx.obj.get("container").get_container().resolve(LogFileService)
|
|
131
|
+
)
|
|
128
132
|
StatisticsFormatter(True)
|
|
129
133
|
|
|
130
134
|
try:
|
|
@@ -156,7 +160,9 @@ def validate_log_file(ctx: Context, log_file_path: str) -> None:
|
|
|
156
160
|
"""
|
|
157
161
|
from xp.services.log_file_service import LogFileService
|
|
158
162
|
|
|
159
|
-
service =
|
|
163
|
+
service: LogFileService = (
|
|
164
|
+
ctx.obj.get("container").get_container().resolve(LogFileService)
|
|
165
|
+
)
|
|
160
166
|
OutputFormatter(True)
|
|
161
167
|
|
|
162
168
|
try:
|
|
@@ -28,7 +28,9 @@ def homekit_start(ctx: Context) -> None:
|
|
|
28
28
|
click.echo("Starting XP Protocol HomeKit server...")
|
|
29
29
|
|
|
30
30
|
try:
|
|
31
|
-
service =
|
|
31
|
+
service: HomeKitService = (
|
|
32
|
+
ctx.obj.get("container").get_container().resolve(HomeKitService)
|
|
33
|
+
)
|
|
32
34
|
service.start() # Blocking call - reactor.run() never returns
|
|
33
35
|
|
|
34
36
|
except KeyboardInterrupt:
|
|
@@ -37,7 +37,9 @@ def module_info(ctx: Context, identifier: str) -> None:
|
|
|
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:
|
|
@@ -76,7 +78,9 @@ def module_list(ctx: Context, category: str, group_by_category: bool) -> None:
|
|
|
76
78
|
xp module list --category "Interface Panels"
|
|
77
79
|
xp module list --group-by-category
|
|
78
80
|
"""
|
|
79
|
-
service =
|
|
81
|
+
service: ModuleTypeService = (
|
|
82
|
+
ctx.obj.get("container").get_container().resolve(ModuleTypeService)
|
|
83
|
+
)
|
|
80
84
|
ListFormatter(True)
|
|
81
85
|
|
|
82
86
|
try:
|
|
@@ -130,7 +134,9 @@ def module_search(ctx: Context, query: str, field: tuple) -> None:
|
|
|
130
134
|
xp module search "push button"
|
|
131
135
|
xp module search --field name "XP"
|
|
132
136
|
"""
|
|
133
|
-
service =
|
|
137
|
+
service: ModuleTypeService = (
|
|
138
|
+
ctx.obj.get("container").get_container().resolve(ModuleTypeService)
|
|
139
|
+
)
|
|
134
140
|
ListFormatter(True)
|
|
135
141
|
|
|
136
142
|
try:
|
|
@@ -162,7 +168,9 @@ def module_categories(ctx: Context) -> None:
|
|
|
162
168
|
\b
|
|
163
169
|
xp module categories
|
|
164
170
|
"""
|
|
165
|
-
service =
|
|
171
|
+
service: ModuleTypeService = (
|
|
172
|
+
ctx.obj.get("container").get_container().resolve(ModuleTypeService)
|
|
173
|
+
)
|
|
166
174
|
OutputFormatter(True)
|
|
167
175
|
|
|
168
176
|
try:
|
|
@@ -73,7 +73,9 @@ def start_proxy(ctx: Context, port: int, config: str) -> None:
|
|
|
73
73
|
raise SystemExit(1)
|
|
74
74
|
|
|
75
75
|
# Load configuration and create proxy instance
|
|
76
|
-
service =
|
|
76
|
+
service: ReverseProxyService = (
|
|
77
|
+
ctx.obj.get("container").get_container().resolve(ReverseProxyService)
|
|
78
|
+
)
|
|
77
79
|
global_proxy_instance = service
|
|
78
80
|
|
|
79
81
|
# Handle graceful shutdown on SIGINT
|
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
|
|
@@ -79,7 +78,6 @@ cli.add_command(telegram)
|
|
|
79
78
|
cli.add_command(module)
|
|
80
79
|
cli.add_command(file)
|
|
81
80
|
cli.add_command(server)
|
|
82
|
-
cli.add_command(api)
|
|
83
81
|
cli.add_command(reverse_proxy)
|
|
84
82
|
|
|
85
83
|
# Add the tree command
|
|
@@ -21,6 +21,7 @@ class ConbusDatapointResponse:
|
|
|
21
21
|
sent_telegram: Telegram sent to device.
|
|
22
22
|
received_telegrams: List of telegrams received.
|
|
23
23
|
datapoint_telegram: Parsed datapoint telegram.
|
|
24
|
+
data_value: Value of the datapoint telegram.
|
|
24
25
|
datapoints: List of datapoint values.
|
|
25
26
|
error: Error message if operation failed.
|
|
26
27
|
timestamp: Timestamp of the response.
|
|
@@ -33,6 +34,7 @@ class ConbusDatapointResponse:
|
|
|
33
34
|
sent_telegram: Optional[str] = None
|
|
34
35
|
received_telegrams: Optional[list] = None
|
|
35
36
|
datapoint_telegram: Optional[ReplyTelegram] = None
|
|
37
|
+
data_value: str = ""
|
|
36
38
|
datapoints: Optional[List[Dict[str, str]]] = None
|
|
37
39
|
error: Optional[str] = None
|
|
38
40
|
timestamp: Optional[datetime] = None
|
|
@@ -55,6 +57,7 @@ class ConbusDatapointResponse:
|
|
|
55
57
|
result: Dict[str, Any] = {
|
|
56
58
|
"success": self.success,
|
|
57
59
|
"serial_number": self.serial_number,
|
|
60
|
+
"data_value": self.data_value,
|
|
58
61
|
"error": self.error,
|
|
59
62
|
"timestamp": self.timestamp.isoformat() if self.timestamp else None,
|
|
60
63
|
}
|
|
@@ -2,7 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from datetime import datetime
|
|
5
|
-
from typing import Any, Dict, Optional
|
|
5
|
+
from typing import Any, Dict, Optional, TypedDict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DiscoveredDevice(TypedDict):
|
|
9
|
+
"""Discovered device information.
|
|
10
|
+
|
|
11
|
+
Attributes:
|
|
12
|
+
serial_number: Serial number of the device.
|
|
13
|
+
module_type: Module type name (e.g., "XP24", "XP230"), None if not yet retrieved.
|
|
14
|
+
module_type_code: Module type code (e.g., "13", "10"), None if not yet retrieved.
|
|
15
|
+
module_type_name: Module type name converted from module_type_code, None if not yet retrieved.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
serial_number: str
|
|
19
|
+
module_type: Optional[str]
|
|
20
|
+
module_type_code: Optional[int]
|
|
21
|
+
module_type_name: Optional[str]
|
|
6
22
|
|
|
7
23
|
|
|
8
24
|
@dataclass
|
|
@@ -13,7 +29,7 @@ class ConbusDiscoverResponse:
|
|
|
13
29
|
success: Whether the operation was successful.
|
|
14
30
|
sent_telegram: Telegram sent to discover devices.
|
|
15
31
|
received_telegrams: List of telegrams received.
|
|
16
|
-
discovered_devices: List of discovered
|
|
32
|
+
discovered_devices: List of discovered devices with their module types.
|
|
17
33
|
error: Error message if operation failed.
|
|
18
34
|
timestamp: Timestamp of the response.
|
|
19
35
|
"""
|
|
@@ -21,7 +37,7 @@ class ConbusDiscoverResponse:
|
|
|
21
37
|
success: bool
|
|
22
38
|
sent_telegram: Optional[str] = None
|
|
23
39
|
received_telegrams: Optional[list[str]] = None
|
|
24
|
-
discovered_devices: Optional[list[
|
|
40
|
+
discovered_devices: Optional[list[DiscoveredDevice]] = None
|
|
25
41
|
error: Optional[str] = None
|
|
26
42
|
timestamp: Optional[datetime] = None
|
|
27
43
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Conbus link number response model."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any, Dict, Optional
|
|
6
|
+
|
|
7
|
+
from xp.models.telegram.datapoint_type import DataPointType
|
|
8
|
+
from xp.models.telegram.system_function import SystemFunction
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class ConbusWriteConfigResponse:
|
|
13
|
+
"""Represents a response from Conbus write config operations (set/get).
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
success: Whether the operation was successful.
|
|
17
|
+
serial_number: Serial number of the device.
|
|
18
|
+
datapoint_type: the datapoint to write.
|
|
19
|
+
system_function: ACK or NAK received.
|
|
20
|
+
sent_telegram: Telegram sent to device.
|
|
21
|
+
received_telegrams: List of telegrams received.
|
|
22
|
+
data_value: written value.
|
|
23
|
+
error: Error message if operation failed.
|
|
24
|
+
timestamp: Timestamp of the response.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
success: bool
|
|
28
|
+
serial_number: str
|
|
29
|
+
datapoint_type: Optional[DataPointType] = None
|
|
30
|
+
system_function: Optional[SystemFunction] = None
|
|
31
|
+
sent_telegram: Optional[str] = None
|
|
32
|
+
received_telegrams: Optional[list] = None
|
|
33
|
+
data_value: Optional[str] = None
|
|
34
|
+
error: Optional[str] = None
|
|
35
|
+
timestamp: Optional[datetime] = None
|
|
36
|
+
|
|
37
|
+
def __post_init__(self) -> None:
|
|
38
|
+
"""Initialize timestamp and received_telegrams if not provided."""
|
|
39
|
+
if self.timestamp is None:
|
|
40
|
+
self.timestamp = datetime.now()
|
|
41
|
+
if self.received_telegrams is None:
|
|
42
|
+
self.received_telegrams = []
|
|
43
|
+
|
|
44
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
45
|
+
"""Convert to dictionary for JSON serialization.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Dictionary representation of the response.
|
|
49
|
+
"""
|
|
50
|
+
return {
|
|
51
|
+
"success": self.success,
|
|
52
|
+
"system_function": self.system_function,
|
|
53
|
+
"datapoint_type": self.datapoint_type,
|
|
54
|
+
"data_value": self.data_value,
|
|
55
|
+
"serial_number": self.serial_number,
|
|
56
|
+
"sent_telegram": self.sent_telegram,
|
|
57
|
+
"received_telegrams": self.received_telegrams,
|
|
58
|
+
"error": self.error,
|
|
59
|
+
"timestamp": self.timestamp.isoformat() if self.timestamp else None,
|
|
60
|
+
}
|
|
@@ -22,10 +22,10 @@ class SystemTelegram(Telegram):
|
|
|
22
22
|
Examples: <S0020012521F02D18FN>
|
|
23
23
|
|
|
24
24
|
Attributes:
|
|
25
|
-
serial_number: Serial number of the device
|
|
26
|
-
system_function: System function code.
|
|
27
|
-
data: Data payload
|
|
28
|
-
datapoint_type: Type of datapoint.
|
|
25
|
+
serial_number: Serial number of the device (0020012521)
|
|
26
|
+
system_function: System function code (02).
|
|
27
|
+
data: Data payload (18)
|
|
28
|
+
datapoint_type: Type of datapoint (18).
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
31
|
serial_number: str = ""
|