conson-xp 1.50.1__py3-none-any.whl → 1.51.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: conson-xp
3
- Version: 1.50.1
3
+ Version: 1.51.0
4
4
  Summary: XP Protocol Communication Tools
5
5
  Author-Email: ldvchosal <ldvchosal@github.com>
6
6
  License: MIT License
@@ -1,8 +1,8 @@
1
- conson_xp-1.50.1.dist-info/METADATA,sha256=bCbYqnE9XZK73a4laFt68XxyWDTPC-MlmxJa99Y7JTc,11432
2
- conson_xp-1.50.1.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
3
- conson_xp-1.50.1.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
- conson_xp-1.50.1.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
- xp/__init__.py,sha256=hEOsOLZ2VP2s9c4Fqe0rpmfu56_wnujnc7Wf3f0xDGI,182
1
+ conson_xp-1.51.0.dist-info/METADATA,sha256=8rmZ2V68vB3gZpx_sScMBXxKXqAei3GeqOOUHGe92mo,11432
2
+ conson_xp-1.51.0.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
3
+ conson_xp-1.51.0.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
+ conson_xp-1.51.0.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
+ xp/__init__.py,sha256=IbYggn-GNpmY-NkggNp_7SLbVaF6zPk0wENVaZeOIeE,182
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=G7A1KFRSV0CEeDTqr_khu-K9_sc01CTI2KSfkFcaBRM,4949
@@ -16,7 +16,7 @@ xp/cli/commands/conbus/conbus_custom_commands.py,sha256=TqWo45yqEp_ezmKZ0tymQ0C4
16
16
  xp/cli/commands/conbus/conbus_datapoint_commands.py,sha256=uYsvi37vl2od2XJB0semAF0sH3UrRWTt_qHnBmUBR-w,3788
17
17
  xp/cli/commands/conbus/conbus_discover_commands.py,sha256=gSK5Y4lespNKFNgGtp7VkqStGe4fWxDNNfyPPuJiwXQ,1931
18
18
  xp/cli/commands/conbus/conbus_event_commands.py,sha256=faaSGRNtJCttk-0VO5Z4m4Zz37aOsSgmbuzWbTOUZIQ,3103
19
- xp/cli/commands/conbus/conbus_export_commands.py,sha256=epfoIC1C32IT7SMVxolUDm1xm2q7hz_kvs7Jct4W9FQ,5819
19
+ xp/cli/commands/conbus/conbus_export_commands.py,sha256=pWZlS0MMcc8sZAfXx8xMSn53NT5cg3HpF-msBOU7whI,5992
20
20
  xp/cli/commands/conbus/conbus_lightlevel_commands.py,sha256=WH4ZQHxSbquPlAqd0uRxq8VR-sO4_AnfseMqaoPoGoA,7092
21
21
  xp/cli/commands/conbus/conbus_linknumber_commands.py,sha256=3bkik8nHXY89XfzeUnKWmvKA70r4qJJ79j8FfLL4sL0,3556
22
22
  xp/cli/commands/conbus/conbus_modulenumber_commands.py,sha256=fOIO0f85iDJBfGnRCEN8zK6j4i43uuF_9YKQc_nQ39A,3628
@@ -123,7 +123,7 @@ xp/services/actiontable/msactiontable_xp33_serializer.py,sha256=9JzG9dOrfamu8Ujs
123
123
  xp/services/actiontable/serializer_protocol.py,sha256=PMsZbPwPQD1MJYo_KpZSgpnVQCtXFXSfzXFpCiA6Xi8,2002
124
124
  xp/services/conbus/__init__.py,sha256=Hi35sMKu9o6LpYoi2tQDaQoMb8M5sOt_-LUTxxaCU_0,28
125
125
  xp/services/conbus/actiontable/__init__.py,sha256=oD6vRk_Ye-eZ9s_hldAgtRJFu4mfAnODqpkJUGHHszk,40
