conson-xp 0.11.21__py3-none-any.whl → 1.1.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: 0.11.21
3
+ Version: 1.1.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-0.11.21.dist-info/METADATA,sha256=HwBfLHuKhBtOi-5wmg081HGTAng6BXa2E8W-hkfzkXU,9298
2
- conson_xp-0.11.21.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- conson_xp-0.11.21.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
- conson_xp-0.11.21.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
- xp/__init__.py,sha256=Yo_o4SM3_458AZhuCwUhwwY3C5xsGcGv2-pF3Z-8Fhs,177
1
+ conson_xp-1.1.0.dist-info/METADATA,sha256=KNX3bIZASGxhb2Jhka3QNunZP3mYShzXHmoq1KwMMJ8,9296
2
+ conson_xp-1.1.0.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ conson_xp-1.1.0.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
+ conson_xp-1.1.0.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
+ xp/__init__.py,sha256=xf8lEjT8dAYyPp5o_Owqe-WYUCt94T7RPlhhUrh5Tr0,175
6
6
  xp/api/__init__.py,sha256=fCWjkuTzDlyJ8hIpU_QEBNcah3BB2bqVSfZwmP4ee5k,51
7
7
  xp/api/main.py,sha256=8OMXUYKnpsqjjnLChokC_M0DXZy-whrxY2dU4QTvr8A,3389
8
8
  xp/api/models/__init__.py,sha256=Xl8j2qiHc-Vb8b1ZmNZaMj7RtMvk0G_2SOvMgQumYzs,54
@@ -25,17 +25,17 @@ xp/cli/commands/conbus/conbus.py,sha256=fVLbAg0kuodUdx9RfE4vVR3L_bc8liDP2cOEyup7
25
25
  xp/cli/commands/conbus/conbus_actiontable_commands.py,sha256=CjJKFTB_oHENKY165j0lQBBndf9S36K-ykogv7kSppQ,1436
26
26
  xp/cli/commands/conbus/conbus_autoreport_commands.py,sha256=EfCLZhuDu8uXDVGKE1eJ5Ji9mUauJLoGXqP4zFn2LhA,2501
27
27
  xp/cli/commands/conbus/conbus_blink_commands.py,sha256=g2zGEXce2aTReCCNp7ph0-uI7YhWEgz_Z048-3YC36w,3696
28
- xp/cli/commands/conbus/conbus_config_commands.py,sha256=MBLt7Z95-v2Drvr80r4HQxx8PMmq9rA5odl60IF3j7A,897
28
+ xp/cli/commands/conbus/conbus_config_commands.py,sha256=Wphy_gxjc5pdPRzw8ElHC3G1jLxoUqmIBe-MFL54LN8,593
29
29
  xp/cli/commands/conbus/conbus_custom_commands.py,sha256=NH8WDm31-7tb-KYH8nZprEXgo8a4asLWmNd0EgJVSHQ,1336
30
30
  xp/cli/commands/conbus/conbus_datapoint_commands.py,sha256=Ozc36DFKVfzDZyWU9xVdhebiYy8yodb_DgVKEpzK9Jg,2842
31
31
  xp/cli/commands/conbus/conbus_discover_commands.py,sha256=5HwuhlC3qyYJqLBuqQVyu5kr493BJOZ281V2pXtfoCY,961
32
32
  xp/cli/commands/conbus/conbus_lightlevel_commands.py,sha256=hMzQewTgqGNB6s_Pag2HNfImhpgXnitwUVgMM6XXJv8,4161
33
- xp/cli/commands/conbus/conbus_linknumber_commands.py,sha256=Q8hh222Gq7xDD-dRvwS4tiLQj3l913n-Vk1J73QxGGc,1954
33
+ xp/cli/commands/conbus/conbus_linknumber_commands.py,sha256=IQ_DjBoUOYSkP5JxUuJYaKdxjwcOWGUZz7R-6sFeAAk,2256
34
34
  xp/cli/commands/conbus/conbus_msactiontable_commands.py,sha256=n1g-ZKjjjbCQqTPGCrcCB595QoRClv0DGvGEx8y7BAY,1728
35
- xp/cli/commands/conbus/conbus_output_commands.py,sha256=B_N31H4uBjahBxr6VNsj_bnsJsqkQc4CTIofDBKY4v8,2885
35
+ xp/cli/commands/conbus/conbus_output_commands.py,sha256=Y98-ibcgGB_L52VtczyJqtkGLKESzZjeGvwdLdwM35E,3900
36
36
  xp/cli/commands/conbus/conbus_raw_commands.py,sha256=NRST1cg9tO7zVUwiTKqCBpwfwP1-yvnKTDrwwIMaz68,1572
37
37
  xp/cli/commands/conbus/conbus_receive_commands.py,sha256=jV5zAmiIKK3_oDpTs9yF1YklIRcJNvOrkI6O2deb1eQ,1380
38
- xp/cli/commands/conbus/conbus_scan_commands.py,sha256=HjZMhU1hPRuUSWMURB9UUeZt8aNMDlBYCktwrXUgsCY,4190
38
+ xp/cli/commands/conbus/conbus_scan_commands.py,sha256=5SeRL-RZaXkqgKEGA4wt9zayS8GHiPU3yMHBb1kNfj8,1329
39
39
  xp/cli/commands/file_commands.py,sha256=YEkho5HU5-SEVqTKKWoYPYXI0qWDr9PZaAuEt8fIXak,4855
40
40
  xp/cli/commands/homekit/__init__.py,sha256=qqwY8ulxTx1S74Mzpb6EKjBLT6fWTNdf9PQ3HKuERKY,50
41
41
  xp/cli/commands/homekit/homekit.py,sha256=EOaGvXybNlxYxRr4gtml7OtRWbOIV5wVaYfMrpIFJk4,3355
@@ -71,7 +71,7 @@ xp/models/actiontable/msactiontable_xp20.py,sha256=JNi2gx0ObbEZ-qq-MNECc4zoCypDp
71
71
  xp/models/actiontable/msactiontable_xp24.py,sha256=edDG2wCf1IFgUPm4qnfB9GlXHagf5T6JgCLRVJEfBDw,1390
72
72
  xp/models/actiontable/msactiontable_xp33.py,sha256=vYXJnyqnazUQ_6lkoDnDVh31bo-Mq6-6tQOnYiC766Y,1101
73
73
  xp/models/conbus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
- xp/models/conbus/conbus.py,sha256=Su2NKXizapeN3-mEMpCXDNii7TfZB3p3cAfWSmPpSC4,1763
74
+ xp/models/conbus/conbus.py,sha256=ePdihpX2w-A3t-nrvOpWVNwNoS4cDRJ9jpVvhEM_Jwg,1735
75
75
  xp/models/conbus/conbus_autoreport.py,sha256=dx9CzlDwDWrLkyvfVsz4dKFouiCl4YcQ80rue97Zfbk,1652
76
76
  xp/models/conbus/conbus_blink.py,sha256=xwe8A-C1ywbLKYARRUwUEX0sq6QALQiv1C8R3RyQOSM,2196
77
77
  xp/models/conbus/conbus_client_config.py,sha256=HVaGZkhZI6cBpJaEgybq8TFARyrI9-dM6U6IPc2hOKQ,940
@@ -80,7 +80,7 @@ xp/models/conbus/conbus_custom.py,sha256=hjzL7n5eIWfascyWNA2F6L3W5nnG4JgzAz2wL_c
80
80
  xp/models/conbus/conbus_datapoint.py,sha256=t41goYkzDf7booC6yBbvlYgX-nH5H0-YE7Yb-JncXJ4,2525
81
81
  xp/models/conbus/conbus_discover.py,sha256=lLwWkQYMZXMc0cbjx8oFfippE0aFWjfapgfOBIGkMlc,1087
82
82
  xp/models/conbus/conbus_lightlevel.py,sha256=A4DYVejsTa3_SR37oFfG4XNRqjbOKCDbmHg_vA8PqVM,1091
83
- xp/models/conbus/conbus_linknumber.py,sha256=iN5Aa5MaEl1ClIHvCLrcSKN_aFhzVywNU6f2XtPMw6o,1198
83
+ xp/models/conbus/conbus_linknumber.py,sha256=IaA-Lk6o3KQoEvxcYf9cWNpVdjkzOZIQSPVOylzqCWU,1198
84
84
  xp/models/conbus/conbus_output.py,sha256=tXAAJqySzbpHJauDEQf8PCYP_hbz31NK5bFs6GUJu_U,1238
85
85
  xp/models/conbus/conbus_raw.py,sha256=kP_w9_e-qHv-2cDMm4_nAa1g3G8GFlrxOiYXR5IOq8o,994
86
86
  xp/models/conbus/conbus_receive.py,sha256=hVI3CEGQ74UqqLVH8RhlQvOVtmqlcmeI2kWVY1CPPCI,896
@@ -118,23 +118,22 @@ xp/services/conbus/actiontable/msactiontable_service.py,sha256=89pxbUVlKd6mplpIe
118
118
  xp/services/conbus/actiontable/msactiontable_xp20_serializer.py,sha256=EYspooOdi0Z8oaXGxpazwnUoTmh-d7U9auhu11iBgmU,6527
119
119
  xp/services/conbus/actiontable/msactiontable_xp24_serializer.py,sha256=J_ve6uyMmsb_QT2Py1ciZngf4C0pfHpkbWFc8OL2QEk,3752
120
120
  xp/services/conbus/actiontable/msactiontable_xp33_serializer.py,sha256=AeGBbum5eIqlgVm9t4igfF6vyl-ACVpuzSUQm4TYfUQ,7962
121
- xp/services/conbus/conbus_autoreport_get_service.py,sha256=mNWFOt0-Ahx5N_Ayyq4oa-rdf2Xcu4rwz7erIjfdNBg,5206
121
+ xp/services/conbus/conbus_autoreport_get_service.py,sha256=Jzu8tBIwt9nb9X60LcWnV72wblpVJCZjyfPb45kkCtA,3165
122
122
  xp/services/conbus/conbus_autoreport_set_service.py,sha256=0fa2xGVE1GSoBvEcOH8cnjAdhvEoamvHE27t40f7lUk,4937
123
123
  xp/services/conbus/conbus_blink_all_service.py,sha256=t_oaztEFRirjS3nL50AEBrKKpNXYssWwSBwWjWhhKqU,5959
124
124
  xp/services/conbus/conbus_blink_service.py,sha256=mHaD-84RCmEGqD2cD4Ve85A36D08tMBPwMgDEyAEMCc,5031
125
- xp/services/conbus/conbus_connection_pool.py,sha256=uiuuZ1S2_BBg6sTWqWIStCPFnWJjsfi2PuD53DalPv8,5616
126
125
  xp/services/conbus/conbus_custom_service.py,sha256=jM6B085GTT8epCE9EqVTT8mZLPMXM3tVwvO-yJulJ5s,5290
127
126
  xp/services/conbus/conbus_datapoint_queryall_service.py,sha256=FBpFmwXVKoTiqMwQW-z2eYbamKL_ZGlTI86720ZcGt8,6095
128
- xp/services/conbus/conbus_datapoint_service.py,sha256=CspxjhEi8awX_dv6EpJpYjTtCsfLgjJ4ROl6jD1TOiY,5289
127
+ xp/services/conbus/conbus_datapoint_service.py,sha256=YpInc-Wq4pIjy6ksTWE2mdBSeGWU-VxUNEVyYUi07jM,5577
129
128
  xp/services/conbus/conbus_discover_service.py,sha256=kA_ewxXgbqXng0cXBjSgQSGYesyesbN2wK0tMp1fgfc,4281
130
- xp/services/conbus/conbus_lightlevel_get_service.py,sha256=vrr5HhR5l58oOezTz2rorO-RHoyGbVuHrx2rGfKvH20,5739
129
+ xp/services/conbus/conbus_lightlevel_get_service.py,sha256=Z7Pg_c0sI6gMNnoThN7DruEOGyM3-i4D-rO2WKfHXjw,3699
131
130
  xp/services/conbus/conbus_lightlevel_set_service.py,sha256=6Mhq9xjWx-ixGVfcWBcJSnuYT256m8Lps1g8Tg-1nkM,7483
