In late March I went to a hackathon at Universal Studios. We created a system where guests could bypass the queue line by completing a series of tasks that would lead them around the land the ride is in where the average completion time was 66% of the current ride wait time. This system pulls people from the queue line while providing the incentive of a more rich experience, less down time, and potentially less wait time. Of course that sounds all fancy, but without actually demonstrating the technology behind such a system, it’s still just an idea.
Or is it?
In the video, you can see me demonstrate the backbone of this very system. It uses iBeacons to trigger actions both on the phone and in the environment. The phone is in charge of tracking the guest’s progress moving from location to location by recognizing certain iBeacons. Once the guest has completed every task, it sends a unique iBeacon signature to a Microsoft Azure SQL database, and the guest proceeds to a special entrance of the ride. Here, the guest’s phone now becomes an iBeacon broadcasting the unique signiture. Once the gateway device detects an iBeacon, it checks it against the Azure database. If there is a match, the environment signals that entry is allowed, and the signature is deleted from the database. If there isn’t a match, the guest is turned away. Only guests who complete the tasks are allowed to enter, and they cannot enter more than once per completion.
In this instrucable, I’ll show you how to build and test the gateway device using a Raspberry Pi, iPhone, and Bluetooth LE dongle. We will:
- Learn how to transmit and scan for iBeacons with the Raspberry Pi and Python3
- Learn how to connect the Raspberry Pi to Azure with Python3
- Create a new Azure SQL database and Azure Mobile Service
- Connect all the pieces together to form our gateway
Things you will need:
- A functioning Raspberry Pi (preferably B or B+) with Raspbian connected to the internet
- A Bluetooth LE USB dongle
- A Microsoft Azure account
- An iPhone running iOS 8+ (demo code is written in Swift)
- Optional but recommended: Apple Developer account to sideload the iOS demo app
- Optional: a Blink(1) USB dongle or some other means of indicating program status
The code for this project can be found on my GitHub page.
Have an Android phone? Check out the last page.
Step 1: Installing and Transmitting an iBeacon
Let’s start by turning the Raspberry Pi into an iBeacon. This will install the Bluetooth libraries we need and let us see that our BLE dongle is working. We’ll use apt-get to install our dependencies:
sudo apt-get update;sudo apt-get install -y libbluetooth-dev bluez
For good measure, let’s shutdown the Pi and restart. If the BLE dongle is not already inserted, do that now. Never connect or remove USB devices from the Pi when it’s powered on. Doing so can result in power surges that cause the Pi to reboot. Once the terminal is back up, enter the following commands:
sudo hciconfig hci0 up sudo hciconfig hci0 leadv sudo hciconfig hci0 noscan sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 00 00 00 00 CA 00
Just like that, the Pi should now be broadcasting an iBeacon, but how can we check? A company called Radius Networks offers a free app for iOS and Android that scans for nearby iBeacons. The app needs to be told what iBeacon packet to look for. When adding the new target, the UUID should be “E20A39F4-73F5-4BC4-A12F-17D1AD07A961”, the Major “0”, and the Minor “0”. After saving, there should now be a found entry with the name you gave it. The app will also show you a nifty feature of iBeacons: it can approximate the distance from your phone to the iBeacon.
Once you’re done, use this line to turn the iBeacon off:
sudo hciconfig hci0 noleadv<br>
If you had trouble with this step or want to learn more about what an iBeacon is, check out this Adafruit tutorial about turning the Pi into an iBeacon. Once it’s working, we’ll reverse this and turn the Pi into a scanner.
Note: You can use the above code as-is on an Intel Edison because bluez is already installed and the compute module has Bluetooth built in.
Step 2: Scanning for iBeacons
Scanning for iBeacons is a little more complex. We’re going to need to install the BlueZ Python3 module for this. I’ve found that the easiest way to guarantee that a module was installed for Python3 instead of Python2 is to use pip. You likely already have pip on the Pi, but we need the Python3 version, specifically pip-3.2 (because Python3.2 is the current default version). To install:
sudo apt-get install python-dev python3-dev python3-setuptools python3-pip
sudo pip-3.2 install pybluez
While you might have to change some of the files later on, if you want to follow along with Python2, install via apt-get:
sudo apt-get install pybluez
Now that the module is installed, we can use this file to scan for iBeacons (GitHub / direct download at top of page). This file was originally made by John Shovic (GitHub), and I updated it to work with Python3 and with this project. Of course the easiest way to get this and the other files onto the Pi is clone the repository. Running the file will turn the Pi into an iBeacon scanner.
git clone https://github.com/flyinactor91/RasPi-iBeacons cd RasPi-iBeacons sudo python3 blescan.py
Tada! It’s now…oh wait nothing’s happening. What’s going on? There are no iBeacons in the air. Let’s fix that. That iBeacon app can also broadcast/transmit. Choose any of the default options; it doesn’t matter what the UUID, Major, or Minor values are. Once it’s turned on, you should see the Pi start to print out gibberish, but that gibberish should match the gibberish on your phone. Then turn the app’s iBeacon off, and the Pi should stop.
So far, we’ve enabled the Pi to scan for iBeacons and demonstrated that our phone can transmit them. Before we can do more with the Pi, we need to set-up our Azure back-end.
Step 3: Creating the Azure Mobile Service and SQL Database: Part 1
It’s time to work with Azure. We will create a new Azure Mobile Service, and, in doing so, the SQL database will be made for us. Let’s get started.
Note: For the sake of clarity during this tutorial, I’m going to use the actual server name, application key, user name, and password in plain text during setup. By the time you read this, the server will have been deleted, so make sure you replace the tutorial data with your own.
First go to your Azure management portal. Click “+ NEW” in the bottom left and go to Compute -> Mobile Service -> Create. This should bring up the first set-up dialogue page. We’re going to set-up a new mobile service called “GatewayService” which uses a new SQL database instance. On the second page, we configure the new SQL database. For this tutorial, the database is called “rpitutorial” with the username “myrpiuser” and password “Raspbian#1”.
After clinking ok, it will take a minute for the new service and server to be created. Once it is, there’s a few more things we need to do.
Step 4: Creating the Azure Mobile Service and SQL Database: Part 2
Once the service is created, go to it’s dashboard. Just below the image, set the language option to iOS and expand the “Connect to an existing iOS app” option. Then in step 2, set the language from Objective-C to Swift.
We need to get the server url and application key. This is found in the code line just above step 3. For this tutorial, the url is “https://gatewayservice.azure-mobile.net/” and the key “ljDJAhCqaMSUtTVcPuUxOMDPGqljsE33”.
A few more things. To keep things simple, go ahead and press the green “Create Item Table” button in step 3. This will create a new table called “Item” in the new SQL database. This is where the iBeacon strings will be stored for our gateway system. Also you’ll need to go to our new SQL database to find the database url at the bottom of its dashboard. In this tutorial, that’s “qcezk07lpu.database.windows.net”
Next up we will connect our iOS demo app to our new mobile service.
Step 5: Connect iOS Demo to Azure
In the GitHub repository is a folder named BeaconAzureDemo. This folder contains the XCode project for our Swift iOS app. Yes you’ll need access to a Mac with XCode on it. (If you don’t, see the last page of this tutorial.) Open the xcodeproj file to begin.
There are two view controllers. ScannerViewController.swift is used when scanning for iBeacons. SenderViewController.swift is in charge of talking to Azure and broadcasting the phone’s iBeacon. We’ll be working in SenderViewController.swift here.
First off, set serverLocation to be the server url (“https://gatewayservice.azure-mobile.net/”) and serverApplicationKey to be the server key (“ljDJAhCqaMSUtTVcPuUxOMDPGqljsE33”). Above this you can change the values in the iBeacon packet, but notice that Apple uses non-standard spacing for the UUID. That should be it. Make sure that your iPhone(4S or later) or iPad(3 or later) is set as the build destination and install it.
In the video above, you can see me demonstrate the phone successfully sending the BLE string to the server.You can see there is a “Broadcast” toggle just below the button. It will turn the iPhone’s iBeacon broadcast on and off. You can test this by loading blescan.py on the Pi again.
If you’ve gotten this far, good job. The next part is going to be the hardest in terms of configuration.
Step 6: Install and Configure pyodbc: Part 1
Here we go. While Microsoft offers an official Azure SDK for Python, it does not give us direct access to our Azure SQL databases. Instead, we will use pyodbc to do this. The pyodbc library is a Python wrapper for two other UNIX database utilities, each of which need to be individually configured. Did you write down the database url, database name, user name, and password? You’re going to need them here.
First let’s install the dependencies:
sudo apt-get install unixodbc unixodbc-dev freetds-dev freetds-bin tdsodbc
Now that the dependencies are installed, they need to be configured.
First we need to configure a generic connection to our server. Use
sudo nano /etc/freetds/freetds.conf
to edit the first file. At the end of the file, add the following lines:
[rpitestsqlserver] host = qcezk07lpu.database.windows.net port = 1433 tds version = 8.0
You can use any name you want in those brackets as long as it doesn’t contain any spaces. Use ctrl+x and then y + enter to save the file.
Now we can test to make sure the config file works. We’re going to use the tsql utility. It needs the name of the configuration from the previous file, the user name (and server ID), and the password.
tsql -S rpitestsqlserver -U [email protected] -P Raspbian#1
If the config file is correct, you should eventually see a prompt line like that in the second screenshot above. Note: Many corporate networks and some ISPs block port 1433. If you’re having connection issues, this is a likely cause.
For more detail: IBeacon Entry System with the Raspberry Pi and Azure