When RaspberryPi 3+ first came out after playing with sensors and an Arduino Uno board for a while, I used it for monitoring wireless and internet connections in different premises. Thanks to the compact size and the low power needed it was the best tool. I thought it would be interesting to know how consistent was the available bandwidth was during the day and eventually know if there were some unnoticed outages happening.
During these years I’ve used similar utilities, but I decided to write and share with you a simpler script that could be implemented quickly and help you to achieve similar results regardless that you run it inside a docker container, virtual machine or raspberry pi.
Without re-inventing the wheel I’ve used Speedtest CLI, knowing that most likely it would be for many of us the first tool to run to test an internet connection. Speedtest CLI
Install speedtest-cli
https://pypi.org/project/speedtest-cli/
1 |
pip3 install speedtest-cli |
Check the version
1 2 3 |
paolo@casa:~$ speedtest --version speedtest-cli 2.1.3 Python 3.8.5 (default, May 27 2021, 13:30:53) [GCC 9.3.0] |
You can use the speedtest cli from bash to output JSON (speedtest –json) or CSV (speedtests –csv).
Running a simple speedtest
1 2 3 4 |
➜ ~ speedtest --simple Ping: 7.458 ms Download: 195.67 Mbit/s Upload: 127.45 Mbit/s |
How to simulate a file transfer using the single connection option
Testing with multiple connections is useful to ‘stress’ the link and if you want to know what is the full potential, but it’s not a good estimate for a file transfer, in that regards it’s better to use the —single option and if you want to know the bandwidth values in byte instead of bit you can also use –byte.
1 2 3 4 5 6 7 8 |
paolo@ws:/mnt/c/Users/Paolo$ speedtest-cli --simple --single Ping: 15.24 ms Download: 40.25 Mbit/s Upload: 15.87 Mbit/s paolo@ws:/mnt/c/Users/Paolo$ speedtest-cli --simple --single --byte Ping: 14.824 ms Download: 5.17 Mbyte/s Upload: 2.02 Mbyte/s |
JSON And CSV outputs and other options
For more options check the –help and the GitHub repository of the maintainer Matt Martz (https://github.com/sivel/speedtest-cli)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
speedtest-cli --help usage: speedtest-cli [-h] [--no-download] [--no-upload] [--single] [--bytes] [--share] [--simple] [--csv] [--csv-delimiter CSV_DELIMITER] [--csv-header] [--json] [--list] [--server SERVER] [--exclude EXCLUDE] [--mini MINI] [--source SOURCE] [--timeout TIMEOUT] [--secure] [--no-pre-allocate] [--version] Command line interface for testing internet bandwidth using speedtest.net. -------------------------------------------------------------------------- https://github.com/sivel/speedtest-cli optional arguments: -h, --help show this help message and exit --no-download Do not perform download test --no-upload Do not perform upload test --single Only use a single connection instead of multiple. This simulates a typical file transfer. --bytes Display values in bytes instead of bits. Does not affect the image generated by --share, nor output from --json or --csv --share Generate and provide a URL to the speedtest.net share results image, not displayed with --csv --simple Suppress verbose output, only show basic information --csv Suppress verbose output, only show basic information in CSV format. Speeds listed in bit/s and not affected by --bytes --csv-delimiter CSV_DELIMITER Single character delimiter to use in CSV output. Default "," --csv-header Print CSV headers --json Suppress verbose output, only show basic information in JSON format. Speeds listed in bit/s and not affected by --bytes --list Display a list of speedtest.net servers sorted by distance --server SERVER Specify a server ID to test against. Can be supplied multiple times --exclude EXCLUDE Exclude a server from selection. Can be supplied multiple times --mini MINI URL of the Speedtest Mini server --source SOURCE Source IP address to bind to --timeout TIMEOUT HTTP timeout in seconds. Default 10 --secure Use HTTPS instead of HTTP when communicating with speedtest.net operated servers --no-pre-allocate Do not pre allocate upload data. Pre allocation is enabled by default to improve upload performance. To support systems with insufficient memory, use this option to avoid a MemoryError --version Show the version number and exit |
My Python Script
I’ve used F Strings and Format String both in that script to let you show the options that the Python language offers to you.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/usr/bin/python3 #Paolo Frigo, https://scriptinglibrary.com import speedtest #pip3 install speedtest-cli import os from datetime import datetime logfile = "/var/log/speedtest.log" isp = speedtest.Speedtest() srv = isp.get_best_server() downstream = "{0:,.2f} Mb".format(float(isp.download()/10**6)) upstream = "{0:,.2f} Mb".format(float(isp.upload()/10**6)) latency = "{0:,.0f} ms".format(float(srv['latency'])) update = datetime.strftime(datetime.now(),'%d/%m/%y %I:%M%p') with open(logfile, 'a+') as file: file.write(F"{update},{downstream},{upstream},{latency}\n") print (f"{logfile} updated") |
Change the permissions on your script:
1 2 |
chmod +x your_python_script dos2unix your_python_script |
create a log file and set relaxed permissions accordingly
1 2 |
sudo touch /var/log/speedtest.log sudo chmod 666 /var/log/speedtest.log |
For scheduling your script you can use crontab.guru to double-check your crontab syntax.
Scheduling your script
I generally run this test every hour, but for this specific script, I ran it every 5 minutes.
Use crontab to schedule the execution of your python script every 5 minutes
1 |
*/5 * * * * your_python_script >> out.log 2>&1 |
or simply
1 |
*/5 * * * * your_python_script |
Checking the log file
tail-ing “speedtest.log” to get the last 5 tests completed during the last 25 minutes (5x5minutes).
1 2 3 4 5 6 |
paolo@ws:/$ tail -n 5 /var/log/speedtest.log 11/06/21 11:40AM,51.73 Mb,18.56 Mb,16 ms 11/06/21 11:45AM,48.96 Mb,18.65 Mb,16 ms 11/06/21 11:55AM,52.29 Mb,18.84 Mb,15 ms 11/06/21 12:00PM,54.34 Mb,18.62 Mb,16 ms 11/06/21 12:05PM,53.72 Mb,18.58 Mb,15 ms |
I hope you will find it useful! As usual, you can find this script on my Github repository.