pypck 0.8.3__tar.gz → 0.8.5__tar.gz

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.
Files changed (28) hide show
  1. {pypck-0.8.3/pypck.egg-info → pypck-0.8.5}/PKG-INFO +2 -2
  2. pypck-0.8.5/VERSION +1 -0
  3. {pypck-0.8.3 → pypck-0.8.5}/pypck/connection.py +22 -17
  4. {pypck-0.8.3 → pypck-0.8.5}/pypck/inputs.py +11 -1
  5. {pypck-0.8.3 → pypck-0.8.5}/pypck/pck_commands.py +1 -1
  6. {pypck-0.8.3 → pypck-0.8.5}/pypck/timeout_retry.py +1 -4
  7. {pypck-0.8.3 → pypck-0.8.5/pypck.egg-info}/PKG-INFO +2 -2
  8. pypck-0.8.5/tests/test_messages.py +329 -0
  9. pypck-0.8.3/VERSION +0 -1
  10. pypck-0.8.3/tests/test_messages.py +0 -257
  11. {pypck-0.8.3 → pypck-0.8.5}/LICENSE +0 -0
  12. {pypck-0.8.3 → pypck-0.8.5}/README.md +0 -0
  13. {pypck-0.8.3 → pypck-0.8.5}/pypck/__init__.py +0 -0
  14. {pypck-0.8.3 → pypck-0.8.5}/pypck/helpers.py +0 -0
  15. {pypck-0.8.3 → pypck-0.8.5}/pypck/lcn_addr.py +0 -0
  16. {pypck-0.8.3 → pypck-0.8.5}/pypck/lcn_defs.py +0 -0
  17. {pypck-0.8.3 → pypck-0.8.5}/pypck/module.py +0 -0
  18. {pypck-0.8.3 → pypck-0.8.5}/pypck/request_handlers.py +0 -0
  19. {pypck-0.8.3 → pypck-0.8.5}/pypck.egg-info/SOURCES.txt +0 -0
  20. {pypck-0.8.3 → pypck-0.8.5}/pypck.egg-info/dependency_links.txt +0 -0
  21. {pypck-0.8.3 → pypck-0.8.5}/pypck.egg-info/not-zip-safe +0 -0
  22. {pypck-0.8.3 → pypck-0.8.5}/pypck.egg-info/top_level.txt +0 -0
  23. {pypck-0.8.3 → pypck-0.8.5}/pyproject.toml +0 -0
  24. {pypck-0.8.3 → pypck-0.8.5}/setup.cfg +0 -0
  25. {pypck-0.8.3 → pypck-0.8.5}/tests/test_commands.py +0 -0
  26. {pypck-0.8.3 → pypck-0.8.5}/tests/test_connection.py +0 -0
  27. {pypck-0.8.3 → pypck-0.8.5}/tests/test_dyn_text.py +0 -0
  28. {pypck-0.8.3 → pypck-0.8.5}/tests/test_vars.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pypck
3
- Version: 0.8.3
3
+ Version: 0.8.5
4
4
  Summary: LCN-PCK library
5
5
  Home-page: https://github.com/alengwenus/pypck
6
6
  Author-email: Andre Lengwenus <alengwenus@gmail.com>
pypck-0.8.5/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.8.5
@@ -164,17 +164,25 @@ class PchkConnectionManager:
164
164
  break
165
165
 
166
166
  try:
167
- message = data.decode().split(PckGenerator.TERMINATION)[0]
167
+ message = data.decode("utf-8").split(PckGenerator.TERMINATION)[0]
168
168
  except UnicodeDecodeError as err:
169
- _LOGGER.warning(
170
- "PCK decoding error: %s - skipping received PCK message", err
171
- )
172
- continue
169
+ try:
170
+ message = data.decode("cp1250").split(PckGenerator.TERMINATION)[
171
+ 0
172
+ ]
173
+ _LOGGER.warning(
174
+ "Incorrect PCK encoding detected, possibly caused by LinHK: %s - PCK recovered using cp1250",
175
+ err,
176
+ )
177
+ except UnicodeDecodeError as err2:
178
+ _LOGGER.warning(
179
+ "PCK decoding error: %s - skipping received PCK message",
180
+ err2,
181
+ )
182
+ continue
173
183
  await self.process_message(message)
174
- except asyncio.CancelledError:
175
- pass
176
-
177
- _LOGGER.debug("Read data loop closed")
184
+ finally:
185
+ _LOGGER.debug("Read data loop closed")
178
186
 
179
187
  async def write_data_loop(self) -> None:
180
188
  """Processes queue and writes data."""
@@ -194,14 +202,11 @@ class PchkConnectionManager:
194
202
  self.writer.write(data)
195
203
  await self.writer.drain()
196
204
  self.last_bus_activity = time.time()
197
- except asyncio.CancelledError:
198
- pass
199
-
200
- # empty the queue
201
- while not self.buffer.empty():
202
- await self.buffer.get()
203
-
204
- _LOGGER.debug("Write data loop closed")
205
+ finally:
206
+ # empty the queue
207
+ while not self.buffer.empty():
208
+ await self.buffer.get()
209
+ _LOGGER.debug("Write data loop closed")
205
210
 
206
211
  # Open/close connection, authentication & setup.
207
212
 
@@ -392,7 +392,17 @@ class ModSn(ModInput):
392
392
  if matcher:
393
393
  addr = LcnAddr(int(matcher.group("seg_id")), int(matcher.group("mod_id")))
394
394
  hardware_serial = int(matcher.group("hardware_serial"), 16)
395
- manu = int(matcher.group("manu"), 16)
395
+ try:
396
+ manu = int(matcher.group("manu"), 16)
397
+ except (
398
+ ValueError
399
+ ): # unconventional manufacturer code (e.g., due to LinHK VM)
400
+ manu = 0xFF
401
+ _LOGGER.debug(
402
+ "Unconventional manufacturer code: %s. Defaulting to 0x%02X",
403
+ matcher.group("manu"),
404
+ manu,
405
+ )
396
406
  software_serial = int(matcher.group("software_serial"), 16)
397
407
  try:
