conson-xp 0.11.21__py3-none-any.whl → 1.0.1__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.0.1
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.0.1.dist-info/METADATA,sha256=wo_NyCrK54bsHkSF0LihKlfeDtxR02DHb8ONbd-Wv_I,9296
2
+ conson_xp-1.0.1.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ conson_xp-1.0.1.dist-info/entry_points.txt,sha256=1OcdIcDM1hz3ljCXgybaPUh1IOFEwkaTgLIW9u9zGeg,50
4
+ conson_xp-1.0.1.dist-info/licenses/LICENSE,sha256=rxj6woMM-r3YCyGq_UHFtbh7kHTAJgrccH6O-33IDE4,1419
5
+ xp/__init__.py,sha256=vAQhsuRRkcqth5YA78Q1OHLSN5KKxSPyl7s7tokrbis,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,14 +25,14 @@ 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
38
  xp/cli/commands/conbus/conbus_scan_commands.py,sha256=HjZMhU1hPRuUSWMURB9UUeZt8aNMDlBYCktwrXUgsCY,4190
@@ -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=ODKXqD84aSkT6z_B7KHolUx2o5yuLP0gpTCAR-UoHOk,4505
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=GKmEB4hXAJO4sr3QHfhS_zF-J5BqV3Yi7QNexeSfzLg,7610
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.0.1.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.0.1"
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
+ )
@@ -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
@@ -4,22 +4,18 @@ This service handles auto report status operations for modules through Conbus te
4
4
  """
5
5
 
6
6
  import logging
7
- from datetime import datetime
8
7
  from typing import Callable, Optional
9
8
 
10
9
  from twisted.internet.posixbase import PosixReactorBase
11
10
 
12
- from xp.models import ConbusClientConfig
11
+ from xp.models import ConbusClientConfig, ConbusDatapointResponse
13
12
  from xp.models.conbus.conbus_autoreport import ConbusAutoreportResponse
14
- from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
15
13
  from xp.models.telegram.datapoint_type import DataPointType
16
- from xp.models.telegram.system_function import SystemFunction
17
- from xp.models.telegram.telegram_type import TelegramType
18
- from xp.services.protocol import ConbusProtocol
14
+ from xp.services.conbus.conbus_datapoint_service import ConbusDatapointService
19
15
  from xp.services.telegram.telegram_service import TelegramService
20
16
 
21
17
 
22
- class ConbusAutoreportGetService(ConbusProtocol):
18
+ class ConbusAutoreportGetService(ConbusDatapointService):
23
19
  """
24
20
  Service for receiving telegrams from Conbus servers.
25
21
 
@@ -34,78 +30,35 @@ class ConbusAutoreportGetService(ConbusProtocol):
34
30
  reactor: PosixReactorBase,
35
31
  ) -> None:
36
32
  """Initialize the Conbus client send service"""
