conson-xp 1.48.0__py3-none-any.whl → 1.50.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.48.0
3
+ Version: 1.50.0
4
4
  Summary: XP Protocol Communication Tools
5
5
  Author-Email: ldvchosal <ldvchosal@github.com>
6
6
  License: MIT License
@@ -1,14 +1,14 @@
1
- conson_xp-1.48.0.dist-info/METADATA,sha256=ik_ZkQlc-4OEqECRAK5REKQjzTHB6QTWeXKrnmBZeyY,11403
2
- conson_xp-1.48.0.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
3
- conson_xp-1.48.0.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
- conson_xp-1.48.0.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
- xp/__init__.py,sha256=4LPDDZ3llI4VJJDFvi6MAvoF53KlCIbPYPSRgPAec_I,182
1
+ conson_xp-1.50.0.dist-info/METADATA,sha256=9CLWQiRR8QJj0Ne3zXyV2XzXqkmv3uL7NfVaGkaogHk,11403
2
+ conson_xp-1.50.0.dist-info/WHEEL,sha256=tsUv_t7BDeJeRHaSrczbGeuK-TtDpGsWi_JfpzD255I,90
3
+ conson_xp-1.50.0.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
+ conson_xp-1.50.0.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
+ xp/__init__.py,sha256=W-aER6IUlDyRVKHOLg5oh4E-KxDbSmRYOT9XO1035Ac,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
9
9
  xp/cli/commands/conbus/__init__.py,sha256=HYaX2__XxwD3Xaw4CzflvL8CwoUa4yR6wOyH8wwyofM,535
10
10
  xp/cli/commands/conbus/conbus.py,sha256=GpWq1QS3mKfQFG77nTED-_hsvcnXb3ZIrC6DhfyhzBE,3538
11
- xp/cli/commands/conbus/conbus_actiontable_commands.py,sha256=9kLP-ISIDWXVUtELCjTAs0JIT3DNGcYGBRnZEo-tp3g,7743
11
+ xp/cli/commands/conbus/conbus_actiontable_commands.py,sha256=EpyLG_6RxhIQY4BWxDXTyo8yzpBwbHfZDOgmRl--R5w,7378
12
12
  xp/cli/commands/conbus/conbus_autoreport_commands.py,sha256=dO3rxgII_xZVhbkxlMqTJCarrUveQCs_7-qf4li0UkQ,3962
13
13
  xp/cli/commands/conbus/conbus_blink_commands.py,sha256=1zLiXV8Nn4XSDI-z7F3f2RN2IO-yxeMkGQ1PCknAkWY,5398
14
14
  xp/cli/commands/conbus/conbus_config_commands.py,sha256=jeZi7J973DrDCyP59Qrvk6tonduj97KnV4fq9zbei2k,721
@@ -20,7 +20,7 @@ xp/cli/commands/conbus/conbus_export_commands.py,sha256=-fA4vzQF3XsDvRD4BjbE7KRq
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
23
- xp/cli/commands/conbus/conbus_msactiontable_commands.py,sha256=cTH6reU7oyqlOah-0-MWI2aWDlSJ-hnSf_0_aWk97uI,10419
23
+ xp/cli/commands/conbus/conbus_msactiontable_commands.py,sha256=oMHfrxDR9yj0Pvx92ZHnwYU3CZqwNNvfAfEoLuo_jhQ,11585
24
24
  xp/cli/commands/conbus/conbus_output_commands.py,sha256=XMEMb5tM0ul7lwhwoo4QRgWprXZ31qswXBno8KCeFMo,5342
25
25
  xp/cli/commands/conbus/conbus_raw_commands.py,sha256=o1dVZqiRw7J3_8Bge7DJucFyAqt7GNP-Azf-f3ir3SU,2019
26
26
  xp/cli/commands/conbus/conbus_receive_commands.py,sha256=LdxoOUdM5atkC8fFlp-GK7HQ7oxTnjrSFDx-lQ3nme0,1925
@@ -54,11 +54,10 @@ xp/cli/utils/formatters.py,sha256=SN_kUkL4M7csay8eftnxoIPS_VvQDlqZueARNElyZZs,98
54
54
  xp/cli/utils/module_type_choice.py,sha256=Hs0VFrssKWWGqfqBtSJPP7DDCzLyv-BfyeNIPC1WxyU,1672
55
55
  xp/cli/utils/serial_number_type.py,sha256=-6MlAAPbpqaGx1Ds3vPPT3PU9hYJG4_C2SmytXV3VyI,1480
56
56
  xp/cli/utils/system_function_choice.py,sha256=3YZrTtBHCw_f6KqqT41wJUiiPBVLAQufyPnrMkesdd0,1637
57
- xp/cli/utils/xp_module_type.py,sha256=rCafAi8k0BNRqtQryoai2WW4zr51lCEY-VRS7asW7VA,1485
58
57
  xp/models/__init__.py,sha256=lROqr559DGd8WpJJUtfPT95VERCwMZHpBDEc96QSxQ0,1312
