Measuring WiFi Signal Strength with Python

I ran into some space problems when I tried installing OpenCV on the raspberry pi. I don’t feel like reinstalling everything on a new SD card so I will just blog about something else not raspberry pi related. I’ll work on it when I get back from visiting my parent’s house.

The wifi reception in my room in my parent’s house has always been terrible. So I figured that I would build a script to figure out how bad the reception really was. I realized that I could also use this script in my apartment since I get wifi issues in certain rooms.

This script uses the the python library subprocess to continuously call the iwconfig program and parse its output. The iwconfig program is a linux program that can tell you the details about your wireless connection. When you run it, it will show your wireless connections and the signal strength.

Intro to iwconfig

So the first thing you should know about this script is that it uses a linux program called iwconfig. This program is already installed on most linux distributions, so you shouldn’t need to worry about installing it. It shows you all the wireless insterfaces you have along with information such as signal strength. Open the command line and type in:

iwconfig

You should see something like this:

What you see is info about my wireless card wlp2s0, and its connection status. Yours may be named something different like wlan0.

The information that I want to focus on is the link quality and the signal quality. By using the pipe operator and grep , we can see just the line of link and signal quality.

iwconfig | grep Link

Using Python to Call iwconfig

Initially I wanted to use the module os.system to call iwconfig, but the documentation on the subprocess module says that subprocess was intended to replace the os.system module.

Let’s start by importing the subprocess library and prepare the command we can use:

from subprocess import *

# Change wlp2s0 to wlan0 if you have problems
shell_cmd = 'iwconfig {} | grep Link'.format('wlp2s0')

The variable shell_cmd holds the command we were using earlier to get the signal strength. I used string substitution so that you can change it to whatever your network card is named.

Now to start a process we use the Popen class and input the command we want to run. The shell argurment set to true means that we want to run this process using the shell. The PIPE arguments and communicate method allow us to read in the output and any errors from the shell. The output comes in as a bytestream, so we need to convert that to utf-8 and remove any surrounding whitespace. Then we can see the signal strength that we had from the beginning of the tutorial.

proc = Popen(shell_cmd, shell=True, stdout=PIPE, stderr=PIPE)
output, err = proc.communicate()
msg = output.decode('utf-8').strip()
print(msg)

Let’s put this code in a try statement in a while loop so that it continues to run until we keyboard interrupt the script. To only show one line and not fill up the whole terminal with text, I print a number of backspaces equal to the length of the signal strength line so that only one line is showing in the terminal.

try:
    while True:
        proc = Popen(shell_cmd, shell=True, stdout=PIPE, stderr=PIPE)
        output, err = proc.communicate()
        msg = output.decode('utf-8').strip()
        print(msg, end='')
        print('\b' * len(msg), end='', flush=True)
except KeyboardInterrupt:
    print('\nExited Scanner')

That’s it! The compiled code is on my github as usual. Now you can measure your WiFi signal strength around the house. I want to come back to this script and make a GUI for it.

Leave a Reply

Your email address will not be published. Required fields are marked *