37
- super().__init__(cli_config, reactor)
38
- self.telegram_service = telegram_service
39
- self.serial_number: str = ""
40
- self.finish_callback: Optional[Callable[[ConbusAutoreportResponse], None]] = (
33
+ super().__init__(telegram_service, cli_config, reactor)
34
+ self.service_callback: Optional[Callable[[ConbusAutoreportResponse], None]] = (
41
35
  None
42
36
  )
43
- self.service_response: ConbusAutoreportResponse = ConbusAutoreportResponse(
44
- success=False,
45
- serial_number=self.serial_number,
46
- )
47
37
 
48
38
  # Set up logging
49
39
  self.logger = logging.getLogger(__name__)
50
40
 
51
- def connection_established(self) -> None:
52
- self.logger.debug("Connection established, retrieving autoreport status...")
53
- self.send_telegram(
54
- telegram_type=TelegramType.SYSTEM,
55
- serial_number=self.serial_number,
56
- system_function=SystemFunction.READ_DATAPOINT,
57
- data_value=str(DataPointType.AUTO_REPORT_STATUS.value),
58
- )
59
-
60
- def telegram_sent(self, telegram_sent: str) -> None:
61
- self.service_response.sent_telegram = telegram_sent
62
-
63
- def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
64
-
65
- self.logger.debug(f"Telegram received: {telegram_received}")
66
- if not self.service_response.received_telegrams:
67
- self.service_response.received_telegrams = []
68
- self.service_response.received_telegrams.append(telegram_received.frame)
41
+ def finish_service_callback(
42
+ self, datapoint_response: ConbusDatapointResponse
43
+ ) -> None:
69
44
 
70
- if (
71
- not telegram_received.checksum_valid
72
- or telegram_received.telegram_type != TelegramType.REPLY
73
- or telegram_received.serial_number != self.serial_number
74
- ):
75
- self.logger.debug("Not a reply")
76
- return
45
+ self.logger.debug("Parsing datapoint response")
46
+ autoreport_status = ""
47
+ if datapoint_response.success and datapoint_response.datapoint_telegram:
48
+ autoreport_status = datapoint_response.datapoint_telegram.data_value
77
49
 
78
- reply_telegram = self.telegram_service.parse_reply_telegram(
79
- telegram_received.frame
50
+ service_response = ConbusAutoreportResponse(
51
+ success=datapoint_response.success,
52
+ serial_number=self.serial_number,
53
+ auto_report_status=autoreport_status,
54
+ error=datapoint_response.error,
55
+ sent_telegram=datapoint_response.sent_telegram,
56
+ received_telegrams=datapoint_response.received_telegrams,
57
+ timestamp=datapoint_response.timestamp,
80
58
  )
81
- if (
82
- not reply_telegram
83
- or reply_telegram.system_function != SystemFunction.READ_DATAPOINT
84
- or reply_telegram.datapoint_type != DataPointType.AUTO_REPORT_STATUS
85
- ):
86
- self.logger.debug("Not an autoreport reply")
87
- return
88
-
89
- autoreport_status = reply_telegram.data_value
90
- self.succeed(autoreport_status)
91
-
92
- def succeed(self, autoreport_status: str) -> None:
93
- self.logger.debug("Received autoreport status: {autoreport_status}")
94
- self.service_response.success = True
95
- self.service_response.serial_number = self.serial_number
96
- self.service_response.timestamp = datetime.now()
97
- self.service_response.auto_report_status = autoreport_status
98
- if self.finish_callback:
99
- self.finish_callback(self.service_response)
100
-
101
- def failed(self, message: str) -> None:
102
- self.logger.debug(f"Failed with message: {message}")
103
- self.service_response.success = False
104
- self.service_response.serial_number = self.serial_number
105
- self.service_response.timestamp = datetime.now()
106
- self.service_response.error = message
107
- if self.finish_callback:
108
- self.finish_callback(self.service_response)
59
+
60
+ if self.service_callback:
61
+ self.service_callback(service_response)
109
62
 
110
63
  def get_autoreport_status(
111
64
  self,
@@ -117,20 +70,16 @@ class ConbusAutoreportGetService(ConbusProtocol):
117
70
  Get the current auto report status for a specific module.
118
71
 
119
72
  Args:
120
- serial_number: 10-digit module serial number
121
- finish_callback: callback function to call when the autoreport status is
122
- timeout_seconds: timeout in seconds
123
-
124
- Returns:
125
- ConbusAutoreportResponse with operation result and auto report status
73
+ :param serial_number: 10-digit module serial number
74
+ :param finish_callback: callback function to call when the linknumber status is
75
+ :param timeout_seconds: timeout in seconds
126
76
 
127
- Raises:
128
- ConbusAutoreportError: If the operation fails
129
77
  """
130
-
131
78
  self.logger.info("Starting get_autoreport_status")
132
79
  if timeout_seconds:
133
80
  self.timeout_seconds = timeout_seconds
134
- self.finish_callback = finish_callback
135
81
  self.serial_number = serial_number
82
+ self.datapoint_type = DataPointType.AUTO_REPORT_STATUS
83
+ self.finish_callback = self.finish_service_callback
84
+ self.service_callback = finish_callback
136
85
  self.start_reactor()
@@ -12,6 +12,7 @@ from twisted.internet.posixbase import PosixReactorBase
12
12
  from xp.models import ConbusClientConfig, ConbusDatapointResponse
13
13
  from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
14
14
  from xp.models.telegram.datapoint_type import DataPointType
15
+ from xp.models.telegram.reply_telegram import ReplyTelegram
15
16
  from xp.models.telegram.system_function import SystemFunction
16
17
  from xp.models.telegram.telegram_type import TelegramType
17
18
  from xp.services.protocol import ConbusProtocol
@@ -93,13 +94,16 @@ class ConbusDatapointService(ConbusProtocol):
93
94
  return
94
95
 
95
96
  self.logger.debug("Received datapoint telegram")
97
+ self.succeed(datapoint_telegram)
98
+
99
+ def succeed(self, datapoint_telegram: ReplyTelegram) -> None:
100
+ self.logger.debug("Succeed querying datapoint")
96
101
  self.service_response.success = True
97
102
  self.service_response.timestamp = datetime.now()
98
103
  self.service_response.serial_number = self.serial_number
99
104
  self.service_response.system_function = SystemFunction.READ_DATAPOINT
100
105
  self.service_response.datapoint_type = self.datapoint_type
101
106
  self.service_response.datapoint_telegram = datapoint_telegram
102
-
103
107
  if self.finish_callback:
104
108
  self.finish_callback(self.service_response)
105
109
 
@@ -107,6 +111,7 @@ class ConbusDatapointService(ConbusProtocol):
107
111
  self.logger.debug(f"Failed with message: {message}")
108
112
  self.service_response.success = False
109
113
  self.service_response.timestamp = datetime.now()
114
+ self.service_response.serial_number = self.serial_number
110
115
  self.service_response.error = message
111
116
  if self.finish_callback:
112
117
  self.finish_callback(self.service_response)