Overview of ProjectRaspberry Pi Sample Code

The aim of this project was to build the basis for some simple home automation. The very basic usage was to create a simple system that would switch on a lamp when I returned to my house. Before researching any of the available technology I decided to create this using a Bluetooth enabled Raspberry Pi 2 which would scan to see if my mobile phone was in range, if my phone was out of range and then came in range (i.e. I was out and came home) my bedside lamp would be switched on.

This tutorial will explain how this was achieved by explaining the basics of the system and then expanding it to add simple automation.

What you need

Ok well this was created on a Raspberry Pi 2 so that would be a good place to start. I assume any model of Raspberry Pi (get a Raspberry Pi) would work and I dare say any other computer may do the trick too. A WiFi connection (get a Wi-Fi Dongle) is pretty handy although this would work fine over ethernet too.

As this uses Bluetooth to see who’s home then I’d suggest getting a Bluetooth dongle (get a Bluetooth dongle) – these can be picked up for a couple of pounds in most shops – if you want a good laugh visit PC World and tell them it’s for a Raspberry Pi, they won’t have a clue what you’re talking about.

To send notifications from our setup we will also need a PushBullet account. This is a free service and there is an available Python API that we can install later. Once you have your PushBullet account setup you will need an API access token. This is found on their website under Settings > Account > Access Tokens. Create your access token and take a note of it as this will be required in your code. Also download the PushBullet app for your smartphone to receive notifications.

Setup

For my setup I connect to my Pi using an SSH connection via the command line from a MacBook Pro. This post should explain how to do achieve this Raspberry Pi – Remote Access. This simply means that you do not have to have your Pi connected to a monitor to run the final script or any updates or package installs. (if you do not want to remotely connect to your Pi, simply keep following these instructions by creating a Python script using the text editor on the Pi.)

To make file transfers very quick and simple I also recommend using Filezilla. Again this is to allow us to be able to create the script on a Mac or PC and easily move files onto the Raspberry Pi. This link to SFTP Filezilla will explain how to set Filezilla up with your Raspberry Pi.

Next make sure your Pi has the most up to date version of Python – again not sure the minimum version needed for this to work but the latest should be the best bet.
Connect to your Raspberry Pi via SSH and then type:

sudo apt-get update

sudo apt-get upgrade

While we’re in the command line we’ll also need a Python package installer called Python Package Index of PIP for short. This will be used to install the PushBullet API and will come in handy for future projects. From the command line type:

sudo apt-get install python-pip

Once this is completed we can the get the PushBullet Python library by typing the command:

sudo pip install pushbullet.py

The initial system that I set up was wired up to a breadboard and a single LED. The LED would light to represent the lamp lighting. For this feature the WiringPi Python library was used to allow access to the Raspberry , to install this library follow the install instructions on the WiringPi website.
The second setup of this project saw me using the Pi-Lite LED matrix which can be purchased here Pi-Lite. To use this we must install the PySerial package which can be installed by typing the following command:

sudo apt-get install python-serial

OK so that is the hard work done. Next is writing the script to make all the magic happen.

Code

On your PC or Mac open up your most trusty code editor. I’m a fan of Brackets but whichever editor you choose is completely up to you. If you want to be super cool you could even just use a plain text editor or even the editor on your Raspberry Pi.

The code is very simple for this project and I will explain the process of building this so that you can develop the code into something that suits your needs. I will also assume little knowledge of Python and where I’m no expert I’ll explain in the simplest terms I can. If you’re super amazing with Python you’ll find a million and one issues with the code so here goes.

So first thing’s first. Create a .py script. Call it whatever you want and save it somewhere that you’ll remember.

Imports

We’ll start by importing all our libraries:

import sys
import time
import bluetooth
from pushbullet import Pushbullet
import wiringpi2 as wpi
import serial

Above we import the system library, time library and bluetooth library. These haven’t been discussed but are fairly obvious as we work through the code.

Creating a User Class

We’ll set up a very basic class to allow us to add as many users as we need without having too much effect on the rest of the code.

class Users(object):
    def __init__(self, name=None, mac=None, pin=4):
        self.name = name
        self.mac = mac
        self.pin = pin
        self.status = 'out'

The above class allows each user to have a name, a mac address which will be used to identify their bluetooth device, a pin number which will be used to switch a GPIO pin on and off and a status which we plan to change later. The default pin will be pin 4 and the default status will be ‘out’ as seen in the class constructor.

Settings

For just now we’ll only add the settings relating to PushBullet. This is simple task which will require the Access Token that we created earlier.

pb = Pushbullet("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") #Replace xxxx with your access token

Users

Next we’ll setup the users we want to track. For this we need a users name and their Bluetooth MAC address, this can be found on the device we want to track. We will add all of our users to an array to allow us to work with many users.

