conson-xp 1.46.0__py3-none-any.whl → 1.47.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.
Files changed (179) hide show
  1. {conson_xp-1.46.0.dist-info → conson_xp-1.47.0.dist-info}/METADATA +1 -1
  2. conson_xp-1.47.0.dist-info/RECORD +210 -0
  3. xp/__init__.py +3 -2
  4. xp/cli/commands/conbus/conbus.py +1 -1
  5. xp/cli/commands/conbus/conbus_actiontable_commands.py +33 -15
  6. xp/cli/commands/conbus/conbus_autoreport_commands.py +8 -4
  7. xp/cli/commands/conbus/conbus_blink_commands.py +20 -10
  8. xp/cli/commands/conbus/conbus_config_commands.py +2 -1
  9. xp/cli/commands/conbus/conbus_custom_commands.py +4 -2
  10. xp/cli/commands/conbus/conbus_datapoint_commands.py +10 -5
  11. xp/cli/commands/conbus/conbus_discover_commands.py +8 -4
  12. xp/cli/commands/conbus/conbus_event_commands.py +8 -4
  13. xp/cli/commands/conbus/conbus_export_commands.py +8 -4
  14. xp/cli/commands/conbus/conbus_lightlevel_commands.py +16 -8
  15. xp/cli/commands/conbus/conbus_linknumber_commands.py +8 -4
  16. xp/cli/commands/conbus/conbus_modulenumber_commands.py +8 -4
  17. xp/cli/commands/conbus/conbus_msactiontable_commands.py +78 -40
  18. xp/cli/commands/conbus/conbus_output_commands.py +16 -8
  19. xp/cli/commands/conbus/conbus_raw_commands.py +6 -3
  20. xp/cli/commands/conbus/conbus_receive_commands.py +6 -3
  21. xp/cli/commands/conbus/conbus_scan_commands.py +6 -3
  22. xp/cli/commands/file_commands.py +6 -3
  23. xp/cli/commands/homekit/homekit.py +4 -2
  24. xp/cli/commands/homekit/homekit_start_commands.py +2 -1
  25. xp/cli/commands/module_commands.py +8 -4
  26. xp/cli/commands/reverse_proxy_commands.py +8 -4
  27. xp/cli/commands/server/server_commands.py +6 -3
  28. xp/cli/commands/telegram/telegram_blink_commands.py +4 -2
  29. xp/cli/commands/telegram/telegram_checksum_commands.py +4 -2
  30. xp/cli/commands/telegram/telegram_discover_commands.py +2 -1
  31. xp/cli/commands/telegram/telegram_linknumber_commands.py +4 -2
  32. xp/cli/commands/telegram/telegram_parse_commands.py +4 -2
  33. xp/cli/commands/telegram/telegram_version_commands.py +2 -1
  34. xp/cli/commands/term/term_commands.py +4 -2
  35. xp/cli/main.py +2 -1
  36. xp/cli/utils/click_tree.py +6 -3
  37. xp/cli/utils/datapoint_type_choice.py +4 -2
  38. xp/cli/utils/decorators.py +42 -21
  39. xp/cli/utils/error_handlers.py +16 -8
  40. xp/cli/utils/formatters.py +22 -11
  41. xp/cli/utils/module_type_choice.py +4 -2
  42. xp/cli/utils/serial_number_type.py +4 -2
  43. xp/cli/utils/system_function_choice.py +4 -2
  44. xp/cli/utils/xp_module_type.py +4 -2
  45. xp/models/actiontable/actiontable.py +8 -8
  46. xp/models/actiontable/actiontable_type.py +20 -0
  47. xp/models/actiontable/msactiontable_xp20.py +8 -4
  48. xp/models/actiontable/msactiontable_xp24.py +12 -6
  49. xp/models/actiontable/msactiontable_xp33.py +20 -10
  50. xp/models/conbus/conbus.py +8 -4
  51. xp/models/conbus/conbus_autoreport.py +4 -2
  52. xp/models/conbus/conbus_blink.py +4 -2
  53. xp/models/conbus/conbus_client_config.py +6 -3
  54. xp/models/conbus/conbus_connection_status.py +4 -2
  55. xp/models/conbus/conbus_custom.py +4 -2
  56. xp/models/conbus/conbus_datapoint.py +4 -2
  57. xp/models/conbus/conbus_discover.py +6 -3
  58. xp/models/conbus/conbus_event_list.py +4 -2
  59. xp/models/conbus/conbus_event_raw.py +4 -2
  60. xp/models/conbus/conbus_export.py +2 -1
  61. xp/models/conbus/conbus_lightlevel.py +4 -2
  62. xp/models/conbus/conbus_linknumber.py +4 -2
  63. xp/models/conbus/conbus_logger_config.py +8 -4
  64. xp/models/conbus/conbus_output.py +4 -2
  65. xp/models/conbus/conbus_raw.py +4 -2
  66. xp/models/conbus/conbus_receive.py +4 -2
  67. xp/models/conbus/conbus_writeconfig.py +4 -2
  68. xp/models/config/conson_module_config.py +8 -4
  69. xp/models/homekit/homekit_accessory.py +4 -2
  70. xp/models/homekit/homekit_config.py +12 -6
  71. xp/models/log_entry.py +16 -8
  72. xp/models/protocol/conbus_protocol.py +36 -18
  73. xp/models/response.py +12 -8
  74. xp/models/telegram/action_type.py +4 -2
  75. xp/models/telegram/datapoint_type.py +4 -2
  76. xp/models/telegram/event_telegram.py +14 -7
  77. xp/models/telegram/event_type.py +2 -1
  78. xp/models/telegram/input_action_type.py +2 -1
  79. xp/models/telegram/input_type.py +2 -1
  80. xp/models/telegram/module_type.py +24 -12
  81. xp/models/telegram/module_type_code.py +2 -1
  82. xp/models/telegram/output_telegram.py +16 -10
  83. xp/models/telegram/reply_telegram.py +24 -13
  84. xp/models/telegram/system_function.py +6 -3
  85. xp/models/telegram/system_telegram.py +10 -6
  86. xp/models/telegram/telegram.py +2 -1
  87. xp/models/telegram/telegram_type.py +2 -1
  88. xp/models/telegram/timeparam_type.py +2 -1
  89. xp/models/term/connection_state.py +4 -2
  90. xp/models/term/module_state.py +2 -1
  91. xp/models/term/protocol_keys_config.py +6 -3
  92. xp/models/term/status_message.py +2 -1
  93. xp/models/term/telegram_display.py +2 -1
  94. xp/models/write_config_type.py +4 -2
  95. xp/services/actiontable/actiontable_serializer.py +34 -41
  96. xp/services/{conbus/actiontable/actiontable_download_state_machine.py → actiontable/download_state_machine.py} +13 -8
  97. xp/services/actiontable/msactiontable_xp20_serializer.py +77 -49
  98. xp/services/actiontable/msactiontable_xp24_serializer.py +78 -53
  99. xp/services/actiontable/msactiontable_xp33_serializer.py +39 -9
  100. xp/services/actiontable/serializer_protocol.py +76 -0
  101. xp/services/conbus/actiontable/actiontable_download_service.py +63 -29
  102. xp/services/conbus/actiontable/actiontable_list_service.py +17 -4
  103. xp/services/conbus/actiontable/actiontable_show_service.py +10 -6
  104. xp/services/conbus/actiontable/actiontable_upload_service.py +17 -9
  105. xp/services/conbus/conbus_blink_all_service.py +16 -8
  106. xp/services/conbus/conbus_blink_service.py +14 -7
  107. xp/services/conbus/conbus_custom_service.py +16 -8
  108. xp/services/conbus/conbus_datapoint_queryall_service.py +18 -9
  109. xp/services/conbus/conbus_datapoint_service.py +18 -9
  110. xp/services/conbus/conbus_discover_service.py +24 -13
  111. xp/services/conbus/conbus_event_list_service.py +11 -7
  112. xp/services/conbus/conbus_event_raw_service.py +18 -10
  113. xp/services/conbus/conbus_export_service.py +28 -14
  114. xp/services/conbus/conbus_output_service.py +18 -10
  115. xp/services/conbus/conbus_raw_service.py +16 -8
  116. xp/services/conbus/conbus_receive_service.py +18 -10
  117. xp/services/conbus/conbus_scan_service.py +18 -10
  118. xp/services/conbus/msactiontable/msactiontable_upload_service.py +17 -9
  119. xp/services/conbus/write_config_service.py +18 -9
  120. xp/services/homekit/homekit_cache_service.py +12 -6
  121. xp/services/homekit/homekit_conbus_service.py +12 -6
  122. xp/services/homekit/homekit_config_validator.py +34 -17
  123. xp/services/homekit/homekit_conson_validator.py +18 -9
  124. xp/services/homekit/homekit_dimminglight.py +14 -7
  125. xp/services/homekit/homekit_dimminglight_service.py +14 -7
  126. xp/services/homekit/homekit_hap_service.py +18 -9
  127. xp/services/homekit/homekit_lightbulb.py +10 -5
  128. xp/services/homekit/homekit_lightbulb_service.py +10 -5
  129. xp/services/homekit/homekit_module_service.py +8 -4
  130. xp/services/homekit/homekit_outlet.py +14 -7
  131. xp/services/homekit/homekit_outlet_service.py +12 -6
  132. xp/services/homekit/homekit_service.py +24 -12
  133. xp/services/log_file_service.py +16 -8
  134. xp/services/module_type_service.py +10 -5
  135. xp/services/protocol/conbus_event_protocol.py +46 -24
  136. xp/services/protocol/conbus_protocol.py +36 -19
  137. xp/services/protocol/protocol_factory.py +12 -6
  138. xp/services/protocol/telegram_protocol.py +12 -6
  139. xp/services/reverse_proxy_service.py +26 -14
  140. xp/services/server/base_server_service.py +42 -23
  141. xp/services/server/client_buffer_manager.py +12 -7
  142. xp/services/server/cp20_server_service.py +10 -7
  143. xp/services/server/device_service_factory.py +12 -8
  144. xp/services/server/server_service.py +18 -11
  145. xp/services/server/xp130_server_service.py +11 -8
  146. xp/services/server/xp20_server_service.py +16 -10
  147. xp/services/server/xp230_server_service.py +10 -7
  148. xp/services/server/xp24_server_service.py +22 -13
  149. xp/services/server/xp33_server_service.py +44 -25
  150. xp/services/telegram/telegram_blink_service.py +14 -8
  151. xp/services/telegram/telegram_checksum_service.py +12 -7
  152. xp/services/telegram/telegram_datapoint_service.py +14 -9
  153. xp/services/telegram/telegram_discover_service.py +28 -15
  154. xp/services/telegram/telegram_link_number_service.py +18 -10
  155. xp/services/telegram/telegram_output_service.py +24 -12
  156. xp/services/telegram/telegram_service.py +22 -11
  157. xp/services/telegram/telegram_version_service.py +14 -8
  158. xp/services/term/protocol_monitor_service.py +30 -16
  159. xp/services/term/state_monitor_service.py +39 -21
  160. xp/term/protocol.py +12 -6
  161. xp/term/state.py +12 -7
  162. xp/term/widgets/help_menu.py +6 -3
  163. xp/term/widgets/modules_list.py +20 -10
  164. xp/term/widgets/protocol_log.py +12 -6
  165. xp/term/widgets/status_footer.py +10 -5
  166. xp/utils/checksum.py +6 -3
  167. xp/utils/dependencies.py +25 -30
  168. xp/utils/event_helper.py +6 -4
  169. xp/utils/logging.py +6 -3
  170. xp/utils/serialization.py +30 -16
  171. xp/utils/state_machine.py +16 -9
  172. xp/utils/time_utils.py +6 -3
  173. conson_xp-1.46.0.dist-info/RECORD +0 -211
  174. xp/services/conbus/msactiontable/msactiontable_download_service.py +0 -275
  175. xp/services/conbus/msactiontable/msactiontable_list_service.py +0 -100
  176. xp/services/conbus/msactiontable/msactiontable_show_service.py +0 -89
  177. {conson_xp-1.46.0.dist-info → conson_xp-1.47.0.dist-info}/WHEEL +0 -0
  178. {conson_xp-1.46.0.dist-info → conson_xp-1.47.0.dist-info}/entry_points.txt +0 -0
  179. {conson_xp-1.46.0.dist-info → conson_xp-1.47.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,76 @@
1
+ """Protocol for action table serializers."""
2
+
3
+ from typing import Any, Protocol
4
+
5
+ from xp.models.telegram.system_function import SystemFunction
6
+
7
+
8
+ class ActionTableSerializerProtocol(Protocol):
9
+ """
10
+ Protocol defining the interface for action table serializers.
11
+
12
+ All action table serializers (ActionTableSerializer, Xp20MsActionTableSerializer,
13
+ Xp24MsActionTableSerializer, Xp33MsActionTableSerializer) implement this protocol.
14
+ """
15
+
16
+ @staticmethod
17
+ def download_type() -> SystemFunction:
18
+ """
19
+ Get the download system function type.
20
+
21
+ Returns:
22
+ The download system function: DOWNLOAD_MSACTIONTABLE or DOWNLOAD_ACTIONTABLE
23
+ """
24
+ ...
25
+
26
+ @staticmethod
27
+ def from_encoded_string(encoded_data: str) -> Any:
28
+ """
29
+ Deserialize encoded telegram data to action table model.
30
+
31
+ Args:
32
+ encoded_data: Encoded string from telegram (A-P nibble encoding).
33
+
34
+ Returns:
35
+ Deserialized action table model.
36
+ """
37
+ ...
38
+
39
+ @staticmethod
40
+ def to_encoded_string(action_table: Any) -> str:
41
+ """
42
+ Serialize action table model to encoded telegram format.
43
+
44
+ Args:
45
+ action_table: Action table model to serialize.
46
+
47
+ Returns:
48
+ Encoded string for telegram transmission.
49
+ """
50
+ ...
51
+
52
+ @staticmethod
53
+ def from_short_string(action_strings: list[str]) -> Any:
54
+ """
55
+ Deserialize human-readable short format to action table model.
56
+
57
+ Args:
58
+ action_strings: List of short format strings.
59
+
60
+ Returns:
61
+ Deserialized action table model.
62
+ """
63
+ ...
64
+
65
+ @staticmethod
66
+ def to_short_string(action_table: Any) -> list[str]:
67
+ """
68
+ Serialize action table model to human-readable short format.
69
+
70
+ Args:
71
+ action_table: Action table model to serialize.
72
+
73
+ Returns:
74
+ List of human-readable short format strings.
75
+ """
76
+ ...
@@ -1,28 +1,38 @@
1
1
  """Service for downloading ActionTable via Conbus protocol."""
2
2
 
3
3
  import logging
4
- from dataclasses import asdict
5
4
  from typing import Any, Optional
6
5
 
7
- from psygnal import SignalInstance
6
+ from psygnal import Signal
8
7
 
9
- from xp.models.actiontable.actiontable import ActionTable
8
+ from xp.models.actiontable.actiontable_type import ActionTableType
10
9
  from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
11
10
  from xp.models.telegram.datapoint_type import DataPointType
12
11
  from xp.models.telegram.reply_telegram import ReplyTelegram
13
12
  from xp.services.actiontable.actiontable_serializer import ActionTableSerializer
14
- from xp.services.conbus.actiontable.actiontable_download_state_machine import (
13
+ from xp.services.actiontable.download_state_machine import (
15
14
  MAX_ERROR_RETRIES,
16
- ActionTableDownloadStateMachine,
15
+ DownloadStateMachine,
17
16
  )
17
+ from xp.services.actiontable.msactiontable_xp20_serializer import (
18
+ Xp20MsActionTableSerializer,
19
+ )
20
+ from xp.services.actiontable.msactiontable_xp24_serializer import (
21
+ Xp24MsActionTableSerializer,
22
+ )
23
+ from xp.services.actiontable.msactiontable_xp33_serializer import (
24
+ Xp33MsActionTableSerializer,
25
+ )
26
+ from xp.services.actiontable.serializer_protocol import ActionTableSerializerProtocol
18
27
  from xp.services.protocol.conbus_event_protocol import (
19
28
  NO_ERROR_CODE,
20
29
  ConbusEventProtocol,
21
30
  )
22
31
 
23
32
 
24
- class ActionTableDownloadService(ActionTableDownloadStateMachine):
25
- """Service for downloading action tables from Conbus modules via TCP.
33
+ class ActionTableDownloadService(DownloadStateMachine):
34
+ """
35
+ Service for downloading action tables from Conbus modules via TCP.
26
36
 
27
37
  Inherits from ActionTableDownloadStateMachine and overrides on_enter_*
28
38
  methods to add protocol-specific behavior.
@@ -51,31 +61,41 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
51
61
  ... service.start_reactor()
52
62
  """
53
63
 
64
+ # Service signals
65
+ on_progress: Signal = Signal(str)
66
+ on_error: Signal = Signal(str)
67
+ on_finish: Signal = Signal()
68
+ on_actiontable_received: Signal = Signal(Any, dict[str, Any], list[str])
69
+
54
70
  def __init__(
55
71
  self,
56
72
  conbus_protocol: ConbusEventProtocol,
57
73
  actiontable_serializer: ActionTableSerializer,
74
+ msactiontable_serializer_xp20: Xp20MsActionTableSerializer,
75
+ msactiontable_serializer_xp24: Xp24MsActionTableSerializer,
76
+ msactiontable_serializer_xp33: Xp33MsActionTableSerializer,
58
77
  ) -> None:
59
- """Initialize the action table download service.
78
+ """
79
+ Initialize the action table download service.
60
80
 
61
81
  Args:
62
82
  conbus_protocol: ConbusEventProtocol instance.
63
83
  actiontable_serializer: Action table serializer.
84
+ msactiontable_serializer_xp20: XP20 master station action table serializer.
85
+ msactiontable_serializer_xp24: XP24 master station action table serializer.
86
+ msactiontable_serializer_xp33: XP33 master station action table serializer.
64
87
  """
65
88
  self.conbus_protocol = conbus_protocol
66
- self.serializer = actiontable_serializer
89
+ self.actiontable_serializer = actiontable_serializer
90
+ self.msactiontable_serializer_xp20 = msactiontable_serializer_xp20
91
+ self.msactiontable_serializer_xp24 = msactiontable_serializer_xp24
92
+ self.msactiontable_serializer_xp33 = msactiontable_serializer_xp33
93
+ self.serializer: ActionTableSerializerProtocol = actiontable_serializer
94
+
67
95
  self.serial_number: str = ""
68
96
  self.actiontable_data: list[str] = []
69
97
  self._signals_connected: bool = False
70
98
 
71
- # Service signals
72
- self.on_progress: SignalInstance = SignalInstance((str,))
73
- self.on_error: SignalInstance = SignalInstance((str,))
74
- self.on_finish: SignalInstance = SignalInstance()
75
- self.on_actiontable_received: SignalInstance = SignalInstance(
76
- (ActionTable, dict[str, Any], list[str])
77
- )
78
-
79
99
  # Initialize state machine (must be last - triggers introspection)
80
100
  super().__init__()
81
101
 
@@ -125,11 +145,8 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
125
145
  self.logger.debug("Entering PROCESSING_EOF state - deserializing")
126
146
  all_data = "".join(self.actiontable_data)
127
147
  actiontable = self.serializer.from_encoded_string(all_data)
128
- actiontable_dict = asdict(actiontable)
129
- actiontable_short = self.serializer.format_decoded_output(actiontable)
130
- self.on_actiontable_received.emit(
131
- actiontable, actiontable_dict, actiontable_short
132
- )
148
+ actiontable_short = self.serializer.to_short_string(actiontable)
149
+ self.on_actiontable_received.emit(actiontable, actiontable_short)
133
150
  # Switch to CLEANUP phase
134
151
  self.start_cleanup_phase()
135
152
 
@@ -152,7 +169,8 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
152
169
  self.do_connect()
153
170
 
154
171
  def _on_read_datapoint_received(self, reply_telegram: ReplyTelegram) -> None:
155
- """Handle READ_DATAPOINT response for error status check.
172
+ """
173
+ Handle READ_DATAPOINT response for error status check.
156
174
 
157
175
  Args:
158
176
  reply_telegram: The parsed reply telegram.
@@ -176,7 +194,8 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
176
194
  def _on_actiontable_chunk_received(
177
195
  self, reply_telegram: ReplyTelegram, actiontable_chunk: str
178
196
  ) -> None:
179
- """Handle actiontable chunk telegram received.
197
+ """
198
+ Handle actiontable chunk telegram received.
180
199
 
181
200
  Args:
182
201
  reply_telegram: The parsed reply telegram containing chunk data.
@@ -192,7 +211,8 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
192
211
  self.receive_chunk()
193
212
 
194
213
  def _on_eof_received(self, reply_telegram: ReplyTelegram) -> None:
195
- """Handle EOF telegram received.
214
+ """
215
+ Handle EOF telegram received.
196
216
 
197
217
  Args:
198
218
  reply_telegram: The parsed reply telegram (unused).
@@ -205,7 +225,8 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
205
225
  self.receive_eof()
206
226
 
207
227
  def _on_telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
208
- """Handle telegram received event.
228
+ """
229
+ Handle telegram received event.
209
230
 
210
231
  Args:
211
232
  telegram_received: The telegram received event.
@@ -233,7 +254,8 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
233
254
  self.on_error.emit("Timeout")
234
255
 
235
256
  def _on_failed(self, message: str) -> None:
236
- """Handle failed connection event.
257
+ """
258
+ Handle failed connection event.
237
259
 
238
260
  Args:
239
261
  message: Failure message.
@@ -246,15 +268,18 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
246
268
  def configure(
247
269
  self,
248
270
  serial_number: str,
271
+ actiontable_type: ActionTableType,
249
272
  timeout_seconds: Optional[float] = 2.0,
250
273
  ) -> None:
251
- """Configure download parameters before starting.
274
+ """
275
+ Configure download parameters before starting.
252
276
 
253
277
  Sets the target module serial number and timeout. Call this before
254
278
  start_reactor() to configure the download target.
255
279
 
256
280
  Args:
257
281
  serial_number: Module serial number to download from.
282
+ actiontable_type: Type of action table to download.
258
283
  timeout_seconds: Timeout in seconds for each operation (default 2.0).
259
284
 
260
285
  Raises:
@@ -264,11 +289,20 @@ class ActionTableDownloadService(ActionTableDownloadStateMachine):
264
289
  raise RuntimeError("Cannot configure while download in progress")
265
290
  self.logger.info("Configuring actiontable download")
266
291
  self.serial_number = serial_number
292
+ if actiontable_type == ActionTableType.ACTIONTABLE:
293
+ self.serializer = self.actiontable_serializer
294
+ elif actiontable_type == ActionTableType.MSACTIONTABLE_XP20:
295
+ self.serializer = self.msactiontable_serializer_xp20
296
+ elif actiontable_type == ActionTableType.MSACTIONTABLE_XP24:
297
+ self.serializer = self.msactiontable_serializer_xp24
298
+ elif actiontable_type == ActionTableType.MSACTIONTABLE_XP33:
299
+ self.serializer = self.msactiontable_serializer_xp33
267
300
  if timeout_seconds:
268
301
  self.conbus_protocol.timeout_seconds = timeout_seconds
269
302
 
270
303
  def set_timeout(self, timeout_seconds: float) -> None:
271
- """Set operation timeout.
304
+ """
305
+ Set operation timeout.
272
306
 
273
307
  Args:
274
308
  timeout_seconds: Timeout in seconds.
@@ -8,7 +8,8 @@ from psygnal import Signal
8
8
 
9
9
 
10
10
  class ActionTableListService:
11
- """Service for listing modules with action table configurations.
11
+ """
12
+ Service for listing modules with action table configurations.
12
13
 
13
14
  Reads conson.yml and returns a list of all modules that have action table
14
15
  configurations defined.
@@ -26,7 +27,8 @@ class ActionTableListService:
26
27
  self.logger = logging.getLogger(__name__)
27
28
 
28
29
  def __enter__(self) -> "ActionTableListService":
29
- """Context manager entry.
30
+ """
31
+ Context manager entry.
30
32
 
31
33
  Returns:
32
34
  Self for context manager use.
@@ -43,7 +45,8 @@ class ActionTableListService:
43
45
  self,
44
46
  config_path: Optional[Path] = None,
45
47
  ) -> None:
46
- """List all modules with action table configurations.
48
+ """
49
+ List all modules with action table configurations.
47
50
 
48
51
  Args:
49
52
  config_path: Optional path to conson.yml. Defaults to current directory.
@@ -73,6 +76,15 @@ class ActionTableListService:
73
76
  "serial_number": module.serial_number,
74
77
  "module_type": module.module_type,
75
78
  "action_table": len(module.action_table) if module.action_table else 0,
79
+ "msaction_table": (
80
+ 1
81
+ if (
82
+ module.xp20_msaction_table
83
+ or module.xp24_msaction_table
84
+ or module.xp33_msaction_table
85
+ )
86
+ else 0
87
+ ),
76
88
  }
77
89
  for module in config.root
78
90
  ]
@@ -84,7 +96,8 @@ class ActionTableListService:
84
96
  self.on_finish.emit(result)
85
97
 
86
98
  def _handle_error(self, message: str) -> None:
87
- """Handle error and emit error signal.
99
+ """
100
+ Handle error and emit error signal.
88
101
 
89
102
  Args:
90
103
  message: Error message.
@@ -8,10 +8,11 @@ from xp.models.config.conson_module_config import ConsonModuleConfig
8
8
 
9
9
 
10
10
  class ActionTableShowService:
11
- """Service for showing action table configuration for a specific module.
11
+ """
12
+ Service for showing action table configuration for a specific module.
12
13
 
13
- Reads conson.yml and returns the action table configuration for the specified
14
- module serial number.
14
+ Reads conson.yml and returns the action table configuration for the specified module
15
+ serial number.
15
16
  """
16
17
 
17
18
  def __init__(self) -> None:
@@ -21,7 +22,8 @@ class ActionTableShowService:
21
22
  self.error_callback: Optional[Callable[[str], None]] = None
22
23
 
23
24
  def __enter__(self) -> "ActionTableShowService":
24
- """Context manager entry.
25
+ """
26
+ Context manager entry.
25
27
 
26
28
  Returns:
27
29
  Self for context manager use.
@@ -39,7 +41,8 @@ class ActionTableShowService:
39
41
  error_callback: Callable[[str], None],
40
42
  config_path: Optional[Path] = None,
41
43
  ) -> None:
42
- """Show action table configuration for a specific module.
44
+ """
45
+ Show action and msaction table configuration for a specific module.
43
46
 
44
47
  Args:
45
48
  serial_number: Module serial number.
@@ -80,7 +83,8 @@ class ActionTableShowService:
80
83
  self.finish_callback(module)
81
84
 
82
85
  def _handle_error(self, message: str) -> None:
83
- """Handle error and invoke error callback.
86
+ """
87
+ Handle error and invoke error callback.
84
88
 
85
89
  Args:
86
90
  message: Error message.
@@ -15,7 +15,8 @@ from xp.services.telegram.telegram_service import TelegramService
15
15
 
16
16
 
17
17
  class ActionTableUploadService:
18
- """TCP client service for uploading action tables to Conbus modules.
18
+ """
19
+ TCP client service for uploading action tables to Conbus modules.
19
20
 
20
21
  Manages TCP socket connections, handles telegram generation and transmission,
21
22
  and processes server responses for action table uploads.
@@ -37,7 +38,8 @@ class ActionTableUploadService:
37
38
  telegram_service: TelegramService,
38
39
  conson_config: ConsonModuleListConfig,
39
40
  ) -> None:
40
- """Initialize the action table upload service.
41
+ """
42
+ Initialize the action table upload service.
41
43
 
42
44
  Args:
43
45
  conbus_protocol: ConbusEventProtocol for communication.
@@ -76,7 +78,8 @@ class ActionTableUploadService:
76
78
  )
77
79
 
78
80
  def telegram_sent(self, telegram_sent: str) -> None:
79
- """Handle telegram sent event.
81
+ """
82
+ Handle telegram sent event.
80
83
 
81
84
  Args:
82
85
  telegram_sent: The telegram that was sent.
@@ -84,7 +87,8 @@ class ActionTableUploadService:
84
87
  self.logger.debug(f"Telegram sent: {telegram_sent}")
85
88
 
86
89
  def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
87
- """Handle telegram received event.
90
+ """
91
+ Handle telegram received event.
88
92
 
89
93
  Args:
90
94
  telegram_received: The telegram received event.
@@ -105,7 +109,8 @@ class ActionTableUploadService:
105
109
  self._handle_upload_response(reply_telegram)
106
110
 
107
111
  def _handle_upload_response(self, reply_telegram: Any) -> None:
108
- """Handle telegram responses during upload.
112
+ """
113
+ Handle telegram responses during upload.
109
114
 
110
115
  Args:
111
116
  reply_telegram: Parsed reply telegram.
@@ -152,7 +157,8 @@ class ActionTableUploadService:
152
157
  self.failed("Upload timeout")
153
158
 
154
159
  def failed(self, message: str) -> None:
155
- """Handle failed connection event.
160
+ """
161
+ Handle failed connection event.
156
162
 
157
163
  Args:
158
164
  message: Failure message.
@@ -165,7 +171,8 @@ class ActionTableUploadService:
165
171
  serial_number: str,
166
172
  timeout_seconds: Optional[float] = None,
167
173
  ) -> None:
168
- """Upload action table to module.
174
+ """
175
+ Upload action table to module.
169
176
 
170
177
  Uploads the action table configuration to the specified module.
171
178
 
@@ -187,7 +194,7 @@ class ActionTableUploadService:
187
194
  # Parse action table strings to ActionTable object
188
195
  try:
189
196
  module_action_table = module.action_table or []
190
- action_table = self.serializer.parse_action_table(module_action_table)
197
+ action_table = self.serializer.from_short_string(module_action_table)
191
198
  except ValueError as e:
192
199
  self.logger.error(f"Invalid action table format: {e}")
193
200
  self.failed(f"Invalid action table format: {e}")
@@ -210,7 +217,8 @@ class ActionTableUploadService:
210
217
  )
211
218
 
212
219
  def set_timeout(self, timeout_seconds: float) -> None:
213
- """Set operation timeout.
220
+ """
221
+ Set operation timeout.
214
222
 
215
223
  Args:
216
224
  timeout_seconds: Timeout in seconds.
@@ -1,4 +1,5 @@
1
- """Conbus Blink All Service for TCP communication with Conbus servers.
1
+ """
2
+ Conbus Blink All Service for TCP communication with Conbus servers.
2
3
 
3
4
  This service implements a TCP client that connects to Conbus servers and sends
4
5
  blink/unblink telegrams to all discovered modules on the network.
@@ -38,7 +39,8 @@ class ConbusBlinkAllService:
38
39
  conbus_protocol: ConbusEventProtocol,
39
40
  telegram_service: TelegramService,
40
41
  ) -> None:
41
- """Initialize the Conbus blink all service.
42
+ """
43
+ Initialize the Conbus blink all service.
42
44
 
43
45
  Args:
44
46
  conbus_protocol: ConbusEventProtocol instance for communication.
@@ -77,7 +79,8 @@ class ConbusBlinkAllService:
77
79
  self.on_progress.emit(".")
78
80
 
79
81
  def send_blink(self, serial_number: str) -> None:
80
- """Send blink or unblink telegram to a discovered module.
82
+ """
83
+ Send blink or unblink telegram to a discovered module.
81
84
 
82
85
  Args:
83
86
  serial_number: 10-digit module serial number.
@@ -101,7 +104,8 @@ class ConbusBlinkAllService:
101
104
  self.on_progress.emit(".")
102
105
 
103
106
  def telegram_sent(self, telegram_sent: str) -> None:
104
- """Handle telegram sent event.
107
+ """
108
+ Handle telegram sent event.
105
109
 
106
110
  Args:
107
111
  telegram_sent: The telegram that was sent.
@@ -110,7 +114,8 @@ class ConbusBlinkAllService:
110
114
  self.service_response.sent_telegram = system_telegram
111
115
 
112
116
  def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
113
- """Handle telegram received event.
117
+ """
118
+ Handle telegram received event.
114
119
 
115
120
  Args:
116
121
  telegram_received: The telegram received event.
@@ -157,7 +162,8 @@ class ConbusBlinkAllService:
157
162
  self.on_finish.emit(self.service_response)
158
163
 
159
164
  def failed(self, message: str) -> None:
160
- """Handle failed connection event.
165
+ """
166
+ Handle failed connection event.
161
167
 
162
168
  Args:
163
169
  message: Failure message.
@@ -173,7 +179,8 @@ class ConbusBlinkAllService:
173
179
  on_or_off: str,
174
180
  timeout_seconds: Optional[float] = None,
175
181
  ) -> None:
176
- """Send blink command to all discovered modules.
182
+ """
183
+ Send blink command to all discovered modules.
177
184
 
178
185
  Args:
179
186
  on_or_off: "on" to blink or "off" to unblink all devices.
@@ -186,7 +193,8 @@ class ConbusBlinkAllService:
186
193
  # Caller invokes start_reactor()
187
194
 
188
195
  def set_timeout(self, timeout_seconds: float) -> None:
189
- """Set operation timeout.
196
+ """
197
+ Set operation timeout.
190
198
 
191
199
  Args:
192
200
  timeout_seconds: Timeout in seconds.
@@ -1,4 +1,5 @@
1
- """Conbus Blink Service for TCP communication with Conbus servers.
1
+ """
2
+ Conbus Blink Service for TCP communication with Conbus servers.
2
3
 
3
4
  This service implements a TCP client that connects to Conbus servers and sends
4
5
  blink/unblink telegrams to control module LED indicators.
@@ -36,7 +37,8 @@ class ConbusBlinkService:
36
37
  conbus_protocol: ConbusEventProtocol,
37
38
  telegram_service: TelegramService,
38
39
  ) -> None:
39
- """Initialize the Conbus blink service.
40
+ """
41
+ Initialize the Conbus blink service.
40
42
 
41
43
  Args:
42
44
  conbus_protocol: ConbusEventProtocol instance for communication.
@@ -81,7 +83,8 @@ class ConbusBlinkService:
81
83
  self.service_response.operation = self.on_or_off
82
84
 
83
85
  def telegram_sent(self, telegram_sent: str) -> None:
84
- """Handle telegram sent event.
86
+ """
87
+ Handle telegram sent event.
85
88
 
86
89
  Args:
87
90
  telegram_sent: The telegram that was sent.
@@ -90,7 +93,8 @@ class ConbusBlinkService:
90
93
  self.service_response.sent_telegram = system_telegram
91
94
 
92
95
  def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
93
- """Handle telegram received event.
96
+ """
97
+ Handle telegram received event.
94
98
 
95
99
  Args:
96
100
  telegram_received: The telegram received event.
@@ -131,7 +135,8 @@ class ConbusBlinkService:
131
135
  self.on_finish.emit(self.service_response)
132
136
 
133
137
  def failed(self, message: str) -> None:
134
- """Handle failed connection event.
138
+ """
139
+ Handle failed connection event.
135
140
 
136
141
  Args:
137
142
  message: Failure message.
@@ -148,7 +153,8 @@ class ConbusBlinkService:
148
153
  on_or_off: str,
149
154
  timeout_seconds: Optional[float] = None,
150
155
  ) -> None:
151
- r"""Send blink command to start blinking module LED.
156
+ r"""
157
+ Send blink command to start blinking module LED.
152
158
 
153
159
  Args:
154
160
  serial_number: 10-digit module serial number.
@@ -168,7 +174,8 @@ class ConbusBlinkService:
168
174
  # Caller invokes start_reactor()
169
175
 
170
176
  def set_timeout(self, timeout_seconds: float) -> None:
171
- """Set operation timeout.
177
+ """
178
+ Set operation timeout.
172
179
 
173
180
  Args:
174
181
  timeout_seconds: Timeout in seconds.
@@ -1,4 +1,5 @@
1
- """Conbus Custom Service for sending custom telegrams to modules.
1
+ """
2
+ Conbus Custom Service for sending custom telegrams to modules.
2
3
 
3
4
  This service handles custom telegram operations for modules through Conbus telegrams.
4
5
  """