132
- xp/services/conbus/conbus_linknumber_service.py,sha256=r3Lyb7IV4i5kRY6zTnRK9jmC1vo8dpyHwh4WwdwrlL4,7703
133
- xp/services/conbus/conbus_output_service.py,sha256=_sHGF6AWadhT_CNSnRPaXwQLaNEwQHSVuyKtyZ9jgFc,5115
131
+ xp/services/conbus/conbus_linknumber_get_service.py,sha256=debaacIbwFLUkXwhG0cJ9Wh31rzmWEmd_o1YC9PvpBY,3195
132
+ xp/services/conbus/conbus_linknumber_set_service.py,sha256=cmCP8zZ8Szb-vwYHvDbZUyEfZJOjO_zSptJUZhHRctQ,6019
133
+ xp/services/conbus/conbus_output_service.py,sha256=w2yBeMdZn3g3wbwUoUnv3gKbqUuGcabeEaH8qw1AyUs,6689
134
134
  xp/services/conbus/conbus_raw_service.py,sha256=riANTAiXTdSzOWbp_g-IQjdRhAf8CzZnNJtlT-aDvRs,3746
135
135
  xp/services/conbus/conbus_receive_service.py,sha256=k6hzxh-D4piizb3e5Vsz-2Mfft_5KnAXoov4xk9wVY0,3123
136
- xp/services/conbus/conbus_scan_service.py,sha256=uDI4rRAeBMg4Z5gdO0Evn-ejEoPpB5X4FTxMpfKTw78,4025
137
- xp/services/conbus/conbus_service.py,sha256=MdT01cE_KjAqx6gZOiL0k6z9dPBd-CG19wiKrK8GqB4,10873
136
+ xp/services/conbus/conbus_scan_service.py,sha256=faiSeaNGYRPb9qWsmFE4cjiz3Tkv6vQVZHdwIlPzU9s,4494
138
137
  xp/services/homekit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
138
  xp/services/homekit/homekit_cache_service.py,sha256=XMZBTz2ZVTq8OZM3h0Fxu738XPlPRdvq6JLaWMbAS4Q,10289
140
139
  xp/services/homekit/homekit_conbus_service.py,sha256=71JeM-phBTiGMRr2bEfCiF85eHNIzmxtkCi2Zn0B5uA,2595
@@ -152,7 +151,7 @@ xp/services/homekit/homekit_service.py,sha256=yksnbcqbrckxWTqtJkaaPh_wd2xYH9yCOt
152
151
  xp/services/log_file_service.py,sha256=E2CSVbw5W_uk13efILb6OGqeERbxCBWjIsCbHjeps_0,10401
153
152
  xp/services/module_type_service.py,sha256=Q3TFZdiknF24OqGAP6Op1F8_SL8aslkHwPh6o_M7wxM,7010
154
153
  xp/services/protocol/__init__.py,sha256=XUj54if_nJTfqrEDZfj40nfLr-2xjfKm4CIgHMabp-o,719
155
- xp/services/protocol/conbus_protocol.py,sha256=a-R7WCRJ9YOk64VJnrKdR_Hef-53JY2PTIaDQx5nRIQ,7514
154
+ xp/services/protocol/conbus_protocol.py,sha256=ePDP3O-xmEFROaOJ-2ndSUpN0TMrVGhodWT66spfdlE,7676
156
155
  xp/services/protocol/protocol_factory.py,sha256=c3CkMoWAuk9lmHdXIG51B5-S0aIaB7-mHuyULyr_jS4,1248
157
156
  xp/services/protocol/telegram_protocol.py,sha256=4mybR5gFreN_Kxw04fujt1gKIvr3Mg6O_6WwoTXe2i8,8568
158
157
  xp/services/reverse_proxy_service.py,sha256=OIPm-9y2I-xf1tESZBfgiLd_hgfGQdgrsxAFdhotmJ0,13231
@@ -175,8 +174,8 @@ xp/services/telegram/telegram_service.py,sha256=Mp20QB50WDp43QBl8TzsR9BKV_hHP53R
175
174
  xp/services/telegram/telegram_version_service.py,sha256=21v256THg0lidTyUtp2i8r6TAl8J0CTaZo4bZw59nFk,10479
176
175
  xp/utils/__init__.py,sha256=clisBctja_VwtkAM9wnbOGDRPfbKHlCUqq4Sa4Z6zng,331
177
176
  xp/utils/checksum.py,sha256=HDpiQxmdIedbCbZ4o_Box0i_Zig417BtCV_46ZyhiTk,1711