59
58
  xp/models/actiontable/__init__.py,sha256=6kVq1rTOlpc24sZxGGVWkY48tqR42YWHLQHqakWqlPc,43
60
59
  xp/models/actiontable/actiontable.py,sha256=IAV3KhA5B4jNOHFvVQmhJQV3vbX7EOug2UNAJuTslvk,1258
61
- xp/models/actiontable/actiontable_type.py,sha256=wfJXnXMz9IeU4RIM21BfXqAzJJ9I1Ak7cEPyJ8c6j94,610
60
+ xp/models/actiontable/actiontable_type.py,sha256=HjQ9Z-akdhMJaVx6fgyjqqFCAdFwQp0vO1YmSznlW1M,887
62
61
  xp/models/actiontable/msactiontable_xp20.py,sha256=E2JQpZzWuAb_ZdFApzx80tqfF1qFjiO4zp-PtrRBYeQ,5034
63
62
  xp/models/actiontable/msactiontable_xp24.py,sha256=WNtUmJVizyUs0RmG9EQW21tgiUB9ofqVQxrzEVpOjdk,9423
64
63
  xp/models/actiontable/msactiontable_xp33.py,sha256=nM4v7jICY3woXV50ji02rBbMxAu6CNjydoh9QNAMsF4,11859
@@ -88,7 +87,7 @@ xp/models/homekit/homekit_accessory.py,sha256=ANjDWlFxeNTstl7lKdmf6vMOC0wc005vpi
88
87
  xp/models/homekit/homekit_config.py,sha256=OMq0eayAJ6NRr8PXANvQzgEYGW9RN_ycyEmnTlTlHrQ,2938
89
88
  xp/models/log_entry.py,sha256=tAiNwouCP2d4jKiHJY9a-2iAi8LWTpG-TZsOPDIstlA,4423
90
89
  xp/models/protocol/__init__.py,sha256=TJ_CJKchA-xgQiv5vCo_ndBBZjrcaTmjT74bR0T-5Cw,38
91
- xp/models/protocol/conbus_protocol.py,sha256=TB7L2d_UausI6SXoNGCyi2nSn8cSuQA19pTA5evEsrI,9229
90
+ xp/models/protocol/conbus_protocol.py,sha256=hF78N5xvBzMiyWoKd8i_avA8kJ1As_9Pplkw1GMqKzk,9145
92
91
  xp/models/response.py,sha256=z0376hEVNh1Z_R9CtzmKNbJBzCo_Aun2ImI9dTtrVe4,1254
93
92
  xp/models/telegram/__init__.py,sha256=-_exhjlRLbBNuPxHC4tLA2SAgf8M0yHJMeyEoQIk9PI,53
94
93
  xp/models/telegram/action_type.py,sha256=ys3yInmD97bKotB-nlPdfo8ZPXKaYxzG0CxV9wHK-zo,797
@@ -127,13 +126,13 @@ xp/services/conbus/actiontable/__init__.py,sha256=oD6vRk_Ye-eZ9s_hldAgtRJFu4mfAn
127
126
  xp/services/conbus/actiontable/actiontable_download_service.py,sha256=ZTQCC1D9TLmyDu3b5GAO4VxUVGSr6HuqZI9fxHB1qW8,14992
128
127
  xp/services/conbus/actiontable/actiontable_list_service.py,sha256=oTDSpBkp-MJeaF5bhRnwkSy3na55xqQ4e2ykJzbMCUo,3236
129
128
  xp/services/conbus/actiontable/actiontable_show_service.py,sha256=WISY2VsmSlceGa5_9lpFO-gs5TnTjv6YidQksUjCapk,3058
130
- xp/services/conbus/actiontable/actiontable_upload_service.py,sha256=4crX4OZeTLYC_9ZjhV1Cqqc-WOhhBlXDmEHToLS6N9g,9772
129
+ xp/services/conbus/actiontable/actiontable_upload_service.py,sha256=FaQzOSg8s2zUL5xz9qZY9fvzrdDosc3CoxkVDvNg2SU,13252
131
130
  xp/services/conbus/conbus_blink_all_service.py,sha256=toDIZDXBGBYnEishcdnJrVzkmfPi7g5nCDXuyA_wFCs,8536
132
131
  xp/services/conbus/conbus_blink_service.py,sha256=ggLuzeq_UsgCoxRxg2bsNs9p8Lw_shjsj-niRzb5dKk,7953
133
132
  xp/services/conbus/conbus_custom_service.py,sha256=9OIRC2CG_rN96vbv_EZXf7BrX_abhqi5MZx0Se8fEhU,7826
134
133
  xp/services/conbus/conbus_datapoint_queryall_service.py,sha256=YCeieYgS73HAplAB1NpyEFary8L3yJXm2z9XOuUOLkI,8468
135
134
  xp/services/conbus/conbus_datapoint_service.py,sha256=WBQC42-6xuPWhMKKRtHtRzwEmVfYFt7cmS5uS-iv3P0,8095