userList = []
userList.append(Users("David", "60:95:6D:5A:AF:E7:90", 22))

You can add as many users as needed by repeating the last line for each user.

Main Program

To allow the main program to run and be terminated safely from the command line we’ll use a ‘Try:Catch’ method. Simply add:

try:
    #Running code will go in here
except (KeyboardInterrupt, SystemExit):
    #This will run when we quit the script
    #We'll reset GPIO pins and the Pi-Lite here later on

Next we’ll add a while True: loop within ‘try:’

We’ll also add some text output to allow the user to see that the script is running. The code should read as follows:

try:
    while True: 
        print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
except (KeyboardInterrupt, SystemExit):
    #This will run when we quit the script
    #We'll reset GPIO pins and the Pi-Lite here later on

Next we will run through all of the users that we have created and check to see if their MAC address can be found. This process does not require the device to be paired with the Raspberry Pi but does require Bluetooth to be enabled. We’ll add a for loop to read through the users. We will also get their current status and store it as the variable oldStatus

try:
    while True: 
        print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
        for user in userList:
            result = bluetooth.lookup_name(user.mac, timeout=3)
            oldStatus = user.status
except (KeyboardInterrupt, SystemExit):
    #This will run when we quit the script
    #We'll reset GPIO pins and the Pi-Lite here later on

For each of the users we will either receive a response from Bluetooth or we will receive a None response. Using an ‘if’ ‘else’ statement we will check the response and run the appropriate code.

try:
    while True: 
        print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
        for user in userList:
            result = bluetooth.lookup_name(user.mac, timeout=3)
            oldStatus = user.status
            if (result != None):
                #What we'll do if a device is in range

            else:
                #What we'll do if a device is NOT in range

except (KeyboardInterrupt, SystemExit):
    #This will run when we quit the script
    #We'll reset GPIO pins and the Pi-Lite here later on

The logic of the next part of the program can be a little difficult to follow. If the Bluetooth device is in range, we want to then check if the user was previously marked as out. If the user was out and has returned we then want to send a notification to our device otherwise at this point we don’t need to do anything.
We also have to do the opposite if there was no response from the Bluetooth device. The code should now look like this:

try:
    while True: 
        print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
        for user in userList:
            result = bluetooth.lookup_name(user.mac, timeout=3)
            oldStatus = user.status
            if (result != None):
                #What we'll do if a device is in range
                if (oldStatus == 'out'):
                    push = pb.push_note("Home Pi", user.name + " is home")
                    user.status = 'in'

            else:
                #What we'll do if a device is NOT in range
                if (oldStatus == 'in'):
                    push = pb.push_note("Home Pi", user.name + " has just left")
                    user.status = 'out'

except (KeyboardInterrupt, SystemExit):
    #This will run when we quit the script
    #We'll reset GPIO pins and the Pi-Lite here later on

To add some feedback to the console we’ll add a simple print message to both parts of the first ‘if’ statement:

try:
    while True: 
        print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
        for user in userList:
            result = bluetooth.lookup_name(user.mac, timeout=3)
            oldStatus = user.status
            if (result != None):
                #What we'll do if a device is in range
                if (oldStatus == 'out'):
                    push = pb.push_note("Home Pi", user.name + " is home")
                    user.status = 'in'
                print user.name + " is home"

            else:
                #What we'll do if a device is NOT in range
                if (oldStatus == 'in'):
                    push = pb.push_note("Home Pi", user.name + " has just left")
                    user.status = 'out'
                print user.name + " is out"

except (KeyboardInterrupt, SystemExit):
    #This will run when we quit the script
    #We'll reset GPIO pins and the Pi-Lite here later on

Basic Script

That’s about it for the basics of this script. I have also added a simple sleep() function so as to stop the program running constantly.

import sys
import time
import bluetooth
from pushbullet import Pushbullet
import wiringpi2 as wpi
import serial

class Users(object):
    def __init__(self, name=None, mac=None, pin=4):
        self.name = name
        self.mac = mac
        self.pin = pin
        self.status = 'out'

pb = Pushbullet("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") #Replace xxxx with your access token

userList = []
userList.append(Users("David", "60:95:6D:5A:AF:E7:90", 22))

try:
    while True: 
        print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
        for user in userList:
            result = bluetooth.lookup_name(user.mac, timeout=3)
            oldStatus = user.status
            if (result != None):
                #What we'll do if a device is in range
                if (oldStatus == 'out'):
                    push = pb.push_note("Home Pi", user.name + " is home")
                    user.status = 'in'
                print user.name + " is home"

            else:
                #What we'll do if a device is NOT in range
                if (oldStatus == 'in'):
                    push = pb.push_note("Home Pi", user.name + " has just left")
                    user.status = 'out'
                print user.name + " is out"

        print "Next check will be in 30 seconds"
        time.sleep(30)