178
- xp/utils/dependencies.py,sha256=VztcJM27MA6mykoVuX84zXMRsmKYuSGsVOKu5Gaw0b4,20490
177
+ xp/utils/dependencies.py,sha256=PbdI30ug3JCNn1IS9B1jGDEq5wQ_3hDrTLE2Pr-f7AA,19602
179
178
  xp/utils/event_helper.py,sha256=W-A_xmoXlpWZBbJH6qdaN50o3-XrwFsDgvAGMJDiAgo,1001
180
179
  xp/utils/serialization.py,sha256=hZcrpzaBOe3a2wS_RFCIRs9PvnYsrbK7Ulq6s1rU0q4,4456
181
180
  xp/utils/time_utils.py,sha256=Yi3JxHrHsd9ZZxTBRIqlTOz1FYTCeE1IZbefDaXIop8,3800
182
- conson_xp-0.11.21.dist-info/RECORD,,
181
+ conson_xp-1.1.0.dist-info/RECORD,,
xp/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  """conson-xp"""
4
4
 
5
- __version__ = "0.11.21"
5
+ __version__ = "1.1.0"
6
6
  __manufacturer__ = "salchichon"
7
7
  __model__ = "xp.cli"
8
8
  __serial__ = "2025.09.23.000"
@@ -5,9 +5,7 @@ from click import Context
5
5
 
6
6
  from xp.cli.commands.conbus.conbus import conbus
7
7
  from xp.cli.utils.decorators import handle_service_errors
8
- from xp.cli.utils.error_handlers import CLIErrorHandler
9
- from xp.cli.utils.formatters import OutputFormatter
10
- from xp.services.conbus.conbus_service import ConbusService
8
+ from xp.models import ConbusClientConfig
11
9
 
12
10
 
13
11
  @conbus.command("config")
@@ -22,12 +20,5 @@ def show_config(ctx: Context) -> None:
22
20
  \b
23
21
  xp conbus config
24
22
  """
25
- service = ctx.obj.get("container").get_container().resolve(ConbusService)
26
- OutputFormatter(True)
27
-
28
- try:
29
- config = service.get_config()
30
- click.echo(json.dumps(config.conbus.model_dump(mode="json"), indent=2))
31
-
32
- except Exception as e:
33
- CLIErrorHandler.handle_service_error(e, "configuration retrieval")
23
+ config = ctx.obj.get("container").get_container().resolve(ConbusClientConfig)
24
+ click.echo(json.dumps(config.conbus.model_dump(mode="json"), indent=2))
@@ -7,11 +7,11 @@ import click
7
7
  from xp.cli.commands.conbus.conbus import conbus_linknumber
8
8
  from xp.cli.utils.decorators import (
9
9
  connection_command,
10
- handle_service_errors,
11
10
  )
12
11
  from xp.cli.utils.serial_number_type import SERIAL
13
- from xp.services.conbus.conbus_linknumber_service import ConbusLinknumberService
14
- from xp.services.telegram.telegram_link_number_service import LinkNumberError
12
+ from xp.models.conbus.conbus_linknumber import ConbusLinknumberResponse
13
+ from xp.services.conbus.conbus_linknumber_get_service import ConbusLinknumberGetService
14
+ from xp.services.conbus.conbus_linknumber_set_service import ConbusLinknumberSetService
15
15
 
16
16
 
17
17
  @conbus_linknumber.command("set", short_help="Set link number for a module")
@@ -19,7 +19,6 @@ from xp.services.telegram.telegram_link_number_service import LinkNumberError
19
19
  @click.argument("link_number", type=click.IntRange(0, 99))
20
20
  @click.pass_context
21
21
  @connection_command()
22
- @handle_service_errors(LinkNumberError)
23
22
  def set_linknumber_command(
24
23
  ctx: click.Context, serial_number: str, link_number: int
25
24
  ) -> None:
@@ -34,18 +33,25 @@ def set_linknumber_command(
34
33
  \b
35
34
  xp conbus linknumber set 0123450001 25
36
35
  """
37
- service = ctx.obj.get("container").get_container().resolve(ConbusLinknumberService)
36
+ service = (
37
+ ctx.obj.get("container").get_container().resolve(ConbusLinknumberSetService)
38
+ )
38
39
 
