conson-xp 1.46.0__py3-none-any.whl → 1.48.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.48.0.dist-info}/METADATA +1 -1
  2. conson_xp-1.48.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 -19
  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 +73 -50
  98. xp/services/actiontable/msactiontable_xp24_serializer.py +73 -54
  99. xp/services/actiontable/msactiontable_xp33_serializer.py +44 -20
  100. xp/services/actiontable/serializer_protocol.py +76 -0
  101. xp/services/conbus/actiontable/actiontable_download_service.py +68 -31
  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 +18 -10
  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 +51 -26
  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.48.0.dist-info}/WHEEL +0 -0
  178. {conson_xp-1.46.0.dist-info → conson_xp-1.48.0.dist-info}/entry_points.txt +0 -0
  179. {conson_xp-1.46.0.dist-info → conson_xp-1.48.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,5 @@
1
- """HomeKit Outlet Service.
1
+ """
2
+ HomeKit Outlet Service.
2
3
 
3
4
  This module provides service implementation for outlet accessories.
4
5
  """
@@ -18,7 +19,8 @@ from xp.models.telegram.datapoint_type import DataPointType
18
19
 
19
20
 
20
21
  class HomeKitOutletService:
21
- """Outlet service for HomeKit.
22
+ """
23
+ Outlet service for HomeKit.
22
24
 
23
25
  Attributes:
24
26
  event_bus: Event bus for inter-service communication.
@@ -28,7 +30,8 @@ class HomeKitOutletService:
28
30
  event_bus: EventBus
29
31
 
30
32
  def __init__(self, event_bus: EventBus):
31
- """Initialize the outlet service.
33
+ """
34
+ Initialize the outlet service.
32
35
 
33
36
  Args:
34
37
  event_bus: Event bus instance.
@@ -42,7 +45,8 @@ class HomeKitOutletService:
42
45
  self.event_bus.on(OutletGetInUseEvent, self.handle_outlet_get_in_use)
43
46
 
44
47
  def handle_outlet_get_on(self, event: OutletGetOnEvent) -> bool:
45
- """Handle outlet get on event.
48
+ """
49
+ Handle outlet get on event.
46
50
 
47
51
  Args:
48
52
  event: Outlet get on event.
@@ -65,7 +69,8 @@ class HomeKitOutletService:
65
69
  return True
66
70
 
67
71
  def handle_outlet_set_on(self, event: OutletSetOnEvent) -> bool:
68
- """Handle outlet set on event.
72
+ """
73
+ Handle outlet set on event.
69
74
 
70
75
  Args:
71
76
  event: Outlet set on event.
@@ -97,7 +102,8 @@ class HomeKitOutletService:
97
102
  return True
98
103
 
99
104
  def handle_outlet_get_in_use(self, event: OutletGetInUseEvent) -> bool:
100
- """Handle outlet get in-use event.
105
+ """
106
+ Handle outlet get in-use event.
101
107
 
102
108
  Args:
103
109
  event: Outlet get in-use event.
@@ -1,4 +1,5 @@
1
- """HomeKit Service for Apple HomeKit integration.
1
+ """
2
+ HomeKit Service for Apple HomeKit integration.
2
3
 
3
4
  This module provides the main service for HomeKit integration.
4
5
  """
@@ -34,7 +35,8 @@ from xp.services.protocol.protocol_factory import TelegramFactory
34
35
 
35
36
 
36
37
  class HomeKitService:
37
- """Main HomeKit service for Apple HomeKit integration.
38
+ """
39
+ Main HomeKit service for Apple HomeKit integration.
38
40
 
39
41
  Attributes:
40
42
  cli_config: Conbus client configuration.
@@ -66,7 +68,8 @@ class HomeKitService:
66
68
  module_factory: HomekitHapService,
67
69
  telegram_service: TelegramService,
68
70
  ):
69
- """Initialize the HomeKit service.
71
+ """
72
+ Initialize the HomeKit service.
70
73
 
71
74
  Args:
72
75
  cli_config: Conbus client configuration.
@@ -142,7 +145,8 @@ class HomeKitService:
142
145
  self.reactor.run()
143
146
 
144
147
  def _start_module_factory(self) -> None:
145
- """Start module factory after reactor starts.
148
+ """
149
+ Start module factory after reactor starts.
146
150
 
147
151
  Creates and schedules an async task to start the HAP service.
