pypck 0.8.9__tar.gz → 0.8.10__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.
- {pypck-0.8.9/pypck.egg-info → pypck-0.8.10}/PKG-INFO +1 -1
- pypck-0.8.10/VERSION +1 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck/connection.py +4 -4
- {pypck-0.8.9 → pypck-0.8.10}/pypck/helpers.py +3 -3
- {pypck-0.8.9 → pypck-0.8.10}/pypck/lcn_defs.py +46 -44
- {pypck-0.8.9 → pypck-0.8.10}/pypck/request_handlers.py +2 -1
- {pypck-0.8.9 → pypck-0.8.10/pypck.egg-info}/PKG-INFO +1 -1
- {pypck-0.8.9 → pypck-0.8.10}/tests/test_commands.py +20 -16
- {pypck-0.8.9 → pypck-0.8.10}/tests/test_connection.py +76 -25
- {pypck-0.8.9 → pypck-0.8.10}/tests/test_dyn_text.py +10 -3
- {pypck-0.8.9 → pypck-0.8.10}/tests/test_messages.py +6 -1
- {pypck-0.8.9 → pypck-0.8.10}/tests/test_vars.py +4 -2
- pypck-0.8.9/VERSION +0 -1
- {pypck-0.8.9 → pypck-0.8.10}/LICENSE +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/README.md +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck/__init__.py +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck/inputs.py +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck/lcn_addr.py +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck/module.py +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck/pck_commands.py +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck/timeout_retry.py +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck.egg-info/SOURCES.txt +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck.egg-info/dependency_links.txt +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck.egg-info/not-zip-safe +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pypck.egg-info/top_level.txt +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/pyproject.toml +0 -0
- {pypck-0.8.9 → pypck-0.8.10}/setup.cfg +0 -0
pypck-0.8.10/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.8.10
|
|
@@ -13,7 +13,7 @@ from pypck import inputs, lcn_defs
|
|
|
13
13
|
from pypck.helpers import TaskRegistry
|
|
14
14
|
from pypck.lcn_addr import LcnAddr
|
|
15
15
|
from pypck.lcn_defs import LcnEvent
|
|
16
|
-
from pypck.module import
|
|
16
|
+
from pypck.module import GroupConnection, ModuleConnection
|
|
17
17
|
from pypck.pck_commands import PckGenerator
|
|
18
18
|
|
|
19
19
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -243,7 +243,7 @@ class PchkConnectionManager:
|
|
|
243
243
|
if isinstance(exc, (ConnectionRefusedError, OSError)):
|
|
244
244
|
raise PchkConnectionRefusedError()
|
|
245
245
|
else:
|
|
246
|
-
raise
|
|
246
|
+
raise exc
|
|
247
247
|
|
|
248
248
|
if pending:
|
|
249
249
|
for awaitable in pending:
|
|
@@ -405,8 +405,8 @@ class PchkConnectionManager:
|
|
|
405
405
|
|
|
406
406
|
def get_address_conn(
|
|
407
407
|
self, addr: LcnAddr, request_serials: bool = True
|
|
408
|
-
) ->
|
|
409
|
-
"""Create and/or return
|
|
408
|
+
) -> ModuleConnection | GroupConnection:
|
|
409
|
+
"""Create and/or return a connection to the given module or group."""
|
|
410
410
|
if addr.is_group:
|
|
411
411
|
return self.get_group_conn(addr)
|
|
412
412
|
return self.get_module_conn(addr, request_serials)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Helper functions for pypck."""
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
-
from collections.abc import
|
|
4
|
+
from collections.abc import Coroutine
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
7
|
|
|
@@ -30,9 +30,9 @@ class TaskRegistry:
|
|
|
30
30
|
if task in self.tasks:
|
|
31
31
|
self.tasks.remove(task)
|
|
32
32
|
|
|
33
|
-
def create_task(self, coro:
|
|
33
|
+
def create_task(self, coro: Coroutine[Any, Any, Any]) -> "asyncio.Task[None]":
|
|
34
34
|
"""Create a task and store a reference in the task registry."""
|
|
35
|
-
task = asyncio.create_task(coro)
|
|
35
|
+
task: asyncio.Task[Any] = asyncio.create_task(coro)
|
|
36
36
|
task.add_done_callback(self.remove_task)
|
|
37
37
|
self.tasks.append(task)
|
|
38
38
|
return task
|
|
@@ -360,6 +360,44 @@ class Var(Enum):
|
|
|
360
360
|
S0INPUT3 = auto()
|
|
361
361
|
S0INPUT4 = auto() # LCN-BU4LJVarValue
|
|
362
362
|
|
|
363
|
+
@classmethod
|
|
364
|
+
def variables(cls) -> list[Var]:
|
|
365
|
+
"""Return a list of all variable types."""
|
|
366
|
+
return [
|
|
367
|
+
cls.VAR1ORTVAR,
|
|
368
|
+
cls.VAR2ORR1VAR,
|
|
369
|
+
cls.VAR3ORR2VAR,
|
|
370
|
+
cls.VAR4,
|
|
371
|
+
cls.VAR5,
|
|
372
|
+
cls.VAR6,
|
|
373
|
+
cls.VAR7,
|
|
374
|
+
cls.VAR8,
|
|
375
|
+
cls.VAR9,
|
|
376
|
+
cls.VAR10,
|
|
377
|
+
cls.VAR11,
|
|
378
|
+
cls.VAR12,
|
|
379
|
+
]
|
|
380
|
+
|
|
381
|
+
@classmethod
|
|
382
|
+
def set_points(cls) -> list[Var]:
|
|
383
|
+
"""Return a list of all set-point variable types."""
|
|
384
|
+
return [cls.R1VARSETPOINT, cls.R2VARSETPOINT]
|
|
385
|
+
|
|
386
|
+
@classmethod
|
|
387
|
+
def thresholds(cls) -> list[list[Var]]:
|
|
388
|
+
"""Return a list of all threshold variable types."""
|
|
389
|
+
return [
|
|
390
|
+
[cls.THRS1, cls.THRS2, cls.THRS3, cls.THRS4, cls.THRS5],
|
|
391
|
+
[cls.THRS2_1, cls.THRS2_2, cls.THRS2_3, cls.THRS2_4],
|
|
392
|
+
[cls.THRS3_1, cls.THRS3_2, cls.THRS3_3, cls.THRS3_4],
|
|
393
|
+
[cls.THRS4_1, cls.THRS4_2, cls.THRS4_3, cls.THRS4_4],
|
|
394
|
+
]
|
|
395
|
+
|
|
396
|
+
@classmethod
|
|
397
|
+
def s0s(cls) -> list[Var]:
|
|
398
|
+
"""Return a list of all S0-input variable types."""
|
|
399
|
+
return [cls.S0INPUT1, cls.S0INPUT2, cls.S0INPUT3, cls.S0INPUT4]
|
|
400
|
+
|
|
363
401
|
@staticmethod
|
|
364
402
|
def var_id_to_var(var_id: int) -> Var:
|
|
365
403
|
"""Translate a given id into a variable type.
|
|
@@ -369,9 +407,9 @@ class Var(Enum):
|
|
|
369
407
|
:returns: The translated variable enum.
|
|
370
408
|
:rtype: Var
|
|
371
409
|
"""
|
|
372
|
-
if (var_id < 0) or (var_id >= len(Var.variables)):
|
|
410
|
+
if (var_id < 0) or (var_id >= len(Var.variables())):
|
|
373
411
|
raise ValueError("Bad var_id.")
|
|
374
|
-
return Var.variables[var_id]
|
|
412
|
+
return Var.variables()[var_id]
|
|
375
413
|
|
|
376
414
|
@staticmethod
|
|
377
415
|
def set_point_id_to_var(set_point_id: int) -> Var:
|
|
@@ -382,9 +420,9 @@ class Var(Enum):
|
|
|
382
420
|
:return: The translated var
|
|
383
421
|
:rtype: Var
|
|
384
422
|
"""
|
|
385
|
-
if (set_point_id < 0) or (set_point_id >= len(Var.set_points)):
|
|
423
|
+
if (set_point_id < 0) or (set_point_id >= len(Var.set_points())):
|
|
386
424
|
raise ValueError("Bad set_point_id.")
|
|
387
|
-
return Var.set_points[set_point_id]
|
|
425
|
+
return Var.set_points()[set_point_id]
|
|
388
426
|
|
|
389
427
|
@staticmethod
|
|
390
428
|
def thrs_id_to_var(register_id: int, thrs_id: int) -> Var:
|
|
@@ -399,12 +437,12 @@ class Var(Enum):
|
|
|
399
437
|
"""
|
|
400
438
|
if (
|
|
401
439
|
(register_id < 0)
|
|
402
|
-
or (register_id >= len(Var.thresholds))
|
|
440
|
+
or (register_id >= len(Var.thresholds()))
|
|
403
441
|
or (thrs_id < 0)
|
|
404
442
|
or (thrs_id >= (5 if (register_id == 0) else 4))
|
|
405
443
|
):
|
|
406
444
|
raise ValueError("Bad register_id and/or thrs_id.")
|
|
407
|
-
return Var.thresholds[register_id][thrs_id]
|
|
445
|
+
return Var.thresholds()[register_id][thrs_id]
|
|
408
446
|
|
|
409
447
|
@staticmethod
|
|
410
448
|
def s0_id_to_var(s0_id: int) -> Var:
|
|
@@ -415,9 +453,9 @@ class Var(Enum):
|
|
|
415
453
|
:return: The translated var
|
|
416
454
|
:rtype: Var
|
|
417
455
|
"""
|
|
418
|
-
if (s0_id < 0) or (s0_id >= len(Var.s0s)):
|
|
456
|
+
if (s0_id < 0) or (s0_id >= len(Var.s0s())):
|
|
419
457
|
raise ValueError("Bad s0_id.")
|
|
420
|
-
return Var.s0s[s0_id]
|
|
458
|
+
return Var.s0s()[s0_id]
|
|
421
459
|
|
|
422
460
|
@staticmethod
|
|
423
461
|
def to_var_id(var: Var) -> int:
|
|
@@ -658,42 +696,6 @@ class Var(Enum):
|
|
|
658
696
|
return (not lock_state) and (software_serial < 0x170206)
|
|
659
697
|
|
|
660
698
|
|
|
661
|
-
# Helper list to get var by numeric id.
|
|
662
|
-
Var.variables = [ # type: ignore
|
|
663
|
-
Var.VAR1ORTVAR,
|
|
664
|
-
Var.VAR2ORR1VAR,
|
|
665
|
-
Var.VAR3ORR2VAR,
|
|
666
|
-
Var.VAR4,
|
|
667
|
-
Var.VAR5,
|
|
668
|
-
Var.VAR6,
|
|
669
|
-
Var.VAR7,
|
|
670
|
-
Var.VAR8,
|
|
671
|
-
Var.VAR9,
|
|
672
|
-
Var.VAR10,
|
|
673
|
-
Var.VAR11,
|
|
674
|
-
Var.VAR12,
|
|
675
|
-
]
|
|
676
|
-
|
|
677
|
-
# Helper list to get set-point var by numeric id.
|
|
678
|
-
Var.set_points = [Var.R1VARSETPOINT, Var.R2VARSETPOINT] # type: ignore
|
|
679
|
-
|
|
680
|
-
# Helper list to get threshold var by numeric id.
|
|
681
|
-
Var.thresholds = [ # type: ignore
|
|
682
|
-
[Var.THRS1, Var.THRS2, Var.THRS3, Var.THRS4, Var.THRS5],
|
|
683
|
-
[Var.THRS2_1, Var.THRS2_2, Var.THRS2_3, Var.THRS2_4],
|
|
684
|
-
[Var.THRS3_1, Var.THRS3_2, Var.THRS3_3, Var.THRS3_4],
|
|
685
|
-
[Var.THRS4_1, Var.THRS4_2, Var.THRS4_3, Var.THRS4_4],
|
|
686
|
-
]
|
|
687
|
-
|
|
688
|
-
# Helper list to get S0-input var by numeric id.
|
|
689
|
-
Var.s0s = [ # type: ignore
|
|
690
|
-
Var.S0INPUT1,
|
|
691
|
-
Var.S0INPUT2,
|
|
692
|
-
Var.S0INPUT3,
|
|
693
|
-
Var.S0INPUT4,
|
|
694
|
-
]
|
|
695
|
-
|
|
696
|
-
|
|
697
699
|
class VarUnit(Enum):
|
|
698
700
|
"""Measurement units used with LCN variables."""
|
|
699
701
|
|
|
@@ -660,6 +660,7 @@ class StatusRequestsHandler:
|
|
|
660
660
|
async def activate_all(self, activate_s0: bool = False) -> None:
|
|
661
661
|
"""Activate all status requests."""
|
|
662
662
|
await self.addr_conn.conn.segment_scan_completed_event.wait()
|
|
663
|
+
var_s0s = lcn_defs.Var.s0s()
|
|
663
664
|
for item in (
|
|
664
665
|
list(lcn_defs.OutputPort)
|
|
665
666
|
+ list(lcn_defs.RelayPort)
|
|
@@ -673,7 +674,7 @@ class StatusRequestsHandler:
|
|
|
673
674
|
if (
|
|
674
675
|
(not activate_s0)
|
|
675
676
|
and isinstance(item, lcn_defs.Var)
|
|
676
|
-
and (item in
|
|
677
|
+
and (item in var_s0s)
|
|
677
678
|
):
|
|
678
679
|
continue
|
|
679
680
|
await self.activate(item)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Tests for command generation directed at bus modules and groups."""
|
|
2
2
|
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
3
5
|
import pytest
|
|
4
6
|
|
|
5
7
|
from pypck.lcn_addr import LcnAddr
|
|
@@ -24,7 +26,7 @@ from pypck.pck_commands import PckGenerator
|
|
|
24
26
|
|
|
25
27
|
NEW_VAR_SW_AGE = 0x170206
|
|
26
28
|
|
|
27
|
-
COMMANDS = {
|
|
29
|
+
COMMANDS: dict[str | bytes, Any] = {
|
|
28
30
|
# Host commands
|
|
29
31
|
**{
|
|
30
32
|
f"^ping{counter:d}": (PckGenerator.ping, counter)
|
|
@@ -93,7 +95,7 @@ COMMANDS = {
|
|
|
93
95
|
var,
|
|
94
96
|
NEW_VAR_SW_AGE,
|
|
95
97
|
)
|
|
96
|
-
for var in Var.variables
|
|
98
|
+
for var in Var.variables()
|
|
97
99
|
},
|
|
98
100
|
**{
|
|
99
101
|
f"MWS{Var.to_set_point_id(var) + 1:03d}": (
|
|
@@ -101,7 +103,7 @@ COMMANDS = {
|
|
|
101
103
|
var,
|
|
102
104
|
NEW_VAR_SW_AGE,
|
|
103
105
|
)
|
|
104
|
-
for var in Var.set_points
|
|
106
|
+
for var in Var.set_points()
|
|
105
107
|
},
|
|
106
108
|
**{
|
|
107
109
|
f"MWC{Var.to_s0_id(var) + 1:03d}": (
|
|
@@ -109,7 +111,7 @@ COMMANDS = {
|
|
|
109
111
|
var,
|
|
110
112
|
NEW_VAR_SW_AGE,
|
|
111
113
|
)
|
|
112
|
-
for var in Var.s0s
|
|
114
|
+
for var in Var.s0s()
|
|
113
115
|
},
|
|
114
116
|
**{
|
|
115
117
|
f"SE{Var.to_thrs_register_id(var) + 1:03d}": (
|
|
@@ -117,7 +119,7 @@ COMMANDS = {
|
|
|
117
119
|
var,
|
|
118
120
|
NEW_VAR_SW_AGE,
|
|
119
121
|
)
|
|
120
|
-
for reg in Var.thresholds
|
|
122
|
+
for reg in Var.thresholds()
|
|
121
123
|
for var in reg
|
|
122
124
|
},
|
|
123
125
|
# Variable status (legacy commands)
|
|
@@ -128,7 +130,7 @@ COMMANDS = {
|
|
|
128
130
|
"MWSB": (PckGenerator.request_var_status, Var.R2VARSETPOINT, NEW_VAR_SW_AGE - 1),
|
|
129
131
|
**{
|
|
130
132
|
"SL1": (PckGenerator.request_var_status, var, NEW_VAR_SW_AGE - 1)
|
|
131
|
-
for var in Var.thresholds[0]
|
|
133
|
+
for var in Var.thresholds()[0]
|
|
132
134
|
},
|
|
133
135
|
# Output manipulation
|
|
134
136
|
**{
|
|
@@ -305,7 +307,7 @@ COMMANDS = {
|
|
|
305
307
|
# Variable manipulation
|
|
306
308
|
**{
|
|
307
309
|
f"X2{var.value | 0x40:03d}016225": (PckGenerator.update_status_var, var, 4321)
|
|
308
|
-
for var in Var.variables
|
|
310
|
+
for var in Var.variables()
|
|
309
311
|
},
|
|
310
312
|
"X2030044129": (PckGenerator.var_abs, Var.R1VARSETPOINT, 4201),
|
|
311
313
|
"X2030108129": (PckGenerator.var_abs, Var.R2VARSETPOINT, 4201),
|
|
@@ -314,7 +316,7 @@ COMMANDS = {
|
|
|
314
316
|
"ZS30000": (PckGenerator.var_reset, Var.TVAR, 0x170205),
|
|
315
317
|
**{
|
|
316
318
|
f"Z-{var.value + 1:03d}4090": (PckGenerator.var_reset, var, 0x170206)
|
|
317
|
-
for var in Var.variables
|
|
319
|
+
for var in Var.variables()
|
|
318
320
|
},
|
|
319
321
|
"ZA23423": (PckGenerator.var_rel, Var.TVAR, RelVarRef.CURRENT, 23423, 0x170205),
|
|
320
322
|
"ZS23423": (PckGenerator.var_rel, Var.TVAR, RelVarRef.CURRENT, -23423, 0x170205),
|
|
@@ -326,7 +328,7 @@ COMMANDS = {
|
|
|
326
328
|
-3000,
|
|
327
329
|
0x170206,
|
|
328
330
|
)
|
|
329
|
-
for var in Var.variables
|
|
331
|
+
for var in Var.variables()
|
|
330
332
|
if var != Var.TVAR
|
|
331
333
|
},
|
|
332
334
|
**{
|
|
@@ -337,7 +339,7 @@ COMMANDS = {
|
|
|
337
339
|
-500,
|
|
338
340
|
sw_age,
|
|
339
341
|
)
|
|
340
|
-
for nvar, var in enumerate(Var.set_points)
|
|
342
|
+
for nvar, var in enumerate(Var.set_points())
|
|
341
343
|
for nref, ref in enumerate(RelVarRef)
|
|
342
344
|
for sw_age in (0x170206, 0x170205)
|
|
343
345
|
},
|
|
@@ -349,14 +351,14 @@ COMMANDS = {
|
|
|
349
351
|
500,
|
|
350
352
|
sw_age,
|
|
351
353
|
)
|
|
352
|
-
for nvar, var in enumerate(Var.set_points)
|
|
354
|
+
for nvar, var in enumerate(Var.set_points())
|
|
353
355
|
for nref, ref in enumerate(RelVarRef)
|
|
354
356
|
for sw_age in (0x170206, 0x170205)
|
|
355
357
|
},
|
|
356
358
|
**{
|
|
357
359
|
f"SS{('R', 'E')[nref]}0500SR{r + 1}{i + 1}": (
|
|
358
360
|
PckGenerator.var_rel,
|
|
359
|
-
Var.thresholds[r][i],
|
|
361
|
+
Var.thresholds()[r][i],
|
|
360
362
|
ref,
|
|
361
363
|
-500,
|
|
362
364
|
0x170206,
|
|
@@ -368,7 +370,7 @@ COMMANDS = {
|
|
|
368
370
|
**{
|
|
369
371
|
f"SS{('R', 'E')[nref]}0500AR{r + 1}{i + 1}": (
|
|
370
372
|
PckGenerator.var_rel,
|
|
371
|
-
Var.thresholds[r][i],
|
|
373
|
+
Var.thresholds()[r][i],
|
|
372
374
|
ref,
|
|
373
375
|
500,
|
|
374
376
|
0x170206,
|
|
@@ -380,7 +382,7 @@ COMMANDS = {
|
|
|
380
382
|
**{
|
|
381
383
|
f"SS{('R', 'E')[nref]}0500S{1 << (4 - i):05b}": (
|
|
382
384
|
PckGenerator.var_rel,
|
|
383
|
-
Var.thresholds[0][i],
|
|
385
|
+
Var.thresholds()[0][i],
|
|
384
386
|
ref,
|
|
385
387
|
-500,
|
|
386
388
|
0x170205,
|
|
@@ -391,7 +393,7 @@ COMMANDS = {
|
|
|
391
393
|
**{
|
|
392
394
|
f"SS{('R', 'E')[nref]}0500A{1 << (4 - i):05b}": (
|
|
393
395
|
PckGenerator.var_rel,
|
|
394
|
-
Var.thresholds[0][i],
|
|
396
|
+
Var.thresholds()[0][i],
|
|
395
397
|
ref,
|
|
396
398
|
500,
|
|
397
399
|
0x170205,
|
|
@@ -562,6 +564,8 @@ COMMANDS = {
|
|
|
562
564
|
|
|
563
565
|
|
|
564
566
|
@pytest.mark.parametrize("expected, command", COMMANDS.items())
|
|
565
|
-
def test_command_generation_single_mod_noack(
|
|
567
|
+
def test_command_generation_single_mod_noack(
|
|
568
|
+
expected: str, command: tuple[Any, ...]
|
|
569
|
+
) -> None:
|
|
566
570
|
"""Test if InputMod parses message correctly."""
|
|
567
571
|
assert expected == command[0](*command[1:])
|
|
@@ -16,22 +16,29 @@ from pypck.lcn_addr import LcnAddr
|
|
|
16
16
|
from pypck.lcn_defs import LcnEvent
|
|
17
17
|
from pypck.module import ModuleConnection
|
|
18
18
|
|
|
19
|
+
from .conftest import MockPchkConnectionManager
|
|
20
|
+
from .mock_pchk import MockPchkServer
|
|
21
|
+
|
|
19
22
|
|
|
20
23
|
@pytest.mark.asyncio
|
|
21
|
-
async def test_close_without_connect(pypck_client):
|
|
24
|
+
async def test_close_without_connect(pypck_client: MockPchkConnectionManager) -> None:
|
|
22
25
|
"""Test closing of PchkConnectionManager without connecting."""
|
|
23
26
|
await pypck_client.async_close()
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
@pytest.mark.asyncio
|
|
27
|
-
async def test_authenticate(
|
|
30
|
+
async def test_authenticate(
|
|
31
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
32
|
+
) -> None:
|
|
28
33
|
"""Test authentication procedure."""
|
|
29
34
|
await pypck_client.async_connect()
|
|
30
35
|
assert pypck_client.is_ready()
|
|
31
36
|
|
|
32
37
|
|
|
33
38
|
@pytest.mark.asyncio
|
|
34
|
-
async def test_port_error(
|
|
39
|
+
async def test_port_error(
|
|
40
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
41
|
+
) -> None:
|
|
35
42
|
"""Test wrong port."""
|
|
36
43
|
pypck_client.port = 55555
|
|
37
44
|
with pytest.raises(PchkConnectionRefusedError):
|
|
@@ -39,7 +46,9 @@ async def test_port_error(pchk_server, pypck_client):
|
|
|
39
46
|
|
|
40
47
|
|
|
41
48
|
@pytest.mark.asyncio
|
|
42
|
-
async def test_authentication_error(
|
|
49
|
+
async def test_authentication_error(
|
|
50
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
51
|
+
) -> None:
|
|
43
52
|
"""Test wrong login credentials."""
|
|
44
53
|
pypck_client.password = "wrong_password"
|
|
45
54
|
with pytest.raises(PchkAuthenticationError):
|
|
@@ -47,7 +56,9 @@ async def test_authentication_error(pchk_server, pypck_client):
|
|
|
47
56
|
|
|
48
57
|
|
|
49
58
|
@pytest.mark.asyncio
|
|
50
|
-
async def test_license_error(
|
|
59
|
+
async def test_license_error(
|
|
60
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
61
|
+
) -> None:
|
|
51
62
|
"""Test license error."""
|
|
52
63
|
pchk_server.set_license_error(True)
|
|
53
64
|
|
|
@@ -56,14 +67,18 @@ async def test_license_error(pchk_server, pypck_client):
|
|
|
56
67
|
|
|
57
68
|
|
|
58
69
|
@pytest.mark.asyncio
|
|
59
|
-
async def test_timeout_error(
|
|
70
|
+
async def test_timeout_error(
|
|
71
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
72
|
+
) -> None:
|
|
60
73
|
"""Test timeout when connecting."""
|
|
61
74
|
with pytest.raises(PchkConnectionFailedError):
|
|
62
75
|
await pypck_client.async_connect(timeout=0)
|
|
63
76
|
|
|
64
77
|
|
|
65
78
|
@pytest.mark.asyncio
|
|
66
|
-
async def test_lcn_connected(
|
|
79
|
+
async def test_lcn_connected(
|
|
80
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
81
|
+
) -> None:
|
|
67
82
|
"""Test lcn disconnected event."""
|
|
68
83
|
event_callback = Mock()
|
|
69
84
|
pypck_client.register_for_events(event_callback)
|
|
@@ -80,7 +95,9 @@ async def test_lcn_connected(pchk_server, pypck_client):
|
|
|
80
95
|
|
|
81
96
|
|
|
82
97
|
@pytest.mark.asyncio
|
|
83
|
-
async def test_lcn_disconnected(
|
|
98
|
+
async def test_lcn_disconnected(
|
|
99
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
100
|
+
) -> None:
|
|
84
101
|
"""Test lcn disconnected event."""
|
|
85
102
|
event_callback = Mock()
|
|
86
103
|
pypck_client.register_for_events(event_callback)
|
|
@@ -94,7 +111,9 @@ async def test_lcn_disconnected(pchk_server, pypck_client):
|
|
|
94
111
|
|
|
95
112
|
|
|
96
113
|
@pytest.mark.asyncio
|
|
97
|
-
async def test_connection_lost(
|
|
114
|
+
async def test_connection_lost(
|
|
115
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
116
|
+
) -> None:
|
|
98
117
|
"""Test pchk server connection close."""
|
|
99
118
|
event_callback = Mock()
|
|
100
119
|
pypck_client.register_for_events(event_callback)
|
|
@@ -109,8 +128,11 @@ async def test_connection_lost(pchk_server, pypck_client):
|
|
|
109
128
|
|
|
110
129
|
@pytest.mark.asyncio
|
|
111
130
|
async def test_multiple_connections(
|
|
112
|
-
pchk_server
|
|
113
|
-
|
|
131
|
+
pchk_server: MockPchkServer,
|
|
132
|
+
pypck_client: MockPchkConnectionManager,
|
|
133
|
+
pchk_server_2: MockPchkServer,
|
|
134
|
+
pypck_client_2: MockPchkConnectionManager,
|
|
135
|
+
) -> None:
|
|
114
136
|
"""Test that two independent connections can coexists."""
|
|
115
137
|
await pypck_client_2.async_connect()
|
|
116
138
|
|
|
@@ -128,7 +150,9 @@ async def test_multiple_connections(
|
|
|
128
150
|
|
|
129
151
|
|
|
130
152
|
@pytest.mark.asyncio
|
|
131
|
-
async def test_segment_coupler_search(
|
|
153
|
+
async def test_segment_coupler_search(
|
|
154
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
155
|
+
) -> None:
|
|
132
156
|
"""Test segment coupler search."""
|
|
133
157
|
await pypck_client.async_connect()
|
|
134
158
|
await pypck_client.scan_segment_couplers(3, 0)
|
|
@@ -141,7 +165,9 @@ async def test_segment_coupler_search(pchk_server, pypck_client):
|
|
|
141
165
|
|
|
142
166
|
|
|
143
167
|
@pytest.mark.asyncio
|
|
144
|
-
async def test_segment_coupler_response(
|
|
168
|
+
async def test_segment_coupler_response(
|
|
169
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
170
|
+
) -> None:
|
|
145
171
|
"""Test segment coupler response."""
|
|
146
172
|
await pypck_client.async_connect()
|
|
147
173
|
|
|
@@ -159,7 +185,9 @@ async def test_segment_coupler_response(pchk_server, pypck_client):
|
|
|
159
185
|
|
|
160
186
|
|
|
161
187
|
@pytest.mark.asyncio
|
|
162
|
-
async def test_module_scan(
|
|
188
|
+
async def test_module_scan(
|
|
189
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
190
|
+
) -> None:
|
|
163
191
|
"""Test module scan."""
|
|
164
192
|
await pypck_client.async_connect()
|
|
165
193
|
await pypck_client.scan_modules(3, 0)
|
|
@@ -170,7 +198,9 @@ async def test_module_scan(pchk_server, pypck_client):
|
|
|
170
198
|
|
|
171
199
|
|
|
172
200
|
@pytest.mark.asyncio
|
|
173
|
-
async def test_module_sn_response(
|
|
201
|
+
async def test_module_sn_response(
|
|
202
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
203
|
+
) -> None:
|
|
174
204
|
"""Test module scan."""
|
|
175
205
|
await pypck_client.async_connect()
|
|
176
206
|
module = pypck_client.get_address_conn(LcnAddr(0, 7, False))
|
|
@@ -187,7 +217,9 @@ async def test_module_sn_response(pchk_server, pypck_client):
|
|
|
187
217
|
|
|
188
218
|
|
|
189
219
|
@pytest.mark.asyncio
|
|
190
|
-
async def test_send_command_to_server(
|
|
220
|
+
async def test_send_command_to_server(
|
|
221
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
222
|
+
) -> None:
|
|
191
223
|
"""Test sending a command to the PCHK server."""
|
|
192
224
|
await pypck_client.async_connect()
|
|
193
225
|
message = ">M000007.PIN003"
|
|
@@ -196,14 +228,16 @@ async def test_send_command_to_server(pchk_server, pypck_client):
|
|
|
196
228
|
|
|
197
229
|
|
|
198
230
|
@pytest.mark.asyncio
|
|
199
|
-
async def test_ping(
|
|
231
|
+
async def test_ping(
|
|
232
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
233
|
+
) -> None:
|
|
200
234
|
"""Test if pings are send."""
|
|
201
235
|
await pypck_client.async_connect()
|
|
202
236
|
assert await pchk_server.received("^ping0")
|
|
203
237
|
|
|
204
238
|
|
|
205
239
|
@pytest.mark.asyncio
|
|
206
|
-
async def test_add_address_connections(pypck_client):
|
|
240
|
+
async def test_add_address_connections(pypck_client: MockPchkConnectionManager) -> None:
|
|
207
241
|
"""Test if new address connections are added on request."""
|
|
208
242
|
lcn_addr = LcnAddr(0, 10, False)
|
|
209
243
|
assert lcn_addr not in pypck_client.address_conns
|
|
@@ -215,7 +249,9 @@ async def test_add_address_connections(pypck_client):
|
|
|
215
249
|
|
|
216
250
|
|
|
217
251
|
@pytest.mark.asyncio
|
|
218
|
-
async def test_add_address_connections_by_message(
|
|
252
|
+
async def test_add_address_connections_by_message(
|
|
253
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
254
|
+
) -> None:
|
|
219
255
|
"""Test if new address connections are added by received message."""
|
|
220
256
|
await pypck_client.async_connect()
|
|
221
257
|
lcn_addr = LcnAddr(0, 10, False)
|
|
@@ -229,10 +265,13 @@ async def test_add_address_connections_by_message(pchk_server, pypck_client):
|
|
|
229
265
|
|
|
230
266
|
|
|
231
267
|
@pytest.mark.asyncio
|
|
232
|
-
async def test_groups_static_membership_discovery(
|
|
268
|
+
async def test_groups_static_membership_discovery(
|
|
269
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
270
|
+
) -> None:
|
|
233
271
|
"""Test module scan."""
|
|
234
272
|
await pypck_client.async_connect()
|
|
235
273
|
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
274
|
+
assert isinstance(module, ModuleConnection)
|
|
236
275
|
|
|
237
276
|
task = asyncio.create_task(module.request_static_groups())
|
|
238
277
|
assert await pchk_server.received(">M000010.GP")
|
|
@@ -245,10 +284,13 @@ async def test_groups_static_membership_discovery(pchk_server, pypck_client):
|
|
|
245
284
|
|
|
246
285
|
|
|
247
286
|
@pytest.mark.asyncio
|
|
248
|
-
async def test_groups_dynamic_membership_discovery(
|
|
287
|
+
async def test_groups_dynamic_membership_discovery(
|
|
288
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
289
|
+
) -> None:
|
|
249
290
|
"""Test module scan."""
|
|
250
291
|
await pypck_client.async_connect()
|
|
251
292
|
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
293
|
+
assert isinstance(module, ModuleConnection)
|
|
252
294
|
|
|
253
295
|
task = asyncio.create_task(module.request_dynamic_groups())
|
|
254
296
|
assert await pchk_server.received(">M000010.GD")
|
|
@@ -261,10 +303,13 @@ async def test_groups_dynamic_membership_discovery(pchk_server, pypck_client):
|
|
|
261
303
|
|
|
262
304
|
|
|
263
305
|
@pytest.mark.asyncio
|
|
264
|
-
async def test_groups_membership_discovery(
|
|
306
|
+
async def test_groups_membership_discovery(
|
|
307
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
308
|
+
) -> None:
|
|
265
309
|
"""Test module scan."""
|
|
266
310
|
await pypck_client.async_connect()
|
|
267
311
|
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
312
|
+
assert isinstance(module, ModuleConnection)
|
|
268
313
|
|
|
269
314
|
task = asyncio.create_task(module.request_groups())
|
|
270
315
|
assert await pchk_server.received(">M000010.GP")
|
|
@@ -282,7 +327,9 @@ async def test_groups_membership_discovery(pchk_server, pypck_client):
|
|
|
282
327
|
|
|
283
328
|
|
|
284
329
|
@pytest.mark.asyncio
|
|
285
|
-
async def test_multiple_serial_requests(
|
|
330
|
+
async def test_multiple_serial_requests(
|
|
331
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
332
|
+
) -> None:
|
|
286
333
|
"""Test module scan."""
|
|
287
334
|
await pypck_client.async_connect()
|
|
288
335
|
|
|
@@ -302,7 +349,9 @@ async def test_multiple_serial_requests(pchk_server, pypck_client):
|
|
|
302
349
|
|
|
303
350
|
|
|
304
351
|
@pytest.mark.asyncio
|
|
305
|
-
async def test_dump_modules_no_segement_couplers(
|
|
352
|
+
async def test_dump_modules_no_segement_couplers(
|
|
353
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
354
|
+
) -> None:
|
|
306
355
|
"""Test module information dumping."""
|
|
307
356
|
await pypck_client.async_connect()
|
|
308
357
|
|
|
@@ -359,7 +408,9 @@ async def test_dump_modules_no_segement_couplers(pchk_server, pypck_client):
|
|
|
359
408
|
|
|
360
409
|
|
|
361
410
|
@pytest.mark.asyncio
|
|
362
|
-
async def test_dump_modules_multi_segment(
|
|
411
|
+
async def test_dump_modules_multi_segment(
|
|
412
|
+
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
413
|
+
) -> None:
|
|
363
414
|
"""Test module information dumping."""
|
|
364
415
|
await pypck_client.async_connect()
|
|
365
416
|
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
from unittest.mock import patch
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
|
+
|
|
6
7
|
from pypck.lcn_addr import LcnAddr
|
|
7
8
|
from pypck.module import ModuleConnection
|
|
8
9
|
|
|
10
|
+
from .conftest import MockPchkConnectionManager
|
|
11
|
+
|
|
9
12
|
TEST_VECTORS = {
|
|
10
13
|
# empty
|
|
11
14
|
"": (b"", b"", b"", b"", b""),
|
|
@@ -57,8 +60,12 @@ TEST_VECTORS = {
|
|
|
57
60
|
|
|
58
61
|
@pytest.mark.asyncio
|
|
59
62
|
@pytest.mark.parametrize("text, parts", TEST_VECTORS.items())
|
|
60
|
-
async def test_dyn_text(
|
|
61
|
-
|
|
63
|
+
async def test_dyn_text(
|
|
64
|
+
pypck_client: MockPchkConnectionManager,
|
|
65
|
+
text: str,
|
|
66
|
+
parts: tuple[bytes, bytes, bytes, bytes, bytes],
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Tests for dynamic text."""
|
|
62
69
|
# await pypck_client.async_connect()
|
|
63
70
|
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
64
71
|
|
|
@@ -70,4 +77,4 @@ async def test_dyn_text(pypck_client, text, parts):
|
|
|
70
77
|
_, commands = zip(*await_args)
|
|
71
78
|
|
|
72
79
|
for i, part in enumerate(parts):
|
|
73
|
-
assert f"GTDT4{i+1:d}".encode() + part in commands
|
|
80
|
+
assert f"GTDT4{i + 1:d}".encode() + part in commands
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Tests for input message parsing for bus messages."""
|
|
2
2
|
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
3
5
|
import pytest
|
|
4
6
|
|
|
5
7
|
from pypck.inputs import (
|
|
@@ -348,7 +350,10 @@ MESSAGES = {
|
|
|
348
350
|
|
|
349
351
|
|
|
350
352
|
@pytest.mark.parametrize("message, expected", MESSAGES.items())
|
|
351
|
-
def test_message_parsing_mod_inputs(
|
|
353
|
+
def test_message_parsing_mod_inputs(
|
|
354
|
+
message: str,
|
|
355
|
+
expected: list[tuple[Any, ...]],
|
|
356
|
+
) -> None:
|
|
352
357
|
"""Test if InputMod parses message correctly."""
|
|
353
358
|
inputs = InputParser.parse(message)
|
|
354
359
|
assert len(inputs) == len(expected)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Tests for variable value and unit handling."""
|
|
2
2
|
|
|
3
3
|
import math
|
|
4
|
+
|
|
4
5
|
import pytest
|
|
6
|
+
|
|
5
7
|
from pypck.lcn_defs import VarUnit, VarValue
|
|
6
8
|
|
|
7
9
|
VARIABLE_TEST_VALUES = (
|
|
@@ -108,7 +110,7 @@ CALIBRATION_TEST_VECTORS = (
|
|
|
108
110
|
|
|
109
111
|
|
|
110
112
|
@pytest.mark.parametrize("unit, native, expected", ROUNDTRIP_TEST_VECTORS)
|
|
111
|
-
def test_roundtrip(unit, native, expected):
|
|
113
|
+
def test_roundtrip(unit: VarUnit, native: int, expected: VarValue) -> None:
|
|
112
114
|
"""Test that variable conversion roundtrips."""
|
|
113
115
|
assert (
|
|
114
116
|
expected
|
|
@@ -119,6 +121,6 @@ def test_roundtrip(unit, native, expected):
|
|
|
119
121
|
|
|
120
122
|
|
|
121
123
|
@pytest.mark.parametrize("unit, native, value", CALIBRATION_TEST_VECTORS)
|
|
122
|
-
def test_calibration(unit, native, value):
|
|
124
|
+
def test_calibration(unit: VarUnit, native: int, value: int | float) -> None:
|
|
123
125
|
"""Test proper calibration of variable conversion."""
|
|
124
126
|
assert value == VarValue.to_var_unit(VarValue.from_native(native), unit)
|
pypck-0.8.9/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.8.9
|
|
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
|