conson-xp 0.11.19__py3-none-any.whl → 0.11.21__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.
- {conson_xp-0.11.19.dist-info → conson_xp-0.11.21.dist-info}/METADATA +1 -1
- {conson_xp-0.11.19.dist-info → conson_xp-0.11.21.dist-info}/RECORD +12 -11
- xp/__init__.py +1 -1
- xp/cli/commands/__init__.py +0 -1
- xp/cli/commands/conbus/conbus_lightlevel_commands.py +35 -16
- xp/services/conbus/conbus_autoreport_get_service.py +17 -10
- xp/services/conbus/conbus_lightlevel_get_service.py +149 -0
- xp/services/conbus/conbus_lightlevel_set_service.py +205 -0
- xp/utils/dependencies.py +5 -6
- xp/services/conbus/conbus_lightlevel_service.py +0 -205
- {conson_xp-0.11.19.dist-info → conson_xp-0.11.21.dist-info}/WHEEL +0 -0
- {conson_xp-0.11.19.dist-info → conson_xp-0.11.21.dist-info}/entry_points.txt +0 -0
- {conson_xp-0.11.19.dist-info → conson_xp-0.11.21.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
conson_xp-0.11.
|
|
2
|
-
conson_xp-0.11.
|
|
3
|
-
conson_xp-0.11.
|
|
4
|
-
conson_xp-0.11.
|
|
5
|
-
xp/__init__.py,sha256=
|
|
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
|
|
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
|
|
@@ -17,7 +17,7 @@ xp/api/routers/conbus_output.py,sha256=U-i7kjZv7H6aE0O_8AcZIKZDJuYwU8XostEWoNccn
|
|
|
17
17
|
xp/api/routers/errors.py,sha256=5vzpeTt0cPQZDHL5YgrYJUxMh4uI7IgUNFAvL0NpLKM,1267
|
|
18
18
|
xp/cli/__init__.py,sha256=KWYwhOU46dNEerlc2i4FHsVR4Fxmt90Pw5L5i2v1Jqc,80
|
|
19
19
|
xp/cli/__main__.py,sha256=l2iKwMdat5rTGd3JWs-uGksnYYDDffp_Npz05QdKEeU,117
|
|
20
|
-
xp/cli/commands/__init__.py,sha256=
|
|
20
|
+
xp/cli/commands/__init__.py,sha256=dJ_VaOojg14vdx4OwxbDH-egJd16h3uT7f5DSQX4ZB0,4459
|
|
21
21
|
xp/cli/commands/api.py,sha256=d9uD5NnDV807suEK6eLzJSl62TGTtFSwIA_foPc6wtg,340
|
|
22
22
|
xp/cli/commands/api_start_commands.py,sha256=q9yOkiIY-NmRD04pq3N6rRe-BjnrcMRZmai8Jg5TKhA,3116
|
|
23
23
|
xp/cli/commands/conbus/__init__.py,sha256=gE3K5OEoXkkZX8UOc2v3nreQQzwkOQi7n0VZ-Z2juXA,495
|
|
@@ -29,7 +29,7 @@ xp/cli/commands/conbus/conbus_config_commands.py,sha256=MBLt7Z95-v2Drvr80r4HQxx8
|
|
|
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
|
-
xp/cli/commands/conbus/conbus_lightlevel_commands.py,sha256
|
|
32
|
+
xp/cli/commands/conbus/conbus_lightlevel_commands.py,sha256=hMzQewTgqGNB6s_Pag2HNfImhpgXnitwUVgMM6XXJv8,4161
|
|
33
33
|
xp/cli/commands/conbus/conbus_linknumber_commands.py,sha256=Q8hh222Gq7xDD-dRvwS4tiLQj3l913n-Vk1J73QxGGc,1954
|
|
34
34
|
xp/cli/commands/conbus/conbus_msactiontable_commands.py,sha256=n1g-ZKjjjbCQqTPGCrcCB595QoRClv0DGvGEx8y7BAY,1728
|
|
35
35
|
xp/cli/commands/conbus/conbus_output_commands.py,sha256=B_N31H4uBjahBxr6VNsj_bnsJsqkQc4CTIofDBKY4v8,2885
|
|
@@ -118,7 +118,7 @@ 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=
|
|
121
|
+
xp/services/conbus/conbus_autoreport_get_service.py,sha256=mNWFOt0-Ahx5N_Ayyq4oa-rdf2Xcu4rwz7erIjfdNBg,5206
|
|
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
|
|
@@ -127,7 +127,8 @@ xp/services/conbus/conbus_custom_service.py,sha256=jM6B085GTT8epCE9EqVTT8mZLPMXM
|
|
|
127
127
|
xp/services/conbus/conbus_datapoint_queryall_service.py,sha256=FBpFmwXVKoTiqMwQW-z2eYbamKL_ZGlTI86720ZcGt8,6095
|
|
128
128
|
xp/services/conbus/conbus_datapoint_service.py,sha256=CspxjhEi8awX_dv6EpJpYjTtCsfLgjJ4ROl6jD1TOiY,5289
|
|
129
129
|
xp/services/conbus/conbus_discover_service.py,sha256=kA_ewxXgbqXng0cXBjSgQSGYesyesbN2wK0tMp1fgfc,4281
|
|
130
|
-
xp/services/conbus/
|
|
130
|
+
xp/services/conbus/conbus_lightlevel_get_service.py,sha256=vrr5HhR5l58oOezTz2rorO-RHoyGbVuHrx2rGfKvH20,5739
|
|
131
|
+
xp/services/conbus/conbus_lightlevel_set_service.py,sha256=6Mhq9xjWx-ixGVfcWBcJSnuYT256m8Lps1g8Tg-1nkM,7483
|
|
131
132
|
xp/services/conbus/conbus_linknumber_service.py,sha256=r3Lyb7IV4i5kRY6zTnRK9jmC1vo8dpyHwh4WwdwrlL4,7703
|
|
132
133
|
xp/services/conbus/conbus_output_service.py,sha256=_sHGF6AWadhT_CNSnRPaXwQLaNEwQHSVuyKtyZ9jgFc,5115
|
|
133
134
|
xp/services/conbus/conbus_raw_service.py,sha256=riANTAiXTdSzOWbp_g-IQjdRhAf8CzZnNJtlT-aDvRs,3746
|
|
@@ -174,8 +175,8 @@ xp/services/telegram/telegram_service.py,sha256=Mp20QB50WDp43QBl8TzsR9BKV_hHP53R
|
|
|
174
175
|
xp/services/telegram/telegram_version_service.py,sha256=21v256THg0lidTyUtp2i8r6TAl8J0CTaZo4bZw59nFk,10479
|
|
175
176
|
xp/utils/__init__.py,sha256=clisBctja_VwtkAM9wnbOGDRPfbKHlCUqq4Sa4Z6zng,331
|
|
176
177
|
xp/utils/checksum.py,sha256=HDpiQxmdIedbCbZ4o_Box0i_Zig417BtCV_46ZyhiTk,1711
|
|
177
|
-
xp/utils/dependencies.py,sha256=
|
|
178
|
+
xp/utils/dependencies.py,sha256=VztcJM27MA6mykoVuX84zXMRsmKYuSGsVOKu5Gaw0b4,20490
|
|
178
179
|
xp/utils/event_helper.py,sha256=W-A_xmoXlpWZBbJH6qdaN50o3-XrwFsDgvAGMJDiAgo,1001
|
|
179
180
|
xp/utils/serialization.py,sha256=hZcrpzaBOe3a2wS_RFCIRs9PvnYsrbK7Ulq6s1rU0q4,4456
|
|
180
181
|
xp/utils/time_utils.py,sha256=Yi3JxHrHsd9ZZxTBRIqlTOz1FYTCeE1IZbefDaXIop8,3800
|
|
181
|
-
conson_xp-0.11.
|
|
182
|
+
conson_xp-0.11.21.dist-info/RECORD,,
|
xp/__init__.py
CHANGED
xp/cli/commands/__init__.py
CHANGED
|
@@ -38,7 +38,6 @@ from xp.cli.commands.conbus.conbus_datapoint_commands import (
|
|
|
38
38
|
)
|
|
39
39
|
from xp.cli.commands.conbus.conbus_discover_commands import send_discover_telegram
|
|
40
40
|
from xp.cli.commands.conbus.conbus_lightlevel_commands import (
|
|
41
|
-
xp_lightlevel_get,
|
|
42
41
|
xp_lightlevel_off,
|
|
43
42
|
xp_lightlevel_on,
|
|
44
43
|
xp_lightlevel_set,
|
|
@@ -10,9 +10,10 @@ from xp.cli.utils.decorators import (
|
|
|
10
10
|
handle_service_errors,
|
|
11
11
|
)
|
|
12
12
|
from xp.cli.utils.serial_number_type import SERIAL
|
|
13
|
-
from xp.
|
|
13
|
+
from xp.models.conbus.conbus_lightlevel import ConbusLightlevelResponse
|
|
14
|
+
from xp.services.conbus.conbus_lightlevel_set_service import (
|
|
14
15
|
ConbusLightlevelError,
|
|
15
|
-
|
|
16
|
+
ConbusLightlevelSetService,
|
|
16
17
|
)
|
|
17
18
|
|
|
18
19
|
|
|
@@ -34,12 +35,17 @@ def xp_lightlevel_set(
|
|
|
34
35
|
xp conbus lightlevel set 0123450001 2 50 # Set output 2 to 50%
|
|
35
36
|
xp conbus lightlevel set 0011223344 0 100 # Set output 0 to 100%
|
|
36
37
|
"""
|
|
37
|
-
service = ctx.obj.get("container").get_container().resolve(ConbusLightlevelService)
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
response = service.set_lightlevel(serial_number, output_number, level)
|
|
39
|
+
def finish(response: "ConbusLightlevelResponse") -> None:
|
|
41
40
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
42
41
|
|
|
42
|
+
service = (
|
|
43
|
+
ctx.obj.get("container").get_container().resolve(ConbusLightlevelSetService)
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
with service:
|
|
47
|
+
service.set_lightlevel(serial_number, output_number, level, finish, 0.5)
|
|
48
|
+
|
|
43
49
|
|
|
44
50
|
@conbus_lightlevel.command("off")
|
|
45
51
|
@click.argument("serial_number", type=SERIAL)
|
|
@@ -58,12 +64,17 @@ def xp_lightlevel_off(
|
|
|
58
64
|
xp conbus lightlevel off 0123450001 2 # Turn off output 2
|
|
59
65
|
xp conbus lightlevel off 0011223344 0 # Turn off output 0
|
|
60
66
|
"""
|
|
61
|
-
service = ctx.obj.get("container").get_container().resolve(ConbusLightlevelService)
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
response = service.turn_off(serial_number, output_number)
|
|
68
|
+
def finish(response: "ConbusLightlevelResponse") -> None:
|
|
65
69
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
66
70
|
|
|
71
|
+
service = (
|
|
72
|
+
ctx.obj.get("container").get_container().resolve(ConbusLightlevelSetService)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
with service:
|
|
76
|
+
service.turn_off(serial_number, output_number, finish, 0.5)
|
|
77
|
+
|
|
67
78
|
|
|
68
79
|
@conbus_lightlevel.command("on")
|
|
69
80
|
@click.argument("serial_number", type=SERIAL)
|
|
@@ -82,12 +93,17 @@ def xp_lightlevel_on(
|
|
|
82
93
|
xp conbus lightlevel on 0123450001 2 # Turn on output 2 (80%)
|
|
83
94
|
xp conbus lightlevel on 0011223344 0 # Turn on output 0 (80%)
|
|
84
95
|
"""
|
|
85
|
-
service = ctx.obj.get("container").get_container().resolve(ConbusLightlevelService)
|
|
86
96
|
|
|
87
|
-
|
|
88
|
-
response = service.turn_on(serial_number, output_number)
|
|
97
|
+
def finish(response: "ConbusLightlevelResponse") -> None:
|
|
89
98
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
90
99
|
|
|
100
|
+
service = (
|
|
101
|
+
ctx.obj.get("container").get_container().resolve(ConbusLightlevelSetService)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
with service:
|
|
105
|
+
service.turn_on(serial_number, output_number, finish, 0.5)
|
|
106
|
+
|
|
91
107
|
|
|
92
108
|
@conbus_lightlevel.command("get")
|
|
93
109
|
@click.argument("serial_number", type=SERIAL)
|
|
@@ -99,15 +115,18 @@ def xp_lightlevel_get(
|
|
|
99
115
|
ctx: click.Context, serial_number: str, output_number: int
|
|
100
116
|
) -> None:
|
|
101
117
|
"""Get current light level for output_number on XP module serial_number
|
|
102
|
-
|
|
103
118
|
Examples:
|
|
104
|
-
|
|
105
119
|
\b
|
|
106
120
|
xp conbus lightlevel get 0123450001 2 # Get light level for output 2
|
|
107
121
|
xp conbus lightlevel get 0011223344 0 # Get light level for output 0
|
|
108
122
|
"""
|
|
109
|
-
service = ctx.obj.get("container").get_container().resolve(ConbusLightlevelService)
|
|
110
123
|
|
|
111
|
-
|
|
112
|
-
response = service.get_lightlevel(serial_number, output_number)
|
|
124
|
+
def finish(response: "ConbusLightlevelResponse") -> None:
|
|
113
125
|
click.echo(json.dumps(response.to_dict(), indent=2))
|
|
126
|
+
|
|
127
|
+
service = (
|
|
128
|
+
ctx.obj.get("container").get_container().resolve(ConbusLightlevelSetService)
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
with service:
|
|
132
|
+
service.get_lightlevel(serial_number, output_number, finish, 0.5)
|
|
@@ -79,22 +79,29 @@ class ConbusAutoreportGetService(ConbusProtocol):
|
|
|
79
79
|
telegram_received.frame
|
|
80
80
|
)
|
|
81
81
|
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
not reply_telegram
|
|
83
|
+
or reply_telegram.system_function != SystemFunction.READ_DATAPOINT
|
|
84
|
+
or reply_telegram.datapoint_type != DataPointType.AUTO_REPORT_STATUS
|
|
85
85
|
):
|
|
86
|
-
self.logger.debug("
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
self.logger.debug("Not an autoreport reply")
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
autoreport_status = reply_telegram.data_value
|
|
90
|
+
self.succeed(autoreport_status)
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
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)
|
|
94
100
|
|
|
95
101
|
def failed(self, message: str) -> None:
|
|
96
102
|
self.logger.debug(f"Failed with message: {message}")
|
|
97
103
|
self.service_response.success = False
|
|
104
|
+
self.service_response.serial_number = self.serial_number
|
|
98
105
|
self.service_response.timestamp = datetime.now()
|
|
99
106
|
self.service_response.error = message
|
|
100
107
|
if self.finish_callback:
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""Conbus Auto Report Service for getting and setting module auto report status.
|
|
2
|
+
|
|
3
|
+
This service handles auto report status operations for modules through Conbus telegrams.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Callable, Optional
|
|
9
|
+
|
|
10
|
+
from twisted.internet.posixbase import PosixReactorBase
|
|
11
|
+
|
|
12
|
+
from xp.models import ConbusClientConfig
|
|
13
|
+
from xp.models.conbus.conbus_lightlevel import ConbusLightlevelResponse
|
|
14
|
+
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
15
|
+
from xp.models.telegram.datapoint_type import DataPointType
|
|
16
|
+
from xp.models.telegram.reply_telegram import ReplyTelegram
|
|
17
|
+
from xp.models.telegram.system_function import SystemFunction
|
|
18
|
+
from xp.models.telegram.telegram_type import TelegramType
|
|
19
|
+
from xp.services.protocol import ConbusProtocol
|
|
20
|
+
from xp.services.telegram.telegram_service import TelegramService
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConbusLightlevelGetService(ConbusProtocol):
|
|
24
|
+
"""
|
|
25
|
+
Service for receiving telegrams from Conbus servers.
|
|
26
|
+
|
|
27
|
+
Uses composition with ConbusService to provide receive-only functionality
|
|
28
|
+
for collecting waiting event telegrams from the server.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
telegram_service: TelegramService,
|
|
34
|
+
cli_config: ConbusClientConfig,
|
|
35
|
+
reactor: PosixReactorBase,
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Initialize the Conbus client send service"""
|
|
38
|
+
super().__init__(cli_config, reactor)
|
|
39
|
+
self.telegram_service = telegram_service
|
|
40
|
+
self.serial_number: str = ""
|
|
41
|
+
self.output_number: int = 0
|
|
42
|
+
self.finish_callback: Optional[Callable[[ConbusLightlevelResponse], None]] = (
|
|
43
|
+
None
|
|
44
|
+
)
|
|
45
|
+
self.service_response: ConbusLightlevelResponse = ConbusLightlevelResponse(
|
|
46
|
+
success=False,
|
|
47
|
+
serial_number=self.serial_number,
|
|
48
|
+
output_number=self.output_number,
|
|
49
|
+
level=0,
|
|
50
|
+
timestamp=datetime.now(),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Set up logging
|
|
54
|
+
self.logger = logging.getLogger(__name__)
|
|
55
|
+
|
|
56
|
+
def connection_established(self) -> None:
|
|
57
|
+
self.logger.debug("Connection established, retrieving lightlevel status...")
|
|
58
|
+
self.send_telegram(
|
|
59
|
+
telegram_type=TelegramType.SYSTEM,
|
|
60
|
+
serial_number=self.serial_number,
|
|
61
|
+
system_function=SystemFunction.READ_DATAPOINT,
|
|
62
|
+
data_value=str(DataPointType.MODULE_LIGHT_LEVEL.value),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def telegram_sent(self, telegram_sent: str) -> None:
|
|
66
|
+
self.service_response.sent_telegram = telegram_sent
|
|
67
|
+
|
|
68
|
+
def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
|
|
69
|
+
|
|
70
|
+
self.logger.debug(f"Telegram received: {telegram_received}")
|
|
71
|
+
if not self.service_response.received_telegrams:
|
|
72
|
+
self.service_response.received_telegrams = []
|
|
73
|
+
self.service_response.received_telegrams.append(telegram_received.frame)
|
|
74
|
+
|
|
75
|
+
if (
|
|
76
|
+
not telegram_received.checksum_valid
|
|
77
|
+
or telegram_received.telegram_type != TelegramType.REPLY
|
|
78
|
+
or telegram_received.serial_number != self.serial_number
|
|
79
|
+
):
|
|
80
|
+
self.logger.debug("Not a reply")
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
reply_telegram = self.telegram_service.parse_reply_telegram(
|
|
84
|
+
telegram_received.frame
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
if (
|
|
88
|
+
not reply_telegram
|
|
89
|
+
or reply_telegram.system_function != SystemFunction.READ_DATAPOINT
|
|
90
|
+
or reply_telegram.datapoint_type != DataPointType.MODULE_LIGHT_LEVEL
|
|
91
|
+
):
|
|
92
|
+
self.logger.debug("Not a lightlevel telegram")
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
self.logger.debug("Received lightlevel status telegram")
|
|
96
|
+
lightlevel = self.extract_lightlevel(reply_telegram)
|
|
97
|
+
self.succeed(lightlevel)
|
|
98
|
+
|
|
99
|
+
def extract_lightlevel(self, reply_telegram: ReplyTelegram) -> int:
|
|
100
|
+
level = 0
|
|
101
|
+
for output_data in reply_telegram.data_value.split(","):
|
|
102
|
+
if ":" in output_data:
|
|
103
|
+
output_str, level_str = output_data.split(":")
|
|
104
|
+
if int(output_str) == self.output_number:
|
|
105
|
+
level_str = level_str.replace("[%]", "")
|
|
106
|
+
level = int(level_str)
|
|
107
|
+
break
|
|
108
|
+
return level
|
|
109
|
+
|
|
110
|
+
def succeed(self, lightlevel: int) -> None:
|
|
111
|
+
self.service_response.success = True
|
|
112
|
+
self.service_response.timestamp = datetime.now()
|
|
113
|
+
self.service_response.serial_number = self.serial_number
|
|
114
|
+
self.service_response.level = lightlevel
|
|
115
|
+
if self.finish_callback:
|
|
116
|
+
self.finish_callback(self.service_response)
|
|
117
|
+
|
|
118
|
+
def failed(self, message: str) -> None:
|
|
119
|
+
self.logger.debug(f"Failed with message: {message}")
|
|
120
|
+
self.service_response.success = False
|
|
121
|
+
self.service_response.timestamp = datetime.now()
|
|
122
|
+
self.service_response.error = message
|
|
123
|
+
if self.finish_callback:
|
|
124
|
+
self.finish_callback(self.service_response)
|
|
125
|
+
|
|
126
|
+
def get_light_level(
|
|
127
|
+
self,
|
|
128
|
+
serial_number: str,
|
|
129
|
+
output_number: int,
|
|
130
|
+
finish_callback: Callable[[ConbusLightlevelResponse], None],
|
|
131
|
+
timeout_seconds: Optional[float] = None,
|
|
132
|
+
) -> None:
|
|
133
|
+
"""
|
|
134
|
+
Get the current auto report status for a specific module.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
:param serial_number: 10-digit module serial number
|
|
138
|
+
:param output_number: output module number
|
|
139
|
+
:param finish_callback: callback function to call when the lightlevel status is
|
|
140
|
+
:param timeout_seconds: timeout in seconds
|
|
141
|
+
|
|
142
|
+
"""
|
|
143
|
+
self.logger.info("Starting get_lightlevel_status")
|
|
144
|
+
if timeout_seconds:
|
|
145
|
+
self.timeout_seconds = timeout_seconds
|
|
146
|
+
self.finish_callback = finish_callback
|
|
147
|
+
self.serial_number = serial_number
|
|
148
|
+
self.output_number = output_number
|
|
149
|
+
self.start_reactor()
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"""Conbus Lightlevel Service for controlling light levels on Conbus modules.
|
|
2
|
+
|
|
3
|
+
This service implements lightlevel control operations for XP modules,
|
|
4
|
+
including setting specific light levels, turning lights on/off, and
|
|
5
|
+
querying current light levels.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Callable, Optional
|
|
11
|
+
|
|
12
|
+
from twisted.internet.posixbase import PosixReactorBase
|
|
13
|
+
|
|
14
|
+
from xp.models import ConbusClientConfig
|
|
15
|
+
from xp.models.conbus.conbus_lightlevel import ConbusLightlevelResponse
|
|
16
|
+
from xp.models.protocol.conbus_protocol import TelegramReceivedEvent
|
|
17
|
+
from xp.models.telegram.datapoint_type import DataPointType
|
|
18
|
+
from xp.models.telegram.system_function import SystemFunction
|
|
19
|
+
from xp.models.telegram.telegram_type import TelegramType
|
|
20
|
+
from xp.services.protocol import ConbusProtocol
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConbusLightlevelError(Exception):
|
|
24
|
+
"""Raised when Conbus lightlevel operations fail"""
|
|
25
|
+
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ConbusLightlevelSetService(ConbusProtocol):
|
|
30
|
+
"""
|
|
31
|
+
Service for controlling light levels on Conbus modules.
|
|
32
|
+
|
|
33
|
+
Manages lightlevel operations including setting specific levels,
|
|
34
|
+
turning lights on/off, and querying current states.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
cli_config: ConbusClientConfig,
|
|
40
|
+
reactor: PosixReactorBase,
|
|
41
|
+
):
|
|
42
|
+
"""Initialize the Conbus lightlevel service"""
|
|
43
|
+
super().__init__(cli_config, reactor)
|
|
44
|
+
self.serial_number: str = ""
|
|
45
|
+
self.output_number: int = 0
|
|
46
|
+
self.level: int = 0
|
|
47
|
+
self.finish_callback: Optional[Callable[[ConbusLightlevelResponse], None]] = (
|
|
48
|
+
None
|
|
49
|
+
)
|
|
50
|
+
self.service_response: ConbusLightlevelResponse = ConbusLightlevelResponse(
|
|
51
|
+
success=False,
|
|
52
|
+
serial_number=self.serial_number,
|
|
53
|
+
output_number=self.output_number,
|
|
54
|
+
level=None,
|
|
55
|
+
timestamp=datetime.now(),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Set up logging
|
|
59
|
+
self.logger = logging.getLogger(__name__)
|
|
60
|
+
|
|
61
|
+
def connection_established(self) -> None:
|
|
62
|
+
self.logger.debug(
|
|
63
|
+
f"Connection established, setting light level for output {self.output_number} to {self.level}%..."
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Format data as output_number:level (e.g., ""15" + "02:050")
|
|
67
|
+
data_value = f"{DataPointType.MODULE_LIGHT_LEVEL.value}{self.output_number:02d}:{self.level:03d}"
|
|
68
|
+
|
|
69
|
+
# Send telegram using WRITE_CONFIG function with MODULE_LIGHT_LEVEL datapoint
|
|
70
|
+
self.send_telegram(
|
|
71
|
+
telegram_type=TelegramType.SYSTEM,
|
|
72
|
+
serial_number=self.serial_number,
|
|
73
|
+
system_function=SystemFunction.WRITE_CONFIG, # "04"
|
|
74
|
+
data_value=data_value,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def telegram_sent(self, telegram_sent: str) -> None:
|
|
78
|
+
self.service_response.sent_telegram = telegram_sent
|
|
79
|
+
|
|
80
|
+
def telegram_received(self, telegram_received: TelegramReceivedEvent) -> None:
|
|
81
|
+
self.logger.debug(f"Telegram received: {telegram_received}")
|
|
82
|
+
if not self.service_response.received_telegrams:
|
|
83
|
+
self.service_response.received_telegrams = []
|
|
84
|
+
self.service_response.received_telegrams.append(telegram_received.frame)
|
|
85
|
+
|
|
86
|
+
if (
|
|
87
|
+
not telegram_received.checksum_valid
|
|
88
|
+
or telegram_received.telegram_type != TelegramType.REPLY
|
|
89
|
+
or telegram_received.serial_number != self.serial_number
|
|
90
|
+
):
|
|
91
|
+
self.logger.debug("Not a reply for our serial number")
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
# Any valid reply means success (ACK or NAK)
|
|
95
|
+
if telegram_received.telegram_type == TelegramType.REPLY:
|
|
96
|
+
self.logger.debug("Received lightlevel response")
|
|
97
|
+
self.succeed()
|
|
98
|
+
|
|
99
|
+
def succeed(self) -> None:
|
|
100
|
+
self.logger.debug("Succeed")
|
|
101
|
+
self.service_response.success = True
|
|
102
|
+
self.service_response.serial_number = self.serial_number
|
|
103
|
+
self.service_response.output_number = self.output_number
|
|
104
|
+
self.service_response.level = self.level
|
|
105
|
+
self.service_response.timestamp = datetime.now()
|
|
106
|
+
|
|
107
|
+
if self.finish_callback:
|
|
108
|
+
self.finish_callback(self.service_response)
|
|
109
|
+
|
|
110
|
+
def failed(self, message: str) -> None:
|
|
111
|
+
self.logger.debug(f"Failed with message: {message}")
|
|
112
|
+
self.service_response.success = False
|
|
113
|
+
self.service_response.serial_number = self.serial_number
|
|
114
|
+
self.service_response.output_number = self.output_number
|
|
115
|
+
self.service_response.level = self.level
|
|
116
|
+
self.service_response.timestamp = datetime.now()
|
|
117
|
+
self.service_response.error = message
|
|
118
|
+
|
|
119
|
+
if self.finish_callback:
|
|
120
|
+
self.finish_callback(self.service_response)
|
|
121
|
+
|
|
122
|
+
def set_lightlevel(
|
|
123
|
+
self,
|
|
124
|
+
serial_number: str,
|
|
125
|
+
output_number: int,
|
|
126
|
+
level: int,
|
|
127
|
+
finish_callback: Callable[[ConbusLightlevelResponse], None],
|
|
128
|
+
timeout_seconds: Optional[float] = None,
|
|
129
|
+
) -> None:
|
|
130
|
+
"""Set light level for a specific output on a module.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
serial_number: Module serial number
|
|
134
|
+
output_number: Output number (0-based, 0-8)
|
|
135
|
+
level: Light level percentage (0-100)
|
|
136
|
+
finish_callback: Callback function to call when operation completes
|
|
137
|
+
timeout_seconds: Optional timeout in seconds
|
|
138
|
+
|
|
139
|
+
Examples:
|
|
140
|
+
\b
|
|
141
|
+
xp conbus lightlevel set 0012345008 2 50
|
|
142
|
+
xp conbus lightlevel set 0012345008 0 100
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
self.logger.info(
|
|
146
|
+
f"Setting light level for {serial_number} output {output_number} to {level}%"
|
|
147
|
+
)
|
|
148
|
+
if timeout_seconds:
|
|
149
|
+
self.timeout_seconds = timeout_seconds
|
|
150
|
+
self.finish_callback = finish_callback
|
|
151
|
+
self.serial_number = serial_number
|
|
152
|
+
self.output_number = output_number
|
|
153
|
+
self.level = level
|
|
154
|
+
|
|
155
|
+
# Validate output_number range (0-8)
|
|
156
|
+
if not 0 <= self.output_number <= 8:
|
|
157
|
+
self.failed(
|
|
158
|
+
f"Output number must be between 0 and 8, got {self.output_number}"
|
|
159
|
+
)
|
|
160
|
+
return
|
|
161
|
+
|
|
162
|
+
# Validate level range
|
|
163
|
+
if not 0 <= self.level <= 100:
|
|
164
|
+
self.failed(f"Light level must be between 0 and 100, got {self.level}")
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
self.start_reactor()
|
|
168
|
+
|
|
169
|
+
def turn_off(
|
|
170
|
+
self,
|
|
171
|
+
serial_number: str,
|
|
172
|
+
output_number: int,
|
|
173
|
+
finish_callback: Callable[[ConbusLightlevelResponse], None],
|
|
174
|
+
timeout_seconds: Optional[float] = None,
|
|
175
|
+
) -> None:
|
|
176
|
+
"""Turn off light (set level to 0) for a specific output.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
serial_number: Module serial number
|
|
180
|
+
output_number: Output number (0-8)
|
|
181
|
+
finish_callback: Callback function to call when operation completes
|
|
182
|
+
timeout_seconds: Optional timeout in seconds
|
|
183
|
+
"""
|
|
184
|
+
self.set_lightlevel(
|
|
185
|
+
serial_number, output_number, 0, finish_callback, timeout_seconds
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def turn_on(
|
|
189
|
+
self,
|
|
190
|
+
serial_number: str,
|
|
191
|
+
output_number: int,
|
|
192
|
+
finish_callback: Callable[[ConbusLightlevelResponse], None],
|
|
193
|
+
timeout_seconds: Optional[float] = None,
|
|
194
|
+
) -> None:
|
|
195
|
+
"""Turn on light (set level to 80%) for a specific output.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
serial_number: Module serial number
|
|
199
|
+
output_number: Output number (0-8)
|
|
200
|
+
finish_callback: Callback function to call when operation completes
|
|
201
|
+
timeout_seconds: Optional timeout in seconds
|
|
202
|
+
"""
|
|
203
|
+
self.set_lightlevel(
|
|
204
|
+
serial_number, output_number, 80, finish_callback, timeout_seconds
|
|
205
|
+
)
|
xp/utils/dependencies.py
CHANGED
|
@@ -37,7 +37,7 @@ from xp.services.conbus.conbus_datapoint_service import (
|
|
|
37
37
|
ConbusDatapointService,
|
|
38
38
|
)
|
|
39
39
|
from xp.services.conbus.conbus_discover_service import ConbusDiscoverService
|
|
40
|
-
from xp.services.conbus.
|
|
40
|
+
from xp.services.conbus.conbus_lightlevel_set_service import ConbusLightlevelSetService
|
|
41
41
|
from xp.services.conbus.conbus_linknumber_service import ConbusLinknumberService
|
|
42
42
|
from xp.services.conbus.conbus_output_service import ConbusOutputService
|
|
43
43
|
from xp.services.conbus.conbus_raw_service import ConbusRawService
|
|
@@ -224,11 +224,10 @@ class ServiceContainer:
|
|
|
224
224
|
)
|
|
225
225
|
|
|
226
226
|
self.container.register(
|
|
227
|
-
|
|
228
|
-
factory=lambda:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
datapoint_service=self.container.resolve(ConbusDatapointService),
|
|
227
|
+
ConbusLightlevelSetService,
|
|
228
|
+
factory=lambda: ConbusLightlevelSetService(
|
|
229
|
+
cli_config=self.container.resolve(ConbusClientConfig),
|
|
230
|
+
reactor=self.container.resolve(PosixReactorBase),
|
|
232
231
|
),
|
|
233
232
|
scope=punq.Scope.singleton,
|
|
234
233
|
)
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
"""Conbus Lightlevel Service for controlling light levels on Conbus modules.
|
|
2
|
-
|
|
3
|
-
This service implements lightlevel control operations for XP modules,
|
|
4
|
-
including setting specific light levels, turning lights on/off, and
|
|
5
|
-
querying current light levels.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import logging
|
|
9
|
-
from datetime import datetime
|
|
10
|
-
from typing import Any, Optional
|
|
11
|
-
|
|
12
|
-
from xp.models.conbus.conbus_lightlevel import ConbusLightlevelResponse
|
|
13
|
-
from xp.models.telegram.datapoint_type import DataPointType
|
|
14
|
-
from xp.models.telegram.system_function import SystemFunction
|
|
15
|
-
from xp.services.conbus.conbus_datapoint_service import ConbusDatapointService
|
|
16
|
-
from xp.services.conbus.conbus_service import ConbusService
|
|
17
|
-
from xp.services.telegram.telegram_service import TelegramService
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class ConbusLightlevelError(Exception):
|
|
21
|
-
"""Raised when Conbus lightlevel operations fail"""
|
|
22
|
-
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class ConbusLightlevelService:
|
|
27
|
-
"""
|
|
28
|
-
Service for controlling light levels on Conbus modules.
|
|
29
|
-
|
|
30
|
-
Manages lightlevel operations including setting specific levels,
|
|
31
|
-
turning lights on/off, and querying current states.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
def __init__(
|
|
35
|
-
self,
|
|
36
|
-
telegram_service: TelegramService,
|
|
37
|
-
conbus_service: ConbusService,
|
|
38
|
-
datapoint_service: ConbusDatapointService,
|
|
39
|
-
):
|
|
40
|
-
"""Initialize the Conbus lightlevel service"""
|
|
41
|
-
|
|
42
|
-
# Service dependencies
|
|
43
|
-
self.telegram_service = telegram_service
|
|
44
|
-
self.conbus_service = conbus_service
|
|
45
|
-
self.datapoint_service = datapoint_service
|
|
46
|
-
|
|
47
|
-
# Set up logging
|
|
48
|
-
self.logger = logging.getLogger(__name__)
|
|
49
|
-
|
|
50
|
-
def __enter__(self) -> "ConbusLightlevelService":
|
|
51
|
-
return self
|
|
52
|
-
|
|
53
|
-
def __exit__(
|
|
54
|
-
self,
|
|
55
|
-
_exc_type: Optional[type],
|
|
56
|
-
_exc_val: Optional[Exception],
|
|
57
|
-
_exc_tb: Optional[Any],
|
|
58
|
-
) -> None:
|
|
59
|
-
# Cleanup logic if needed
|
|
60
|
-
pass
|
|
61
|
-
|
|
62
|
-
def set_lightlevel(
|
|
63
|
-
self, serial_number: str, output_number: int, level: int
|
|
64
|
-
) -> ConbusLightlevelResponse:
|
|
65
|
-
"""Set light level for a specific output on a module.
|
|
66
|
-
|
|
67
|
-
Args:
|
|
68
|
-
serial_number: Module serial number
|
|
69
|
-
output_number: Output number (0-based)
|
|
70
|
-
level: Light level percentage (0-100)
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
ConbusLightlevelResponse with operation result
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
# Validate output_number range (0-8)
|
|
77
|
-
if not 0 <= output_number <= 8:
|
|
78
|
-
return ConbusLightlevelResponse(
|
|
79
|
-
success=False,
|
|
80
|
-
serial_number=serial_number,
|
|
81
|
-
output_number=output_number,
|
|
82
|
-
level=level,
|
|
83
|
-
timestamp=datetime.now(),
|
|
84
|
-
error=f"Output number must be between 0 and 8, got {output_number}",
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
# Validate level range
|
|
88
|
-
if not 0 <= level <= 100:
|
|
89
|
-
return ConbusLightlevelResponse(
|
|
90
|
-
success=False,
|
|
91
|
-
serial_number=serial_number,
|
|
92
|
-
output_number=output_number,
|
|
93
|
-
level=level,
|
|
94
|
-
timestamp=datetime.now(),
|
|
95
|
-
error=f"Light level must be between 0 and 100, got {level}",
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
# Format data as output_number:level (e.g., "02:050")
|
|
99
|
-
data = f"{output_number:02d}:{level:03d}"
|
|
100
|
-
|
|
101
|
-
# Send telegram using WRITE_CONFIG function with MODULE_LIGHT_LEVEL datapoint
|
|
102
|
-
response = self.conbus_service.send_telegram(
|
|
103
|
-
serial_number,
|
|
104
|
-
SystemFunction.WRITE_CONFIG, # "04"
|
|
105
|
-
f"{DataPointType.MODULE_LIGHT_LEVEL.value}{data}", # "15" + "02:050"
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
return ConbusLightlevelResponse(
|
|
109
|
-
success=response.success,
|
|
110
|
-
serial_number=serial_number,
|
|
111
|
-
output_number=output_number,
|
|
112
|
-
level=level,
|
|
113
|
-
timestamp=response.timestamp or datetime.now(),
|
|
114
|
-
sent_telegram=response.sent_telegram,
|
|
115
|
-
received_telegrams=response.received_telegrams,
|
|
116
|
-
error=response.error,
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
def turn_off(
|
|
120
|
-
self, serial_number: str, output_number: int
|
|
121
|
-
) -> ConbusLightlevelResponse:
|
|
122
|
-
"""Turn off light (set level to 0) for a specific output.
|
|
123
|
-
|
|
124
|
-
Args:
|
|
125
|
-
serial_number: Module serial number
|
|
126
|
-
output_number: Output number (0-8)
|
|
127
|
-
|
|
128
|
-
Returns:
|
|
129
|
-
ConbusLightlevelResponse with operation result
|
|
130
|
-
"""
|
|
131
|
-
return self.set_lightlevel(serial_number, output_number, 0)
|
|
132
|
-
|
|
133
|
-
def turn_on(
|
|
134
|
-
self, serial_number: str, output_number: int
|
|
135
|
-
) -> ConbusLightlevelResponse:
|
|
136
|
-
"""Turn on light (set level to 80%) for a specific output.
|
|
137
|
-
|
|
138
|
-
Args:
|
|
139
|
-
serial_number: Module serial number
|
|
140
|
-
output_number: Output number (0-8)
|
|
141
|
-
|
|
142
|
-
Returns:
|
|
143
|
-
ConbusLightlevelResponse with operation result
|
|
144
|
-
"""
|
|
145
|
-
return self.set_lightlevel(serial_number, output_number, 80)
|
|
146
|
-
|
|
147
|
-
def get_lightlevel(
|
|
148
|
-
self, serial_number: str, output_number: int
|
|
149
|
-
) -> ConbusLightlevelResponse:
|
|
150
|
-
"""Query current light level for a specific output.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
serial_number: Module serial number
|
|
154
|
-
output_number: Output number (0-8)
|
|
155
|
-
|
|
156
|
-
Returns:
|
|
157
|
-
ConbusLightlevelResponse with current light level
|
|
158
|
-
"""
|
|
159
|
-
|
|
160
|
-
# TODO: Migrate to new ConbusDatapointService callback-based API
|
|
161
|
-
# Query MODULE_LIGHT_LEVEL datapoint
|
|
162
|
-
datapoint_response = self.datapoint_service.query_datapoint( # type: ignore[call-arg,func-returns-value]
|
|
163
|
-
serial_number=serial_number,
|
|
164
|
-
datapoint_type=DataPointType.MODULE_LIGHT_LEVEL,
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
if not datapoint_response.success:
|
|
168
|
-
return ConbusLightlevelResponse(
|
|
169
|
-
success=False,
|
|
170
|
-
serial_number=serial_number,
|
|
171
|
-
output_number=output_number,
|
|
172
|
-
level=None,
|
|
173
|
-
timestamp=datetime.now(),
|
|
174
|
-
error=datapoint_response.error or "Failed to query light level",
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
# Parse the response to extract level for specific output
|
|
178
|
-
level = None
|
|
179
|
-
if (
|
|
180
|
-
datapoint_response.datapoint_telegram
|
|
181
|
-
and datapoint_response.datapoint_telegram.data_value
|
|
182
|
-
):
|
|
183
|
-
try:
|
|
184
|
-
# Parse response format like "00:050,01:025,02:100"
|
|
185
|
-
data_value = str(datapoint_response.datapoint_telegram.data_value)
|
|
186
|
-
for output_data in data_value.split(","):
|
|
187
|
-
if ":" in output_data:
|
|
188
|
-
output_str, level_str = output_data.split(":")
|
|
189
|
-
if int(output_str) == output_number:
|
|
190
|
-
level_str = level_str.replace("[%]", "")
|
|
191
|
-
level = int(level_str)
|
|
192
|
-
break
|
|
193
|
-
except (ValueError, AttributeError) as e:
|
|
194
|
-
self.logger.debug(f"Failed to parse light level data: {e}")
|
|
195
|
-
|
|
196
|
-
return ConbusLightlevelResponse(
|
|
197
|
-
success=datapoint_response.success,
|
|
198
|
-
serial_number=serial_number,
|
|
199
|
-
output_number=output_number,
|
|
200
|
-
level=level,
|
|
201
|
-
timestamp=datetime.now(),
|
|
202
|
-
sent_telegram=datapoint_response.sent_telegram,
|
|
203
|
-
received_telegrams=datapoint_response.received_telegrams,
|
|
204
|
-
error=datapoint_response.error if level is None else None,
|
|
205
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|