148
152
  """
@@ -181,7 +185,8 @@ class HomeKitService:
181
185
  event.protocol.sendFrame(b"S0000000000F01D00")
182
186
 
183
187
  def handle_connection_failed(self, event: ConnectionFailedEvent) -> None:
184
- """Handle connection failed.
188
+ """
189
+ Handle connection failed.
185
190
 
186
191
  Args:
187
192
  event: Connection failed event.
@@ -189,7 +194,8 @@ class HomeKitService:
189
194
  self.logger.error(f"Connection failed: {event.reason}")
190
195
 
191
196
  def handle_connection_lost(self, event: ConnectionLostEvent) -> None:
192
- """Handle connection lost.
197
+ """
198
+ Handle connection lost.
193
199
 
194
200
  Args:
195
201
  event: Connection lost event.
@@ -199,7 +205,8 @@ class HomeKitService:
199
205
  )
200
206
 
201
207
  def handle_telegram_received(self, event: TelegramReceivedEvent) -> str:
202
- """Handle received telegram events.
208
+ """
209
+ Handle received telegram events.
203
210
 
204
211
  Args:
205
212
  event: Telegram received event.
@@ -236,7 +243,8 @@ class HomeKitService:
236
243
  return event.frame
237
244
 
238
245
  def dispatch_light_level_event(self, event: TelegramReceivedEvent) -> None:
239
- """Dispatch light level received event.
246
+ """
247
+ Dispatch light level received event.
240
248
 
241
249
  Args:
242
250
  event: Telegram received event.
@@ -260,7 +268,8 @@ class HomeKitService:
260
268
  self.logger.debug("LightLevelReceivedEvent dispatched successfully")
261
269
 
262
270
  def dispatch_output_state_event(self, event: TelegramReceivedEvent) -> None:
263
- """Dispatch output state received event.
271
+ """
272
+ Dispatch output state received event.
264
273
 
265
274
  Args:
266
275
  event: Telegram received event.
@@ -286,7 +295,8 @@ class HomeKitService:
286
295
  def dispatch_event_telegram_received_event(
287
296
  self, event: TelegramReceivedEvent
288
297
  ) -> None:
289
- """Dispatch event telegram received event.
298
+ """
299
+ Dispatch event telegram received event.
290
300
 
291
301
  Args:
292
302
  event: Telegram received event.
@@ -319,7 +329,8 @@ class HomeKitService:
319
329
  self.logger.debug("ModuleStateChangedEvent dispatched successfully")
320
330
 
321
331
  def dispatch_module_discovered_event(self, event: TelegramReceivedEvent) -> None:
322
- """Dispatch module discovered event.
332
+ """
333
+ Dispatch module discovered event.
323
334
 
324
335
  Args:
325
336
  event: Telegram received event.
@@ -339,7 +350,8 @@ class HomeKitService:
339
350
  self.logger.debug("ModuleDiscoveredEvent dispatched successfully")
340
351
 
341
352
  def handle_module_discovered(self, event: ModuleDiscoveredEvent) -> str:
342
- """Handle module discovered event.
353
+ """
354
+ Handle module discovered event.
343
355
 
344
356
  Args:
345
357
  event: Module discovered event.
@@ -38,7 +38,8 @@ class LogFileService:
38
38
  )
39
39
 
40
40
  def __init__(self, telegram_service: TelegramService):
41
- """Initialize the log file service.
41
+ """
42
+ Initialize the log file service.
42
43
 
43
44
  Args:
44
45
  telegram_service: Telegram service for parsing telegrams.
@@ -48,7 +49,8 @@ class LogFileService:
48
49
  def parse_log_file(
49
50
  self, file_path: str, base_date: Optional[datetime] = None
50
51
  ) -> List[LogEntry]:
51
- """Parse a console bus log file into LogEntry objects.
52
+ """
53
+ Parse a console bus log file into LogEntry objects.
52
54
 
53
55
  Args:
54
56
  file_path: Path to the log file.
@@ -79,7 +81,8 @@ class LogFileService:
79
81
  def parse_log_lines(
80
82
  self, lines: List[str], base_date: Optional[datetime] = None
81
83
  ) -> List[LogEntry]:
82
- """Parse log lines into LogEntry objects.
84
+ """
85
+ Parse log lines into LogEntry objects.
83
86
 
84
87
  Args:
85
88
  lines: List of log lines to parse.
@@ -115,7 +118,8 @@ class LogFileService:
115
118
  def _parse_log_line(
116
119
  self, line: str, line_number: int, base_date: Optional[datetime] = None
117
120
  ) -> Optional[LogEntry]:
118
- """Parse a single log line into a LogEntry.
121
+ """
122
+ Parse a single log line into a LogEntry.
119
123
 
120
124
  Args:
121
125
  line: Log line to parse.
@@ -157,7 +161,8 @@ class LogFileService:
157
161
  return entry
158
162
 
159
163
  def validate_log_format(self, file_path: str) -> bool:
160
- """Validate that a file follows the expected log format.
164
+ """
165
+ Validate that a file follows the expected log format.
161
166
 
162
167
  Args:
163
168
  file_path: Path to the log file.
@@ -174,7 +179,8 @@ class LogFileService:
174
179
  return False
175
180
 
176
181
  def extract_telegrams(self, file_path: str) -> List[str]:
177
- """Extract all telegram strings from a log file.
182
+ """
183
+ Extract all telegram strings from a log file.
178
184
 
179
185
  Args:
180
186
  file_path: Path to the log file.
@@ -187,7 +193,8 @@ class LogFileService:
187
193
 
188
194
  @staticmethod
189
195
  def get_file_statistics(entries: List[LogEntry]) -> Dict[str, Any]:
190
- """Generate statistics for a list of log entries.
196
+ """
197
+ Generate statistics for a list of log entries.
191
198
 
192
199
  Args:
193
200
  entries: List of LogEntry objects.
@@ -280,7 +287,8 @@ class LogFileService:
280
287
  start_time: Optional[datetime] = None,
281
288
  end_time: Optional[datetime] = None,
282
289
  ) -> List[LogEntry]:
283
- """Filter log entries based on criteria.
290
+ """
291
+ Filter log entries based on criteria.
284
292
 
285
293
  Args:
286
294
  entries: List of LogEntry objects to filter.
@@ -1,6 +1,8 @@
1
- """Module Type Service for XP module management.
1
+ """
2
+ Module Type Service for XP module management.
2
3
 
3
- This module provides lookup, validation, and search functionality for XP system module types.
4
+ This module provides lookup, validation, and search functionality for XP system module
5
+ types.
4
6
  """