except (KeyboardInterrupt, SystemExit):
    #This will run when we quit the script
    #We'll reset GPIO pins and the Pi-Lite here later on

With this basic script completed, it’s time to test it out to see if it works.
Save the file and open a connection to your Raspberry Pi using Filezilla. We want to copy the script over to a folder on the Raspberry Pi. I chose to place this directly on the Desktop.

From the terminal of your PC or Mac, navigate to the folder on your Raspberry Pi containing your script using:

cd path/to/folder

and then run the script using the command:

sudo python filename.py

Here you should see the script running and feedback being printed directly to the console. You should also receive notifications to your mobile about who’s in and who’s out.

In the next tutorial I’ll explain how to add GPIO controls and Pi-Lite feedback.

I would greatly appreciate any comments that could help improve this code or the process in general. Being a web developer I have mainly focused on procedural code and would greatly appreciate feedback with regards to creating an Object Orientated version of this although I feel it may over complicate things.

Who’s home? Raspberry Pi 2 Project
Like this? Share thisTweet about this on Twitter
Twitter
Share on Facebook
Facebook
Pin on Pinterest
Pinterest
Share on Reddit
Reddit
Tagged on:                                 

8 thoughts on “Who’s home? Raspberry Pi 2 Project

  • 24th January 2016 at 3:14 pm
    Permalink

    How would I change this so that it works from IP addresses over a wifi rather than bluetooth?

    So:
    userList = []
    userList.append(Users(“Ali”, “192.18.1.14”, 22))
    userList.append(Users(“Sophie”, “192.18.1.9”, 22))
    userList.append(Users(“Adam”, “192.18.1.8”, 22))
    userList.append(Users(“Paul”, “192.18.1.3”, 22))
    userList.append(Users(“TV”, “192.18.1.7”, 22))

    I’m guessing the line I need to change is:

    result = bluetooth.lookup_name(user.mac, timeout=3)

    But to what?

    Thanks

  • 24th January 2016 at 3:55 pm
    Permalink

    Hi Paul,

    Not sure that this would work directly as I imported the bluetooth library at the beginning of the code. You would have to find a library that would allow you to ping the IP address of each user.

    I think the main logic of this could would still work but check out this Python Package that might be your solution https://pypi.python.org/pypi/ping

    Would be great to hear how you get on with it.

    Cheers
    Dave

  • 24th January 2016 at 6:03 pm
    Permalink

    Hi Dave,

    Thanks for the response, I think i’m trying to run before I can walk! Lots to learn

    As I was struggling with all sorts of errors, I took your script and ran it without any modifications and I was still getting errors with Indentation and syntax errors which is weird. I obviously knew it would find the MAC but it must be copy/paste issues.

    Great tutorial though

    Regards

    Paul

  • 24th January 2016 at 6:07 pm
    Permalink

    I think it can be done and I’m glad to hear that you’re running with it.

    Bluetooth and Wifi will work in very different ways but the logic behind both will be very similar.

    Python is very funny with indentation – coming from HTML, CSS, PHP and JavaScript I’m finding it very fiddly.

    Glad to hear that it’s been useful thanks.

    Follow us on Instagram and Twitter for more projects and if you have anyone else that you think would like this then share it with them too.

    Thanks again
    Dave

  • 28th January 2016 at 11:35 pm
    Permalink

    Hi

    I think that with some changes it could help also for wifi security of Network if it works via wifi. Checking wifi network with Mac ids and if it’s figure out new Mac id which not listed before, it’ll send push notifications and if known Mac id connected send message with similar logic (online/offline)

    If someone connect to your system first time you will receive message. 🙂

    And make it smarter log these ınfo in text file and write known Mac ids in different txt file 🙂

  • 30th January 2016 at 7:25 pm
    Permalink

    Just ping the phones in your Wifi every 5 or so minutes. You can assign Stativ IPs in the router setup. No need for a huge script, cron will do the job.

  • 10th December 2016 at 5:18 am
    Permalink

    This is awesome. I wonder if there’s a way to use this as a generic people counter when you don’t know what devices are nearby.

  • 16th January 2017 at 8:05 pm
    Permalink

    Hi Paul,

    I’m having a look at this as a plan b. I was originally looking to see if there was a way my Rpi could poll bluetooth devices in the vicinity and report / alert their battery status?

    My car is forever telling me my phone is about to go flat, so it must be possible and I’d like to add it to my notification centre and/or pushbullet notifications.

    Cheers,
    Nick

Comments are closed.