pypck 0.8.10__tar.gz → 0.8.12__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.10/pypck.egg-info → pypck-0.8.12}/PKG-INFO +1 -1
- pypck-0.8.12/VERSION +1 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/module.py +4 -1
- {pypck-0.8.10 → pypck-0.8.12}/pypck/pck_commands.py +4 -2
- {pypck-0.8.10 → pypck-0.8.12/pypck.egg-info}/PKG-INFO +1 -1
- {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/SOURCES.txt +1 -0
- {pypck-0.8.10 → pypck-0.8.12}/tests/test_commands.py +10 -2
- pypck-0.8.12/tests/test_connection.py +155 -0
- {pypck-0.8.10 → pypck-0.8.12}/tests/test_dyn_text.py +3 -9
- pypck-0.8.12/tests/test_input.py +46 -0
- pypck-0.8.10/VERSION +0 -1
- pypck-0.8.10/tests/test_connection.py +0 -471
- {pypck-0.8.10 → pypck-0.8.12}/LICENSE +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/README.md +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/__init__.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/connection.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/helpers.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/inputs.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/lcn_addr.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/lcn_defs.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/request_handlers.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck/timeout_retry.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/dependency_links.txt +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/not-zip-safe +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/top_level.txt +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/pyproject.toml +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/setup.cfg +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/tests/test_messages.py +0 -0
- {pypck-0.8.10 → pypck-0.8.12}/tests/test_vars.py +0 -0
pypck-0.8.12/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.8.12
|
|
@@ -596,7 +596,10 @@ class AbstractConnection:
|
|
|
596
596
|
)
|
|
597
597
|
|
|
598
598
|
async def lock_keys_tab_a_temporary(
|
|
599
|
-
self,
|
|
599
|
+
self,
|
|
600
|
+
delay_time: int,
|
|
601
|
+
delay_unit: lcn_defs.TimeUnit,
|
|
602
|
+
states: list[lcn_defs.KeyLockStateModifier],
|
|
600
603
|
) -> bool:
|
|
601
604
|
"""Send a command to lock keys in table A temporary.
|
|
602
605
|
|
|
@@ -1048,7 +1048,9 @@ class PckGenerator:
|
|
|
1048
1048
|
|
|
1049
1049
|
@staticmethod
|
|
1050
1050
|
def lock_keys_tab_a_temporary(
|
|
1051
|
-
time: int,
|
|
1051
|
+
time: int,
|
|
1052
|
+
time_unit: lcn_defs.TimeUnit,
|
|
1053
|
+
keys: list[lcn_defs.KeyLockStateModifier],
|
|
1052
1054
|
) -> str:
|
|
1053
1055
|
"""Generate a command to lock keys for table A temporary.
|
|
1054
1056
|
|
|
@@ -1085,7 +1087,7 @@ class PckGenerator:
|
|
|
1085
1087
|
raise ValueError("Wrong time_unit.")
|
|
1086
1088
|
|
|
1087
1089
|
for key in keys:
|
|
1088
|
-
ret += "1" if key else "0"
|
|
1090
|
+
ret += "1" if key == lcn_defs.KeyLockStateModifier.ON else "0"
|
|
1089
1091
|
|
|
1090
1092
|
return ret
|
|
1091
1093
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
|
-
|
|
7
6
|
from pypck.lcn_addr import LcnAddr
|
|
8
7
|
from pypck.lcn_defs import (
|
|
9
8
|
BeepSound,
|
|
@@ -466,7 +465,16 @@ COMMANDS: dict[str | bytes, Any] = {
|
|
|
466
465
|
PckGenerator.lock_keys_tab_a_temporary,
|
|
467
466
|
40,
|
|
468
467
|
unit,
|
|
469
|
-
[
|
|
468
|
+
[
|
|
469
|
+
KeyLockStateModifier.ON,
|
|
470
|
+
KeyLockStateModifier.ON,
|
|
471
|
+
KeyLockStateModifier.OFF,
|
|
472
|
+
KeyLockStateModifier.OFF,
|
|
473
|
+
KeyLockStateModifier.ON,
|
|
474
|
+
KeyLockStateModifier.ON,
|
|
475
|
+
KeyLockStateModifier.ON,
|
|
476
|
+
KeyLockStateModifier.OFF,
|
|
477
|
+
],
|
|
470
478
|
)
|
|
471
479
|
for unit in TimeUnit
|
|
472
480
|
},
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Connection tests."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from unittest.mock import AsyncMock, Mock, call, patch
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from pypck import inputs
|
|
9
|
+
from pypck.connection import (
|
|
10
|
+
PchkAuthenticationError,
|
|
11
|
+
PchkConnectionFailedError,
|
|
12
|
+
PchkConnectionManager,
|
|
13
|
+
PchkConnectionRefusedError,
|
|
14
|
+
PchkLicenseError,
|
|
15
|
+
)
|
|
16
|
+
from pypck.lcn_defs import LcnEvent
|
|
17
|
+
from pypck.pck_commands import PckGenerator
|
|
18
|
+
|
|
19
|
+
from .conftest import HOST, PASSWORD, PORT, USERNAME, MockPchkConnectionManager
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def test_close_without_connect(pypck_client: MockPchkConnectionManager) -> None:
|
|
23
|
+
"""Test closing of PchkConnectionManager without connecting."""
|
|
24
|
+
await pypck_client.async_close()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
28
|
+
@patch.object(PchkConnectionManager, "scan_segment_couplers")
|
|
29
|
+
async def test_async_connect(
|
|
30
|
+
mock_scan_segment_couplers: AsyncMock,
|
|
31
|
+
mock_open_connection: AsyncMock,
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Test successful connection."""
|
|
34
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
35
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
36
|
+
await asyncio.sleep(0)
|
|
37
|
+
|
|
38
|
+
pypck_client.license_error_future.set_result(True)
|
|
39
|
+
pypck_client.authentication_completed_future.set_result(True)
|
|
40
|
+
pypck_client.segment_scan_completed_event.set()
|
|
41
|
+
|
|
42
|
+
await connect_task
|
|
43
|
+
|
|
44
|
+
mock_scan_segment_couplers.assert_awaited()
|
|
45
|
+
mock_open_connection.assert_awaited()
|
|
46
|
+
assert pypck_client.is_ready()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@patch.object(PchkConnectionManager, "ping")
|
|
50
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
51
|
+
@patch.object(PchkConnectionManager, "scan_segment_couplers")
|
|
52
|
+
@patch.object(PchkConnectionManager, "send_command")
|
|
53
|
+
async def test_successful_connection_procedure(
|
|
54
|
+
mock_send_command: AsyncMock,
|
|
55
|
+
mock_scan_segment_couplers: AsyncMock,
|
|
56
|
+
mock_open_connection: AsyncMock,
|
|
57
|
+
mock_ping: AsyncMock,
|
|
58
|
+
) -> None:
|
|
59
|
+
"""Test successful connection procedure."""
|
|
60
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
61
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
62
|
+
await asyncio.sleep(0)
|
|
63
|
+
|
|
64
|
+
await pypck_client.async_process_input(inputs.AuthUsername())
|
|
65
|
+
mock_send_command.assert_awaited_with(USERNAME, to_host=True)
|
|
66
|
+
|
|
67
|
+
await pypck_client.async_process_input(inputs.AuthPassword())
|
|
68
|
+
mock_send_command.assert_awaited_with(PASSWORD, to_host=True)
|
|
69
|
+
|
|
70
|
+
await pypck_client.async_process_input(inputs.AuthOk())
|
|
71
|
+
mock_send_command.assert_awaited_with(PckGenerator.set_dec_mode(), to_host=True)
|
|
72
|
+
assert pypck_client.authentication_completed_future.result()
|
|
73
|
+
|
|
74
|
+
await pypck_client.async_process_input(inputs.DecModeSet())
|
|
75
|
+
mock_send_command.assert_awaited_with(
|
|
76
|
+
PckGenerator.set_operation_mode(
|
|
77
|
+
pypck_client.dim_mode, pypck_client.status_mode
|
|
78
|
+
),
|
|
79
|
+
to_host=True,
|
|
80
|
+
)
|
|
81
|
+
assert pypck_client.license_error_future.result()
|
|
82
|
+
|
|
83
|
+
await connect_task
|
|
84
|
+
|
|
85
|
+
mock_open_connection.assert_awaited()
|
|
86
|
+
mock_scan_segment_couplers.assert_awaited()
|
|
87
|
+
mock_ping.assert_awaited()
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@pytest.mark.parametrize("side_effect", [ConnectionRefusedError, OSError])
|
|
91
|
+
async def test_connection_error(side_effect: ConnectionRefusedError | OSError) -> None:
|
|
92
|
+
"""Test connection error."""
|
|
93
|
+
with (
|
|
94
|
+
patch.object(PchkConnectionManager, "open_connection", side_effect=side_effect),
|
|
95
|
+
pytest.raises(PchkConnectionRefusedError),
|
|
96
|
+
):
|
|
97
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
98
|
+
await pypck_client.async_connect()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
102
|
+
async def test_authentication_error(mock_open_connection: AsyncMock) -> None:
|
|
103
|
+
"""Test wrong login credentials."""
|
|
104
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
105
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
106
|
+
await asyncio.sleep(0)
|
|
107
|
+
await pypck_client.async_process_input(inputs.AuthFailed())
|
|
108
|
+
|
|
109
|
+
with (
|
|
110
|
+
pytest.raises(PchkAuthenticationError),
|
|
111
|
+
):
|
|
112
|
+
await connect_task
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
116
|
+
async def test_license_error(mock_open_connection: AsyncMock) -> None:
|
|
117
|
+
"""Test wrong login credentials."""
|
|
118
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
119
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
120
|
+
await asyncio.sleep(0)
|
|
121
|
+
await pypck_client.async_process_input(inputs.LicenseError())
|
|
122
|
+
|
|
123
|
+
with (
|
|
124
|
+
pytest.raises(PchkLicenseError),
|
|
125
|
+
):
|
|
126
|
+
await connect_task
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
130
|
+
async def test_timeout_error(mock_open_connection: AsyncMock) -> None:
|
|
131
|
+
"""Test timeout when connecting."""
|
|
132
|
+
with pytest.raises(PchkConnectionFailedError):
|
|
133
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
134
|
+
await pypck_client.async_connect(timeout=0)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
async def test_lcn_connected(pypck_client: MockPchkConnectionManager) -> None:
|
|
138
|
+
"""Test lcn connected events."""
|
|
139
|
+
event_callback = Mock()
|
|
140
|
+
pypck_client.register_for_events(event_callback)
|
|
141
|
+
await pypck_client.async_connect()
|
|
142
|
+
|
|
143
|
+
# bus disconnected
|
|
144
|
+
await pypck_client.async_process_input(inputs.LcnConnState(is_lcn_connected=False))
|
|
145
|
+
assert not pypck_client.is_lcn_connected
|
|
146
|
+
event_callback.assert_has_calls(
|
|
147
|
+
(call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED), call(LcnEvent.BUS_DISCONNECTED))
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# bus connected
|
|
151
|
+
await pypck_client.async_process_input(inputs.LcnConnState(is_lcn_connected=True))
|
|
152
|
+
assert pypck_client.is_lcn_connected
|
|
153
|
+
event_callback.assert_has_calls(
|
|
154
|
+
(call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED), call(LcnEvent.BUS_CONNECTED))
|
|
155
|
+
)
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"""Module connection tests."""
|
|
2
2
|
|
|
3
|
-
from unittest.mock import patch
|
|
4
|
-
|
|
5
3
|
import pytest
|
|
6
4
|
|
|
7
5
|
from pypck.lcn_addr import LcnAddr
|
|
8
|
-
from pypck.module import ModuleConnection
|
|
9
6
|
|
|
10
7
|
from .conftest import MockPchkConnectionManager
|
|
11
8
|
|
|
@@ -58,7 +55,6 @@ TEST_VECTORS = {
|
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
|
|
61
|
-
@pytest.mark.asyncio
|
|
62
58
|
@pytest.mark.parametrize("text, parts", TEST_VECTORS.items())
|
|
63
59
|
async def test_dyn_text(
|
|
64
60
|
pypck_client: MockPchkConnectionManager,
|
|
@@ -66,14 +62,12 @@ async def test_dyn_text(
|
|
|
66
62
|
parts: tuple[bytes, bytes, bytes, bytes, bytes],
|
|
67
63
|
) -> None:
|
|
68
64
|
"""Tests for dynamic text."""
|
|
69
|
-
# await pypck_client.async_connect()
|
|
70
65
|
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
await module.dyn_text(3, text)
|
|
67
|
+
await module.dyn_text(3, text)
|
|
74
68
|
|
|
75
|
-
send_command.assert_awaited()
|
|
76
|
-
await_args = (call.args for call in send_command.await_args_list)
|
|
69
|
+
module.send_command.assert_awaited() # type: ignore[attr-defined]
|
|
70
|
+
await_args = (call.args for call in module.send_command.await_args_list) # type: ignore[attr-defined]
|
|
77
71
|
_, commands = zip(*await_args)
|
|
78
72
|
|
|
79
73
|
for i, part in enumerate(parts):
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Test the data flow for Input objects."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
from pypck.inputs import Input, ModInput
|
|
6
|
+
from pypck.lcn_addr import LcnAddr
|
|
7
|
+
from pypck.module import ModuleConnection
|
|
8
|
+
|
|
9
|
+
from .conftest import MockPchkConnectionManager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def test_message_to_input(pypck_client: MockPchkConnectionManager) -> None:
|
|
13
|
+
"""Test data flow from message to input."""
|
|
14
|
+
inp = Input()
|
|
15
|
+
message = "dummy_message"
|
|
16
|
+
with patch.object(
|
|
17
|
+
pypck_client, "async_process_input"
|
|
18
|
+
) as pypck_client_process_input:
|
|
19
|
+
with patch("pypck.inputs.InputParser.parse", return_value=[inp]) as inp_parse:
|
|
20
|
+
await pypck_client.process_message(message)
|
|
21
|
+
|
|
22
|
+
inp_parse.assert_called_with(message)
|
|
23
|
+
pypck_client_process_input.assert_awaited_with(inp)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def test_physical_to_logical_segment_id(
|
|
27
|
+
pypck_client: MockPchkConnectionManager,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Test conversion from logical to physical segment id."""
|
|
30
|
+
pypck_client.local_seg_id = 20
|
|
31
|
+
module = pypck_client.get_address_conn(LcnAddr(20, 7, False))
|
|
32
|
+
assert isinstance(module, ModuleConnection)
|
|
33
|
+
with (
|
|
34
|
+
patch("tests.conftest.MockPchkConnectionManager.is_ready", return_value=True),
|
|
35
|
+
patch.object(module, "async_process_input") as module_process_input,
|
|
36
|
+
):
|
|
37
|
+
inp = ModInput(LcnAddr(20, 7, False))
|
|
38
|
+
await pypck_client.async_process_input(inp)
|
|
39
|
+
|
|
40
|
+
inp = ModInput(LcnAddr(0, 7, False))
|
|
41
|
+
await pypck_client.async_process_input(inp)
|
|
42
|
+
|
|
43
|
+
inp = ModInput(LcnAddr(4, 7, False))
|
|
44
|
+
await pypck_client.async_process_input(inp)
|
|
45
|
+
|
|
46
|
+
assert module_process_input.await_count == 3
|
pypck-0.8.10/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.8.10
|
|
@@ -1,471 +0,0 @@
|
|
|
1
|
-
"""Connection tests."""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import json
|
|
5
|
-
from unittest.mock import Mock, call
|
|
6
|
-
|
|
7
|
-
import pytest
|
|
8
|
-
|
|
9
|
-
from pypck.connection import (
|
|
10
|
-
PchkAuthenticationError,
|
|
11
|
-
PchkConnectionFailedError,
|
|
12
|
-
PchkConnectionRefusedError,
|
|
13
|
-
PchkLicenseError,
|
|
14
|
-
)
|
|
15
|
-
from pypck.lcn_addr import LcnAddr
|
|
16
|
-
from pypck.lcn_defs import LcnEvent
|
|
17
|
-
from pypck.module import ModuleConnection
|
|
18
|
-
|
|
19
|
-
from .conftest import MockPchkConnectionManager
|
|
20
|
-
from .mock_pchk import MockPchkServer
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.mark.asyncio
|
|
24
|
-
async def test_close_without_connect(pypck_client: MockPchkConnectionManager) -> None:
|
|
25
|
-
"""Test closing of PchkConnectionManager without connecting."""
|
|
26
|
-
await pypck_client.async_close()
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@pytest.mark.asyncio
|
|
30
|
-
async def test_authenticate(
|
|
31
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
32
|
-
) -> None:
|
|
33
|
-
"""Test authentication procedure."""
|
|
34
|
-
await pypck_client.async_connect()
|
|
35
|
-
assert pypck_client.is_ready()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@pytest.mark.asyncio
|
|
39
|
-
async def test_port_error(
|
|
40
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
41
|
-
) -> None:
|
|
42
|
-
"""Test wrong port."""
|
|
43
|
-
pypck_client.port = 55555
|
|
44
|
-
with pytest.raises(PchkConnectionRefusedError):
|
|
45
|
-
await pypck_client.async_connect()
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@pytest.mark.asyncio
|
|
49
|
-
async def test_authentication_error(
|
|
50
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
51
|
-
) -> None:
|
|
52
|
-
"""Test wrong login credentials."""
|
|
53
|
-
pypck_client.password = "wrong_password"
|
|
54
|
-
with pytest.raises(PchkAuthenticationError):
|
|
55
|
-
await pypck_client.async_connect()
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@pytest.mark.asyncio
|
|
59
|
-
async def test_license_error(
|
|
60
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
61
|
-
) -> None:
|
|
62
|
-
"""Test license error."""
|
|
63
|
-
pchk_server.set_license_error(True)
|
|
64
|
-
|
|
65
|
-
with pytest.raises(PchkLicenseError):
|
|
66
|
-
await pypck_client.async_connect()
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@pytest.mark.asyncio
|
|
70
|
-
async def test_timeout_error(
|
|
71
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
72
|
-
) -> None:
|
|
73
|
-
"""Test timeout when connecting."""
|
|
74
|
-
with pytest.raises(PchkConnectionFailedError):
|
|
75
|
-
await pypck_client.async_connect(timeout=0)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@pytest.mark.asyncio
|
|
79
|
-
async def test_lcn_connected(
|
|
80
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
81
|
-
) -> None:
|
|
82
|
-
"""Test lcn disconnected event."""
|
|
83
|
-
event_callback = Mock()
|
|
84
|
-
pypck_client.register_for_events(event_callback)
|
|
85
|
-
await pypck_client.async_connect()
|
|
86
|
-
await pchk_server.send_message("$io:#LCN:connected")
|
|
87
|
-
await pypck_client.received("$io:#LCN:connected")
|
|
88
|
-
|
|
89
|
-
event_callback.assert_has_calls(
|
|
90
|
-
[
|
|
91
|
-
call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED),
|
|
92
|
-
call(LcnEvent.BUS_CONNECTED),
|
|
93
|
-
]
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@pytest.mark.asyncio
|
|
98
|
-
async def test_lcn_disconnected(
|
|
99
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
100
|
-
) -> None:
|
|
101
|
-
"""Test lcn disconnected event."""
|
|
102
|
-
event_callback = Mock()
|
|
103
|
-
pypck_client.register_for_events(event_callback)
|
|
104
|
-
await pypck_client.async_connect()
|
|
105
|
-
await pchk_server.send_message("$io:#LCN:disconnected")
|
|
106
|
-
await pypck_client.received("$io:#LCN:disconnected")
|
|
107
|
-
|
|
108
|
-
event_callback.assert_has_calls(
|
|
109
|
-
[call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED), call(LcnEvent.BUS_DISCONNECTED)]
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
@pytest.mark.asyncio
|
|
114
|
-
async def test_connection_lost(
|
|
115
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
116
|
-
) -> None:
|
|
117
|
-
"""Test pchk server connection close."""
|
|
118
|
-
event_callback = Mock()
|
|
119
|
-
pypck_client.register_for_events(event_callback)
|
|
120
|
-
await pypck_client.async_connect()
|
|
121
|
-
|
|
122
|
-
await pchk_server.stop()
|
|
123
|
-
# ensure that pypck_client is about to be closed
|
|
124
|
-
await pypck_client.wait_closed()
|
|
125
|
-
|
|
126
|
-
event_callback.assert_has_calls([call(LcnEvent.CONNECTION_LOST)])
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@pytest.mark.asyncio
|
|
130
|
-
async def test_multiple_connections(
|
|
131
|
-
pchk_server: MockPchkServer,
|
|
132
|
-
pypck_client: MockPchkConnectionManager,
|
|
133
|
-
pchk_server_2: MockPchkServer,
|
|
134
|
-
pypck_client_2: MockPchkConnectionManager,
|
|
135
|
-
) -> None:
|
|
136
|
-
"""Test that two independent connections can coexists."""
|
|
137
|
-
await pypck_client_2.async_connect()
|
|
138
|
-
|
|
139
|
-
event_callback = Mock()
|
|
140
|
-
pypck_client.register_for_events(event_callback)
|
|
141
|
-
await pypck_client.async_connect()
|
|
142
|
-
|
|
143
|
-
await pchk_server.stop()
|
|
144
|
-
await pypck_client.wait_closed()
|
|
145
|
-
|
|
146
|
-
event_callback.assert_has_calls([call(LcnEvent.CONNECTION_LOST)])
|
|
147
|
-
|
|
148
|
-
assert len(pypck_client.task_registry.tasks) == 0
|
|
149
|
-
assert len(pypck_client_2.task_registry.tasks) > 0
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
@pytest.mark.asyncio
|
|
153
|
-
async def test_segment_coupler_search(
|
|
154
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
155
|
-
) -> None:
|
|
156
|
-
"""Test segment coupler search."""
|
|
157
|
-
await pypck_client.async_connect()
|
|
158
|
-
await pypck_client.scan_segment_couplers(3, 0)
|
|
159
|
-
|
|
160
|
-
assert await pchk_server.received(">G003003.SK")
|
|
161
|
-
assert await pchk_server.received(">G003003.SK")
|
|
162
|
-
assert await pchk_server.received(">G003003.SK")
|
|
163
|
-
|
|
164
|
-
assert pypck_client.is_ready()
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
@pytest.mark.asyncio
|
|
168
|
-
async def test_segment_coupler_response(
|
|
169
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
170
|
-
) -> None:
|
|
171
|
-
"""Test segment coupler response."""
|
|
172
|
-
await pypck_client.async_connect()
|
|
173
|
-
|
|
174
|
-
assert pypck_client.local_seg_id == 0
|
|
175
|
-
|
|
176
|
-
await pchk_server.send_message("=M000005.SK020")
|
|
177
|
-
await pchk_server.send_message("=M021021.SK021")
|
|
178
|
-
await pchk_server.send_message("=M022010.SK022")
|
|
179
|
-
assert await pypck_client.received("=M000005.SK020")
|
|
180
|
-
assert await pypck_client.received("=M021021.SK021")
|
|
181
|
-
assert await pypck_client.received("=M022010.SK022")
|
|
182
|
-
|
|
183
|
-
assert pypck_client.local_seg_id == 20
|
|
184
|
-
assert set(pypck_client.segment_coupler_ids) == {20, 21, 22}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
@pytest.mark.asyncio
|
|
188
|
-
async def test_module_scan(
|
|
189
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
190
|
-
) -> None:
|
|
191
|
-
"""Test module scan."""
|
|
192
|
-
await pypck_client.async_connect()
|
|
193
|
-
await pypck_client.scan_modules(3, 0)
|
|
194
|
-
|
|
195
|
-
assert await pchk_server.received(">G000003!LEER")
|
|
196
|
-
assert await pchk_server.received(">G000003!LEER")
|
|
197
|
-
assert await pchk_server.received(">G000003!LEER")
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
@pytest.mark.asyncio
|
|
201
|
-
async def test_module_sn_response(
|
|
202
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
203
|
-
) -> None:
|
|
204
|
-
"""Test module scan."""
|
|
205
|
-
await pypck_client.async_connect()
|
|
206
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 7, False))
|
|
207
|
-
|
|
208
|
-
message = "=M000007.SN1AB20A123401FW190B11HW015"
|
|
209
|
-
await pchk_server.send_message(message)
|
|
210
|
-
assert await pypck_client.received(message)
|
|
211
|
-
|
|
212
|
-
assert await module.serial_known
|
|
213
|
-
assert module.hardware_serial == 0x1AB20A1234
|
|
214
|
-
assert module.manu == 1
|
|
215
|
-
assert module.software_serial == 0x190B11
|
|
216
|
-
assert module.hardware_type.value == 15
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
@pytest.mark.asyncio
|
|
220
|
-
async def test_send_command_to_server(
|
|
221
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
222
|
-
) -> None:
|
|
223
|
-
"""Test sending a command to the PCHK server."""
|
|
224
|
-
await pypck_client.async_connect()
|
|
225
|
-
message = ">M000007.PIN003"
|
|
226
|
-
await pypck_client.send_command(message)
|
|
227
|
-
assert await pchk_server.received(message)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
@pytest.mark.asyncio
|
|
231
|
-
async def test_ping(
|
|
232
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
233
|
-
) -> None:
|
|
234
|
-
"""Test if pings are send."""
|
|
235
|
-
await pypck_client.async_connect()
|
|
236
|
-
assert await pchk_server.received("^ping0")
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
@pytest.mark.asyncio
|
|
240
|
-
async def test_add_address_connections(pypck_client: MockPchkConnectionManager) -> None:
|
|
241
|
-
"""Test if new address connections are added on request."""
|
|
242
|
-
lcn_addr = LcnAddr(0, 10, False)
|
|
243
|
-
assert lcn_addr not in pypck_client.address_conns
|
|
244
|
-
|
|
245
|
-
addr_conn = pypck_client.get_address_conn(lcn_addr)
|
|
246
|
-
assert isinstance(addr_conn, ModuleConnection)
|
|
247
|
-
|
|
248
|
-
assert lcn_addr in pypck_client.address_conns
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
@pytest.mark.asyncio
|
|
252
|
-
async def test_add_address_connections_by_message(
|
|
253
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
254
|
-
) -> None:
|
|
255
|
-
"""Test if new address connections are added by received message."""
|
|
256
|
-
await pypck_client.async_connect()
|
|
257
|
-
lcn_addr = LcnAddr(0, 10, False)
|
|
258
|
-
assert lcn_addr not in pypck_client.address_conns
|
|
259
|
-
|
|
260
|
-
message = ":M000010A1050"
|
|
261
|
-
await pchk_server.send_message(message)
|
|
262
|
-
assert await pypck_client.received(message)
|
|
263
|
-
|
|
264
|
-
assert lcn_addr in pypck_client.address_conns
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
@pytest.mark.asyncio
|
|
268
|
-
async def test_groups_static_membership_discovery(
|
|
269
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
270
|
-
) -> None:
|
|
271
|
-
"""Test module scan."""
|
|
272
|
-
await pypck_client.async_connect()
|
|
273
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
274
|
-
assert isinstance(module, ModuleConnection)
|
|
275
|
-
|
|
276
|
-
task = asyncio.create_task(module.request_static_groups())
|
|
277
|
-
assert await pchk_server.received(">M000010.GP")
|
|
278
|
-
await pchk_server.send_message("=M000010.GP012011200051")
|
|
279
|
-
assert await task == {
|
|
280
|
-
LcnAddr(0, 11, True),
|
|
281
|
-
LcnAddr(0, 200, True),
|
|
282
|
-
LcnAddr(0, 51, True),
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
@pytest.mark.asyncio
|
|
287
|
-
async def test_groups_dynamic_membership_discovery(
|
|
288
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
289
|
-
) -> None:
|
|
290
|
-
"""Test module scan."""
|
|
291
|
-
await pypck_client.async_connect()
|
|
292
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
293
|
-
assert isinstance(module, ModuleConnection)
|
|
294
|
-
|
|
295
|
-
task = asyncio.create_task(module.request_dynamic_groups())
|
|
296
|
-
assert await pchk_server.received(">M000010.GD")
|
|
297
|
-
await pchk_server.send_message("=M000010.GD008011200051")
|
|
298
|
-
assert await task == {
|
|
299
|
-
LcnAddr(0, 11, True),
|
|
300
|
-
LcnAddr(0, 200, True),
|
|
301
|
-
LcnAddr(0, 51, True),
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
@pytest.mark.asyncio
|
|
306
|
-
async def test_groups_membership_discovery(
|
|
307
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
308
|
-
) -> None:
|
|
309
|
-
"""Test module scan."""
|
|
310
|
-
await pypck_client.async_connect()
|
|
311
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
312
|
-
assert isinstance(module, ModuleConnection)
|
|
313
|
-
|
|
314
|
-
task = asyncio.create_task(module.request_groups())
|
|
315
|
-
assert await pchk_server.received(">M000010.GP")
|
|
316
|
-
await pchk_server.send_message("=M000010.GP012011200051")
|
|
317
|
-
assert await pchk_server.received(">M000010.GD")
|
|
318
|
-
await pchk_server.send_message("=M000010.GD008015100052")
|
|
319
|
-
assert await task == {
|
|
320
|
-
LcnAddr(0, 11, True),
|
|
321
|
-
LcnAddr(0, 200, True),
|
|
322
|
-
LcnAddr(0, 51, True),
|
|
323
|
-
LcnAddr(0, 15, True),
|
|
324
|
-
LcnAddr(0, 100, True),
|
|
325
|
-
LcnAddr(0, 52, True),
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
@pytest.mark.asyncio
|
|
330
|
-
async def test_multiple_serial_requests(
|
|
331
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
332
|
-
) -> None:
|
|
333
|
-
"""Test module scan."""
|
|
334
|
-
await pypck_client.async_connect()
|
|
335
|
-
|
|
336
|
-
pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
337
|
-
pypck_client.get_address_conn(LcnAddr(0, 11, False))
|
|
338
|
-
pypck_client.get_address_conn(LcnAddr(0, 12, False))
|
|
339
|
-
|
|
340
|
-
assert await pchk_server.received(">M000010.SN")
|
|
341
|
-
assert await pchk_server.received(">M000011.SN")
|
|
342
|
-
assert await pchk_server.received(">M000012.SN")
|
|
343
|
-
|
|
344
|
-
message = "=M000010.SN1AB20A123401FW190B11HW015"
|
|
345
|
-
await pchk_server.send_message(message)
|
|
346
|
-
assert await pypck_client.received(message)
|
|
347
|
-
|
|
348
|
-
await pypck_client.async_close()
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
@pytest.mark.asyncio
|
|
352
|
-
async def test_dump_modules_no_segement_couplers(
|
|
353
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
354
|
-
) -> None:
|
|
355
|
-
"""Test module information dumping."""
|
|
356
|
-
await pypck_client.async_connect()
|
|
357
|
-
|
|
358
|
-
for msg in (
|
|
359
|
-
"=M000007.SN1AB20A123401FW190B11HW015",
|
|
360
|
-
"=M000008.SN1BB20A123401FW1A0B11HW015",
|
|
361
|
-
"=M000007.GP012011200051",
|
|
362
|
-
"=M000008.GP012011220051",
|
|
363
|
-
"=M000007.GD008015100052",
|
|
364
|
-
"=M000008.GD008015120052",
|
|
365
|
-
):
|
|
366
|
-
await pchk_server.send_message(msg)
|
|
367
|
-
assert await pypck_client.received(msg)
|
|
368
|
-
|
|
369
|
-
dump = pypck_client.dump_modules()
|
|
370
|
-
json.dumps(dump)
|
|
371
|
-
|
|
372
|
-
assert dump == {
|
|
373
|
-
"0": {
|
|
374
|
-
"7": {
|
|
375
|
-
"segment": 0,
|
|
376
|
-
"address": 7,
|
|
377
|
-
"is_local_segment": True,
|
|
378
|
-
"serials": {
|
|
379
|
-
"hardware_serial": "1AB20A1234",
|
|
380
|
-
"manu": "01",
|
|
381
|
-
"software_serial": "190B11",
|
|
382
|
-
"hardware_type": "15",
|
|
383
|
-
"hardware_name": "LCN-SH-Plus",
|
|
384
|
-
},
|
|
385
|
-
"name": "",
|
|
386
|
-
"comment": "",
|
|
387
|
-
"oem_text": ["", "", "", ""],
|
|
388
|
-
"groups": {"static": [11, 51, 200], "dynamic": [15, 52, 100]},
|
|
389
|
-
},
|
|
390
|
-
"8": {
|
|
391
|
-
"segment": 0,
|
|
392
|
-
"address": 8,
|
|
393
|
-
"is_local_segment": True,
|
|
394
|
-
"serials": {
|
|
395
|
-
"hardware_serial": "1BB20A1234",
|
|
396
|
-
"manu": "01",
|
|
397
|
-
"software_serial": "1A0B11",
|
|
398
|
-
"hardware_type": "15",
|
|
399
|
-
"hardware_name": "LCN-SH-Plus",
|
|
400
|
-
},
|
|
401
|
-
"name": "",
|
|
402
|
-
"comment": "",
|
|
403
|
-
"oem_text": ["", "", "", ""],
|
|
404
|
-
"groups": {"static": [11, 51, 220], "dynamic": [15, 52, 120]},
|
|
405
|
-
},
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
@pytest.mark.asyncio
|
|
411
|
-
async def test_dump_modules_multi_segment(
|
|
412
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
413
|
-
) -> None:
|
|
414
|
-
"""Test module information dumping."""
|
|
415
|
-
await pypck_client.async_connect()
|
|
416
|
-
|
|
417
|
-
# Populate the bus topology information
|
|
418
|
-
for msg in (
|
|
419
|
-
"=M000007.SK020",
|
|
420
|
-
"=M022008.SK022",
|
|
421
|
-
"=M000007.SN1AB20A123401FW190B11HW015",
|
|
422
|
-
"=M022008.SN1BB20A123401FW1A0B11HW015",
|
|
423
|
-
"=M000007.GP012011200051",
|
|
424
|
-
"=M022008.GP012011220051",
|
|
425
|
-
"=M000007.GD008015100052",
|
|
426
|
-
"=M022008.GD008015120052",
|
|
427
|
-
):
|
|
428
|
-
await pchk_server.send_message(msg)
|
|
429
|
-
assert await pypck_client.received(msg)
|
|
430
|
-
|
|
431
|
-
dump = pypck_client.dump_modules()
|
|
432
|
-
json.dumps(dump)
|
|
433
|
-
|
|
434
|
-
assert dump == {
|
|
435
|
-
"20": {
|
|
436
|
-
"7": {
|
|
437
|
-
"segment": 20,
|
|
438
|
-
"address": 7,
|
|
439
|
-
"is_local_segment": True,
|
|
440
|
-
"serials": {
|
|
441
|
-
"hardware_serial": "1AB20A1234",
|
|
442
|
-
"manu": "01",
|
|
443
|
-
"software_serial": "190B11",
|
|
444
|
-
"hardware_type": "15",
|
|
445
|
-
"hardware_name": "LCN-SH-Plus",
|
|
446
|
-
},
|
|
447
|
-
"name": "",
|
|
448
|
-
"comment": "",
|
|
449
|
-
"oem_text": ["", "", "", ""],
|
|
450
|
-
"groups": {"static": [11, 51, 200], "dynamic": [15, 52, 100]},
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
"22": {
|
|
454
|
-
"8": {
|
|
455
|
-
"segment": 22,
|
|
456
|
-
"address": 8,
|
|
457
|
-
"is_local_segment": False,
|
|
458
|
-
"serials": {
|
|
459
|
-
"hardware_serial": "1BB20A1234",
|
|
460
|
-
"manu": "01",
|
|
461
|
-
"software_serial": "1A0B11",
|
|
462
|
-
"hardware_type": "15",
|
|
463
|
-
"hardware_name": "LCN-SH-Plus",
|
|
464
|
-
},
|
|
465
|
-
"name": "",
|
|
466
|
-
"comment": "",
|
|
467
|
-
"oem_text": ["", "", "", ""],
|
|
468
|
-
"groups": {"static": [11, 51, 220], "dynamic": [15, 52, 120]},
|
|
469
|
-
},
|
|
470
|
-
},
|
|
471
|
-
}
|
|
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
|
|
File without changes
|