Skip to content

Commit bfbb5fe

Browse files
authored
Implement new zigpy packet API (#171)
* WIP * Handle sending packets with extended timeouts * Move concurrency limiting into zigpy * Handle device relays within zigpy * WIP * Start fixing unit tests * WIP * Rename `profile` to `profile_id` * Fix unit tests * Bump zigpy version * Do not default `dst_ep` to `0` * Revert change to radius * Use relays when provided * Bring test coverage to 100% * Use zigpy for making serial connections * Reduce pyserial-specific code to work with `SocketTransport` * Improve error message when there is too much RF interference * Use more specific zigpy exceptions for formation failure * Implement `reset_network_info` * Drop 3.7 from CI * Treat any failure to load network information as an un-formed network * Include `load_devices` keyword argument
1 parent 079d0eb commit bfbb5fe

File tree

16 files changed

+582
-692
lines changed

16 files changed

+582
-692
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
runs-on: ubuntu-latest
1919
strategy:
2020
matrix:
21-
python-version: [3.7, 3.8, 3.9]
21+
python-version: [3.8, 3.9, "3.10"]
2222
steps:
2323
- name: Check out code from GitHub
2424
uses: actions/checkout@v2
@@ -224,7 +224,7 @@ jobs:
224224
needs: prepare-base
225225
strategy:
226226
matrix:
227-
python-version: [3.7, 3.8, 3.9]
227+
python-version: [3.8, 3.9, "3.10"]
228228
name: >-
229229
Run tests Python ${{ matrix.python-version }}
230230
steps:

.github/workflows/publish-to-pypi.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ jobs:
1010
runs-on: ubuntu-latest
1111
steps:
1212
- uses: actions/checkout@master
13-
- name: Set up Python 3.7
13+
- name: Set up Python 3.8
1414
uses: actions/setup-python@v1
1515
with:
16-
python-version: 3.7
16+
python-version: 3.8
1717
- name: Install wheel
1818
run: >-
1919
pip install wheel

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ Below are the defaults with the top-level Home Assistant `zha:` key.
5151
zha:
5252
zigpy_config:
5353
znp_config:
54-
# "auto" picks the largest value that keeps the device's transmit buffer from getting full
55-
max_concurrent_requests: auto
56-
5754
# Only if your stick has a built-in power amplifier (i.e. CC1352P and CC2592)
5855
# If set, must be between:
5956
# * CC1352/2652: -22 and 19

setup.cfg

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ license = GPL-3.0
1313
packages = find:
1414
python_requires = >=3.7
1515
install_requires =
16-
pyserial-asyncio; platform_system!="Windows"
17-
pyserial-asyncio!=0.5; platform_system=="Windows" # 0.5 broke writes
18-
zigpy>=0.50.0
16+
zigpy>=0.51.0
1917
async_timeout
2018
voluptuous
2119
coloredlogs

tests/application/test_joining.py

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -333,107 +333,3 @@ async def test_on_zdo_device_join_and_announce_slow(device, make_application, mo
333333
assert app.handle_join.call_count == 2
334334

335335
await app.shutdown()
336-
337-
338-
@pytest.mark.parametrize("device", FORMED_DEVICES)
339-
async def test_unknown_device_discovery(device, make_application, mocker):
340-
app, znp_server = await make_application(server_cls=device)
341-
await app.startup(auto_form=False)
342-
343-
mocker.spy(app, "handle_join")
344-
345-
# Existing devices do not need to be discovered
346-
existing_nwk = 0x1234
347-
existing_ieee = t.EUI64(range(8))
348-
device = app.add_initialized_device(ieee=existing_ieee, nwk=existing_nwk)
349-
350-
assert (await app._get_or_discover_device(nwk=existing_nwk)) is device
351-
assert app.handle_join.call_count == 0
352-
353-
# If the device changes its NWK but doesn't tell zigpy, it will be re-discovered
354-
did_ieee_addr_req1 = znp_server.reply_once_to(
355-
request=c.ZDO.IEEEAddrReq.Req(
356-
NWK=existing_nwk + 1,
357-
RequestType=c.zdo.AddrRequestType.SINGLE,
358-
StartIndex=0,
359-
),
360-
responses=[
361-
c.ZDO.IEEEAddrReq.Rsp(Status=t.Status.SUCCESS),
362-
c.ZDO.IEEEAddrRsp.Callback(
363-
Status=t.ZDOStatus.SUCCESS,
364-
IEEE=existing_ieee,
365-
NWK=existing_nwk + 1,
366-
NumAssoc=0,
367-
Index=0,
368-
Devices=[],
369-
),
370-
],
371-
)
372-
373-
# The same device is discovered and its NWK was updated. Handles concurrency.
374-
devices = await asyncio.gather(
375-
app._get_or_discover_device(nwk=existing_nwk + 1),
376-
app._get_or_discover_device(nwk=existing_nwk + 1),
377-
app._get_or_discover_device(nwk=existing_nwk + 1),
378-
app._get_or_discover_device(nwk=existing_nwk + 1),
379-
app._get_or_discover_device(nwk=existing_nwk + 1),
380-
)
381-
382-
assert devices == [device] * 5
383-
384-
# Only a single request is sent, since the coroutines are grouped
385-
await did_ieee_addr_req1
386-
assert device.nwk == existing_nwk + 1
387-
assert app.handle_join.call_count == 1
388-
389-
# If a completely unknown device joins the network, it will be treated as a new join
390-
new_nwk = 0x5678
391-
new_ieee = t.EUI64(range(1, 9))
392-
393-
did_ieee_addr_req2 = znp_server.reply_once_to(
394-
request=c.ZDO.IEEEAddrReq.Req(
395-
NWK=new_nwk,
396-
RequestType=c.zdo.AddrRequestType.SINGLE,
397-
StartIndex=0,
398-
),
399-
responses=[
400-
c.ZDO.IEEEAddrReq.Rsp(Status=t.Status.SUCCESS),
401-
c.ZDO.IEEEAddrRsp.Callback(
402-
Status=t.ZDOStatus.SUCCESS,
403-
IEEE=new_ieee,
404-
NWK=new_nwk,
405-
NumAssoc=0,
406-
Index=0,
407-
Devices=[],
408-
),
409-
],
410-
)
411-
412-
new_dev = await app._get_or_discover_device(nwk=new_nwk)
413-
await did_ieee_addr_req2
414-
assert app.handle_join.call_count == 2
415-
assert new_dev.nwk == new_nwk
416-
assert new_dev.ieee == new_ieee
417-
418-
await app.shutdown()
419-
420-
421-
@pytest.mark.parametrize("device", FORMED_DEVICES)
422-
async def test_unknown_device_discovery_failure(device, make_application, mocker):
423-
mocker.patch("zigpy_znp.zigbee.application.IEEE_ADDR_DISCOVERY_TIMEOUT", new=0.1)
424-
425-
app, znp_server = await make_application(server_cls=device)
426-
await app.startup(auto_form=False)
427-
428-
znp_server.reply_once_to(
429-
request=c.ZDO.IEEEAddrReq.Req(partial=True),
430-
responses=[
431-
c.ZDO.IEEEAddrReq.Rsp(Status=t.Status.SUCCESS),
432-
],
433-
)
434-
435-
# Discovery will throw an exception when the device cannot be found
436-
with pytest.raises(KeyError):
437-
await app._get_or_discover_device(nwk=0x3456)
438-
439-
await app.shutdown()

0 commit comments

Comments
 (0)