Raspberry Pi Internet Speed Monitor

In this Raspberry Pi internet speed monitor tutorial, we will be showing you how you can set up your Raspberry Pi to monitor your internet connection and save the data to Google drive.

This tutorial is great if you’re interested in monitoring how your download speed, upload speed, and ping are affected over time. Additionally, this can help you work out what times your network may be at its peak capacity or if you’re suffering from a degraded internet connection.

Ultimate Books of Pi

To achieve this internet speed monitor, we will be showing you how to write a small Python script that interacts with a program called speedtest-cli.

Speedtest-cli is what our internet speed monitor will use to monitor the internet connection. This program works by polling the popular speedtest.net service to get your ping, download speed, and upload speed.

You can find the full tutorial right below or in our ever-growing Raspberry Pi project books.

Equipment List

Below are all the pieces of equipment that we made use of to set up our Raspberry Pi internet speed monitor.

Recommended:

Raspberry Pi 2 or 3

Micro SD Card

USB Drive

Ethernet Cable (Recommended) or Wifi dongle (Pi 3 has Wifi inbuilt)

Optional:

Raspberry Pi Case

Installing speedtest-cli

1. Before we get started with setting up the Raspberry Pi to monitor the internet’s speed, we must first make sure our Raspberry Pi is up to date.

We can update the Raspberry Pi by running the following two commands within the terminal.

sudo apt-get update
sudo apt-get upgrade

2. For our tutorial, we will be utilizing a Python library called speedtest-cli. This Python library acts as a command line interface that talks with speedtest.net.

Using this library, we can quickly poll Speedtest.net to retrieve our current upload and download speeds as well as our current ping. However, before we use this library, we must first install a package called Python pip.

The reason we need the Python pip package is that speedtest-cli is not available in the default Raspbian repository. Instead, we need to retrieve it from the Python Package Index (PyPI) which is thankfully easy to do thanks to pip.

In most cases pip is pre-installed, but we will run the following command to make sure that it is installed.

sudo apt-get install python-pip

3. With pip now installed to the Raspberry Pi, we can move onto using it to download the speedtest-cli python library.

Pip is very easy to use and works the same as apt-get. Just run the following command on the Raspberry Pi to use pip to install speedtest-cli.

sudo pip install speedtest-cli

4. Now that we have installed speedtest-cli we can now test it. Let’s make sure everything is working correctly by running the following command.

speedtest-cli

5. You will see that quite a bit of information is returned by this command. To make things more straightforward we can use the following command.

speedtest-cli --simple

As you can see with the –simple argument, just the download, upload and ping are returned.

Writing our Speed Test Python Script

1. Now that we have speedtest-cli installed on the Raspberry Pi, we can now proceed to write our Python script that will continually monitor our download and upload speeds.

We can begin creating our Python script for the Raspberry Pi internet speed monitor by running the following command.

cd ~
sudo nano speedtest.py

2. Within this file write the following lines of code. We will explain each important section of the code, so you get an idea of how everything works.

import os
import re
import subprocess
import time

These four lines define all of the libraries that we will be relying on in our script. Below we will explain how each of these libraries will be is used.

import os: The os library is used by the script to interact with the operating system itself. For this script, we will be using it to check if a file exists.

import re: The re library allows us to easily do regular expressions by providing a library for handling pattern searches. We use this to find our wanted values out of the data given to us from speedtest-cli.

import subprocess: The subprocess library is essential to this script, as we require it to be able to call another python script.

In our case, we will be using the subprocess library so we can launch up the speedtest-cli script and retrieve the values returned by it.

import time: We utilize the time library so that we can record both the date and time for each call to the speedtest-cli. This library is what will allow us to track our speed over a length of time.

response = subprocess.Popen('/usr/local/bin/speedtest-cli --simple', shell=True, stdout=subprocess.PIPE).stdout.read()

In this line of code, we utilize the subprocess library to launch a call to the speedtest-cli python script and tell it to pipe everything from the speedtest-cli to stdout.

By using stdout.read() at the end of the call we store the response from speedtest-cli to our response variable.

ping = re.findall('Ping:\s(.*?)\s', response, re.MULTILINE)
download = re.findall('Download:\s(.*?)\s', response, re.MULTILINE)
upload = re.findall('Upload:\s(.*?)\s', response, re.MULTILINE)

