Skip to content

Instantly share code, notes, and snippets.

@balzer82
Last active August 22, 2018 09:48
Show Gist options
  • Save balzer82/b59c0f5460bbb8dd7244bcfb9fed869c to your computer and use it in GitHub Desktop.
Save balzer82/b59c0f5460bbb8dd7244bcfb9fed869c to your computer and use it in GitHub Desktop.
Graphical Output of MacOS airport Util to analyze Wifi
#!/usr/bin/python
# coding: utf-8
from datetime import datetime, timedelta
import subprocess
import os
import time
import csv
import matplotlib.pyplot as plt
# This is only available on MacOSX
AIRPORT = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport'
def sniffWifi():
'''
funtion to grab output of MacOS airport tool and convert it to dictionary
'''
wifidata = subprocess.check_output([AIRPORT, '-I']).decode('utf-8')
wifidict = {'time': datetime.now()}
for data in wifidata.split('\n')[:-1]:
try: # if numeric value, parse it
wifidict[data.split(':')[0].strip()] = int(data.split(':')[1].strip())
except: # if not, use as text
wifidict[data.split(':')[0].strip()] = data.split(':')[1].strip()
return wifidict
def startwifianalyzer(dt=.1, timespan=10,
withliveplot=True,
withsummaryplot=True,
withlogfile=True):
try:
zeit = []
rssi = []
noise = []
csvheaderwrote = False
if withliveplot:
# Prepare the Live Plot
plt.ion()
graph = plt.plot(zeit, rssi)[0]
datemin = datetime.now()
datemax = datetime.now() + timedelta(seconds=timespan)
plt.xlim(datemin, datemax)
plt.ylim(-98, -12)
plt.ylabel('RSSI in dBm')
plt.xlabel('Zeit')
while True:
# Grab some WiFi Data
wifi = sniffWifi()
# Print Output
os.system('cls' if os.name == 'nt' else 'clear')
print('==== Wifi Analyzer: \"%s\" ====' % wifi['SSID'])
for k, v in wifi.items():
if k != 'time':
print('{:>18}: {:<8}'.format(k, v))
print("timestamp: %s" % wifi['time'].isoformat(' '))
print('\'CTRL\' + \'C\' to cancel')
if withlogfile:
csvfilename = datemin.isoformat().replace(':','-') + '.csv'
with open(csvfilename, 'a') as csvfile:
writer = csv.writer(csvfile)
if not csvheaderwrote:
writer.writerow(wifi.keys())
csvheaderwrote = True
writer.writerow(wifi.values())
if withliveplot:
# Live Plot update
zeit.append(wifi['time'])
rssi.append(wifi['agrCtlRSSI'])
noise.append(wifi['agrCtlNoise'])
graph.set_xdata(zeit)
graph.set_ydata(rssi)
if wifi['time'] > datemax: # timescroll
plt.xlim(wifi['time']-timedelta(seconds=timespan), wifi['time'])
plt.gcf().autofmt_xdate()
plt.draw()
plt.pause(0.01)
time.sleep(dt)
except KeyboardInterrupt:
print('Canceled')
plt.close()
except Exception as e:
print('Something went wrong:')
print(e)
if withsummaryplot:
if len(zeit)>10:
# Save final plot
pngfile = ('%s.png' % datemin.isoformat().replace(':','-'))
print('Saving to %s' % pngfile)
plt.plot(zeit, rssi, label='RSSI')
plt.plot(zeit, noise, label='Noise')
plt.ylabel('dBm')
plt.xlabel('Zeit')
plt.title('Wifi \"%s\" (Channel %s)' % (wifi['SSID'], wifi['channel']))
plt.ylim(-98, -12)
plt.legend()
plt.gcf().autofmt_xdate()
plt.tight_layout()
plt.savefig(pngfile, dpi=150)
plt.close()
else:
print('Not enough data for summary plot')
if __name__ == "__main__":
startwifianalyzer()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment