Skip to content

Commit 26871ba

Browse files
authored
Add network reset, permit, and change-channel commands (#20)
* Add a `change_channel` command * Add a `reset` command * Add a `permit` command * Add documentation * Only send a single channel change broadcast
1 parent 260491b commit 26871ba

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,29 @@ Channel energy (mean of 1 / 5):
115115
- 26* 81.96% #################################################################################
116116
```
117117

118+
## Reset a radio
119+
120+
```console
121+
$ zigpy radio --baudrate 115200 ezsp /dev/serial/by-id/some-radio reset
122+
```
123+
124+
## Permit joins
125+
126+
Mainly useful for testing requests.
127+
128+
```console
129+
$ zigpy radio deconz /dev/ttyUSB0 permit -t 60
130+
```
131+
132+
## Changing the network channel
133+
134+
Note that not all devices will migrate. This is currently only supported on deCONZ and ZNP coordinators.
135+
Other radios will successfully broadcast the change to other devices but you will need to perform a network backup, change the channel, and then restore the backup.
136+
137+
```console
138+
$ zigpy radio znp /dev/ttyUSB0 change-channel --channel 25
139+
```
140+
118141
# OTA
119142
## Display basic information about OTA files
120143
```console

zigpy_cli/radio.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
from __future__ import annotations
22

33
import json
4+
import asyncio
45
import logging
56
import importlib
67
import itertools
78
import collections
89
import importlib.util
910

1011
import click
12+
import zigpy.zdo
1113
import zigpy.state
1214
import zigpy.types
1315
import zigpy.zdo.types
@@ -142,6 +144,24 @@ async def form(app):
142144
await app.form_network()
143145

144146

147+
@radio.command()
148+
@click.pass_obj
149+
@click_coroutine
150+
async def reset(app):
151+
await app.connect()
152+
await app.reset_network_info()
153+
154+
155+
@radio.command()
156+
@click.pass_obj
157+
@click.option("-t", "--join-time", type=int, default=250)
158+
@click_coroutine
159+
async def permit(app, join_time):
160+
await app.startup(auto_form=True)
161+
await app.permit(join_time)
162+
await asyncio.sleep(join_time)
163+
164+
145165
@radio.command()
146166
@click.pass_obj
147167
@click.option("--nwk", type=HEX_OR_DEC_INT, default=0x0000)
@@ -209,3 +229,32 @@ async def energy_scan(app, nwk, num_scans):
209229
)
210230

211231
print()
232+
233+
234+
@radio.command()
235+
@click.pass_obj
236+
@click.option("-c", "--channel", type=int)
237+
@click_coroutine
238+
async def change_channel(app, channel):
239+
await app.startup()
240+
241+
await zigpy.zdo.broadcast(
242+
app=app,
243+
command=zigpy.zdo.types.ZDOCmd.Mgmt_NWK_Update_req,
244+
grpid=None,
245+
radius=0,
246+
broadcast_address=zigpy.types.BroadcastAddress.ALL_DEVICES,
247+
NwkUpdate=zigpy.zdo.types.NwkUpdate(
248+
ScanChannels=zigpy.types.Channels.from_channel_list([channel]),
249+
ScanDuration=zigpy.zdo.types.NwkUpdate.CHANNEL_CHANGE_REQ,
250+
nwkUpdateId=app.state.network_info.nwk_update_id + 1,
251+
),
252+
)
253+
254+
await app.get_device(nwk=0x0000).zdo.Mgmt_NWK_Update_req(
255+
zigpy.zdo.types.NwkUpdate(
256+
ScanChannels=zigpy.types.Channels.from_channel_list([channel]),
257+
ScanDuration=zigpy.zdo.types.NwkUpdate.CHANNEL_CHANGE_REQ,
258+
nwkUpdateId=app.state.network_info.nwk_update_id + 1,
259+
),
260+
)

0 commit comments

Comments
 (0)