These three lines of code are fairly simple, and all do the same thing. They use the re library to run a regular expression for a certain piece of text and find the number located next to each piece of text.

For instance, the search for ping finds “Ping: 47.943 ms” but only grabs the number that is between the text.

ping = ping[0].replace(',', '.')
download = download[0].replace(',', '.')
upload = upload[0].replace(',', '.')

These lines are important as we use them to clean up the numbers that we grabbed from the speedtest-cli output.

Since we plan on outputting the data into a CSV format, all number values need to have the commas (,) replaced with decimal points (.). Otherwise, the CSV format will split the numbers into new columns.

Thanks to Pythons .replace we can easily do this on each piece of text.

try:
    f = open('/home/pi/speedtest/speedtest.csv', 'a+')
    if os.stat('/home/pi/speedtest/speedtest.csv').st_size == 0:
            f.write('Date,Time,Ping (ms),Download (Mbit/s),Upload (Mbit/s)\r\n')
except:
    pass

This bit of code is straightforward. The code is kept within a try statement so that if any errors occur, it will not stop the script from operating.

Within the try statement, we first open up a call to our speedtest.csv file. By using, “a+” in the arguments, we tell it that we want to create the file if it doesn’t exist and that any new data should be appended to whatever is already in there.

Afterward, we utilize the os library to check our speedtest.csv files actual size in bytes.

If the file’s bytes is equal to 0, we go ahead.

If the file does exist we proceed on as normal.

f.write('{},{},{},{},{}\r\n'.format(time.strftime('%m/%d/%y'), time.strftime('%H:%M'), ping, download, upload))

Finally, we print out all our data separated by commas.

We use the time library’s strftime function to insert both the current date and the current time into our formatted string.

After that, we insert our ping, download, and upload.

Below we have an included an example of what the output data will look like on the first run of our code.

Date, Time, Ping (ms), Download (Mbit/s),Upload(Mbit/s)
04/28/18,13:34,27.833,27.28,9.02

3. Once you have finished writing your code, it should end up looking like what we have displayed below.

import os
import re
import subprocess
import time

response = subprocess.Popen('/usr/local/bin/speedtest-cli --simple', shell=True, stdout=subprocess.PIPE).stdout.read()

ping = re.findall('Ping:\s(.*?)\s', response, re.MULTILINE)
download = re.findall('Download:\s(.*?)\s', response, re.MULTILINE)
upload = re.findall('Upload:\s(.*?)\s', response, re.MULTILINE)

ping = ping[0].replace(',', '.')
download = download[0].replace(',', '.')
upload = upload[0].replace(',', '.')

try:
    f = open('/home/pi/speedtest/speedtest.csv', 'a+')
    if os.stat('/home/pi/speedtest/speedtest.csv').st_size == 0:
            f.write('Date,Time,Ping (ms),Download (Mbit/s),Upload (Mbit/s)\r\n')
except:
    pass

f.write('{},{},{},{},{}\r\n'.format(time.strftime('%m/%d/%y'), time.strftime('%H:%M'), ping, download, upload))

4. You can now save the file by pressing Ctrl + X then Y and finally press Enter.

5. With our script now written we need to make a folder where our speedtest.csv file will be stored. Run the following command to create this folder.

mkdir ~/speedtest

6. Now that we have made the required folder, we can go ahead and test the script.

We can test our script by running the following command.

python ~/speedtest.py

7. Once the script has finished executing you can then check out the results by opening up the newly created speedtest.csv.

Let’s open up this file by running the following command on the Raspberry Pi.

nano ~/speedtest/speedtest.csv

8. Within this file, you should see something like what we have below. The column headers and some rows of data.

Date, Time, Ping (ms), Download (Mbit/s),Upload(Mbit/s)
04/28/18,13:34,27.833,27.28,9.02

Next, we will be showing how you can take this data and upload it to Google Drive so you can quickly view the data wherever you are.

Uploading Speed Test Data to Google Drive

1. For this section of the guide, we will be showing you how you can upload your speed test data from your Raspberry Pi to Google Drive.