5
7
 
6
8
  from typing import Dict, List, Optional, Union
@@ -199,7 +201,8 @@ class ModuleTypeService:
199
201
 
200
202
  @staticmethod
201
203
  def _format_module_summary(module_type: ModuleType) -> str:
202
- """Format a single module type for display.
204
+ """
205
+ Format a single module type for display.
203
206
 
204
207
  Args:
205
208
  module_type: The module type to format.
@@ -226,7 +229,8 @@ class ModuleTypeService:
226
229
 
227
230
  @staticmethod
228
231
  def _format_all_modules() -> str:
229
- """Format all modules in a simple list.
232
+ """
233
+ Format all modules in a simple list.
230
234
 
231
235
  Returns:
232
236
  Formatted string with all modules.
@@ -241,7 +245,8 @@ class ModuleTypeService:
241
245
 
242
246
  @staticmethod
243
247
  def _format_modules_by_category() -> str:
244
- """Format modules grouped by category.
248
+ """
249
+ Format modules grouped by category.
245
250
 
246
251
  Returns:
247
252
  Formatted string with modules grouped by category.
@@ -1,4 +1,5 @@
1
- """Conbus Event Protocol for XP telegram communication.
1
+ """
2
+ Conbus Event Protocol for XP telegram communication.
2
3
 
3
4
  This module implements the Twisted protocol for Conbus communication.
4
5
  """
@@ -34,7 +35,8 @@ CHUNK_HEADER_LENGTH = 2 # data_value format: 2-char counter + actiontable chunk
34
35
 
35
36
 
36
37
  class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
37
- """Twisted protocol for XP telegram communication.
38
+ """
39
+ Twisted protocol for XP telegram communication.
38
40
 
39
41
  Attributes:
40
42
  buffer: Buffer for incoming telegram data.
@@ -95,7 +97,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
95
97
  reactor: PosixReactorBase,
96
98
  telegram_service: TelegramService,
97
99
  ) -> None:
98
- """Initialize ConbusProtocol.
100
+ """
101
+ Initialize ConbusProtocol.
99
102
 
100
103
  Args:
101
104
  cli_config: Configuration for Conbus client connection.
@@ -111,10 +114,11 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
111
114
  self.telegram_service = telegram_service
112
115
 
113
116
  def connectionMade(self) -> None:
114
- """Handle connection established event.
117
+ """
118
+ Handle connection established event.
115
119
 
116
- Called when TCP connection is successfully established.
117
- Starts inactivity timeout monitoring.
120
+ Called when TCP connection is successfully established. Starts inactivity
121
+ timeout monitoring.
118
122
  """
