Last active
January 26, 2022 15:58
-
-
Save n8henrie/ea6a2d3687a99264e2ddbc9cc23ce8e4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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