398
408
  hardware_type = lcn_defs.HardwareType(
@@ -60,7 +60,7 @@ class PckParser:
60
60
  # Pattern to parse serial number and firmware date responses.
61
61
  PATTERN_SN = re.compile(
62
62
  r"=M(?P<seg_id>\d{3})(?P<mod_id>\d{3})\.SN(?P<hardware_serial>[0-9|A-F]{10})"
63
- r"(?P<manu>[0-9|A-F]{2})FW(?P<software_serial>[0-9|A-F]{6})"
63
+ r"(?P<manu>.{2})FW(?P<software_serial>[0-9|A-F]{6})"
64
64
  r"HW(?P<hardware_type>\d+)"
65
65
  )
66
66
 
@@ -65,10 +65,7 @@ class TimeoutRetryHandler:
65
65
  async def done(self) -> None:
66
66
  """Signal the completion of the TimeoutRetryHandler."""
67
67
  if self.timeout_loop_task is not None:
68
- try:
69
- await self.timeout_loop_task
70
- except asyncio.CancelledError:
71
- pass
68
+ await self.timeout_loop_task
72
69
 
73
70
  async def cancel(self) -> None:
74
71
  """Must be called when a response (requested or not) is received."""
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pypck
3
- Version: 0.8.3
3
+ Version: 0.8.5
4
4
  Summary: LCN-PCK library
5
5
  Home-page: https://github.com/alengwenus/pypck
6
6
  Author-email: Andre Lengwenus <alengwenus@gmail.com>
@@ -0,0 +1,329 @@
1
+ """Tests for input message parsing for bus messages."""
2
+
3
+ import pytest
4
+
5
+ from pypck.inputs import (
6
+ InputParser,
7
+ ModAck,
8
+ ModNameComment,
9
+ ModSendCommandHost,
10
+ ModSendKeysHost,
11
+ ModSk,
12
+ ModSn,
13
+ ModStatusAccessControl,
14
+ ModStatusBinSensors,
15
+ ModStatusGroups,
16
+ ModStatusKeyLocks,
17
+ ModStatusLedsAndLogicOps,
18
+ ModStatusOutput,
19
+ ModStatusOutputNative,
20
+ ModStatusRelays,
21
+ ModStatusSceneOutputs,
22
+ ModStatusVar,
23
+ )
24
+ from pypck.lcn_addr import LcnAddr
25
+ from pypck.lcn_defs import (
26
+ AccessControlPeriphery,
27
+ BatteryStatus,
28
+ HardwareType,
29
+ KeyAction,
30
+ LedStatus,
31
+ LogicOpStatus,
32
+ OutputPort,
33
+ SendKeyCommand,
34
+ Var,
35
+ VarValue,
36
+ )
37
+
38
+ MESSAGES = {
39
+ # Ack
40
+ "-M000010!": [(ModAck, -1)],
41
+ "-M000010005": [(ModAck, 5)],
42
+ # SK
43
+ "=M000010.SK007": [(ModSk, 7)],
44
+ # SN
45
+ "=M000010.SN1AB20A123401FW190B11HW015": [
46
+ (
47
+ ModSn,
48
+ 0x1AB20A1234,
49
+ 0x1,
50
+ 0x190B11,
51
+ HardwareType.SH_PLUS,
52
+ )
53
+ ],
54
+ "=M000010.SN1234567890AFFW190011HW011": [
55
+ (
56
+ ModSn,
57
+ 0x1234567890,
58
+ 0xAF,
59
+ 0x190011,
60
+ HardwareType.UPP,
61
+ )
62
+ ],
63
+ "=M000010.SN1234567890vMFW190011HW011": [
64
+ (
65
+ ModSn,
66
+ 0x1234567890,
67
+ 0xFF,
68
+ 0x190011,
69
+ HardwareType.UPP,
70
+ )
71
+ ],
72
+ # Name
73
+ "=M000010.N1EG HWR Hau": [(ModNameComment, "N", 0, "EG HWR Hau")],
74
+ "=M000010.N2EG HWR Hau": [(ModNameComment, "N", 1, "EG HWR Hau")],
75
+ # Comment
76
+ "=M000010.K1EG HWR Hau": [(ModNameComment, "K", 0, "EG HWR Hau")],
77
+ "=M000010.K2EG HWR Hau": [(ModNameComment, "K", 1, "EG HWR Hau")],
78
+ "=M000010.K3EG HWR Hau": [(ModNameComment, "K", 2, "EG HWR Hau")],
79
+ # Oem
80
+ "=M000010.O1EG HWR Hau": [(ModNameComment, "O", 0, "EG HWR Hau")],
81
+ "=M000010.O2EG HWR Hau": [(ModNameComment, "O", 1, "EG HWR Hau")],
82
+ "=M000010.O3EG HWR Hau": [(ModNameComment, "O", 2, "EG HWR Hau")],
83
+ "=M000010.O4EG HWR Hau": [(ModNameComment, "O", 3, "EG HWR Hau")],
84
+ # Groups
85
+ "=M000010.GP012005040": [
86
+ (
87
+ ModStatusGroups,
88
+ False,
89
+ 12,
90
+ [LcnAddr(0, 5, True), LcnAddr(0, 40, True)],
91
+ )
92
+ ],
93
+ "=M000010.GD008005040": [
94
+ (
95
+ ModStatusGroups,
96
+ True,
97
+ 8,
98
+ [LcnAddr(0, 5, True), LcnAddr(0, 40, True)],
99
+ )
100
+ ],
101
+ "=M000010.GD010005040030020010100200150099201": [
102
+ (
103
+ ModStatusGroups,
104
+ True,
105
+ 10,
106
+ [
107
+ LcnAddr(0, 5, True),
108
+ LcnAddr(0, 40, True),
109
+ LcnAddr(0, 30, True),
110
+ LcnAddr(0, 20, True),
111
+ LcnAddr(0, 10, True),
112
+ LcnAddr(0, 100, True),
113
+ LcnAddr(0, 200, True),
114
+ LcnAddr(0, 150, True),
115
+ LcnAddr(0, 99, True),
116
+ LcnAddr(0, 201, True),
117
+ ],
118
+ )
119
+ ],
120
+ # Status Output
121
+ ":M000010A1050": [(ModStatusOutput, OutputPort.OUTPUT1.value, 50.0)],
122
+ # Status Output Native
123
+ ":M000010O1050": [(ModStatusOutputNative, OutputPort.OUTPUT1.value, 50)],
124
+ # Status Relays
125
+ ":M000010Rx204": [
126
+ (
127
+ ModStatusRelays,
128
+ [False, False, True, True, False, False, True, True],
129
+ )
130
+ ],
131
+ # Status BinSensors
132
+ ":M000010Bx204": [
133
+ (
134
+ ModStatusBinSensors,
135
+ [False, False, True, True, False, False, True, True],
136
+ )
137
+ ],
138
+ # Status Var
139
+ "%M000010.A00301200": [(ModStatusVar, Var.VAR3, VarValue(1200))],
140
+ "%M000010.01200": [(ModStatusVar, Var.UNKNOWN, VarValue(1200))],
141
+ "%M000010.S101200": [(ModStatusVar, Var.R1VARSETPOINT, VarValue(1200))],
142
+ "%M000010.T1100050": [(ModStatusVar, Var.THRS1, VarValue(50))],
143
+ "%M000010.T3400050": [(ModStatusVar, Var.THRS3_4, VarValue(50))],
144
+ "=M000010.S1111112222233333444445555512345": [
145
+ (ModStatusVar, Var.THRS1, VarValue(11111)),
146
+ (ModStatusVar, Var.THRS2, VarValue(22222)),
147
+ (ModStatusVar, Var.THRS3, VarValue(33333)),
148
+ (ModStatusVar, Var.THRS4, VarValue(44444)),
149
+ (ModStatusVar, Var.THRS5, VarValue(55555)),
150
+ ],
151
+ # Status Leds and LogicOps
152
+ "=M000010.TLAEBFAAAAAAAANTVN": [
153
+ (
154
+ ModStatusLedsAndLogicOps,
155
+ [
156
+ LedStatus.OFF,
157
+ LedStatus.ON,
158
+ LedStatus.BLINK,
159
+ LedStatus.FLICKER,
160
+ LedStatus.OFF,
161
+ LedStatus.OFF,
162
+ LedStatus.OFF,
163
+ LedStatus.OFF,
164
+ LedStatus.OFF,
165
+ LedStatus.OFF,
166
+ LedStatus.OFF,
167
+ LedStatus.OFF,
168
+ ],
169
+ [
170
+ LogicOpStatus.NONE,
171
+ LogicOpStatus.SOME,
172
+ LogicOpStatus.ALL,
173
+ LogicOpStatus.NONE,
174
+ ],
175
+ )
176
+ ],
177
+ # Status Key Locks
178
+ "=M000010.TX255000063204": [
179
+ (
180
+ ModStatusKeyLocks,
181
+ [
182
+ [True, True, True, True, True, True, True, True],
183
+ [False, False, False, False, False, False, False, False],
184
+ [True, True, True, True, True, True, False, False],
185
+ [False, False, True, True, False, False, True, True],
186
+ ],
187
+ )
188
+ ],
189
+ # Status Access Control
190
+ "=M000010.ZI026043060013002": [
191
+ (
192
+ ModStatusAccessControl,
193
+ AccessControlPeriphery.TRANSMITTER,
194
+ "1a2b3c",
195
+ 1,
196
+ 2,
197
+ KeyAction.MAKE,
198
+ BatteryStatus.FULL,
199
+ )
200
+ ],
201
+ "=M000010.ZI026043060013011": [
202
+ (
203
+ ModStatusAccessControl,
204
+ AccessControlPeriphery.TRANSMITTER,
205
+ "1a2b3c",
206
+ 1,
207
+ 2,
208
+ KeyAction.HIT,
209
+ BatteryStatus.WEAK,
210
+ )
211
+ ],
212
+ "=M000010.ZT026043060": [
213
+ (
214
+ ModStatusAccessControl,
215
+ AccessControlPeriphery.TRANSPONDER,
216
+ "1a2b3c",
217
+ )
218
+ ],
219
+ "=M000010.ZF026043060": [
220
+ (
221
+ ModStatusAccessControl,
222
+ AccessControlPeriphery.FINGERPRINT,
223
+ "1a2b3c",
224
+ )
225
+ ],
226
+ "=M000010.ZC026043060": [
227
+ (
228
+ ModStatusAccessControl,
229
+ AccessControlPeriphery.CODELOCK,
230
+ "1a2b3c",
231
+ )
232
+ ],
233
+ # Status scene outputs
234
+ "=M000010.SZ003025150075100140000033200": [
235
+ (
236
+ ModStatusSceneOutputs,
237
+ 3,
238
+ [25, 75, 140, 33],
239
+ [150, 100, 0, 200],
240
+ )
241
+ ],
242
+ # SKH
243
+ "+M004000010.SKH000001": [(ModSendCommandHost, (0, 1))],
244
+ "+M004000010.SKH000001002003004005": [
245
+ (
246
+ ModSendCommandHost,
247
+ tuple(i for i in range(6)),
248
+ )
249
+ ],
250
+ "+M004000010.SKH000001002003004005006007008009010011012013": [
251
+ (
252
+ ModSendCommandHost,
253
+ tuple(i for i in range(14)),
254
+ )
255
+ ],
256
+ # SKH with partially invalid data
257
+ "+M004000010.SKH000001002": [(ModSendCommandHost, (0, 1))],
258
+ "+M004000010.SKH000001002003": [(ModSendCommandHost, (0, 1))],
259
+ "+M004000010.SKH000001002003004005006": [
260
+ (
261
+ ModSendCommandHost,
262
+ tuple(i for i in range(6)),
263
+ )
264
+ ],
265
+ # SKH (new header)
266
+ "$M000010.SKH000001": [(ModSendCommandHost, (0, 1))],
267
+ "$M000010.SKH000001002003004005": [
268
+ (
269
+ ModSendCommandHost,
270
+ tuple(i for i in range(6)),
271
+ )
272
+ ],
273
+ "$M000010.SKH000001002003004005006007008009010011012013": [
274
+ (
275
+ ModSendCommandHost,
276
+ tuple(i for i in range(14)),
277
+ )
278
+ ],
279
+ # SKH (new header) with partially invalid data
280
+ "$M000010.SKH000001002": [(ModSendCommandHost, (0, 1))],
281
+ "$M000010.SKH000001002003": [(ModSendCommandHost, (0, 1))],
282
+ "$M000010.SKH000001002003004005006": [
283
+ (
284
+ ModSendCommandHost,
285
+ tuple(i for i in range(6)),
286
+ )
287
+ ],
288
+ # STH
289
+ "+M004000010.STH000000": [
290
+ (
291
+ ModSendKeysHost,
292
+ [SendKeyCommand.DONTSEND] * 3,
293
+ [False] * 8,
294
+ )
295
+ ],
296
+ "+M004000010.STH057078": [
297
+ (
298
+ ModSendKeysHost,
299
+ [SendKeyCommand.HIT, SendKeyCommand.MAKE, SendKeyCommand.BREAK],
300
+ [False, True, True, True, False, False, True, False],
301
+ )
302
+ ],
303
+ # STH
304
+ "$M000010.STH000000": [
305
+ (
306
+ ModSendKeysHost,
307
+ [SendKeyCommand.DONTSEND] * 3,
308
+ [False] * 8,
309
+ )
310
+ ],
311
+ "$M000010.STH057078": [
312
+ (
313
+ ModSendKeysHost,
314
+ [SendKeyCommand.HIT, SendKeyCommand.MAKE, SendKeyCommand.BREAK],
315
+ [False, True, True, True, False, False, True, False],
316
+ )
317
+ ],
318
+ }
319
+
320
+
321
+ @pytest.mark.parametrize("message, expected", MESSAGES.items())
322
+ def test_message_parsing_mod_inputs(message, expected):
323
+ """Test if InputMod parses message correctly."""
324
+ inputs = InputParser.parse(message)
325
+ assert len(inputs) == len(expected)
326
+ for idx, inp in enumerate(inputs):
327
+ exp = (expected[idx][0])(LcnAddr(0, 10, False), *expected[idx][1:])
328
+ assert type(inp) is type(exp) # pylint: disable=unidiomatic-typecheck
329
+ assert vars(inp) == vars(exp)
pypck-0.8.3/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.8.3
@@ -1,257 +0,0 @@
1
- """Tests for input message parsing for bus messages."""
2
-
3
- import pytest
4
-
5
- from pypck.inputs import (
6
- InputParser,
7
- ModAck,
8
- ModNameComment,
9
- ModSendCommandHost,
10
- ModSendKeysHost,
11
- ModSk,
12
- ModSn,
13
- ModStatusAccessControl,
14
- ModStatusBinSensors,
15
- ModStatusGroups,
16
- ModStatusKeyLocks,
17
- ModStatusLedsAndLogicOps,
18
- ModStatusOutput,
19
- ModStatusOutputNative,
20
- ModStatusRelays,
21
- ModStatusSceneOutputs,
22
- ModStatusVar,
23
- )
24
- from pypck.lcn_addr import LcnAddr
25
- from pypck.lcn_defs import (
26
- AccessControlPeriphery,
27
- BatteryStatus,
28
- HardwareType,
29
- KeyAction,
30
- LedStatus,
31
- LogicOpStatus,
32
- OutputPort,
33
- SendKeyCommand,
34
- Var,
35
- VarValue,
36
- )
37
-
38
- MESSAGES = {
39
- # Ack
40
- "-M000010!": (ModAck, -1),
41
- "-M000010005": (ModAck, 5),
42
- # SK
43
- "=M000010.SK007": (ModSk, 7),
44
- # SN
45
- "=M000010.SN1AB20A123401FW190B11HW015": (
46
- ModSn,
47
- 0x1AB20A1234,
48
- 0x1,
49
- 0x190B11,
50
- HardwareType.SH_PLUS,
51
- ),
52
- "=M000010.SN1234567890AFFW190011HW011": (
53
- ModSn,
54
- 0x1234567890,
55
- 0xAF,
56
- 0x190011,
57
- HardwareType.UPP,
58
- ),
59
- # Name
60
- "=M000010.N1EG HWR Hau": (ModNameComment, "N", 0, "EG HWR Hau"),
61
- "=M000010.N2EG HWR Hau": (ModNameComment, "N", 1, "EG HWR Hau"),
62
- # Comment
63
- "=M000010.K1EG HWR Hau": (ModNameComment, "K", 0, "EG HWR Hau"),
64
- "=M000010.K2EG HWR Hau": (ModNameComment, "K", 1, "EG HWR Hau"),
65
- "=M000010.K3EG HWR Hau": (ModNameComment, "K", 2, "EG HWR Hau"),
66
- # Oem
67
- "=M000010.O1EG HWR Hau": (ModNameComment, "O", 0, "EG HWR Hau"),
68
- "=M000010.O2EG HWR Hau": (ModNameComment, "O", 1, "EG HWR Hau"),
69
- "=M000010.O3EG HWR Hau": (ModNameComment, "O", 2, "EG HWR Hau"),
70
- "=M000010.O4EG HWR Hau": (ModNameComment, "O", 3, "EG HWR Hau"),
71
- # Groups
72
- "=M000010.GP012005040": (
73
- ModStatusGroups,
74
- False,
75
- 12,
76
- [LcnAddr(0, 5, True), LcnAddr(0, 40, True)],
77
- ),
78
- "=M000010.GD008005040": (
79
- ModStatusGroups,
80
- True,
81
- 8,
82
- [LcnAddr(0, 5, True), LcnAddr(0, 40, True)],
83
- ),
84
- "=M000010.GD010005040030020010100200150099201": (
85
- ModStatusGroups,
86
- True,
87
- 10,
88
- [
89
- LcnAddr(0, 5, True),
90
- LcnAddr(0, 40, True),
91
- LcnAddr(0, 30, True),
92
- LcnAddr(0, 20, True),
93
- LcnAddr(0, 10, True),
94
- LcnAddr(0, 100, True),
95
- LcnAddr(0, 200, True),
96
- LcnAddr(0, 150, True),
97
- LcnAddr(0, 99, True),
98
- LcnAddr(0, 201, True),
99
- ],
100
- ),
101
- # Status Output
102
- ":M000010A1050": (ModStatusOutput, OutputPort.OUTPUT1.value, 50.0),
103
- # Status Output Native
104
- ":M000010O1050": (ModStatusOutputNative, OutputPort.OUTPUT1.value, 50),
105
- # Status Relays
106
- ":M000010Rx204": (
107
- ModStatusRelays,
108
- [False, False, True, True, False, False, True, True],
109
- ),
110
- # Status BinSensors
111
- ":M000010Bx204": (
112
- ModStatusBinSensors,
113
- [False, False, True, True, False, False, True, True],
114
- ),
115
- # Status Var
116
- "%M000010.A00301200": (ModStatusVar, Var.VAR3, VarValue(1200)),
117
- "%M000010.01200": (ModStatusVar, Var.UNKNOWN, VarValue(1200)),
118
- "%M000010.S101200": (ModStatusVar, Var.R1VARSETPOINT, VarValue(1200)),
119
- "%M000010.T1100050": (ModStatusVar, Var.THRS1, VarValue(50)),
120
- "%M000010.T3400050": (ModStatusVar, Var.THRS3_4, VarValue(50)),
121
- # Status Leds and LogicOps
122
- "=M000010.TLAEBFAAAAAAAANTVN": (
123
- ModStatusLedsAndLogicOps,
124
- [
125
- LedStatus.OFF,
126
- LedStatus.ON,
127
- LedStatus.BLINK,
128
- LedStatus.FLICKER,
129
- LedStatus.OFF,
130
- LedStatus.OFF,
131
- LedStatus.OFF,
132
- LedStatus.OFF,
133
- LedStatus.OFF,
134
- LedStatus.OFF,
135
- LedStatus.OFF,
136
- LedStatus.OFF,
137
- ],
138
- [LogicOpStatus.NONE, LogicOpStatus.SOME, LogicOpStatus.ALL, LogicOpStatus.NONE],
139
- ),
140
- # Status Key Locks
141
- "=M000010.TX255000063204": (
142
- ModStatusKeyLocks,
143
- [
144
- [True, True, True, True, True, True, True, True],
145
- [False, False, False, False, False, False, False, False],
146
- [True, True, True, True, True, True, False, False],
147
- [False, False, True, True, False, False, True, True],
148
- ],
149
- ),
150
- # Status Access Control
151
- "=M000010.ZI026043060013002": (
152
- ModStatusAccessControl,
153
- AccessControlPeriphery.TRANSMITTER,
154
- "1a2b3c",
155
- 1,
156
- 2,
157
- KeyAction.MAKE,
158
- BatteryStatus.FULL,
159
- ),
160
- "=M000010.ZI026043060013011": (
161
- ModStatusAccessControl,
162
- AccessControlPeriphery.TRANSMITTER,
163
- "1a2b3c",
164
- 1,
165
- 2,
166
- KeyAction.HIT,
167
- BatteryStatus.WEAK,
168
- ),
169
- "=M000010.ZT026043060": (
170
- ModStatusAccessControl,
171
- AccessControlPeriphery.TRANSPONDER,
172
- "1a2b3c",
173
- ),
174
- "=M000010.ZF026043060": (
175
- ModStatusAccessControl,
176
- AccessControlPeriphery.FINGERPRINT,
177
- "1a2b3c",
178
- ),
179
- "=M000010.ZC026043060": (
180
- ModStatusAccessControl,
181
- AccessControlPeriphery.CODELOCK,
182
- "1a2b3c",
183
- ),
184
- # Status scene outputs
185
- "=M000010.SZ003025150075100140000033200": (
186
- ModStatusSceneOutputs,
187
- 3,
188
- [25, 75, 140, 33],
189
- [150, 100, 0, 200],
190
- ),
191
- # SKH
192
- "+M004000010.SKH000001": (ModSendCommandHost, (0, 1)),
193
- "+M004000010.SKH000001002003004005": (
194
- ModSendCommandHost,
195
- tuple(i for i in range(6)),
196
- ),
197
- "+M004000010.SKH000001002003004005006007008009010011012013": (
198
- ModSendCommandHost,
199
- tuple(i for i in range(14)),
200
- ),
201
- # SKH with partially invalid data
202
- "+M004000010.SKH000001002": (ModSendCommandHost, (0, 1)),
203
- "+M004000010.SKH000001002003": (ModSendCommandHost, (0, 1)),
204
- "+M004000010.SKH000001002003004005006": (
205
- ModSendCommandHost,
206
- tuple(i for i in range(6)),
207
- ),
208
- # SKH (new header)
209
- "$M000010.SKH000001": (ModSendCommandHost, (0, 1)),
210
- "$M000010.SKH000001002003004005": (
211
- ModSendCommandHost,
212
- tuple(i for i in range(6)),
213
- ),
214
- "$M000010.SKH000001002003004005006007008009010011012013": (
215
- ModSendCommandHost,
216
- tuple(i for i in range(14)),
217
- ),
218
- # SKH (new header) with partially invalid data
219
- "$M000010.SKH000001002": (ModSendCommandHost, (0, 1)),
220
- "$M000010.SKH000001002003": (ModSendCommandHost, (0, 1)),
221
- "$M000010.SKH000001002003004005006": (
222
- ModSendCommandHost,
223
- tuple(i for i in range(6)),
224
- ),
225
- # STH
226
- "+M004000010.STH000000": (
227
- ModSendKeysHost,
228
- [SendKeyCommand.DONTSEND] * 3,
229
- [False] * 8,
230
- ),
231
- "+M004000010.STH057078": (
232
- ModSendKeysHost,
233
- [SendKeyCommand.HIT, SendKeyCommand.MAKE, SendKeyCommand.BREAK],
234
- [False, True, True, True, False, False, True, False],
235
- ),
236
- # STH
237
- "$M000010.STH000000": (
238
- ModSendKeysHost,
239
- [SendKeyCommand.DONTSEND] * 3,
240
- [False] * 8,
241
- ),
242
- "$M000010.STH057078": (
243
- ModSendKeysHost,
244
- [SendKeyCommand.HIT, SendKeyCommand.MAKE, SendKeyCommand.BREAK],
245
- [False, True, True, True, False, False, True, False],
246
- ),
247
- }
248
-
249
-
250
- @pytest.mark.parametrize("message, expected", MESSAGES.items())
251
- def test_message_parsing_single_mod_input(message, expected):
252
- """Test if InputMod parses message correctly."""
253
- exp = (expected[0])(LcnAddr(0, 10, False), *expected[1:])
254
- inp = InputParser.parse(message)
255
- assert len(inp) == 1
256
- assert type(inp[0]) is type(exp) # pylint: disable=unidiomatic-typecheck
257
- assert vars(inp[0]) == vars(exp)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes