Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advanced energy scan #49

Draft
wants to merge 6 commits into
base: dev
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions zigpy_cli/radio.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import itertools
import json
import logging
import random
import time

Check warning on line 11 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L10-L11

Added lines #L10 - L11 were not covered by tests

import click
import zigpy.state
Expand Down Expand Up @@ -224,6 +226,124 @@
print()


@radio.command()
@click.pass_obj
@click.option("-e", "--num-energy-scans", type=int, default=10 * 2**8)
@click.option("-n", "--num-network-scans", type=int, default=5)
@click.option("-r", "--randomize", type=bool, default=True)
@click.argument("output", type=click.File("w"), default="-")
@click_coroutine
async def advanced_energy_scan(

Check warning on line 236 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L229-L236

Added lines #L229 - L236 were not covered by tests
app,
output,
num_energy_scans,
num_network_scans,
randomize,
):
import bellows.types
from bellows.zigbee.application import (

Check warning on line 244 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L243-L244

Added lines #L243 - L244 were not covered by tests
ControllerApplication as EzspControllerApplication,
)
from bellows.zigbee.util import map_energy_to_rssi as ezsp_map_energy_to_rssi

Check warning on line 247 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L247

Added line #L247 was not covered by tests

await app.startup()
LOGGER.info("Running scan...")

Check warning on line 250 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L249-L250

Added lines #L249 - L250 were not covered by tests

channels = zigpy.types.Channels.ALL_CHANNELS
scan_counts = {channel: num_energy_scans for channel in channels}

Check warning on line 253 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L252-L253

Added lines #L252 - L253 were not covered by tests

scan_data = {

Check warning on line 255 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L255

Added line #L255 was not covered by tests
"current_channel": app.state.network_info.channel,
"energy_scan": [],
"network_scan": [],
}

if randomize:

Check warning on line 261 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L261

Added line #L261 was not covered by tests

def iter_channels():
while scan_counts:
channel = random.choice(tuple(scan_counts))
scan_counts[channel] -= 1

Check warning on line 266 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L263-L266

Added lines #L263 - L266 were not covered by tests

yield channel

Check warning on line 268 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L268

Added line #L268 was not covered by tests

if scan_counts[channel] <= 0:
del scan_counts[channel]

Check warning on line 271 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L270-L271

Added lines #L270 - L271 were not covered by tests

else:

def iter_channels():
for channel, count in scan_counts.items():
for i in range(count):
yield channel

Check warning on line 278 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L275-L278

Added lines #L275 - L278 were not covered by tests

with click.progressbar(

Check warning on line 280 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L280

Added line #L280 was not covered by tests
iterable=iter_channels(),
length=len(list(channels)) * num_energy_scans,
item_show_func=lambda item: None if item is None else f"Channel {item}",
) as bar:
for channel in bar:
results = await app.energy_scan(

Check warning on line 286 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L285-L286

Added lines #L285 - L286 were not covered by tests
channels=zigpy.types.Channels.from_channel_list([channel]),
duration_exp=0,
count=1,
)

rssi = None

Check warning on line 292 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L292

Added line #L292 was not covered by tests

if isinstance(app, EzspControllerApplication):
rssi = ezsp_map_energy_to_rssi(results[channel])

Check warning on line 295 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L294-L295

Added lines #L294 - L295 were not covered by tests

scan_data["energy_scan"].append(

Check warning on line 297 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L297

Added line #L297 was not covered by tests
{
"timestamp": time.time(),
"channel": channel,
"energy": results[channel],
"rssi": rssi,
}
)

if not isinstance(app, EzspControllerApplication):
json.dump(scan_data, output, separators=(",", ":"))
return

Check warning on line 308 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L306-L308

Added lines #L306 - L308 were not covered by tests

for channel in channels:
networks = set()

Check warning on line 311 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L310-L311

Added lines #L310 - L311 were not covered by tests

for attempt in range(num_network_scans):
print(

Check warning on line 314 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L313-L314

Added lines #L313 - L314 were not covered by tests
"Scanning for networks on channel"
f" {channel} ({attempt + 1} / {num_network_scans})"
)
networks_scan = await app._ezsp.startScan(

Check warning on line 318 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L318

Added line #L318 was not covered by tests
scanType=bellows.types.EzspNetworkScanType.ACTIVE_SCAN,
channelMask=zigpy.types.Channels.from_channel_list([channel]),
duration=6,
)

for network, lqi, rssi in networks_scan:
if network.replace(allowingJoin=None).freeze() in networks:
continue

Check warning on line 326 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L324-L326

Added lines #L324 - L326 were not covered by tests

networks.add(network.replace(allowingJoin=None).freeze())

Check warning on line 328 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L328

Added line #L328 was not covered by tests

print(f"Found network {network}: LQI={lqi}, RSSI={rssi}")
scan_data["network_scan"].append(

Check warning on line 331 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L330-L331

Added lines #L330 - L331 were not covered by tests
{
"channel": channel,
"lqi": lqi,
"rssi": rssi,
"allowing_join": network.allowingJoin,
"extended_pan_id": str(network.extendedPanId),
"nwk_update_id": network.nwkUpdateId,
"pan_id": network.panId,
"stack_profile": network.stackProfile,
}
)

json.dump(scan_data, output, separators=(",", ":"))

Check warning on line 344 in zigpy_cli/radio.py

View check run for this annotation

Codecov / codecov/patch

zigpy_cli/radio.py#L344

Added line #L344 was not covered by tests


@radio.command()
@click.pass_obj
@click.option("-c", "--channel", type=int)
Expand Down
Loading