Skip to content

Instantly share code, notes, and snippets.

@n8henrie
Last active January 26, 2022 15:58
Embed
What would you like to do?
#!/usr/bin/env python3
"""
Use the MacOS `airport` utility to get a running average of the WiFi signal
strength (RSSI).
Python 3.8+, so works with `/usr/bin/python3` on Monterey.
"""
import os
import statistics
import subprocess
import typing as t
from argparse import ArgumentParser
from collections import deque
from pathlib import Path
def airport():
path = (
Path(Path().absolute().anchor)
/ "System"
/ "Library"
/ "PrivateFrameworks"
/ "Apple80211.framework"
/ "Versions"
/ "Current"
/ "Resources"
)
env = {"PATH": str(path)}
result = subprocess.run(
"airport --getinfo".split(),
env=env,
capture_output=True,
)
parts: t.Dict[str, str | int | None] = {
next(items): next(items, None)
for line in result.stdout.decode().splitlines()
if (items := (item.strip() for item in line.split(": ")))
}
for k, v in parts.items():
if v is None:
continue
try:
# If it looks identical to an int, make it an int
newv = int(v)
if str(newv) == v:
parts[k] = newv
except ValueError:
pass
return parts
def get_rssi(wifi: dict):
return wifi.get("agrCtlRSSI")
def cli():
parser = ArgumentParser()
n_default = 500
n_help = (
"Number of values to include in running average. 0 means "
f"inifinite. Default is {n_default}"
)
parser.add_argument(
"-n",
"--num-running",
type=int,
help=n_help,
default=n_default,
)
return parser.parse_args()
def main():
args = cli()
maxlen = args.num_running
if maxlen == 0:
maxlen = None
vals = deque(maxlen=maxlen)
while True:
wifi = airport()
rssi = get_rssi(wifi)
# I think it will have a value on every call, but JIC
if rssi is None:
continue
if len(vals) == vals.maxlen:
vals.popleft()
vals.append(rssi)
os.system("clear")
mean = statistics.mean(vals)
print(f"{mean:.2f}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment