Overview of Project

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