Comcast Internet Speed Monitor With Tweet
Runs a speed test and tweets at Comcast/Xfinity if it’s slower than what you pay for. Logs results locally too. Set your speed targets, plug in your API keys, and let it call them out.
import os
from pathlib import Path
from datetime import datetime, timezone
from dotenv import load_dotenv
import speedtest
import twitter
def run_speed_test() -> tuple[float, float]:
s = speedtest.Speedtest()
s.get_best_server(s.set_mini_server(os.getenv("SPEEDTEST_SERVER_URL", "http://stosat-nash-01.sys.comcast.net/")))
s.download()
s.upload()
results = s.results.dict()
download = results["download"] / 1_000_000
upload = results["upload"] / 1_000_000
return download, upload
def post_to_twitter(message: str) -> None:
api = twitter.Api(
consumer_key=os.getenv("CONSUMER_KEY"),
consumer_secret=os.getenv("CONSUMER_SECRET"),
access_token_key=os.getenv("ACCESS_TOKEN_KEY"),
access_token_secret=os.getenv("ACCESS_TOKEN_SECRET"),
)
api.PostUpdate(message)
def log_speeds(download: float, upload: float, log_path: Path) -> None:
timestamp = datetime.now(timezone.utc).astimezone().isoformat()
with log_path.open("a") as f:
f.write(f"{timestamp} - Download speed: {download:.2f}, Upload speed: {upload:.2f}\n")
def main() -> None:
load_dotenv()
paid_download = 1000.0
paid_upload = 30.0
location = os.getenv("LOCATION", "Knoxville, TN")
log_path = Path("/var/log/speeds.log")
try:
download, upload = run_speed_test()
except Exception as e:
print(f"Speedtest failed: {e}")
return
paid_down_str = f"{int(paid_download)}down"
paid_up_str = f"{int(paid_upload)}up"
message = (
f"Hey @Comcast @ComcastCares @xfinity why is my internet speed "
f"{download:.2f}down/{upload:.2f}up when I pay for {paid_down_str}/{paid_up_str} in {location}?"
)
if download < paid_download or upload < paid_upload:
try:
post_to_twitter(message)
except Exception as e:
print(f"Twitter post failed: {e}")
print(message)
try:
log_speeds(download, upload, log_path)
except Exception as e:
print(f"Logging failed: {e}")
if __name__ == "__main__":
main()