39
- with service:
40
- response = service.set_linknumber(serial_number, link_number)
40
+ def on_finish(response: ConbusLinknumberResponse) -> None:
41
41
  click.echo(json.dumps(response.to_dict(), indent=2))
42
42
 
43
+ with service:
44
+ service.set_linknumber(
45
+ serial_number=serial_number,
46
+ link_number=link_number,
47
+ finish_callback=on_finish,
48
+ )
49
+
43
50
 
44
51
  @conbus_linknumber.command("get", short_help="Get link number for a module")
45
52
  @click.argument("serial_number", type=SERIAL)
46
53
  @click.pass_context
47
54
  @connection_command()
48
- @handle_service_errors(LinkNumberError)
49
55
  def get_linknumber_command(ctx: click.Context, serial_number: str) -> None:
50
56
  """
51
57
  Get the current link number for a specific module.
@@ -57,8 +63,15 @@ def get_linknumber_command(ctx: click.Context, serial_number: str) -> None:
57
63
  \b
58
64
  xp conbus linknumber get 0123450001
59
65
  """
60
- service = ctx.obj.get("container").get_container().resolve(ConbusLinknumberService)
66
+ service = (
67
+ ctx.obj.get("container").get_container().resolve(ConbusLinknumberGetService)
68
+ )
61
69
 
62
- with service:
63
- response = service.get_linknumber(serial_number)
70
+ def on_finish(response: ConbusLinknumberResponse) -> None:
64
71
  click.echo(json.dumps(response.to_dict(), indent=2))
72
+
73
+ with service:
74
+ service.get_linknumber(
75
+ serial_number=serial_number,
76
+ finish_callback=on_finish,
77
+ )
@@ -9,7 +9,11 @@ from xp.cli.utils.decorators import (
9
9
  connection_command,
10
10
  )
11
11
  from xp.cli.utils.serial_number_type import SERIAL
12
+ from xp.models import ConbusDatapointResponse
13
+ from xp.models.conbus.conbus_output import ConbusOutputResponse
12
14
  from xp.models.telegram.action_type import ActionType
15
+ from xp.models.telegram.datapoint_type import DataPointType
16
+ from xp.services.conbus.conbus_datapoint_service import ConbusDatapointService
13
17
  from xp.services.conbus.conbus_output_service import ConbusOutputService
14
18
 
15
19
 
@@ -24,16 +28,20 @@ def xp_output_on(ctx: click.Context, serial_number: str, output_number: int) ->
24
28
  Examples:
25
29
 
26
30
  \b
27
- xp conbus input on 0011223344 0 # Toggle input 0
31
+ xp conbus output on 0011223344 0 # Turn on output 0
28
32
  """
29
33
  service = ctx.obj.get("container").get_container().resolve(ConbusOutputService)
30
34
 
31
- with service:
35
+ def on_finish(response: ConbusOutputResponse) -> None:
36
+ click.echo(json.dumps(response.to_dict(), indent=2))
32
37
 
33
- response = service.send_action(
34
- serial_number, output_number, ActionType.ON_RELEASE
38
+ with service:
39
+ service.send_action(
40
+ serial_number=serial_number,
41
+ output_number=output_number,
42
+ action_type=ActionType.ON_RELEASE,
43
+ finish_callback=on_finish,
35
44
  )
36
- click.echo(json.dumps(response.to_dict(), indent=2))
37
45
 
38
46
 
39
47
  @conbus_output.command("off")
@@ -47,16 +55,20 @@ def xp_output_off(ctx: click.Context, serial_number: str, output_number: int) ->
47
55
  Examples:
48
56
 
49
57
  \b
50
- xp conbus input off 0011223344 1 # Toggle input 1
58
+ xp conbus output off 0011223344 1 # Turn off output 1
51
59
  """
52
60
  service = ctx.obj.get("container").get_container().resolve(ConbusOutputService)
53
61
 
54
- with service:
62
+ def on_finish(response: ConbusOutputResponse) -> None:
63
+ click.echo(json.dumps(response.to_dict(), indent=2))
55
64
 
56
- response = service.send_action(
57
- serial_number, output_number, ActionType.OFF_PRESS
65
+ with service:
66
+ service.send_action(
67
+ serial_number=serial_number,
68
+ output_number=output_number,
69
+ action_type=ActionType.OFF_PRESS,
70
+ finish_callback=on_finish,
58
71
  )
59
- click.echo(json.dumps(response.to_dict(), indent=2))
60
72
 
61
73
 
62
74
  @conbus_output.command("status")
@@ -71,13 +83,20 @@ def xp_output_status(ctx: click.Context, serial_number: str) -> None:
71
83
  \b
72
84
  xp conbus output status 0011223344 # Query output status
73
85
  """
74
- service = ctx.obj.get("container").get_container().resolve(ConbusOutputService)
75
-
76
- with service:
86
+ service: ConbusDatapointService = (
87
+ ctx.obj.get("container").get_container().resolve(ConbusDatapointService)
88
+ )
77
89
 
78
- response = service.get_output_state(serial_number)
90
+ def on_finish(response: ConbusDatapointResponse) -> None:
79
91
  click.echo(json.dumps(response.to_dict(), indent=2))
80
92
 
93
+ with service:
94
+ service.query_datapoint(
95
+ serial_number=serial_number,
96
+ datapoint_type=DataPointType.MODULE_OUTPUT_STATE,
97
+ finish_callback=on_finish,
98
+ )
99
+
81
100
 
82
101
  @conbus_output.command("state")
83
102
  @click.argument("serial_number", type=SERIAL)
@@ -91,9 +110,16 @@ def xp_module_state(ctx: click.Context, serial_number: str) -> None:
91
110
  \b
92
111
  xp conbus output state 0011223344 # Query module state
93
112
  """
94
- service = ctx.obj.get("container").get_container().resolve(ConbusOutputService)
113
+ service: ConbusDatapointService = (
114
+ ctx.obj.get("container").get_container().resolve(ConbusDatapointService)
115
+ )
95
116
 
96
- with service:
97
-
98
- response = service.get_module_state(serial_number)
117
+ def on_finish(response: ConbusDatapointResponse) -> None:
99
118
  click.echo(json.dumps(response.to_dict(), indent=2))
119
+
120
+ with service:
121
+ service.query_datapoint(
122
+ serial_number=serial_number,
123
+ datapoint_type=DataPointType.MODULE_STATE,
124
+ finish_callback=on_finish,
125
+ )
@@ -1,7 +1,6 @@
1
1
  """Conbus client operations CLI commands."""
2
2
 
3
3
  import json
4
- import threading
5
4
 
6
5
  import click
7
6
  from click import Context
@@ -16,18 +15,9 @@ from xp.services.conbus.conbus_scan_service import ConbusScanService
16
15
  @conbus.command("scan")
17
16
  @click.argument("serial_number", type=SERIAL)
18
17
  @click.argument("function_code", type=str)
19
- @click.option(
20
- "--background",
21
- "-b",
22
- default=True,
23
- is_flag=True,
24
- help="Run scan in background with live output",
25
- )
26
18
  @click.pass_context
27
19
  @connection_command()
28
- def scan_module(
29
- ctx: Context, serial_number: str, function_code: str, background: bool
30
- ) -> None:
20
+ def scan_module(ctx: Context, serial_number: str, function_code: str) -> None:
31
21
  """
32
22
  Scan all datapoints of a function_code for a module.
33
23
 
@@ -36,90 +26,20 @@ def scan_module(
36
26
  \b
37
27
  xp conbus scan 0012345011 02 # Scan all datapoints of function Read data points (02)
38
28
  """
39
- service = ctx.obj.get("container").get_container().resolve(ConbusScanService)
40
-
41
- # Shared state for results collection and live output
42
- results = []
43
- successful_count = 0
44
- failed_count = 0
45
-
46
- def progress_callback(response: ConbusResponse, total: int, count: int) -> None:
47
- nonlocal successful_count, failed_count
48
- results.append(response)
49
-
50
- if count % 10 == 0:
51
- click.echo(f"{count}/{total} datapoints scanned.")
52
-
53
- # Count results for JSON output
54
- if response.success:
55
- successful_count += 1
56
- else:
57
- failed_count += 1
58
-
59
- try:
60
- with service:
61
- if background:
62
- # Background processing
63
-
64
- # Use background scanning with progress callback
65
- scan_complete = threading.Event()
66
-
67
- def background_scan() -> None:
68
- try:
69
- service.scan_module(
70
- serial_number, function_code, progress_callback
71
- )
72
- except (ValueError, KeyError, ConnectionError):
73
- pass # Will be handled by outer error handling
74
- finally:
75
- scan_complete.set()
76
-
77
- # Start background thread
78
- scan_thread = threading.Thread(target=background_scan, daemon=True)
79
- scan_thread.start()
80
-
81
- # Wait for completion or user interrupt
82
- try:
83
- while not scan_complete.is_set():
84
- scan_complete.wait(1.0) # Check every second
85
- except KeyboardInterrupt:
86
- # Output partial results in JSON format
87
- output = {
88
- "serial_number": serial_number,
89
- "total_scans": len(results),
90
- "successful_scans": successful_count,
91
- "failed_scans": failed_count,
92
- "background_mode": background,
93
- "interrupted": True,
94
- "results": [result.to_dict() for result in results],
95
- }
96
- click.echo(json.dumps(output, indent=2))
97
- raise click.Abort()
98
-
99
- # Wait for thread to complete
100
- scan_thread.join(timeout=1.0)
101
-
102
- else:
103
- # Traditional synchronous scanning
104
- results = service.scan_module(
105
- serial_number,
106
- function_code,
107
- progress_callback,
108
- )
109
- successful_count = len([r for r in results if r.success])
110
- failed_count = len([r for r in results if not r.success])
111
-
112
- # Final output
113
- output = {
114
- "serial_number": serial_number,
115
- "total_scans": len(results),
116
- "successful_scans": successful_count,
117
- "failed_scans": failed_count,
118
- "background_mode": background,
119
- "results": [result.to_dict() for result in results],
120
- }
121
- click.echo(json.dumps(output, indent=2))
122
-
123
- except click.Abort:
124
- # User interrupted the scan
125
- raise
29
+ service: ConbusScanService = (
30
+ ctx.obj.get("container").get_container().resolve(ConbusScanService)
31
+ )
32
+
33
+ def on_progress(progress: str) -> None:
34
+ click.echo(progress)
35
+
36
+ def on_finish(service_response: ConbusResponse) -> None:
37
+ click.echo(json.dumps(service_response.to_dict(), indent=2))
38
+
39
+ with service:
40
+ service.scan_module(
41
+ serial_number=serial_number,
42
+ function_code=function_code,
43
+ progress_callback=on_progress,
44
+ finish_callback=on_finish,
45
+ )
@@ -32,24 +32,25 @@ class ConbusResponse:
32
32
  """Represents a response from Conbus send operation"""
33
33
 
34
34
  success: bool
35
- request: ConbusRequest
36
- sent_telegram: Optional[str] = None
37
- received_telegrams: Optional[list[str]] = None
38
- error: Optional[str] = None
39
- timestamp: Optional[datetime] = None
35
+ sent_telegrams: list[str]
36
+ received_telegrams: list[str]
37
+ timestamp: datetime
38
+ error: str = ""
39
+ serial_number: str = ""
40
+ function_code: str = ""
40
41
 
41
42
  def __post_init__(self) -> None:
42
- if self.timestamp is None:
43
- self.timestamp = datetime.now()
44
- if self.received_telegrams is None:
45
- self.received_telegrams = []
43
+ self.timestamp = datetime.now()
44
+ self.sent_telegrams = []
45
+ self.received_telegrams = []
46
46
 
47
47
  def to_dict(self) -> Dict[str, Any]:
48
48
  """Convert to dictionary for JSON serialization"""
49
49
  return {
50
50
  "success": self.success,
51
- "request": self.request.to_dict(),
52
- "sent_telegram": self.sent_telegram,
51
+ "serial_number": self.serial_number,
52
+ "function_code": self.function_code,
53
+ "sent_telegrams": self.sent_telegrams,
53
54
  "received_telegrams": self.received_telegrams,
54
55
  "error": self.error,
55
56
  "timestamp": self.timestamp.isoformat() if self.timestamp else None,
@@ -8,8 +8,8 @@ class ConbusLinknumberResponse:
8
8
  """Represents a response from Conbus link number operations (set/get)"""
9
9
 
10
10
  success: bool
11
- result: str
12
11
  serial_number: str
12
+ result: str
13
13
  sent_telegram: Optional[str] = None
14
14
  received_telegrams: Optional[list] = None
15
15
  link_number: Optional[int] = None