Skip to content

Commit 0736090

Browse files
authored
Merge pull request #141 from puddly/rc
0.18.0 Release
2 parents 555c0df + f624b50 commit 0736090

File tree

3 files changed

+75
-54
lines changed

3 files changed

+75
-54
lines changed

tests/test_application.py

+56-48
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import asyncio
22

33
import pytest
4-
from zigpy import types as t
54
import zigpy.exceptions
6-
from zigpy.zdo.types import ZDOCmd
5+
import zigpy.state
6+
import zigpy.types as t
7+
import zigpy.zdo.types as zdo_t
78

89
from zigpy_xbee.api import ModemStatus, XBee
910
import zigpy_xbee.config as config
@@ -21,6 +22,42 @@
2122
}
2223

2324

25+
@pytest.fixture
26+
def node_info():
27+
return zigpy.state.NodeInfo(
28+
nwk=t.NWK(0x0000),
29+
ieee=t.EUI64.convert("00:12:4b:00:1c:a1:b8:46"),
30+
logical_type=zdo_t.LogicalType.Coordinator,
31+
)
32+
33+
34+
@pytest.fixture
35+
def network_info(node_info):
36+
return zigpy.state.NetworkInfo(
37+
extended_pan_id=t.ExtendedPanId.convert("bd:27:0b:38:37:95:dc:87"),
38+
pan_id=t.PanId(0x9BB0),
39+
nwk_update_id=18,
40+
nwk_manager_id=t.NWK(0x0000),
41+
channel=t.uint8_t(15),
42+
channel_mask=t.Channels.ALL_CHANNELS,
43+
security_level=t.uint8_t(5),
44+
network_key=zigpy.state.Key(
45+
key=t.KeyData.convert("2ccade06b3090c310315b3d574d3c85a"),
46+
seq=108,
47+
tx_counter=118785,
48+
),
49+
tc_link_key=zigpy.state.Key(
50+
key=t.KeyData(b"ZigBeeAlliance09"),
51+
partner_ieee=node_info.ieee,
52+
tx_counter=8712428,
53+
),
54+
key_table=[],
55+
children=[],
56+
nwk_addresses={},
57+
58+
)
59+
60+
2461
@pytest.fixture
2562
def app(monkeypatch):
2663
monkeypatch.setattr(application, "TIMEOUT_TX_STATUS", 0.1)
@@ -242,59 +279,22 @@ async def test_get_association_state(app):
242279
assert ai is mock.sentinel.ai
243280

244281

245-
async def test_form_network(app):
246-
legacy_module = False
282+
async def test_write_network_info(app, node_info, network_info):
283+
app._api._queued_at = mock.AsyncMock(spec=XBee._queued_at)
284+
app._api._at_command = mock.AsyncMock(spec=XBee._at_command)
285+
app._api._running = mock.AsyncMock(spec=app._api._running)
247286

248-
async def mock_at_command(cmd, *args):
249-
if cmd == "MY":
250-
return 0x0000
251-
if cmd == "OI":
252-
return 0x1234
253-
elif cmd == "ID":
254-
return 0x1234567812345678
255-
elif cmd == "SL":
256-
return 0x11223344
257-
elif cmd == "SH":
258-
return 0x55667788
259-
elif cmd == "WR":
260-
app._api.coordinator_started_event.set()
261-
elif cmd == "CE" and legacy_module:
262-
raise RuntimeError
263-
return None
264-
265-
app._api._at_command = mock.MagicMock(
266-
spec=XBee._at_command, side_effect=mock_at_command
267-
)
268-
app._api._queued_at = mock.MagicMock(
269-
spec=XBee._at_command, side_effect=mock_at_command
270-
)
271287
app._get_association_state = mock.AsyncMock(
272288
spec=application.ControllerApplication._get_association_state,
273289
return_value=0x00,
274290
)
275291

276-
app.write_network_info = mock.MagicMock(wraps=app.write_network_info)
277-
278-
await app.form_network()
279-
assert app._api._at_command.call_count >= 1
280-
assert app._api._queued_at.call_count >= 7
281-
282-
network_info = app.write_network_info.mock_calls[0][2]["network_info"]
283-
284-
app._api._queued_at.assert_any_call("SC", 1 << (network_info.channel - 11))
285-
app._api._queued_at.assert_any_call("KY", b"ZigBeeAlliance09")
286-
287-
app._api._at_command.reset_mock()
288-
app._api._queued_at.reset_mock()
289-
legacy_module = True
290-
await app.form_network()
291-
assert app._api._at_command.call_count >= 1
292-
assert app._api._queued_at.call_count >= 7
293-
294-
network_info = app.write_network_info.mock_calls[0][2]["network_info"]
292+
await app.write_network_info(network_info=network_info, node_info=node_info)
295293