119
123
  self.logger.debug("connectionMade")
120
124
  self.on_connection_made.emit()
@@ -123,7 +127,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
123
127
  self._reset_timeout()
124
128
 
125
129
  def wait(self, wait_timeout: Optional[float] = None) -> None:
126
- """Wait for incoming telegrams with optional timeout override.
130
+ """
131
+ Wait for incoming telegrams with optional timeout override.
127
132
 
128
133
  Args:
129
134
  wait_timeout: Optional timeout in seconds to override default.
@@ -133,7 +138,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
133
138
  self._reset_timeout()
134
139
 
135
140
  def dataReceived(self, data: bytes) -> None:
136
- """Handle received data from TCP connection.
141
+ """
142
+ Handle received data from TCP connection.
137
143
 
138
144
  Parses incoming telegram frames and dispatches events.
139
145
 
@@ -193,7 +199,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
193
199
  self.emit_telegram_received(telegram_received)
194
200
 
195
201
  def emit_telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
196
- """Handle telegram received event.
202
+ """
203
+ Handle telegram received event.
197
204
 
198
205
  Args:
199
206
  telegram_received: The telegram received event.
@@ -232,7 +239,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
232
239
  return
233
240
 
234
241
  def sendFrame(self, data: bytes) -> None:
235
- """Send telegram frame.
242
+ """
243
+ Send telegram frame.
236
244
 
237
245
  Args:
238
246
  data: Raw telegram payload (without checksum/framing).
@@ -261,7 +269,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
261
269
  system_function: SystemFunction,
262
270
  data_value: str,
263
271
  ) -> None:
264
- """Send telegram with specified parameters.
272
+ """
273
+ Send telegram with specified parameters.
265
274
 
266
275
  Args:
267
276
  telegram_type: Type of telegram to send.
@@ -280,7 +289,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
280
289
  def send_event_telegram(
281
290
  self, module_type_code: ModuleTypeCode, link_number: int, input_number: int
282
291
  ) -> None:
283
- """Send telegram with specified parameters.
292
+ """
293
+ Send telegram with specified parameters.
284
294
 
285
295
  Args:
286
296
  module_type_code: Type code of module.
@@ -293,7 +303,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
293
303
  self.send_raw_telegram(payload)
294
304
 
295
305
  def send_raw_telegram(self, payload: str) -> None:
296
- """Send telegram with specified parameters.
306
+ """
307
+ Send telegram with specified parameters.
297
308
 
298
309
  Args:
299
310
  payload: Telegram to send.
@@ -302,7 +313,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
302
313
  self.call_later(0.0, self.start_queue_manager)
303
314
 
304
315
  def send_error_status_query(self, serial_number: str) -> None:
305
- """Send error status query telegram.
316
+ """
317
+ Send error status query telegram.
306
318
 
307
319
  Args:
308
320
  serial_number: Device serial number.
@@ -314,21 +326,26 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
314
326
  data_value=DataPointType.MODULE_ERROR_CODE.value,
315
327
  )
316
328
 
317
- def send_download_request(self, serial_number: str) -> None:
318
- """Send download request telegram.
329
+ def send_download_request(
330
+ self, serial_number: str, actiontable_type: SystemFunction
331
+ ) -> None:
332
+ """
333
+ Send download request telegram.
319
334
 
320
335
  Args:
321
336
  serial_number: Device serial number.
337
+ actiontable_type: DOWNLOAD_ACTIONTABLE or DOWNLOAD_MSACTIONTABLE.
322
338
  """
323
339
  self.send_telegram(
324
340
  telegram_type=TelegramType.SYSTEM,
325
341
  serial_number=serial_number,
326
- system_function=SystemFunction.DOWNLOAD_ACTIONTABLE,
342
+ system_function=actiontable_type,
327
343
  data_value=NO_ERROR_CODE,
328
344
  )
329
345
 
330
346
  def send_ack(self, serial_number: str) -> None:
331
- """Send ACK telegram.
347
+ """
348
+ Send ACK telegram.
332
349
 
333
350
  Args:
334
351
  serial_number: Device serial number.
@@ -347,7 +364,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
347
364
  *args: object,
348
365
  **kw: object,
349
366
  ) -> DelayedCall:
350
- """Schedule a callable to be called later.
367
+ """
368
+ Schedule a callable to be called later.
351
369
 
352
370
  Args:
353
371
  delay: Delay in seconds before calling.
@@ -361,7 +379,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
361
379
  return self._reactor.callLater(delay, callable_action, *args, **kw)
362
380
 
363
381
  def buildProtocol(self, addr: IAddress) -> protocol.Protocol:
364
- """Build protocol instance for connection.
382
+ """
383
+ Build protocol instance for connection.
365
384
 
366
385
  Args:
367
386
  addr: Address of the connection.
@@ -373,7 +392,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
373
392
  return self
374
393
 
375
394
  def clientConnectionFailed(self, connector: IConnector, reason: Failure) -> None:
376
- """Handle client connection failure.
395
+ """
396
+ Handle client connection failure.
377
397
 
378
398
  Args:
379
399
  connector: Connection connector instance.
@@ -385,7 +405,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
385
405
  self._cancel_timeout()
386
406
 
387
407
  def clientConnectionLost(self, connector: IConnector, reason: Failure) -> None:
388
- """Handle client connection lost event.
408
+ """
409
+ Handle client connection lost event.
389
410
 
390
411
  Args:
391
412
  connector: Connection connector instance.
@@ -401,7 +422,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
401
422
  self.on_timeout.emit()
402
423
 
403
424
  def connection_failed(self, reason: Failure) -> None:
404
- """Handle connection failure.
425
+ """
426
+ Handle connection failure.
405
427
 
406
428
  Args:
407
429
  reason: Failure reason details.
@@ -436,7 +458,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
436
458
  self.logger.debug(f"Reactor stop failed (likely already stopped): {e}")
437
459
 
438
460
  def connect(self) -> None:
439
- """Connect to TCP server.
461
+ """
462
+ Connect to TCP server.
440
463
 
441
464
  Automatically detects and integrates with running asyncio event loop if present.
442
465
  """
@@ -494,7 +517,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
494
517
  self.call_later(later, self.process_telegram_queue)
495
518
 
496
519
  def set_event_loop(self, event_loop: asyncio.AbstractEventLoop) -> None:
497
- """Change the event loop.
520
+ """
521
+ Change the event loop.
498
522
 
499
523
  Args:
500
524
  event_loop: the event loop instance.
@@ -511,7 +535,8 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
511
535
  self.logger.info("Set reactor to running state")
512
536
 
513
537
  def __enter__(self) -> "ConbusEventProtocol":
514
- """Enter context manager.
538
+ """
539
+ Enter context manager.
515
540
 
516
541
  Returns:
517
542
  Self for context management.
@@ -1,4 +1,5 @@
1
- """Conbus Protocol for XP telegram communication.
1
+ """
2
+ Conbus Protocol for XP telegram communication.
2
3
 
3
4
  This module implements the Twisted protocol for Conbus communication.
4
5
  """
@@ -22,7 +23,8 @@ from xp.utils import calculate_checksum
22
23
 
23
24
 
24
25
  class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
25
- """Twisted protocol for XP telegram communication.
26
+ """
27
+ Twisted protocol for XP telegram communication.
26
28
 
27
29
  Attributes:
28
30
  buffer: Buffer for incoming telegram data.
@@ -40,7 +42,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
40
42
  cli_config: ConbusClientConfig,
41
43
  reactor: PosixReactorBase,
42
44
  ) -> None:
43
- """Initialize ConbusProtocol.
45
+ """
46
+ Initialize ConbusProtocol.
44
47
 
45
48
  Args:
46
49
  cli_config: Configuration for Conbus client connection.
@@ -54,10 +57,11 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
54
57
  self.timeout_call: Optional[DelayedCall] = None
55
58
 
56
59
  def connectionMade(self) -> None:
57
- """Handle connection established event.
60
+ """
61
+ Handle connection established event.
58
62
 
59
- Called when TCP connection is successfully established.
60
- Starts inactivity timeout monitoring.
63
+ Called when TCP connection is successfully established. Starts inactivity
64
+ timeout monitoring.
61
65
  """
62
66
  self.logger.debug("connectionMade")
63
67
  self.connection_established()
@@ -65,7 +69,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
65
69
  self._reset_timeout()
66
70
 
67
71
  def dataReceived(self, data: bytes) -> None:
68
- """Handle received data from TCP connection.
72
+ """
73
+ Handle received data from TCP connection.
69
74
 
70
75
  Parses incoming telegram frames and dispatches events.
71
76
 
@@ -124,7 +129,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
124
129
  self.telegram_received(telegram_received)
125
130
 
126
131
  def sendFrame(self, data: bytes) -> None:
127
- """Send telegram frame.
132
+ """
133
+ Send telegram frame.
128
134
 
129
135
  Args:
130
136
  data: Raw telegram payload (without checksum/framing).
@@ -153,7 +159,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
153
159
  system_function: SystemFunction,
154
160
  data_value: str,
155
161
  ) -> None:
156
- """Send telegram with specified parameters.
162
+ """
163
+ Send telegram with specified parameters.
157
164
 
158
165
  Args:
159
166
  telegram_type: Type of telegram to send.
@@ -170,7 +177,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
170
177
  self.sendFrame(payload.encode())
171
178
 
172
179
  def buildProtocol(self, addr: IAddress) -> protocol.Protocol:
173
- """Build protocol instance for connection.
180
+ """
181
+ Build protocol instance for connection.
174
182
 
175
183
  Args:
176
184
  addr: Address of the connection.
@@ -182,7 +190,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
182
190
  return self
183
191
 
184
192
  def clientConnectionFailed(self, connector: IConnector, reason: Failure) -> None:
185
- """Handle client connection failure.
193
+ """
194
+ Handle client connection failure.
186
195
 
187
196
  Args:
188
197
  connector: Connection connector instance.
@@ -194,7 +203,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
194
203
  self._stop_reactor()
195
204
 
196
205
  def clientConnectionLost(self, connector: IConnector, reason: Failure) -> None:
197
- """Handle client connection lost event.
206
+ """
207
+ Handle client connection lost event.
198
208
 
199
209
  Args:
200
210
  connector: Connection connector instance.
@@ -206,7 +216,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
206
216
  self._stop_reactor()
207
217
 
208
218
  def timeout(self) -> bool:
209
- """Handle timeout event.
219
+ """
220
+ Handle timeout event.
210
221
 
211
222
  Returns:
212
223
  True to continue waiting for next timeout, False to stop.
@@ -216,7 +227,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
216
227
  return False
217
228
 
218
229
  def connection_failed(self, reason: Failure) -> None:
219
- """Handle connection failure.
230
+ """
231
+ Handle connection failure.
220
232
 
221
233
  Args:
222
234
  reason: Failure reason details.
@@ -262,7 +274,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
262
274
  self.reactor.run()
263
275
 
264
276
  def __enter__(self) -> "ConbusProtocol":
265
- """Enter context manager.
277
+ """
278
+ Enter context manager.
266
279
 
267
280
  Returns:
268
281
  Self for context management.
@@ -282,7 +295,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
282
295
  """Override methods."""
283
296
 
284
297
  def telegram_sent(self, telegram_sent: str) -> None:
285
- """Override callback when telegram has been sent.
298
+ """
299
+ Override callback when telegram has been sent.
286
300
 
287
301
  Args:
288
302
  telegram_sent: The telegram that was sent.
@@ -290,7 +304,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
290
304
  pass
291
305
 
292
306
  def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
293
- """Override callback when telegram is received.
307
+ """
308
+ Override callback when telegram is received.
294
309
 
295
310
  Args:
296
311
  telegram_received: Event containing received telegram details.
@@ -302,7 +317,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
302
317
  pass
303
318
 
304
319
  def connection_lost(self, reason: Failure) -> None:
305
- """Override callback when connection is lost.
320
+ """
321
+ Override callback when connection is lost.
306
322
 
307
323
  Args:
308
324
  reason: Reason for connection loss.
@@ -310,7 +326,8 @@ class ConbusProtocol(protocol.Protocol, protocol.ClientFactory):
310
326
  pass
311
327
 
312
328
  def failed(self, message: str) -> None:
313
- """Override callback when connection failed.
329
+ """
330
+ Override callback when connection failed.
314
331
 
315
332
  Args:
316
333
  message: Error message describing the failure.