To do this, we will need to make use of a piece of software that allows us to interact with Google Drive through the command line. This piece of software is called gDrive and is developed by a user on Github. You can find more information about this piece of software on gdrives developers Github.

Download the Raspberry Pi version of the gDrive software by entering the following two commands.

cd ~
wget -O gdrive https://docs.google.com/uc?id=0B3X9GlR6EmbnVXNLanp4ZFRRbzg&export=download

2. Now that we have downloaded gDrive to our Raspberry Pi we need to give it execution privileges.

We can do this by entering the following command into the terminal, utilizing chmod with the +x argument.

sudo chmod +x /home/pi/gdrive

3. Let’s now begin the process of connecting your Google account with the gDrive application.

To start the process, we will use the following simple command.

./gdrive list

4. After running gDrive with the list command, we should now be told that authentication is required to continue.

Below the message should be an URL. You will need to go to this URL in a web browser and login using your Google account.

Follow the next few prompts in your web browser until you are given a verification code. Copy this verification code into the terminal and press Enter.

5.  After pressing enter with the correct verification code, you should now see a list of all your gDrive files.

Next, let’s use gDrive to create a new folder on your Google Drive to store our speedtest.csv file. We can do that by using the following command within the terminal.

./gdrive mkdir speedtest

This command will show you a message saying the directory was created. This message will also show you an ID. We will need this ID for our next few steps so write it down somewhere safe.

6. Now that we have used the gDrive command line interface to create a folder on our Google Drive and have the ID handy we can now try uploading something to it.

For this test, we will be uploading our speedtest.csv file. Run the following command and make sure you replace YOUR_FOLDER_ID with the id you retrieved in the previous step.

./gdrive sync upload ~/speedtest YOUR_FOLDER_ID

On the initial sync, you should see a message like below appear on the command line. This message tells you that the file has been successfully synced to your Google Drive account.

Starting sync...
Collecting local and remote file information...
Found 1 local files and 0 remote files

1 remote files are missing
[0001/0001] Uploading speedtest.csv -> speedtest/speedtest.csv
Sync finished in 3.119979351s

7. With Google Drive now successfully syncing with the Raspberry Pi we can move onto automating the whole process so that we upload the speedtest.csv every time we edit it.

Automating the Raspberry Pi Internet Speed Monitor

1. Now that we have set up both the gDrive application and written up our Python script, we need to move onto automating the whole process.

To do the automation, we will be writing a simple bash script. This script will be called by crontab so that it will be run routinely.

Begin writing the bash script by running the following Linux command on your Raspberry Pi.

nano ~/speedtest.sh

2. Within this file, we want to enter the following lines.

Make sure that you replace YOUR_FOLDER_ID with the ID that you received when you created the folder on Google drive.

#!/bin/bash
python /home/pi/speedtest.py
/home/pi/gdrive sync upload  /home/pi/speedtest YOUR_FOLDER_ID

3. Now save the file by pressing Ctrl + X then Y and then finally Enter.

4. Before we set up the crontab for our bash script, we must first give the script execution privileges.

We can achieve this by running the following command within the terminal.

sudo chmod +x /home/pi/speedtest.sh

5. Now with everything done, we can finally move onto setting up the crontab.

Begin editing the crontab by running the following command on your Raspberry Pi. If you are asked what editor you want to use, we recommend you select Nano (Typically number 2).

crontab -e

6. Add the following line at the bottom of the file. This line will tell crontab that it should run our bash script once every hour.

If you want to change the behavior of the crontab, you can look at the Crontab Guru to work out your desired values.

0 * * * * /home/pi/speedtest.sh

7. You should now have your speed test monitor up and running. It should also be continually uploading its results to your Google Drive account.

We hope by the end of this Raspberry Pi internet speed monitor tutorial you should now have your Raspberry Pi automatically running internet speed tests on your connection and uploading that data to Google on an hourly basis.

If you have any thoughts, feedback or anything else, then be sure to head over to the forums.

Ultimate Books of Pi Bottom
Pi My Life Up's Crash Course
to the Raspberry Pi

Pi My Life Up's Crash Course

to the Raspberry Pi

Subscribe to our email list to get the

Crash Course delivered straight to your inbox

Please check your inbox for a confirmation email!