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.
Files changed (29) hide show
  1. {pypck-0.8.10/pypck.egg-info → pypck-0.8.12}/PKG-INFO +1 -1
  2. pypck-0.8.12/VERSION +1 -0
  3. {pypck-0.8.10 → pypck-0.8.12}/pypck/module.py +4 -1
  4. {pypck-0.8.10 → pypck-0.8.12}/pypck/pck_commands.py +4 -2
  5. {pypck-0.8.10 → pypck-0.8.12/pypck.egg-info}/PKG-INFO +1 -1
  6. {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/SOURCES.txt +1 -0
  7. {pypck-0.8.10 → pypck-0.8.12}/tests/test_commands.py +10 -2
  8. pypck-0.8.12/tests/test_connection.py +155 -0
  9. {pypck-0.8.10 → pypck-0.8.12}/tests/test_dyn_text.py +3 -9
  10. pypck-0.8.12/tests/test_input.py +46 -0
  11. pypck-0.8.10/VERSION +0 -1
  12. pypck-0.8.10/tests/test_connection.py +0 -471
  13. {pypck-0.8.10 → pypck-0.8.12}/LICENSE +0 -0
  14. {pypck-0.8.10 → pypck-0.8.12}/README.md +0 -0
  15. {pypck-0.8.10 → pypck-0.8.12}/pypck/__init__.py +0 -0
  16. {pypck-0.8.10 → pypck-0.8.12}/pypck/connection.py +0 -0
  17. {pypck-0.8.10 → pypck-0.8.12}/pypck/helpers.py +0 -0
  18. {pypck-0.8.10 → pypck-0.8.12}/pypck/inputs.py +0 -0
  19. {pypck-0.8.10 → pypck-0.8.12}/pypck/lcn_addr.py +0 -0
  20. {pypck-0.8.10 → pypck-0.8.12}/pypck/lcn_defs.py +0 -0
  21. {pypck-0.8.10 → pypck-0.8.12}/pypck/request_handlers.py +0 -0
  22. {pypck-0.8.10 → pypck-0.8.12}/pypck/timeout_retry.py +0 -0
  23. {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/dependency_links.txt +0 -0
  24. {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/not-zip-safe +0 -0
  25. {pypck-0.8.10 → pypck-0.8.12}/pypck.egg-info/top_level.txt +0 -0
  26. {pypck-0.8.10 → pypck-0.8.12}/pyproject.toml +0 -0
  27. {pypck-0.8.10 → pypck-0.8.12}/setup.cfg +0 -0
  28. {pypck-0.8.10 → pypck-0.8.12}/tests/test_messages.py +0 -0
  29. {pypck-0.8.10 → pypck-0.8.12}/tests/test_vars.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypck
3
- Version: 0.8.10
3
+ Version: 0.8.12
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.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, delay_time: int, delay_unit: lcn_defs.TimeUnit, states: list[bool]
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, time_unit: lcn_defs.TimeUnit, keys: list[bool]
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypck
3
- Version: 0.8.10
3
+ Version: 0.8.12
4
4
  Summary: LCN-PCK library
5
5
  Home-page: https://github.com/alengwenus/pypck
6
6
  Author-email: Andre Lengwenus <alengwenus@gmail.com>
@@ -21,5 +21,6 @@ pypck.egg-info/top_level.txt
21
21
  tests/test_commands.py
22
22
  tests/test_connection.py
23
23
  tests/test_dyn_text.py
24
+ tests/test_input.py
24
25
  tests/test_messages.py
25
26
  tests/test_vars.py
@@ -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
- [True, True, False, False, True, True, True, False],
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
- with patch.object(ModuleConnection, "send_command") as send_command:
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