296294
app._api._queued_at.assert_any_call("SC", 1 << (network_info.channel - 11))
297295
app._api._queued_at.assert_any_call("KY", b"ZigBeeAlliance09")
296+
app._api._queued_at.assert_any_call("NK", network_info.network_key.key.serialize())
297+
app._api._queued_at.assert_any_call("ID", 0xBD270B383795DC87)
298298

299299

300300
async def _test_start_network(
@@ -435,7 +435,7 @@ def _mock_command(
435435
seq,
436436
b"\xaa\x55\xbe\xef",
437437
expect_reply=expect_reply,
438-
**kwargs
438+
**kwargs,
439439
)
440440

441441

@@ -509,7 +509,7 @@ def nwk():
509509

510510
def test_rx_device_annce(app, ieee, nwk):
511511
dst_ep = 0
512-
cluster_id = ZDOCmd.Device_annce
512+
cluster_id = zdo_t.ZDOCmd.Device_annce
513513
device = mock.MagicMock()
514514
device.status = device.Status.NEW
515515
app.get_device = mock.MagicMock(return_value=device)
@@ -587,3 +587,11 @@ async def mock_at_command(cmd, *args):
587587
await app.reset_network_info()
588588

589589
app._api._at_command.assert_called_once_with("NR", 0)
590+
591+
592+
async def test_move_network_to_channel(app):
593+
app._api._queued_at = mock.AsyncMock(spec=XBee._at_command)
594+
await app._move_network_to_channel(26, new_nwk_update_id=1)
595+
596+
assert len(app._api._queued_at.mock_calls) == 1
597+
app._api._queued_at.assert_any_call("SC", 1 << (26 - 11))

zigpy_xbee/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
MAJOR_VERSION = 0
2-
MINOR_VERSION = 17
2+
MINOR_VERSION = 18
33
PATCH_VERSION = "0"
44
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
55
__version__ = f"{__short_version__}.{PATCH_VERSION}"

zigpy_xbee/zigbee/application.py

+18-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import zigpy.device
1111
import zigpy.exceptions
1212
import zigpy.quirks
13+
import zigpy.state
1314
import zigpy.types
1415
import zigpy.util
1516
from zigpy.zcl import foundation
@@ -69,13 +70,16 @@ async def start_network(self):
6970
# Enable ZDO passthrough
7071
await self._api._at_command("AO", 0x03)
7172

73+
if self.state.node_info == zigpy.state.NodeInfo():
74+
await self.load_network_info()
75+
7276
enc_enabled = await self._api._at_command("EE")
7377
enc_options = await self._api._at_command("EO")
7478
zb_profile = await self._api._at_command("ZS")
7579

7680
if (
7781
enc_enabled != 1
78-
or enc_options != 2
82+
or enc_options & 0b0010 != 0b0010
7983
or zb_profile != 2
8084
or association_state != 0
8185
or self.state.node_info.nwk != 0x0000
@@ -134,16 +138,18 @@ async def reset_network_info(self) -> None:
134138
await self._api._at_command("NR", 0)
135139

136140
async def write_network_info(self, *, network_info, node_info):
137-
scan_bitmask = 1 << (network_info.channel - 11)
141+
epid, _ = zigpy.types.uint64_t.deserialize(
142+
network_info.extended_pan_id.serialize()
143+
)
144+
await self._api._queued_at("ID", epid)
138145

139146
await self._api._queued_at("ZS", 2)
147+
scan_bitmask = 1 << (network_info.channel - 11)
140148
await self._api._queued_at("SC", scan_bitmask)
141149
await self._api._queued_at("EE", 1)
142-
await self._api._queued_at("EO", 2)
143-
150+
await self._api._queued_at("EO", 0b0010)
144151
await self._api._queued_at("NK", network_info.network_key.key.serialize())
145152
await self._api._queued_at("KY", network_info.tc_link_key.key.serialize())
146-
147153
await self._api._queued_at("NJ", 0)
148154
await self._api._queued_at("SP", CONF_CYCLIC_SLEEP_PERIOD)
149155
await self._api._queued_at("SN", CONF_POLL_TIMEOUT)
@@ -161,6 +167,13 @@ async def write_network_info(self, *, network_info, node_info):
161167
)
162168
LOGGER.debug("Association state: %s", association_state)
163169

170+
async def _move_network_to_channel(
171+
self, new_channel: int, new_nwk_update_id: int
172+
) -> None:
173+
"""Moves the coordinator to a new channel."""
174+
scan_bitmask = 1 << (new_channel - 11)
175+
await self._api._queued_at("SC", scan_bitmask)
176+
164177
async def force_remove(self, dev):
165178
"""Forcibly remove device from NCP."""
166179
pass

0 commit comments

Comments
 (0)