126
- xp/services/conbus/actiontable/actiontable_download_service.py,sha256=ZTQCC1D9TLmyDu3b5GAO4VxUVGSr6HuqZI9fxHB1qW8,14992
126
+ xp/services/conbus/actiontable/actiontable_download_service.py,sha256=41Hr1753IBpUeHQqO57uS7qxOB0rJt8qCpznzKlUPOM,15028
127
127
  xp/services/conbus/actiontable/actiontable_list_service.py,sha256=oTDSpBkp-MJeaF5bhRnwkSy3na55xqQ4e2ykJzbMCUo,3236
128
128
  xp/services/conbus/actiontable/actiontable_show_service.py,sha256=WISY2VsmSlceGa5_9lpFO-gs5TnTjv6YidQksUjCapk,3058
129
129
  xp/services/conbus/actiontable/actiontable_upload_service.py,sha256=FaQzOSg8s2zUL5xz9qZY9fvzrdDosc3CoxkVDvNg2SU,13252
@@ -135,7 +135,7 @@ xp/services/conbus/conbus_datapoint_service.py,sha256=WBQC42-6xuPWhMKKRtHtRzwEmV
135
135
  xp/services/conbus/conbus_discover_service.py,sha256=mvqjHFMmEkQjHD9YDIk9gE8MowPMkOIJRmyjX96G5pw,12868
136
136
  xp/services/conbus/conbus_event_list_service.py,sha256=-jl3WHpyidbh-h4NMK2gERqu48mTNFD6rpPo2EyGxeg,3641
137
137
  xp/services/conbus/conbus_event_raw_service.py,sha256=viXuEXw165-RytdqC76wQShJLD7Yd0rtURxWZZ8hyKA,7060
138
- xp/services/conbus/conbus_export_actiontable_service.py,sha256=_2bxmDVSpkGtepuQVbdYX2nwEnSm91GX9P9UzB_INDQ,11043
138
+ xp/services/conbus/conbus_export_actiontable_service.py,sha256=d6Y2RDiVOH-jTMWOIE_gY_WBJnHFrbJGguk-WZWbNPs,11818
139
139
  xp/services/conbus/conbus_export_service.py,sha256=RP8nADTIs4FGUf_BFLRZMtEJZdXV94zg3QrlWaDnhKA,17536
140
140
  xp/services/conbus/conbus_output_service.py,sha256=e57bRkLgPnJuB8hkllNh0kgGkjPt9IK75tuBxd_bOkE,9361
141
141
  xp/services/conbus/conbus_raw_service.py,sha256=OQuV521VOQraf2PGF2B9868vh7sDgmfc19YebrkZnyw,5844
@@ -198,10 +198,10 @@ xp/term/widgets/protocol_log.py,sha256=E68QmSMpOFrvrPTo_gOQVfyiDqY5c_y8fkNKnQw6V
198
198
  xp/term/widgets/status_footer.py,sha256=YYAT0431p6jmrzzpVgaPhu7yGkRroWGv4e99t2XlkHI,3297
199
199
  xp/utils/__init__.py,sha256=_avMF_UOkfR3tNeDIPqQ5odmbq5raKkaq1rZ9Cn1CJs,332
200
200
  xp/utils/checksum.py,sha256=Px1S3dFGA-_plavBxrq3IqmprNlgtNDunE3whg6Otwg,1722
201
- xp/utils/dependencies.py,sha256=dlSuKVmuA7AZlqINrQkZxfHuU8mzSHDZnMRRDzqjRAI,24067
201
+ xp/utils/dependencies.py,sha256=I8Z89_iTCeR-7adpae3GVQUGZ-1gY6wg0OGKmdJGg3w,24536
202
202
  xp/utils/event_helper.py,sha256=zD0K3TPfGEThU9vUNlDtglTai3Cmm30727iwjDZy6Dk,1007
203
203
  xp/utils/logging.py,sha256=wJ1d-yg97NiZUrt2F8iDMcmnHVwC-PErcI-7dpyiRDc,3777
204
204
  xp/utils/serialization.py,sha256=TS1OwpTOemSvXsCGw3js4JkYYFEqkzrPe8V9QYQefdw,4684
205
205
  xp/utils/state_machine.py,sha256=W9AY4ntRZnFeHAa5d43hm37j53uJPlqkRvWTPiBhJ_0,2464
206
206
  xp/utils/time_utils.py,sha256=K17godWpL18VEypbTlvNOEDG6R3huYnf29yjkcnwRpU,3796
207
- conson_xp-1.50.1.dist-info/RECORD,,
207
+ conson_xp-1.51.0.dist-info/RECORD,,
xp/__init__.py CHANGED
@@ -4,7 +4,7 @@ XP CLI tool for remote console bus operations.
4
4
  conson-xp package.
5
5
  """
6
6
 
7
- __version__ = "1.50.1"
7
+ __version__ = "1.51.0"
8
8
  __manufacturer__ = "salchichon"
9
9
  __model__ = "xp.cli"
10
10
  __serial__ = "2025.09.23.000"
@@ -117,16 +117,21 @@ def export_conbus_actiontable(ctx: click.Context) -> None:
117
117
  xp conbus export actiontable
118
118
  """
119
119
 
120
- def on_progress(serial_number: str, current: int, total: int) -> None:
120
+ def on_progress(
121
+ serial_number: str, actiontable_type: str, current: int, total: int
122
+ ) -> None:
121
123
  """
122
124
  Handle progress updates during export.
123
125
 
124
126
  Args:
125
127
  serial_number: Serial number of discovered device.
128
+ actiontable_type: Type of action table being exported.
126
129
  current: Current device number.
127
130
  total: Total devices discovered.
128
131
  """
129
- click.echo(f"Querying device {current}/{total}: {serial_number}...")
132
+ click.echo(
133
+ f"Querying device {current}/{total}: {serial_number} / {actiontable_type}."
134
+ )
130
135
 
131
136
  def on_device_actiontable_exported(
132
137
  module: ConsonModuleConfig,
@@ -176,4 +181,5 @@ def export_conbus_actiontable(ctx: click.Context) -> None:
176
181
  service.on_device_actiontable_exported.connect(on_device_actiontable_exported)
177
182
  service.on_finish.connect(on_finish)
178
183
  service.set_timeout(5)
184
+ service.configure()
179
185
  service.start_reactor()
@@ -292,6 +292,8 @@ class ActionTableDownloadService(DownloadStateMachine):
292
292
  raise RuntimeError("Cannot configure while download in progress")
293
293
  self.logger.info("Configuring actiontable download")
294
294
  self.serial_number = serial_number
295
+ self.actiontable_data = []
296
+
295
297
  if actiontable_type == ActionTableType.ACTIONTABLE:
296
298
  self.serializer = self.actiontable_serializer
297
299
  elif actiontable_type == ActionTableType.MSACTIONTABLE_XP20:
@@ -3,7 +3,7 @@
3
3
  import asyncio
4
4
  import logging
5
5
  from pathlib import Path
6
- from queue import SimpleQueue
6
+ from queue import Empty, SimpleQueue
7
7
  from typing import Any, Optional, Tuple
8
8
 
9
9
  import yaml
@@ -38,7 +38,7 @@ class ConbusActiontableExportService:
38
38
  """
39
39
 
40
40
  # Signals (class attributes)
41
- on_progress: Signal = Signal(str, int, int) # serial, current, total
41
+ on_progress: Signal = Signal(str, str, int, int) # serial, current, total
42
42
  on_device_actiontable_exported: Signal = Signal(
43
43
  ConsonModuleConfig, ActionTableType, str
44
44
  )
@@ -64,25 +64,35 @@ class ConbusActiontableExportService:
64
64
  self.logger = logging.getLogger(__name__)
65
65
  self.download_service = download_service
66
66
  self._module_list: ConsonModuleListConfig = module_list
67
+ self._module_dic: dict[str, ConsonModuleConfig] = {
68
+ module.serial_number: module for module in module_list.root
69
+ }
67
70
  # State management
68
- self.device_queue: SimpleQueue[Tuple[ConsonModuleConfig, ActionTableType]] = (
71
+ self.device_queue: SimpleQueue[Tuple[str, ActionTableType]] = (
69
72
  SimpleQueue()
70
73
  ) # FIFO
71
74
  for module in self._module_list.root:
72
- self.device_queue.put((module, ActionTableType.ACTIONTABLE))
73
- if module.module_type == "xp20":
74
- self.device_queue.put((module, ActionTableType.MSACTIONTABLE_XP20))
75
- if module.module_type == "xp24":
76
- self.device_queue.put((module, ActionTableType.MSACTIONTABLE_XP24))
77
- if module.module_type == "xp33":
78
- self.device_queue.put((module, ActionTableType.MSACTIONTABLE_XP33))
75
+ self.logger.info("Export module %s", module)
76
+ if module.module_type.lower() == "xp20":
77
+ self.device_queue.put(
78
+ (module.serial_number, ActionTableType.MSACTIONTABLE_XP20)
79
+ )
80
+ if module.module_type.lower() == "xp24":
81
+ self.device_queue.put(
82
+ (module.serial_number, ActionTableType.MSACTIONTABLE_XP24)
83
+ )
84
+ if module.module_type.lower() == "xp33":
85
+ self.device_queue.put(
86
+ (module.serial_number, ActionTableType.MSACTIONTABLE_XP33)
87
+ )
88
+ self.device_queue.put((module.serial_number, ActionTableType.ACTIONTABLE))
89
+
90
+ self.logger.info("Export module %s", self.device_queue.qsize())
79
91
 
80
92
  self.current_module: Optional[ConsonModuleConfig] = None
81
- self.curent_actiontable_type: Optional[ActionTableType] = None
93
+ self.current_actiontable_type: Optional[ActionTableType] = None
82
94
  self.export_result = ConbusExportResponse(success=False)
83
95
  self.export_status = "OK"
84
- # Connect protocol signals
85
- self._connect_signals()
86
96
 
87
97
  def on_module_actiontable_received(
88
98
  self, actiontable: Any, short_actiontable: list[str]
@@ -94,7 +104,7 @@ class ConbusActiontableExportService:
94
104
  actiontable: Full actiontable data.
95
105
  short_actiontable: Short representation of the actiontable.
96
106
  """
97
- if not self.curent_actiontable_type:
107
+ if not self.current_actiontable_type:
98
108
  self._fail("Invalid state (curent_actiontable_type)")
99
109
  return
100
110
 
@@ -102,17 +112,17 @@ class ConbusActiontableExportService:
102
112
  self._fail("Invalid state (current_module)")
103
113
  return
104
114
 
105
- if self.curent_actiontable_type == ActionTableType.ACTIONTABLE:
115
+ if self.current_actiontable_type == ActionTableType.ACTIONTABLE:
106
116
  self.current_module.action_table = short_actiontable
107
- elif self.curent_actiontable_type == ActionTableType.MSACTIONTABLE_XP20:
117
+ elif self.current_actiontable_type == ActionTableType.MSACTIONTABLE_XP20:
108
118
  self.current_module.xp20_msaction_table = short_actiontable
109
- elif self.curent_actiontable_type == ActionTableType.MSACTIONTABLE_XP24:
119
+ elif self.current_actiontable_type == ActionTableType.MSACTIONTABLE_XP24:
110
120
  self.current_module.xp24_msaction_table = short_actiontable
111
- elif self.curent_actiontable_type == ActionTableType.MSACTIONTABLE_XP33:
121
+ elif self.current_actiontable_type == ActionTableType.MSACTIONTABLE_XP33:
112
122
  self.current_module.xp33_msaction_table = short_actiontable
113
123
 
114
124
  self.on_device_actiontable_exported.emit(
115
- self.current_module, self.curent_actiontable_type, actiontable
125
+ self.current_module, self.current_actiontable_type, short_actiontable
116
126
  )
117
127
 
118
128
  def on_module_finish(self) -> None:
@@ -127,10 +137,13 @@ class ConbusActiontableExportService:
127
137
  serial_number = (
128
138
  self.current_module.serial_number if self.current_module else "UNKNOWN"
129
139
  )
140
+ current_actiontable_type = self.current_actiontable_type or "UNKNOWN"
130
141
  total_modules = len(self._module_list.root)
131
142
  current_index = total_modules - self.device_queue.qsize()
132
143
 
133
- self.on_progress.emit(serial_number, current_index, total_modules)
144
+ self.on_progress.emit(
145
+ serial_number, current_actiontable_type, current_index, total_modules
146
+ )
134
147
 
135
148
  def on_module_error(self, error_message: str) -> None:
136
149
  """
@@ -162,7 +175,6 @@ class ConbusActiontableExportService:
162
175
  "enabled",
163
176
  "conbus_ip",
164
177
  "conbus_port",
165
- "action_table",
166
178
  }
167
179
  }
168
180
  },
@@ -203,16 +215,24 @@ class ConbusActiontableExportService:
203
215
  True if there is a module to export, False otherwise.
204
216
  """
205
217
  self.download_service.reset()
206
- (self.current_module, self.curent_actiontable_type) = (
207
- self.device_queue.get_nowait()
208
- )
209
- if not (self.current_module or self.curent_actiontable_type):
218
+ try:
219
+ (current_serial_number, self.current_actiontable_type) = (
220
+ self.device_queue.get_nowait()
221
+ )
222
+ except Empty:
223
+ return False
224
+
225
+ self.current_module = self._module_dic[current_serial_number]
226
+ if not (self.current_module or self.current_actiontable_type):
210
227
  self.logger.error("No module to export")
211
228
  return False
212
229
 
230
+ self.logger.info(
231
+ f"Downloading {self.current_module.serial_number} / {self.current_actiontable_type}"
232
+ )
213
233
  self.download_service.configure(
214
234
  self.current_module.serial_number,
215
- self.curent_actiontable_type,
235
+ self.current_actiontable_type,
216
236
  )
217
237
  self.download_service.do_connect()
218
238
  return True
@@ -275,7 +295,7 @@ class ConbusActiontableExportService:
275
295
 
276
296
  def _disconnect_signals(self) -> None:
277
297
  """Disconnect download service signals from handlers."""
278
- self.download_service.on_actiontable_received.connect(
298
+ self.download_service.on_actiontable_received.disconnect(
279
299
  self.on_module_actiontable_received
280
300
  )
281
301
  self.download_service.on_finish.disconnect(self.on_module_finish)
xp/utils/dependencies.py CHANGED
@@ -46,6 +46,9 @@ from xp.services.conbus.conbus_datapoint_service import (
46
46
  from xp.services.conbus.conbus_discover_service import ConbusDiscoverService
47
47
  from xp.services.conbus.conbus_event_list_service import ConbusEventListService
48
48
  from xp.services.conbus.conbus_event_raw_service import ConbusEventRawService
49
+ from xp.services.conbus.conbus_export_actiontable_service import (
50
+ ConbusActiontableExportService,
51
+ )
49
52
  from xp.services.conbus.conbus_export_service import ConbusExportService
50
53
  from xp.services.conbus.conbus_output_service import ConbusOutputService
51
54
  from xp.services.conbus.conbus_raw_service import ConbusRawService
@@ -217,6 +220,15 @@ class ServiceContainer:
217
220
  scope=punq.Scope.singleton,
218
221
  )
219
222
 
223
+ self.container.register(
224
+ ConbusActiontableExportService,
225
+ factory=lambda: ConbusActiontableExportService(
226
+ download_service=self.container.resolve(ActionTableDownloadService),
227
+ module_list=self.container.resolve(ConsonModuleListConfig),
228
+ ),
229
+ scope=punq.Scope.singleton,
230
+ )
231
+
220
232
  # Terminal UI
221
233
  self.container.register(
222
234
  ProtocolMonitorService,