@@ -228,16 +228,34 @@ async def energy_scan(app, num_scans):
228
228
229
229
@radio .command ()
230
230
@click .pass_obj
231
- @click .option ("-n" , "--num-scans" , type = int , default = 10 * 2 ** 8 )
231
+ @click .option ("-e" , "--num-energy-scans" , type = int , default = 10 * 2 ** 8 )
232
+ @click .option ("-n" , "--num-network-scans" , type = int , default = 5 )
232
233
@click .option ("-r" , "--randomize" , type = bool , default = True )
233
234
@click .argument ("output" , type = click .File ("w" ), default = "-" )
234
235
@click_coroutine
235
- async def advanced_energy_scan (app , output , num_scans , randomize ):
236
+ async def advanced_energy_scan (
237
+ app ,
238
+ output ,
239
+ num_energy_scans ,
240
+ num_network_scans ,
241
+ randomize ,
242
+ ):
243
+ import bellows .types
244
+ from bellows .zigbee .application import (
245
+ ControllerApplication as EzspControllerApplication ,
246
+ )
247
+ from bellows .zigbee .util import map_energy_to_rssi as ezsp_map_energy_to_rssi
248
+
236
249
await app .startup ()
237
250
LOGGER .info ("Running scan..." )
238
251
239
252
channels = zigpy .types .Channels .ALL_CHANNELS
240
- scan_counts = {channel : num_scans for channel in channels }
253
+ scan_counts = {channel : num_energy_scans for channel in channels }
254
+
255
+ scan_data = {
256
+ "energy_scan" : [],
257
+ "network_scan" : [],
258
+ }
241
259
242
260
if randomize :
243
261
@@ -260,40 +278,63 @@ def iter_channels():
260
278
261
279
with click .progressbar (
262
280
iterable = iter_channels (),
263
- length = len (list (channels )) * num_scans ,
281
+ length = len (list (channels )) * num_energy_scans ,
264
282
item_show_func = lambda item : None if item is None else f"Channel { item } " ,
265
283
) as bar :
266
- output .write ("Timestamp,Channel,Energy\n " )
267
-
268
284
for channel in bar :
269
285
results = await app .energy_scan (
270
286
channels = zigpy .types .Channels .from_channel_list ([channel ]),
271
287
duration_exp = 0 ,
272
288
count = 1 ,
273
289
)
274
290
275
- energy = results [channel ]
276
- timestamp = time .time ()
277
- output .write (f"{ timestamp :0.4f} ,{ channel } ,{ energy :0.4f} \n " )
291
+ rssi = None
278
292
279
- import bellows .types
280
- from bellows .zigbee .application import (
281
- ControllerApplication as EzspControllerApplication ,
282
- )
293
+ if isinstance (app , EzspControllerApplication ):
294
+ rssi = ezsp_map_energy_to_rssi (results [channel ])
283
295
284
- if not isinstance (app , EzspControllerApplication ):
285
- return
296
+ scan_data ["energy_scan" ].append (
297
+ {
298
+ "timestamp" : time .time (),
299
+ "channel" : channel ,
300
+ "energy" : results [channel ],
301
+ "rssi" : rssi ,
302
+ }
303
+ )
286
304
287
305
await asyncio .sleep (1 )
288
306
for channel in channels :
289
- networks = await app ._ezsp .startScan (
290
- scanType = bellows .types .EzspNetworkScanType .ACTIVE_SCAN ,
291
- channelMask = zigpy .types .Channels .from_channel_list ([channel ]),
292
- duration = 6 ,
293
- )
294
-
295
- for network , lqi , rssi in networks :
296
- print (f"Found network { network } : LQI={ lqi } , RSSI={ rssi } " )
307
+ print (f"Scanning for networks on channel { channel } " )
308
+ networks = set ()
309
+
310
+ for attempt in range (num_network_scans ):
311
+ networks_scan = await app ._ezsp .startScan (
312
+ scanType = bellows .types .EzspNetworkScanType .ACTIVE_SCAN ,
313
+ channelMask = zigpy .types .Channels .from_channel_list ([channel ]),
314
+ duration = 6 ,
315
+ )
316
+ networks_scan = tuple (
317
+ [(network .freeze (), lqi , rssi ) for network , lqi , rssi in networks_scan ]
318
+ )
319
+ new_networks = set (networks_scan ) - networks
320
+
321
+ for network , lqi , rssi in new_networks :
322
+ print (f"Found network { network } : LQI={ lqi } , RSSI={ rssi } " )
323
+ scan_data ["network_scan" ].append (
324
+ {
325
+ "channel" : channel ,
326
+ "lqi" : lqi ,
327
+ "rssi" : rssi ,
328
+ "network" : {
329
+ ** network .as_dict (),
330
+ "extendedPanId" : str (network .extendedPanId ),
331
+ },
332
+ }
333
+ )
334
+
335
+ networks .update (new_networks )
336
+
337
+ json .dump (scan_data , output , separators = ("," , ":" ))
297
338
298
339
299
340
@radio .command ()
0 commit comments