136
- xp/services/conbus/conbus_discover_service.py,sha256=NYHPBD16196EwcorPSwFqIwcUWcfN6moXctXlIoO9ik,12831
135
+ xp/services/conbus/conbus_discover_service.py,sha256=mvqjHFMmEkQjHD9YDIk9gE8MowPMkOIJRmyjX96G5pw,12868
137
136
  xp/services/conbus/conbus_event_list_service.py,sha256=-jl3WHpyidbh-h4NMK2gERqu48mTNFD6rpPo2EyGxeg,3641
138
137
  xp/services/conbus/conbus_event_raw_service.py,sha256=viXuEXw165-RytdqC76wQShJLD7Yd0rtURxWZZ8hyKA,7060
139
138
  xp/services/conbus/conbus_export_service.py,sha256=coUbwdx3eG7ILhvUvlY3dkxdzZUksjnZHBGPvDDrTdk,17420
@@ -141,8 +140,6 @@ xp/services/conbus/conbus_output_service.py,sha256=e57bRkLgPnJuB8hkllNh0kgGkjPt9
141
140
  xp/services/conbus/conbus_raw_service.py,sha256=OQuV521VOQraf2PGF2B9868vh7sDgmfc19YebrkZnyw,5844
142
141
  xp/services/conbus/conbus_receive_service.py,sha256=TFf3W65brGsy6QZICpIs0Xy9bgqyL1vgQuhS_eHuIZs,5416
143
142
  xp/services/conbus/conbus_scan_service.py,sha256=_Ka0OUDNYhDgZIR49Q0P5GTxJq6RcAAX2DVqEDdtb5U,6888
144
- xp/services/conbus/msactiontable/__init__.py,sha256=rDYzumPSfcTjDADHxjE7bXQoeWtZTDGaYzFTYdVl_9g,42
145
- xp/services/conbus/msactiontable/msactiontable_upload_service.py,sha256=LB9pv0VOUDmyTHKUcY894fmBAqINO7qpM8mW1E3s8aU,12423
146
143
  xp/services/conbus/write_config_service.py,sha256=BCfmLNPRDpwSwRMRYJvx2FXA8IZsdgmyeTXIYvmb4ys,9004
147
144
  xp/services/homekit/__init__.py,sha256=xAMKmln_AmEFdOOJGKWYi96seRlKDQpKx3-hm7XbdIo,36
148
145
  xp/services/homekit/homekit_cache_service.py,sha256=z1TB6icEqd1paoilVTewuFL0lXVCQbvrOJkJvvQECJY,11060
@@ -160,9 +157,8 @@ xp/services/homekit/homekit_outlet_service.py,sha256=VVeuUas5HROaMwfbc_FO-gVp_mX
160
157
  xp/services/homekit/homekit_service.py,sha256=mmO9dHd1PAkOLkM7wwbpC0iBnULN4XZxeHUnCMKOL7g,14127
161
158
  xp/services/log_file_service.py,sha256=y775InPlpG8Z_uitHt7yrgRG-3vlIuCfdJjiZzPc_MA,10578
162
159
  xp/services/module_type_service.py,sha256=ga4WO7dmJEaDKrXPmrJ-72n4UaEZonead23lHBkFN1E,7505
163
- xp/services/protocol/__init__.py,sha256=qRufBmqRKGzpuzZ5bxBbmwf510TT00Ke8s5HcWGnqRY,818
164
- xp/services/protocol/conbus_event_protocol.py,sha256=0EHC8YefW2EcYBAeRm3TX1N0L32KQv5Ed3utTe3JrTQ,19567
165
- xp/services/protocol/conbus_protocol.py,sha256=3RY1dva3XHLyvcBqwV4nuenaVpRnT-ppPz45EXNGCIs,10417
160
+ xp/services/protocol/__init__.py,sha256=4zC__3e-Hma_IrmFCvsL44wJRd5LLHLSI_tahqdaTF8,741
161
+ xp/services/protocol/conbus_event_protocol.py,sha256=7AMn_5jr8lWPbf3C2s0P-r-w4PgdsmsBVcK0UMmrdaw,19572
166
162
  xp/services/protocol/protocol_factory.py,sha256=gWXQtOdgtOyn0Tu_aydYFd_cTdU-jtsKVuMl-ru133s,2512
167
163
  xp/services/protocol/telegram_protocol.py,sha256=hyEMJUUhgQe_2R8CDio8xT5tpLtgoXS8W0aDd7wN48E,9538
168
164
  xp/services/reverse_proxy_service.py,sha256=Xuxo2ajjmTXLg5yd6gRGKHpFPX4-6kpOUg10doZB8vw,15161
@@ -201,10 +197,10 @@ xp/term/widgets/protocol_log.py,sha256=E68QmSMpOFrvrPTo_gOQVfyiDqY5c_y8fkNKnQw6V
201
197
  xp/term/widgets/status_footer.py,sha256=YYAT0431p6jmrzzpVgaPhu7yGkRroWGv4e99t2XlkHI,3297
202
198
  xp/utils/__init__.py,sha256=_avMF_UOkfR3tNeDIPqQ5odmbq5raKkaq1rZ9Cn1CJs,332
