Looking for an easy and useful project for that Pi you just have lying around? Find out who’s home and who’s not, or when your favourite coworkers are at the office, with just a Pi and an internet connection! This WiFi-based presence detector will take hardly any time at all, and you’ll suddenly have a base for triggering all sorts of things when someone is detected, like that theme music you’ve always wanted.

The full article can be found in The MagPi 51 and was written by Rachel-Chloe Gregory.

Presence detection

The way that we’re going to detect ‘presence’ is by scanning the WiFi network for certain devices’ MAC addresses, the unique identifiers that your phone or laptop gives when connecting to a network. Detecting devices can also be done via Bluetooth; however, not everyone will always have their phone’s Bluetooth turned on, so WiFi should be a bit more reliable.

Update your Pi and install arp-scan, an Address Resolution Protocol packet scanner that shows every active IPv4 device on your local internet:

sudo apt-get update sudo apt-get install arp-scan

Once arp-scan is installed, you can test it with:

sudo arp-scan –l

You should see a list of devices and corresponding MAC addresses run down the screen; it could take a little while to load if on a large network.

A quick Google search will tell you how to find your particular phone/laptop MAC address, usually a series of 12 letters and numbers separated by colons. You can check to see if your device appears on the arp-scan list of devices if the following command returns an address:

sudo arp-scan -l | grep DEVICEMACADDRESS

If your phone was found, the command will output its address. If it wasn’t found, make sure that it’s connected to the same WiFi network as the Pi (or vice versa). You may also need to wake up your device, as many devices disappear when they ‘sleep’.

Initial State

We’re going to use Initial State to create a real-time dashboard showing who’s at the office and who isn’t. Initial State is paid-for software and you can get a 14-day-free trial to test out the service. It is currently free for students with an .edu account and $9.99 per month. See Intial State pricing.

Go to app.initialstate.com/#/register/ and create a new account. Install the Initial State Python module on your Pi:

\curl -sSL https://get.initialstate.com/python -o - | sudo bash

You will be prompted to create an example script; this isn’t essential to installing the module, but can help test your ability to stream to Initial State.

The code

You can clone the GitHub repo to get the presence.py script:

git clone https://github.com/initialstate/pi-sensor-free-presence-detector.git

We use threading to create separate pieces of code that run at the same time as each other. This allows us to look for more than one device on the network more reliably. The subprocess module lets us call arp-scan within our Python script.

To customise the script, change the arrays of names and addresses to match your own. In this use case, we’re tracking who’s at the office, so we have an array with our names. The address array contains the corresponding MAC addresses for our phones. If you want to add more devices, simply add more values to both arrays.

You’ll also need to replace YOUR ACCESS KEY with your Initial State access key, which can be found on your Initial State Account page.

Run the script with:

sudo python presence.py

Watch what prints to the terminal to make sure your devices are being detected, and that streaming is working. Head over to Initial State to check out your dashboard!

Run from boot

To make this truly useful and reliable, we need to handle any network issues. We found the easiest solution to be rebooting the Pi whenever the network connection drops. First, we need to create a script to check the WiFi and then trigger shutdown:

sudo nano /usr/local/bin/checkwifi.sh

Place the following inside the file, making sure to replace the IP address with the IP address of your router:

ping -c4 IP_ADDRESS > /dev/null if [ $? != 0 ] then sudo /sbin/shutdown -r now fi

The ping checks for a connection. If it returns with a non-zero exit code, the script sends the shutdown command.

Save and exit the script. Now make sure its permissions are in order:

sudo chmod 775 /usr/local/bin/checkwifi.sh

Running a script from boot on the Pi is pretty straightforward with the service crontab:

sudo crontab -e

Pick your favourite text editor (such as nano) and at the bottom of the file, under all of the comments, add @reboot nohup sudo /usr/bin/python /home/pi/presence.py & to run the presence.py script. If you named your script something else or put it in a different directory, replace /home/pi/presence.py with the correct path. Then, under that, add */5 * * * * /usr/bin/sudo -H /usr/local/bin/checkwifi.sh >> /dev/null 2>&1 to run the checkwifi.sh script. Exit crontab and reboot the Pi to run your new presence detector!