@@ -19,7 +20,8 @@ from xp.services.telegram.telegram_service import TelegramService
19
20
 
20
21
 
21
22
  class ConbusCustomService:
22
- """Service for sending custom telegrams to Conbus modules.
23
+ """
24
+ Service for sending custom telegrams to Conbus modules.
23
25
 
24
26
  Uses ConbusEventProtocol to provide custom telegram functionality
25
27
  for sending arbitrary function codes and data to modules.
@@ -37,7 +39,8 @@ class ConbusCustomService:
37
39
  conbus_protocol: ConbusEventProtocol,
38
40
  telegram_service: TelegramService,
39
41
  ) -> None:
40
- """Initialize the Conbus custom service.
42
+ """
43
+ Initialize the Conbus custom service.
41
44
 
42
45
  Args:
43
46
  conbus_protocol: Protocol instance for Conbus communication.
@@ -82,7 +85,8 @@ class ConbusCustomService:
82
85
  )
83
86
 
84
87
  def telegram_sent(self, telegram_sent: str) -> None:
85
- """Handle telegram sent event.
88
+ """
89
+ Handle telegram sent event.
86
90
 
87
91
  Args:
88
92
  telegram_sent: The telegram that was sent.
@@ -90,7 +94,8 @@ class ConbusCustomService:
90
94
  self.service_response.sent_telegram = telegram_sent
91
95
 
92
96
  def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
93
- """Handle telegram received event.
97
+ """
98
+ Handle telegram received event.
94
99
 
95
100
  Args:
96
101
  telegram_received: The telegram received event.
@@ -131,7 +136,8 @@ class ConbusCustomService:
131
136
  self.failed("Timeout")
132
137
 
133
138
  def failed(self, message: str) -> None:
134
- """Handle failed connection event.
139
+ """
140
+ Handle failed connection event.
135
141
 
136
142
  Args:
137
143
  message: Failure message.
@@ -151,7 +157,8 @@ class ConbusCustomService:
151
157
  data: str,
152
158
  timeout_seconds: Optional[float] = None,
153
159
  ) -> None:
154
- """Send a custom telegram to a module.
160
+ """
161
+ Send a custom telegram to a module.
155
162
 
156
163
  Args:
157
164
  serial_number: 10-digit module serial number.
@@ -167,7 +174,8 @@ class ConbusCustomService:
167
174
  self.set_timeout(timeout_seconds)
168
175
 
169
176
  def set_timeout(self, timeout_seconds: float) -> None:
170
- """Set operation timeout.
177
+ """
178
+ Set operation timeout.
171
179
 
172
180
  Args:
173
181
  timeout_seconds: Timeout in seconds.