203
199
  xp/utils/checksum.py,sha256=Px1S3dFGA-_plavBxrq3IqmprNlgtNDunE3whg6Otwg,1722
204
- xp/utils/dependencies.py,sha256=b3BdBOiTuX7WU734MyZXDE854RDlJgJlQY6oBj2AABQ,25295
200
+ xp/utils/dependencies.py,sha256=tmqgooFjkZ8W_CekzJdPlaQas3IJGnVXbfBZdUimwZU,23992
205
201
  xp/utils/event_helper.py,sha256=zD0K3TPfGEThU9vUNlDtglTai3Cmm30727iwjDZy6Dk,1007
206
202
  xp/utils/logging.py,sha256=wJ1d-yg97NiZUrt2F8iDMcmnHVwC-PErcI-7dpyiRDc,3777
207
203
  xp/utils/serialization.py,sha256=TS1OwpTOemSvXsCGw3js4JkYYFEqkzrPe8V9QYQefdw,4684
208
204
  xp/utils/state_machine.py,sha256=W9AY4ntRZnFeHAa5d43hm37j53uJPlqkRvWTPiBhJ_0,2464
209
205
  xp/utils/time_utils.py,sha256=K17godWpL18VEypbTlvNOEDG6R3huYnf29yjkcnwRpU,3796
210
- conson_xp-1.48.0.dist-info/RECORD,,
206
+ conson_xp-1.50.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.48.0"
7
+ __version__ = "1.50.0"
8
8
  __manufacturer__ = "salchichon"
9
9
  __model__ = "xp.cli"
10
10
  __serial__ = "2025.09.23.000"
@@ -1,8 +1,6 @@
1
1
  """ActionTable CLI commands."""
2
2
 
3
3
  import json
4
- from contextlib import suppress
5
- from pathlib import Path
6
4
 
7
5
  import click
8
6
  from click import Context
@@ -13,10 +11,9 @@ from xp.cli.utils.decorators import (
13
11
  )
14
12
  from xp.cli.utils.serial_number_type import SERIAL
15
13
  from xp.models.actiontable.actiontable import ActionTable
16
- from xp.models.actiontable.actiontable_type import ActionTableType
14
+ from xp.models.actiontable.actiontable_type import ActionTableType, ActionTableType2
17
15
  from xp.models.config.conson_module_config import (
18
16
  ConsonModuleConfig,
19
- ConsonModuleListConfig,
20
17
  )
21
18
  from xp.services.conbus.actiontable.actiontable_download_service import (
22
19
  ActionTableDownloadService,
@@ -164,18 +161,12 @@ def conbus_upload_actiontable(ctx: Context, serial_number: str) -> None:
164
161
 
165
162
  with service:
166
163
  # Load config to get entry count for success message
167
- config_path = Path.cwd() / "conson.yml"
168
- if config_path.exists():
169
- with suppress(Exception):
170
- config = ConsonModuleListConfig.from_yaml(str(config_path))
171
- module = config.find_module(serial_number)
172
- if module and module.action_table:
173
- entries_count = len(module.action_table)
174
-
175
164
  service.on_progress.connect(progress_callback)
176
165
  service.on_finish.connect(on_finish)
177
166
  service.on_error.connect(on_error)
178
- service.start(serial_number=serial_number)
167
+ service.start(
168
+ serial_number=serial_number, actiontable_type=ActionTableType2.ACTIONTABLE
169
+ )
179
170
  service.start_reactor()
180
171
 
181
172
 
@@ -1,7 +1,7 @@
1
1
  """XP24 Action Table CLI commands."""
2
2
 
3
3
  import json
4
- from typing import Any, Union
4
+ from typing import Any, Optional, Union
5
5
 
6
6
  import click
7
7
  from click import Context
@@ -11,8 +11,7 @@ from xp.cli.utils.decorators import (
11
11
  connection_command,
12
12
  )
13
13
  from xp.cli.utils.serial_number_type import SERIAL
14
- from xp.cli.utils.xp_module_type import XP_MODULE_TYPE
15
- from xp.models.actiontable.actiontable_type import ActionTableType
14
+ from xp.models.actiontable.actiontable_type import ActionTableType, ActionTableType2
16
15
  from xp.models.config.conson_module_config import ConsonModuleConfig
17
16
  from xp.services.conbus.actiontable.actiontable_download_service import (
18
17
  ActionTableDownloadService,
@@ -23,11 +22,59 @@ from xp.services.conbus.actiontable.actiontable_list_service import (
23
22
  from xp.services.conbus.actiontable.actiontable_show_service import (
24
23
  ActionTableShowService,
25
24
  )
26
- from xp.services.conbus.msactiontable.msactiontable_upload_service import (
27
- MsActionTableUploadService,
25
+ from xp.services.conbus.actiontable.actiontable_upload_service import (
26
+ ActionTableUploadService,
28
27
  )
29
28
 
30
29
 
30
+ class XpModuleTypeChoice(click.ParamType):
31
+ """
32
+ Click parameter type for validating XP module types.
33
+
34
+ Attributes:
35
+ name: The parameter type name.
36
+ choices: List of valid module type strings.
37
+ """
38
+
39
+ name = "xpmoduletype"
40
+
41
+ def __init__(self) -> None:
42
+ """Initialize the XpModuleTypeChoice parameter type."""
43
+ self.choices = ["xp20", "xp24", "xp31", "xp33"]
44
+
45
+ def convert(
46
+ self,
47
+ value: Any,
48
+ param: Optional[click.Parameter],
49
+ ctx: Optional[click.Context],
50
+ ) -> Any:
51
+ """
52
+ Convert and validate XP module type input.
53
+
54
+ Args:
55
+ value: The input value to convert.
56
+ param: The Click parameter.
57
+ ctx: The Click context.
58
+
59
+ Returns:
60
+ Lowercase module type string if valid, None if input is None.
61
+ """
62
+ if value is None:
63
+ return value
64
+ normalized_value = value.lower()
65
+ if normalized_value in self.choices:
66
+ return normalized_value
67
+ choices_list = "\n".join(f" - {choice}" for choice in sorted(self.choices))
68
+ self.fail(
69
+ f"{value!r} is not a valid choice. Choose from:\n{choices_list}",
70
+ param,
71
+ ctx,
72
+ )
73
+
74
+
75
+ XP_MODULE_TYPE = XpModuleTypeChoice()
76
+
77
+
31
78
  def _get_actiontable_type(xpmoduletype: str) -> ActionTableType:
32
79
  """
33
80
  Map xpmoduletype string to ActionTableType enum.
@@ -244,22 +291,18 @@ def conbus_show_msactiontable(ctx: Context, serial_number: str) -> None:
244
291
 
245
292
  @conbus_msactiontable.command("upload", short_help="Upload MSActionTable")
246
293
  @click.argument("serial_number", type=SERIAL)
247
- @click.argument("xpmoduletype", type=XP_MODULE_TYPE)
248
294
  @click.pass_context
249
295
  @connection_command()
250
- def conbus_upload_msactiontable(
251
- ctx: Context, serial_number: str, xpmoduletype: str
252
- ) -> None:
296
+ def conbus_upload_msactiontable(ctx: Context, serial_number: str) -> None:
253
297
  """
254
298
  Upload MS action table from conson.yml to XP module.
255
299
 
256
300
  Args:
257
301
  ctx: Click context object.
258
302
  serial_number: 10-digit module serial number.
259
- xpmoduletype: XP module type.
260
303
  """
261
- service: MsActionTableUploadService = (
262
- ctx.obj.get("container").get_container().resolve(MsActionTableUploadService)
304
+ service: ActionTableUploadService = (
305
+ ctx.obj.get("container").get_container().resolve(ActionTableUploadService)
263
306
  )
264
307
 
265
308
  def on_progress(progress: str) -> None:
@@ -300,7 +343,7 @@ def conbus_upload_msactiontable(
300
343
  service.on_finish.connect(on_finish)
301
344
  service.start(
302
345
  serial_number=serial_number,
303
- xpmoduletype=xpmoduletype,
346
+ actiontable_type=ActionTableType2.MSACTIONTABLE,
304
347
  )
305
348
  service.start_reactor()
306
349
 
@@ -18,3 +18,16 @@ class ActionTableType(str, Enum):
18
18
  MSACTIONTABLE_XP20 = "msactiontable_xp20"
19
19
  MSACTIONTABLE_XP24 = "msactiontable_xp24"
20
20
  MSACTIONTABLE_XP33 = "msactiontable_xp33"
21
+
22
+
23
+ class ActionTableType2(str, Enum):
24
+ """
25
+ ActionTable types for download/upload operations.
26
+
27
+ Attributes:
28
+ ACTIONTABLE: Standard action table.
29
+ MSACTIONTABLE: MS action table.
30
+ """
31
+
32
+ ACTIONTABLE = "actiontable"
33
+ MSACTIONTABLE = "msactiontable"
@@ -13,7 +13,6 @@ from xp.models.telegram.datapoint_type import DataPointType
13
13
 
14
14
  if TYPE_CHECKING:
15
15
  from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
16
- from xp.services.protocol.conbus_protocol import ConbusProtocol
17
16
  from xp.services.protocol.telegram_protocol import TelegramProtocol
18
17
 
19
18
 
@@ -266,7 +265,7 @@ class TelegramEvent(BaseEvent):
266
265
  checksum_valid: Checksum valid true or false.
267
266
  """
268
267
 
269
- protocol: Union[TelegramProtocol, ConbusProtocol, ConbusEventProtocol] = Field(
268
+ protocol: Union[TelegramProtocol, ConbusEventProtocol] = Field(
270
269
  description="TelegramProtocol instance"
271
270
  )
272
271
  frame: str = Field(description="Frame <S0123450001F02D12FK>")
@@ -5,18 +5,32 @@ from typing import Any, Optional
5
5
 
6
6
  from psygnal import Signal
7
7
 
8
- from xp.models.config.conson_module_config import ConsonModuleListConfig
8
+ from xp.models.actiontable.actiontable_type import ActionTableType2
9
+ from xp.models.config.conson_module_config import (
10
+ ConsonModuleConfig,
11
+ ConsonModuleListConfig,
12
+ )
9
13
  from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
10
14
  from xp.models.telegram.system_function import SystemFunction
11
15
  from xp.models.telegram.telegram_type import TelegramType
12
16
  from xp.services.actiontable.actiontable_serializer import ActionTableSerializer
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
+ )
13
26
  from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
14
27
  from xp.services.telegram.telegram_service import TelegramService
15
28
 
16
29
 
17
30
  class ActionTableUploadService:
18
31
  """
19
- TCP client service for uploading action tables to Conbus modules.
32
+ TCP client service for uploading action tables and MS action tables to Conbus
33
+ modules.
20
34
 
21
35
  Manages TCP socket connections, handles telegram generation and transmission,
22
36
  and processes server responses for action table uploads.
@@ -35,6 +49,9 @@ class ActionTableUploadService:
35
49
  self,
36
50
  conbus_protocol: ConbusEventProtocol,
37
51
  actiontable_serializer: ActionTableSerializer,
52
+ xp20ms_serializer: Xp20MsActionTableSerializer,
53
+ xp24ms_serializer: Xp24MsActionTableSerializer,
54
+ xp33ms_serializer: Xp33MsActionTableSerializer,
38
55
  telegram_service: TelegramService,
39
56
  conson_config: ConsonModuleListConfig,
40
57
  ) -> None:
@@ -44,14 +61,22 @@ class ActionTableUploadService:
44
61
  Args:
45
62
  conbus_protocol: ConbusEventProtocol for communication.
46
63
  actiontable_serializer: Action table serializer.
64
+ xp20ms_serializer: XP20 MS action table serializer.
65
+ xp24ms_serializer: XP24 MS action table serializer.
66
+ xp33ms_serializer: XP33 MS action table serializer.
47
67
  telegram_service: Telegram service for parsing.
48
68
  conson_config: Conson module list configuration.
49
69
  """
50
70
  self.conbus_protocol = conbus_protocol
51
- self.serializer = actiontable_serializer
71
+ self.actiontable_serializer = actiontable_serializer
72
+ self.xp20ms_serializer = xp20ms_serializer
73
+ self.xp24ms_serializer = xp24ms_serializer
74
+ self.xp33ms_serializer = xp33ms_serializer
52
75
  self.telegram_service = telegram_service
53
76
  self.conson_config = conson_config
54
77
  self.serial_number: str = ""
78
+ self.xpmoduletype: str = ""
79
+ self.actiontable_type: ActionTableType2 = ActionTableType2.ACTIONTABLE
55
80
 
56
81
  # Upload state
57
82
  self.upload_data_chunks: list[str] = []
@@ -70,10 +95,17 @@ class ActionTableUploadService:
70
95
  def connection_made(self) -> None:
71
96
  """Handle connection established event."""
72
97
  self.logger.debug("Connection established, sending upload actiontable telegram")
98
+
99
+ system_function = (
100
+ SystemFunction.UPLOAD_ACTIONTABLE
101
+ if self.actiontable_type == ActionTableType2.ACTIONTABLE
102
+ else SystemFunction.UPLOAD_MSACTIONTABLE
103
+ )
104
+
73
105
  self.conbus_protocol.send_telegram(
74
106
  telegram_type=TelegramType.SYSTEM,
75
107
  serial_number=self.serial_number,
76
- system_function=SystemFunction.UPLOAD_ACTIONTABLE,
108
+ system_function=system_function,
77
109
  data_value="00",
78
110
  )
79
111
 
@@ -127,10 +159,16 @@ class ActionTableUploadService:
127
159
  # Second character: 'A' + chunk_index (sequential counter A-O for 15 chunks)
128
160
  prefix_hex = f"AAA{ord('A') + self.current_chunk_index:c}"
129
161
 
162
+ system_function = (
163
+ SystemFunction.ACTIONTABLE
164
+ if self.actiontable_type == ActionTableType2.ACTIONTABLE
165
+ else SystemFunction.MSACTIONTABLE
166
+ )
167
+
130
168
  self.conbus_protocol.send_telegram(
131
169
  telegram_type=TelegramType.SYSTEM,
132
170
  serial_number=self.serial_number,
133
- system_function=SystemFunction.ACTIONTABLE,
171
+ system_function=system_function,
134
172
  data_value=f"{prefix_hex}{chunk}",
135
173
  )
136
174
  self.current_chunk_index += 1
@@ -169,19 +207,24 @@ class ActionTableUploadService:
169
207
  def start(
170
208
  self,
171
209
  serial_number: str,
210
+ actiontable_type: ActionTableType2,
172
211
  timeout_seconds: Optional[float] = None,
173
212
  ) -> None:
174
213
  """
175
- Upload action table to module.
214
+ Upload action table or MS action table to module.
176
215
 
177
216
  Uploads the action table configuration to the specified module.
217
+ Module type will decide which actiontable to use.
178
218
 
179
219
  Args:
180
220
  serial_number: Module serial number.
221
+ actiontable_type: True if actionTable false for MS action table.
181
222
  timeout_seconds: Optional timeout in seconds.
182
223
  """
183
224
  self.logger.info("Starting actiontable upload")
184
225
  self.serial_number = serial_number
226
+ self.actiontable_type = actiontable_type
227
+
185
228
  if timeout_seconds:
186
229
  self.conbus_protocol.timeout_seconds = timeout_seconds
187
230
 
@@ -193,29 +236,65 @@ class ActionTableUploadService:
193
236
 
194
237
  # Parse action table strings to ActionTable object
195
238
  try:
196
- module_action_table = module.action_table or []
197
- action_table = self.serializer.from_short_string(module_action_table)
239
+ encoded_data = self.get_encoded_action_table(module)
240
+ # Chunk the data into 64 byte chunks
241
+ chunk_size = 64
242
+ self.upload_data_chunks = [
243
+ encoded_data[i : i + chunk_size]
244
+ for i in range(0, len(encoded_data), chunk_size)
245
+ ]
246
+ self.current_chunk_index = 0
247
+
198
248
  except ValueError as e:
199
249
  self.logger.error(f"Invalid action table format: {e}")
200
250
  self.failed(f"Invalid action table format: {e}")
201
251
  return
202
252
 
203
- # Encode action table to hex string
204
- encoded_data = self.serializer.to_encoded_string(action_table)
205
-
206
- # Chunk the data into 64 byte chunks
207
- chunk_size = 64
208
- self.upload_data_chunks = [
209
- encoded_data[i : i + chunk_size]
210
- for i in range(0, len(encoded_data), chunk_size)
211
- ]
212
- self.current_chunk_index = 0
213
-
214
253
  self.logger.debug(
215
254
  f"Upload data encoded: {len(encoded_data)} chars, "
216
255
  f"{len(self.upload_data_chunks)} chunks"
217
256
  )
218
257
 
258
+ def get_encoded_action_table(self, module: ConsonModuleConfig) -> str:
259
+ """
260
+ Get encoded action table string for upload.
261
+
262
+ Args:
263
+ module: Module configuration containing action table data.
264
+
265
+ Returns:
266
+ Hex-encoded action table string ready for transmission.
267
+ """
268
+ msactiontable = (
269
+ True if self.actiontable_type == ActionTableType2.MSACTIONTABLE else False
270
+ )
271
+ # Parse MS action table from short format (first element)
272
+ if msactiontable and module.module_type.lower() == "xp20":
273
+ xp20_short_table = module.xp20_msaction_table or []
274
+ xp20_actiontable = self.xp20ms_serializer.from_short_string(
275
+ xp20_short_table
276
+ )
277
+ encoded_string = self.xp20ms_serializer.to_encoded_string(xp20_actiontable)
278
+ elif msactiontable and module.module_type.lower() == "xp24":
279
+ xp24_short_table = module.xp24_msaction_table or []
280
+ xp24_actiontable = self.xp24ms_serializer.from_short_string(
281
+ xp24_short_table
282
+ )
283
+ encoded_string = self.xp24ms_serializer.to_encoded_string(xp24_actiontable)
284
+ elif msactiontable and module.module_type.lower() == "xp33":
285
+ xp33_short_table = module.xp33_msaction_table or []
286
+ xp33_actiontable = self.xp33ms_serializer.from_short_string(
287
+ xp33_short_table
288
+ )
289
+ encoded_string = self.xp33ms_serializer.to_encoded_string(xp33_actiontable)
290
+ else:
291
+ short_table = module.action_table or []
292
+ actiontable = self.actiontable_serializer.from_short_string(short_table)
293
+ encoded_string = self.actiontable_serializer.to_encoded_string(actiontable)
294
+
295
+ # Serialize to telegram data (64 characters: AAAA + 64 data chars)
296
+ return encoded_string
297
+
219
298
  def set_timeout(self, timeout_seconds: float) -> None:
220
299
  """
221
300
  Set operation timeout.
@@ -243,6 +322,7 @@ class ActionTableUploadService:
243
322
  self.upload_data_chunks = []
244
323
  self.current_chunk_index = 0
245
324
  self.serial_number = ""
325
+ self.xpmoduletype = ""
246
326
  return self
247
327
 
248
328
  def __exit__(self, _exc_type: Any, _exc_val: Any, _exc_tb: Any) -> None:
@@ -25,7 +25,7 @@ class ConbusDiscoverService:
25
25
  """
26
26
  Service for discovering modules on Conbus servers.
27
27
 
28
- Uses ConbusProtocol to provide discovery functionality for finding
28
+ Uses ConbusEventProtocol to provide discovery functionality for finding
29
29
  modules connected to the Conbus network.
30
30
 
31
31
  Attributes:
@@ -45,7 +45,7 @@ class ConbusDiscoverService:
45
45
  Initialize the Conbus discover service.
46
46
 
47
47
  Args:
48
- conbus_protocol: ConbusProtocol.
48
+ conbus_protocol: ConbusEventProtocol instance for communication.
49
49
  """
50
50
  self.conbus_protocol: ConbusEventProtocol = conbus_protocol
51
51
  self.conbus_protocol.on_connection_made.connect(self.connection_made)
@@ -8,12 +8,11 @@ from xp.models.protocol.conbus_protocol import (
8
8
  TelegramReceivedEvent,
9
9
  )
10
10
  from xp.services.protocol.conbus_event_protocol import ConbusEventProtocol
11
- from xp.services.protocol.conbus_protocol import ConbusProtocol
12
11
  from xp.services.protocol.telegram_protocol import TelegramProtocol
13
12
 
14
- __all__ = ["TelegramProtocol", "ConbusProtocol", "ConbusEventProtocol"]
13
+ __all__ = ["TelegramProtocol", "ConbusEventProtocol"]
15
14
 
16
- # Rebuild models after TelegramProtocol and ConbusProtocol are imported to resolve forward references
15
+ # Rebuild models after TelegramProtocol and ConbusEventProtocol are imported to resolve forward references
17
16
  ConnectionMadeEvent.model_rebuild()
18
17
  InvalidTelegramReceivedEvent.model_rebuild()
19
18
  ModuleDiscoveredEvent.model_rebuild()
@@ -98,7 +98,7 @@ class ConbusEventProtocol(protocol.Protocol, protocol.ClientFactory):
98
98
  telegram_service: TelegramService,
99
99
  ) -> None:
100
100
  """
101
- Initialize ConbusProtocol.
101
+ Initialize ConbusEventProtocol.
102
102
 
103
103
  Args:
104
104
  cli_config: Configuration for Conbus client connection.
xp/utils/dependencies.py CHANGED
@@ -51,9 +51,6 @@ from xp.services.conbus.conbus_output_service import ConbusOutputService
51
51
  from xp.services.conbus.conbus_raw_service import ConbusRawService
52
52
  from xp.services.conbus.conbus_receive_service import ConbusReceiveService
53
53
  from xp.services.conbus.conbus_scan_service import ConbusScanService
54
- from xp.services.conbus.msactiontable.msactiontable_upload_service import (
55
- MsActionTableUploadService,
56
- )
57
54
  from xp.services.conbus.write_config_service import WriteConfigService
58
55
  from xp.services.homekit.homekit_cache_service import HomeKitCacheService
59
56
  from xp.services.homekit.homekit_conbus_service import HomeKitConbusService
@@ -336,6 +333,9 @@ class ServiceContainer:
336
333
  factory=lambda: ActionTableUploadService(
337
334
  conbus_protocol=self.container.resolve(ConbusEventProtocol),
338
335
  actiontable_serializer=self.container.resolve(ActionTableSerializer),
336
+ xp20ms_serializer=self.container.resolve(Xp20MsActionTableSerializer),
337
+ xp24ms_serializer=self.container.resolve(Xp24MsActionTableSerializer),
338
+ xp33ms_serializer=self.container.resolve(Xp33MsActionTableSerializer),
339
339
  telegram_service=self.container.resolve(TelegramService),
340
340
  conson_config=self.container.resolve(ConsonModuleListConfig),
341
341
  ),
@@ -372,37 +372,6 @@ class ServiceContainer:
372
372
  scope=punq.Scope.singleton,
373
373
  )
374
374
 
375
- self.container.register(
376
- ActionTableDownloadService,
377
- factory=lambda: ActionTableDownloadService(
378
- conbus_protocol=self.container.resolve(ConbusEventProtocol),
379
- actiontable_serializer=self.container.resolve(ActionTableSerializer),
380
- msactiontable_serializer_xp20=self.container.resolve(
381
- Xp20MsActionTableSerializer
382
- ),
383
- msactiontable_serializer_xp24=self.container.resolve(
384
- Xp24MsActionTableSerializer
385
- ),
386
- msactiontable_serializer_xp33=self.container.resolve(
387
- Xp33MsActionTableSerializer
388
- ),
389
- ),
390
- scope=punq.Scope.singleton,
391
- )
392
-
393
- self.container.register(
394
- MsActionTableUploadService,
395
- factory=lambda: MsActionTableUploadService(
396
- conbus_protocol=self.container.resolve(ConbusEventProtocol),
397
- xp20ms_serializer=self.container.resolve(Xp20MsActionTableSerializer),
398
- xp24ms_serializer=self.container.resolve(Xp24MsActionTableSerializer),
399
- xp33ms_serializer=self.container.resolve(Xp33MsActionTableSerializer),
400
- telegram_service=self.container.resolve(TelegramService),
401
- conson_config=self.container.resolve(ConsonModuleListConfig),
402
- ),
403
- scope=punq.Scope.singleton,
404
- )
405
-
406
375
  self.container.register(
407
376
  ConbusCustomService,
408
377
  factory=lambda: ConbusCustomService(