conson-xp 1.33.0__py3-none-any.whl → 1.34.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.33.0.dist-info → conson_xp-1.34.0.dist-info}/METADATA +1 -1
- {conson_xp-1.33.0.dist-info → conson_xp-1.34.0.dist-info}/RECORD +10 -10
- xp/__init__.py +1 -1
- xp/cli/commands/conbus/conbus_blink_commands.py +20 -6
- xp/services/conbus/conbus_blink_all_service.py +89 -35
- xp/services/conbus/conbus_blink_service.py +82 -24
- xp/utils/dependencies.py +2 -4
- {conson_xp-1.33.0.dist-info → conson_xp-1.34.0.dist-info}/WHEEL +0 -0
- {conson_xp-1.33.0.dist-info → conson_xp-1.34.0.dist-info}/entry_points.txt +0 -0
- {conson_xp-1.33.0.dist-info → conson_xp-1.34.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
conson_xp-1.
|
|
2
|
-
conson_xp-1.
|
|
3
|
-
conson_xp-1.
|
|
4
|
-
conson_xp-1.
|
|
5
|
-
xp/__init__.py,sha256=
|
|
1
|
+
conson_xp-1.34.0.dist-info/METADATA,sha256=9ID-C2KoLbshYqzErSWWIRc0q_O9loTVJIOJxGe57NY,11246
|
|
2
|
+
conson_xp-1.34.0.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
|
|
3
|
+
conson_xp-1.34.0.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
|
|
4
|
+
conson_xp-1.34.0.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
|
|
5
|
+
xp/__init__.py,sha256=vXeJqE3QI_Fjqi5W7xgUMPTwKhql9XhCnkj3f7fKMjs,181
|
|
6
6
|
xp/cli/__init__.py,sha256=QjnKB1KaI2aIyKlzrnvCwfbBuUj8HNgwNMvNJVQofbI,81
|
|
7
7
|
xp/cli/__main__.py,sha256=l2iKwMdat5rTGd3JWs-uGksnYYDDffp_Npz05QdKEeU,117
|
|
8
8
|
xp/cli/commands/__init__.py,sha256=noh8fdZAWq-ihJEboP8WugbIgq4LJ3jUWMRA7720xWE,4909
|
|
@@ -10,7 +10,7 @@ xp/cli/commands/conbus/__init__.py,sha256=gE3K5OEoXkkZX8UOc2v3nreQQzwkOQi7n0VZ-Z
|
|
|
10
10
|
xp/cli/commands/conbus/conbus.py,sha256=eqdY8ArapvD08Z4p7Xk7eh4z0dESHuMSw7PKtwTJRYU,3021
|
|
11
11
|
xp/cli/commands/conbus/conbus_actiontable_commands.py,sha256=cdjLV9cnm7teEOlu5Jf1MS_aL7lNy8KiDIyjCQa5Nzw,7138
|
|
12
12
|
xp/cli/commands/conbus/conbus_autoreport_commands.py,sha256=oZgyUUFNsb4yf2WO81l2w1PrasNwdC__QwxNkJ2jCaU,3794
|
|
13
|
-
xp/cli/commands/conbus/conbus_blink_commands.py,sha256=
|
|
13
|
+
xp/cli/commands/conbus/conbus_blink_commands.py,sha256=HRn4Lr_BO7_WynsaUnO_hKezOi3MVhkPYEOnh0rMMlg,5324
|
|
14
14
|
xp/cli/commands/conbus/conbus_config_commands.py,sha256=BugIbgNX6_s4MySGvI6tWZkwguciajHUX2Xz8XBux7k,716
|
|
15
15
|
xp/cli/commands/conbus/conbus_custom_commands.py,sha256=lICT93ijMdhVRm8KjNMLo7kQ2BLlnOZvMPbR3SxSmZ4,1692
|
|
16
16
|
xp/cli/commands/conbus/conbus_datapoint_commands.py,sha256=r36OuTjREtbGKL-bskAGa0-WLw7x06td6woZn3GYJNA,3630
|
|
@@ -127,8 +127,8 @@ xp/services/conbus/actiontable/actiontable_list_service.py,sha256=6izVZkM2hlWXUM
|
|
|
127
127
|
xp/services/conbus/actiontable/actiontable_show_service.py,sha256=jqNZ4UvZPHH66OYuryjnU1Km-a83OCwYvK0vc56oL8I,3017
|
|
128
128
|
xp/services/conbus/actiontable/actiontable_upload_service.py,sha256=txhMumjcIHPI4TZk6CERhjyyTKUNhUb7fdSmaylYC48,8189
|
|
129
129
|
xp/services/conbus/actiontable/msactiontable_service.py,sha256=K0TiYL8g4ac8BS1tqS0UAIYJigOlNhxVLIb8ZFybnVE,8393
|
|
130
|
-
xp/services/conbus/conbus_blink_all_service.py,sha256=
|
|
131
|
-
xp/services/conbus/conbus_blink_service.py,sha256=
|
|
130
|
+
xp/services/conbus/conbus_blink_all_service.py,sha256=6XsqtgHUgPDPWG0Mx2W2gnG_1eiaHrt2DiPXGqGHS50,8472
|
|
131
|
+
xp/services/conbus/conbus_blink_service.py,sha256=wFCUbHYInbzfE4Ks_qjkav0FhtHXsxM9IY6tD5r0oAk,7898
|
|
132
132
|
xp/services/conbus/conbus_custom_service.py,sha256=4aneYdPObiZOGxPFYg5Wr70cl_xFxlQIdJBPQSa0enI,5826
|
|
133
133
|
xp/services/conbus/conbus_datapoint_queryall_service.py,sha256=p9R02cVimhdJILHQ6BoeZj8Hog4oRpqBnMo3t4R8ecY,6816
|
|
134
134
|
xp/services/conbus/conbus_datapoint_service.py,sha256=SYhHj9RmTmaJ750tyZ1IW2kl7tgDQ1xm_EM1zUjk1aQ,6421
|
|
@@ -198,10 +198,10 @@ xp/term/widgets/protocol_log.py,sha256=CJUpckWj7GC1kVqixDadteyGnI4aHyzd4kkH-pSbz
|
|
|
198
198
|
xp/term/widgets/status_footer.py,sha256=bxrcqKzJ9V0aPSn_WwraVpJz7NxBUh3yIjA3fwv5nVA,3256
|
|
199
199
|
xp/utils/__init__.py,sha256=_avMF_UOkfR3tNeDIPqQ5odmbq5raKkaq1rZ9Cn1CJs,332
|
|
200
200
|
xp/utils/checksum.py,sha256=HDpiQxmdIedbCbZ4o_Box0i_Zig417BtCV_46ZyhiTk,1711
|
|
201
|
-
xp/utils/dependencies.py,sha256=
|
|
201
|
+
xp/utils/dependencies.py,sha256=jN2FNwUUacmrEXsOA-zWe-1yWr16x9BaVfLjmFxIJKg,24437
|
|
202
202
|
xp/utils/event_helper.py,sha256=W-A_xmoXlpWZBbJH6qdaN50o3-XrwFsDgvAGMJDiAgo,1001
|
|
203
203
|
xp/utils/logging.py,sha256=rZDXwlBrYK8A6MPq5StsMNpgsRowzJXM6fvROPwJdGM,3750
|
|
204
204
|
xp/utils/serialization.py,sha256=RWHHk86feaB4ZP7rjE4qOWK0900yg2joUBDkP76gfOY,4618
|
|
205
205
|
xp/utils/state_machine.py,sha256=Oe2sLwCh9z_vr1tF6X0ZRGTeuckRQAGzmef7xc9CNdc,2413
|
|
206
206
|
xp/utils/time_utils.py,sha256=dEyViDlAG9GWU-J3D_YVa-sGma6yiyyMTgN4h2x3PY4,3781
|
|
207
|
-
conson_xp-1.
|
|
207
|
+
conson_xp-1.34.0.dist-info/RECORD,,
|
xp/__init__.py
CHANGED
|
@@ -41,12 +41,15 @@ def send_blink_on_telegram(ctx: Context, serial_number: str) -> None:
|
|
|
41
41
|
service_response: Blink response object.
|
|
42
42
|
"""
|
|
43
43
|
click.echo(json.dumps(service_response.to_dict(), indent=2))
|
|
44
|
+
service.stop_reactor()
|
|
44
45
|
|
|
45
46
|
service: ConbusBlinkService = (
|
|
46
47
|
ctx.obj.get("container").get_container().resolve(ConbusBlinkService)
|
|
47
48
|
)
|
|
48
49
|
with service:
|
|
49
|
-
service.
|
|
50
|
+
service.on_finish.connect(on_finish)
|
|
51
|
+
service.send_blink_telegram(serial_number, "on", 0.5)
|
|
52
|
+
service.start_reactor()
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
@conbus_blink.command("off")
|
|
@@ -73,12 +76,15 @@ def send_blink_off_telegram(ctx: Context, serial_number: str) -> None:
|
|
|
73
76
|
service_response: Blink response object.
|
|
74
77
|
"""
|
|
75
78
|
click.echo(json.dumps(service_response.to_dict(), indent=2))
|
|
79
|
+
service.stop_reactor()
|
|
76
80
|
|
|
77
81
|
service: ConbusBlinkService = (
|
|
78
82
|
ctx.obj.get("container").get_container().resolve(ConbusBlinkService)
|
|
79
83
|
)
|
|
80
84
|
with service:
|
|
81
|
-
service.
|
|
85
|
+
service.on_finish.connect(on_finish)
|
|
86
|
+
service.send_blink_telegram(serial_number, "off", 0.5)
|
|
87
|
+
service.start_reactor()
|
|
82
88
|
|
|
83
89
|
|
|
84
90
|
@conbus_blink.group("all", short_help="Control blink state for all devices")
|
|
@@ -109,6 +115,7 @@ def blink_all_off(ctx: Context) -> None:
|
|
|
109
115
|
discovered_devices: Blink response with all devices.
|
|
110
116
|
"""
|
|
111
117
|
click.echo(json.dumps(discovered_devices.to_dict(), indent=2))
|
|
118
|
+
service.stop_reactor()
|
|
112
119
|
|
|
113
120
|
def progress(message: str) -> None:
|
|
114
121
|
"""Handle progress updates during blink all off operation.
|
|
@@ -116,13 +123,16 @@ def blink_all_off(ctx: Context) -> None:
|
|
|
116
123
|
Args:
|
|
117
124
|
message: Progress message string.
|
|
118
125
|
"""
|
|
119
|
-
click.echo(message)
|
|
126
|
+
click.echo(message, nl=False)
|
|
120
127
|
|
|
121
128
|
service: ConbusBlinkAllService = (
|
|
122
129
|
ctx.obj.get("container").get_container().resolve(ConbusBlinkAllService)
|
|
123
130
|
)
|
|
124
131
|
with service:
|
|
125
|
-
service.
|
|
132
|
+
service.on_progress.connect(progress)
|
|
133
|
+
service.on_finish.connect(on_finish)
|
|
134
|
+
service.send_blink_all_telegram("off", 5)
|
|
135
|
+
service.start_reactor()
|
|
126
136
|
|
|
127
137
|
|
|
128
138
|
@conbus_blink_all.command("on", short_help="Turn on blinking for all devices")
|
|
@@ -147,6 +157,7 @@ def blink_all_on(ctx: Context) -> None:
|
|
|
147
157
|
discovered_devices: Blink response with all devices.
|
|
148
158
|
"""
|
|
149
159
|
click.echo(json.dumps(discovered_devices.to_dict(), indent=2))
|
|
160
|
+
service.stop_reactor()
|
|
150
161
|
|
|
151
162
|
def progress(message: str) -> None:
|
|
152
163
|
"""Handle progress updates during blink all on operation.
|
|
@@ -154,10 +165,13 @@ def blink_all_on(ctx: Context) -> None:
|
|
|
154
165
|
Args:
|
|
155
166
|
message: Progress message string.
|
|
156
167
|
"""
|
|
157
|
-
click.echo(message)
|
|
168
|
+
click.echo(message, nl=False)
|
|
158
169
|
|
|
159
170
|
service: ConbusBlinkAllService = (
|
|
160
171
|
ctx.obj.get("container").get_container().resolve(ConbusBlinkAllService)
|
|
161
172
|
)
|
|
162
173
|
with service:
|
|
163
|
-
service.
|
|
174
|
+
service.on_progress.connect(progress)
|
|
175
|
+
service.on_finish.connect(on_finish)
|
|
176
|
+
service.send_blink_all_telegram("on", 5)
|
|
177
|
+
service.start_reactor()
|
|
@@ -6,46 +6,48 @@ blink/unblink telegrams to all discovered modules on the network.
|
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
8
|
from datetime import datetime
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import Any, Optional
|
|
10
10
|
|
|
11
|
-
from
|
|
11
|
+
from psygnal import Signal
|
|
12
12
|
|
|
13
|
-
from xp.models import ConbusClientConfig
|
|
14
13
|
from xp.models.conbus.conbus_blink import ConbusBlinkResponse
|
|
15
14
|
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
16
15
|
from xp.models.telegram.system_function import SystemFunction
|
|
17
16
|
from xp.models.telegram.telegram_type import TelegramType
|
|
18
|
-
from xp.services.protocol import
|
|
17
|
+
from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
|
|
19
18
|
from xp.services.telegram.telegram_service import TelegramService
|
|
20
19
|
|
|
21
20
|
|
|
22
|
-
class ConbusBlinkAllService
|
|
21
|
+
class ConbusBlinkAllService:
|
|
23
22
|
"""
|
|
24
23
|
Service for blinking all modules on Conbus servers.
|
|
25
24
|
|
|
26
|
-
Uses
|
|
25
|
+
Uses ConbusEventProtocol to provide blink/unblink functionality
|
|
27
26
|
for all discovered modules on the network.
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
on_progress: Signal emitted during blink operation progress (with message).
|
|
30
|
+
on_finish: Signal emitted when blink operation completes (with response).
|
|
28
31
|
"""
|
|
29
32
|
|
|
33
|
+
on_progress: Signal = Signal(str)
|
|
34
|
+
on_finish: Signal = Signal(ConbusBlinkResponse)
|
|
35
|
+
|
|
30
36
|
def __init__(
|
|
31
37
|
self,
|
|
38
|
+
conbus_protocol: ConbusEventProtocol,
|
|
32
39
|
telegram_service: TelegramService,
|
|
33
|
-
cli_config: ConbusClientConfig,
|
|
34
|
-
reactor: PosixReactorBase,
|
|
35
40
|
) -> None:
|
|
36
41
|
"""Initialize the Conbus blink all service.
|
|
37
42
|
|
|
38
43
|
Args:
|
|
44
|
+
conbus_protocol: ConbusEventProtocol instance for communication.
|
|
39
45
|
telegram_service: Service for parsing telegrams.
|
|
40
|
-
cli_config: Configuration for Conbus client connection.
|
|
41
|
-
reactor: Twisted reactor for event loop.
|
|
42
46
|
"""
|
|
43
|
-
|
|
47
|
+
self.conbus_protocol = conbus_protocol
|
|
44
48
|
self.telegram_service = telegram_service
|
|
45
49
|
self.serial_number: str = ""
|
|
46
50
|
self.on_or_off = "none"
|
|
47
|
-
self.progress_callback: Optional[Callable[[str], None]] = None
|
|
48
|
-
self.finish_callback: Optional[Callable[[ConbusBlinkResponse], None]] = None
|
|
49
51
|
self.service_response: ConbusBlinkResponse = ConbusBlinkResponse(
|
|
50
52
|
success=False,
|
|
51
53
|
serial_number=self.serial_number,
|
|
@@ -56,17 +58,23 @@ class ConbusBlinkAllService(ConbusProtocol):
|
|
|
56
58
|
# Set up logging
|
|
57
59
|
self.logger = logging.getLogger(__name__)
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
# Connect protocol signals
|
|
62
|
+
self.conbus_protocol.on_connection_made.connect(self.connection_made)
|
|
63
|
+
self.conbus_protocol.on_telegram_sent.connect(self.telegram_sent)
|
|
64
|
+
self.conbus_protocol.on_telegram_received.connect(self.telegram_received)
|
|
65
|
+
self.conbus_protocol.on_timeout.connect(self.timeout)
|
|
66
|
+
self.conbus_protocol.on_failed.connect(self.failed)
|
|
67
|
+
|
|
68
|
+
def connection_made(self) -> None:
|
|
69
|
+
"""Handle connection made event."""
|
|
61
70
|
self.logger.debug("Connection established, send discover telegram.")
|
|
62
|
-
self.send_telegram(
|
|
71
|
+
self.conbus_protocol.send_telegram(
|
|
63
72
|
telegram_type=TelegramType.SYSTEM,
|
|
64
73
|
serial_number="0000000000",
|
|
65
74
|
system_function=SystemFunction.DISCOVERY,
|
|
66
75
|
data_value="00",
|
|
67
76
|
)
|
|
68
|
-
|
|
69
|
-
self.progress_callback(".")
|
|
77
|
+
self.on_progress.emit(".")
|
|
70
78
|
|
|
71
79
|
def send_blink(self, serial_number: str) -> None:
|
|
72
80
|
"""Send blink or unblink telegram to a discovered module.
|
|
@@ -81,7 +89,7 @@ class ConbusBlinkAllService(ConbusProtocol):
|
|
|
81
89
|
if self.on_or_off.lower() == "on":
|
|
82
90
|
system_function = SystemFunction.BLINK
|
|
83
91
|
|
|
84
|
-
self.send_telegram(
|
|
92
|
+
self.conbus_protocol.send_telegram(
|
|
85
93
|
telegram_type=TelegramType.SYSTEM,
|
|
86
94
|
serial_number=serial_number,
|
|
87
95
|
system_function=system_function,
|
|
@@ -90,8 +98,7 @@ class ConbusBlinkAllService(ConbusProtocol):
|
|
|
90
98
|
self.service_response.system_function = system_function
|
|
91
99
|
self.service_response.operation = self.on_or_off
|
|
92
100
|
|
|
93
|
-
|
|
94
|
-
self.progress_callback(".")
|
|
101
|
+
self.on_progress.emit(".")
|
|
95
102
|
|
|
96
103
|
def telegram_sent(self, telegram_sent: str) -> None:
|
|
97
104
|
"""Handle telegram sent event.
|
|
@@ -129,8 +136,7 @@ class ConbusBlinkAllService(ConbusProtocol):
|
|
|
129
136
|
):
|
|
130
137
|
self.logger.debug("Received discovery response")
|
|
131
138
|
self.send_blink(reply_telegram.serial_number)
|
|
132
|
-
|
|
133
|
-
self.progress_callback(".")
|
|
139
|
+
self.on_progress.emit(".")
|
|
134
140
|
return
|
|
135
141
|
|
|
136
142
|
if reply_telegram and reply_telegram.system_function in (
|
|
@@ -138,12 +144,18 @@ class ConbusBlinkAllService(ConbusProtocol):
|
|
|
138
144
|
SystemFunction.UNBLINK,
|
|
139
145
|
):
|
|
140
146
|
self.logger.debug("Received blink response")
|
|
141
|
-
|
|
142
|
-
self.progress_callback(".")
|
|
147
|
+
self.on_progress.emit(".")
|
|
143
148
|
return
|
|
144
149
|
|
|
145
150
|
self.logger.debug("Received unexpected response")
|
|
146
151
|
|
|
152
|
+
def timeout(self) -> None:
|
|
153
|
+
"""Handle timeout event to stop operation."""
|
|
154
|
+
self.logger.info("Blink all operation timeout")
|
|
155
|
+
self.service_response.success = False
|
|
156
|
+
self.service_response.error = "Blink all operation timeout"
|
|
157
|
+
self.on_finish.emit(self.service_response)
|
|
158
|
+
|
|
147
159
|
def failed(self, message: str) -> None:
|
|
148
160
|
"""Handle failed connection event.
|
|
149
161
|
|
|
@@ -154,28 +166,70 @@ class ConbusBlinkAllService(ConbusProtocol):
|
|
|
154
166
|
self.service_response.success = False
|
|
155
167
|
self.service_response.timestamp = datetime.now()
|
|
156
168
|
self.service_response.error = message
|
|
157
|
-
|
|
158
|
-
self.finish_callback(self.service_response)
|
|
169
|
+
self.on_finish.emit(self.service_response)
|
|
159
170
|
|
|
160
171
|
def send_blink_all_telegram(
|
|
161
172
|
self,
|
|
162
173
|
on_or_off: str,
|
|
163
|
-
progress_callback: Callable[[str], None],
|
|
164
|
-
finish_callback: Callable[[ConbusBlinkResponse], None],
|
|
165
174
|
timeout_seconds: Optional[float] = None,
|
|
166
175
|
) -> None:
|
|
167
176
|
"""Send blink command to all discovered modules.
|
|
168
177
|
|
|
169
178
|
Args:
|
|
170
179
|
on_or_off: "on" to blink or "off" to unblink all devices.
|
|
171
|
-
progress_callback: Callback function to call with progress updates.
|
|
172
|
-
finish_callback: Callback function to call when the operation completes.
|
|
173
180
|
timeout_seconds: Timeout in seconds.
|
|
174
181
|
"""
|
|
175
182
|
self.logger.info("Starting send_blink_all_telegram")
|
|
176
183
|
if timeout_seconds:
|
|
177
|
-
self.timeout_seconds = timeout_seconds
|
|
178
|
-
self.progress_callback = progress_callback
|
|
179
|
-
self.finish_callback = finish_callback
|
|
184
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
180
185
|
self.on_or_off = on_or_off
|
|
181
|
-
|
|
186
|
+
# Caller invokes start_reactor()
|
|
187
|
+
|
|
188
|
+
def set_timeout(self, timeout_seconds: float) -> None:
|
|
189
|
+
"""Set operation timeout.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
timeout_seconds: Timeout in seconds.
|
|
193
|
+
"""
|
|
194
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
195
|
+
|
|
196
|
+
def start_reactor(self) -> None:
|
|
197
|
+
"""Start the reactor."""
|
|
198
|
+
self.conbus_protocol.start_reactor()
|
|
199
|
+
|
|
200
|
+
def stop_reactor(self) -> None:
|
|
201
|
+
"""Stop the reactor."""
|
|
202
|
+
self.conbus_protocol.stop_reactor()
|
|
203
|
+
|
|
204
|
+
def __enter__(self) -> "ConbusBlinkAllService":
|
|
205
|
+
"""Enter context manager - reset state for singleton reuse.
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
Self for context manager protocol.
|
|
209
|
+
"""
|
|
210
|
+
# Reset state for singleton reuse
|
|
211
|
+
self.service_response = ConbusBlinkResponse(
|
|
212
|
+
success=False,
|
|
213
|
+
serial_number="",
|
|
214
|
+
system_function=SystemFunction.NONE,
|
|
215
|
+
operation="none",
|
|
216
|
+
)
|
|
217
|
+
self.serial_number = ""
|
|
218
|
+
self.on_or_off = "none"
|
|
219
|
+
return self
|
|
220
|
+
|
|
221
|
+
def __exit__(
|
|
222
|
+
self, _exc_type: Optional[type], _exc_val: Optional[Exception], _exc_tb: Any
|
|
223
|
+
) -> None:
|
|
224
|
+
"""Exit context manager - cleanup signals and reactor."""
|
|
225
|
+
# Disconnect protocol signals
|
|
226
|
+
self.conbus_protocol.on_connection_made.disconnect(self.connection_made)
|
|
227
|
+
self.conbus_protocol.on_telegram_sent.disconnect(self.telegram_sent)
|
|
228
|
+
self.conbus_protocol.on_telegram_received.disconnect(self.telegram_received)
|
|
229
|
+
self.conbus_protocol.on_timeout.disconnect(self.timeout)
|
|
230
|
+
self.conbus_protocol.on_failed.disconnect(self.failed)
|
|
231
|
+
# Disconnect service signals
|
|
232
|
+
self.on_progress.disconnect()
|
|
233
|
+
self.on_finish.disconnect()
|
|
234
|
+
# Stop reactor
|
|
235
|
+
self.stop_reactor()
|
|
@@ -6,45 +6,46 @@ blink/unblink telegrams to control module LED indicators.
|
|
|
6
6
|
|
|
7
7
|
import logging
|
|
8
8
|
from datetime import datetime
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import Any, Optional
|
|
10
10
|
|
|
11
|
-
from
|
|
11
|
+
from psygnal import Signal
|
|
12
12
|
|
|
13
|
-
from xp.models import ConbusClientConfig
|
|
14
13
|
from xp.models.conbus.conbus_blink import ConbusBlinkResponse
|
|
15
14
|
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
16
15
|
from xp.models.telegram.system_function import SystemFunction
|
|
17
16
|
from xp.models.telegram.telegram_type import TelegramType
|
|
18
|
-
from xp.services.protocol import
|
|
17
|
+
from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
|
|
19
18
|
from xp.services.telegram.telegram_service import TelegramService
|
|
20
19
|
|
|
21
20
|
|
|
22
|
-
class ConbusBlinkService
|
|
21
|
+
class ConbusBlinkService:
|
|
23
22
|
"""
|
|
24
23
|
Service for blinking module LEDs on Conbus servers.
|
|
25
24
|
|
|
26
|
-
Uses
|
|
25
|
+
Uses ConbusEventProtocol to provide blink/unblink functionality
|
|
27
26
|
for controlling module LED indicators.
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
on_finish: Signal emitted when blink operation completes (with response).
|
|
28
30
|
"""
|
|
29
31
|
|
|
32
|
+
on_finish: Signal = Signal(ConbusBlinkResponse)
|
|
33
|
+
|
|
30
34
|
def __init__(
|
|
31
35
|
self,
|
|
36
|
+
conbus_protocol: ConbusEventProtocol,
|
|
32
37
|
telegram_service: TelegramService,
|
|
33
|
-
cli_config: ConbusClientConfig,
|
|
34
|
-
reactor: PosixReactorBase,
|
|
35
38
|
) -> None:
|
|
36
39
|
"""Initialize the Conbus blink service.
|
|
37
40
|
|
|
38
41
|
Args:
|
|
42
|
+
conbus_protocol: ConbusEventProtocol instance for communication.
|
|
39
43
|
telegram_service: Service for parsing telegrams.
|
|
40
|
-
cli_config: Configuration for Conbus client connection.
|
|
41
|
-
reactor: Twisted reactor for event loop.
|
|
42
44
|
"""
|
|
43
|
-
|
|
45
|
+
self.conbus_protocol = conbus_protocol
|
|
44
46
|
self.telegram_service = telegram_service
|
|
45
47
|
self.serial_number: str = ""
|
|
46
48
|
self.on_or_off = "none"
|
|
47
|
-
self.finish_callback: Optional[Callable[[ConbusBlinkResponse], None]] = None
|
|
48
49
|
self.service_response: ConbusBlinkResponse = ConbusBlinkResponse(
|
|
49
50
|
success=False,
|
|
50
51
|
serial_number=self.serial_number,
|
|
@@ -55,15 +56,22 @@ class ConbusBlinkService(ConbusProtocol):
|
|
|
55
56
|
# Set up logging
|
|
56
57
|
self.logger = logging.getLogger(__name__)
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
# Connect signals
|
|
60
|
+
self.conbus_protocol.on_connection_made.connect(self.connection_made)
|
|
61
|
+
self.conbus_protocol.on_telegram_sent.connect(self.telegram_sent)
|
|
62
|
+
self.conbus_protocol.on_telegram_received.connect(self.telegram_received)
|
|
63
|
+
self.conbus_protocol.on_timeout.connect(self.timeout)
|
|
64
|
+
self.conbus_protocol.on_failed.connect(self.failed)
|
|
65
|
+
|
|
66
|
+
def connection_made(self) -> None:
|
|
67
|
+
"""Handle connection made event."""
|
|
60
68
|
self.logger.debug("Connection established, sending blink command.")
|
|
61
69
|
# Blink is 05, Unblink is 06
|
|
62
70
|
system_function = SystemFunction.UNBLINK
|
|
63
71
|
if self.on_or_off.lower() == "on":
|
|
64
72
|
system_function = SystemFunction.BLINK
|
|
65
73
|
|
|
66
|
-
self.send_telegram(
|
|
74
|
+
self.conbus_protocol.send_telegram(
|
|
67
75
|
telegram_type=TelegramType.SYSTEM,
|
|
68
76
|
serial_number=self.serial_number,
|
|
69
77
|
system_function=system_function,
|
|
@@ -113,8 +121,14 @@ class ConbusBlinkService(ConbusProtocol):
|
|
|
113
121
|
self.service_response.serial_number = self.serial_number
|
|
114
122
|
self.service_response.reply_telegram = reply_telegram
|
|
115
123
|
|
|
116
|
-
|
|
117
|
-
|
|
124
|
+
self.on_finish.emit(self.service_response)
|
|
125
|
+
|
|
126
|
+
def timeout(self) -> None:
|
|
127
|
+
"""Handle timeout event to stop operation."""
|
|
128
|
+
self.logger.info("Blink operation timeout")
|
|
129
|
+
self.service_response.success = False
|
|
130
|
+
self.service_response.error = "Blink operation timeout"
|
|
131
|
+
self.on_finish.emit(self.service_response)
|
|
118
132
|
|
|
119
133
|
def failed(self, message: str) -> None:
|
|
120
134
|
"""Handle failed connection event.
|
|
@@ -126,14 +140,12 @@ class ConbusBlinkService(ConbusProtocol):
|
|
|
126
140
|
self.service_response.success = False
|
|
127
141
|
self.service_response.timestamp = datetime.now()
|
|
128
142
|
self.service_response.error = message
|
|
129
|
-
|
|
130
|
-
self.finish_callback(self.service_response)
|
|
143
|
+
self.on_finish.emit(self.service_response)
|
|
131
144
|
|
|
132
145
|
def send_blink_telegram(
|
|
133
146
|
self,
|
|
134
147
|
serial_number: str,
|
|
135
148
|
on_or_off: str,
|
|
136
|
-
finish_callback: Callable[[ConbusBlinkResponse], None],
|
|
137
149
|
timeout_seconds: Optional[float] = None,
|
|
138
150
|
) -> None:
|
|
139
151
|
r"""Send blink command to start blinking module LED.
|
|
@@ -141,7 +153,6 @@ class ConbusBlinkService(ConbusProtocol):
|
|
|
141
153
|
Args:
|
|
142
154
|
serial_number: 10-digit module serial number.
|
|
143
155
|
on_or_off: "on" to blink or "off" to unblink.
|
|
144
|
-
finish_callback: Callback function to call when the reply is received.
|
|
145
156
|
timeout_seconds: Timeout in seconds.
|
|
146
157
|
|
|
147
158
|
Examples:
|
|
@@ -151,8 +162,55 @@ class ConbusBlinkService(ConbusProtocol):
|
|
|
151
162
|
"""
|
|
152
163
|
self.logger.info("Starting send_blink_telegram")
|
|
153
164
|
if timeout_seconds:
|
|
154
|
-
self.timeout_seconds = timeout_seconds
|
|
155
|
-
self.finish_callback = finish_callback
|
|
165
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
156
166
|
self.serial_number = serial_number
|
|
157
167
|
self.on_or_off = on_or_off
|
|
158
|
-
|
|
168
|
+
# Caller invokes start_reactor()
|
|
169
|
+
|
|
170
|
+
def set_timeout(self, timeout_seconds: float) -> None:
|
|
171
|
+
"""Set operation timeout.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
timeout_seconds: Timeout in seconds.
|
|
175
|
+
"""
|
|
176
|
+
self.conbus_protocol.timeout_seconds = timeout_seconds
|
|
177
|
+
|
|
178
|
+
def start_reactor(self) -> None:
|
|
179
|
+
"""Start the reactor."""
|
|
180
|
+
self.conbus_protocol.start_reactor()
|
|
181
|
+
|
|
182
|
+
def stop_reactor(self) -> None:
|
|
183
|
+
"""Stop the reactor."""
|
|
184
|
+
self.conbus_protocol.stop_reactor()
|
|
185
|
+
|
|
186
|
+
def __enter__(self) -> "ConbusBlinkService":
|
|
187
|
+
"""Enter context manager - reset state for singleton reuse.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Self for context manager protocol.
|
|
191
|
+
"""
|
|
192
|
+
# Reset state for singleton reuse
|
|
193
|
+
self.service_response = ConbusBlinkResponse(
|
|
194
|
+
success=False,
|
|
195
|
+
serial_number="",
|
|
196
|
+
system_function=SystemFunction.NONE,
|
|
197
|
+
operation="none",
|
|
198
|
+
)
|
|
199
|
+
self.serial_number = ""
|
|
200
|
+
self.on_or_off = "none"
|
|
201
|
+
return self
|
|
202
|
+
|
|
203
|
+
def __exit__(
|
|
204
|
+
self, _exc_type: Optional[type], _exc_val: Optional[Exception], _exc_tb: Any
|
|
205
|
+
) -> None:
|
|
206
|
+
"""Exit context manager - cleanup signals and reactor."""
|
|
207
|
+
# Disconnect protocol signals
|
|
208
|
+
self.conbus_protocol.on_connection_made.disconnect(self.connection_made)
|
|
209
|
+
self.conbus_protocol.on_telegram_sent.disconnect(self.telegram_sent)
|
|
210
|
+
self.conbus_protocol.on_telegram_received.disconnect(self.telegram_received)
|
|
211
|
+
self.conbus_protocol.on_timeout.disconnect(self.timeout)
|
|
212
|
+
self.conbus_protocol.on_failed.disconnect(self.failed)
|
|
213
|
+
# Disconnect service signals
|
|
214
|
+
self.on_finish.disconnect()
|
|
215
|
+
# Stop reactor
|
|
216
|
+
self.stop_reactor()
|
xp/utils/dependencies.py
CHANGED
|
@@ -265,8 +265,7 @@ class ServiceContainer:
|
|
|
265
265
|
self.container.register(
|
|
266
266
|
ConbusBlinkService,
|
|
267
267
|
factory=lambda: ConbusBlinkService(
|
|
268
|
-
|
|
269
|
-
reactor=self.container.resolve(PosixReactorBase),
|
|
268
|
+
conbus_protocol=self.container.resolve(ConbusEventProtocol),
|
|
270
269
|
telegram_service=self.container.resolve(TelegramService),
|
|
271
270
|
),
|
|
272
271
|
scope=punq.Scope.singleton,
|
|
@@ -275,8 +274,7 @@ class ServiceContainer:
|
|
|
275
274
|
self.container.register(
|
|
276
275
|
ConbusBlinkAllService,
|
|
277
276
|
factory=lambda: ConbusBlinkAllService(
|
|
278
|
-
|
|
279
|
-
reactor=self.container.resolve(PosixReactorBase),
|
|
277
|
+
conbus_protocol=self.container.resolve(ConbusEventProtocol),
|
|
280
278
|
telegram_service=self.container.resolve(TelegramService),
|
|
281
279
|
),
|
|
282
280
|
scope=punq.Scope.singleton,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|