OBJECTIVE// While staying in the Design Concepts San Francisco office for a couple months, I was sleeping in a bedroom in the back of the office. Though the commute in the morning was amazing, I would usually wait until I heard someone coming into the office and walking up the stairs before I would jump out of bed and make it look like I was working before they reached the top of the stairs. Inevitably, some days I wouldn’t be quick enough and they would catch emerging from my nook.
One solution would be just set my alarm earlier, but since people’s arrival is inconsistent, this would mean that I could be getting up earlier than I needed to and wasting valuable time that I could be asleep. So I needed a way of detecting when people were arriving before they got to the front door…and the solution: use the bluetooth radios on my coworkers phones to detect when they get close to the building!
INGREDIENTS//
……………(1) Raspberry Pi
……………(2) Auxiliary speaker
……………(3) Python
TECHNICAL// The base for the project was a raspberry pi with a USB Bluetooth antenna. On the Pi was a Python script that handled both the Bluetooth detection and the music playing (full code below). This ran a continuous loop that cycled through the Bluetooth address of the previously paired devices of my co-workers and attempts to connect with them. If the connection is successful, it disconnects and then plays the song that has been selected for that particular person. After their song has been played there is a timeout so that it only registers their arrival in the morning.
The code is short and sweet and can certainly be smarter and more advanced, but for what I wanted to get out of it, it got the job done.
LESSONS LEARNED // The main learning was about the visibility of Android and iPhone Bluetooth signals, which I never fully understood before I determined a work around. The issue I uncovered was that while the Android phones would broadcast a signature that I could scan for whenever it was in range, and subsequently, I could identify the device, the iPhone’s didn’t seem to be actively broadcasting a recognizable signal. The iPhone was only visible when the user had the phone out and was looking at the Bluetooth settings page, which would mean that they would have to be looking at that page for the raspberry pi to pick up it’s signature. This obviously defeats the purpose of the device so I had to find a way around this.
Though you can’t see a signal being broadcast, you can still connect to an iPhone if you know the Bluetooth radio’s address. Once I realized this, the detection process changed from a scanning process that looked for Bluetooth signals and checked to see if any of the signals matched, to a sequence of trying to connect to each known device address and if the connection was successful, playing the corresponding song. The only downside to this approach was that I had to have the phone’s owner agree to a pair with the Raspberry Pi’s Bluetooth dongle. Though I would have preferred this be handled by a bit of code, a little bit of charm and negotiation was enough to convince people to handover their phones.
ADDITIONAL TECHNICAL DETAILS //
INORDER TO CONFIGURE BLUETOOTH DEVICES: http://www.wolfteck.com/projects/raspi/iphone/
pi@raspberrypi ~/Desktop/Bugle $ sudo aptitude install bluetooth bluez-utils bluez-compat
pi@raspberrypi ~/Desktop/Bugle $ sudo bluez-simple-agent hci0 24:E3:14:82:9C:AE
pi@raspberrypi ~/Desktop/Bugle $ sudo bluez-test-device trusted hci0 24:E3:14:82:9C:AE yes
TO CONVERT THE FILES TO .WAV:
ffmpeg -i river.mp3 river.wav
FULL CODE //
################################################################################### Bugle.py // Written by Jack Boland## This program runs on a raspberry pi B+ with a bluetooth dongle. It is# designed to monitor incoming bluetooth signals and tricker a song# based on the signature of the bluetooth signal.##———————————————————————————# “THE BEER-WARE LICENSE” (Revision 42)# <jcboland91@gmail.com> wrote this file. As long as you retain this notice you# can do whatever you want with this stuff. If we meet some day, and you think# this stuff is worth it, you can buy me a beer in return Poul-Henning Kamp#———————————————————————————###################################################################################
import bluetoothimport timeimport os
# Plays the desired song based on which person entersdef playSong(inputTitle):print “Playing Music…”command = ‘aplay ‘ + inputTitleos.system(command)
# checks to see if the selected device is in range. Returns True is this is the casedef checkDevice(device_addr):try:sock = bluetooth.BluetoothSocket( bluetooth.RFCOMM )port = 1sock.connect((device_addr, port))sock.close()print “Found”return True
except:return Falseclass Person:
def __init__(self, initName, addr, title):self.name = initName # Name of the userself.btAddr = addr # Address of their bluetooth deviceself.lastPlayed = time.time() # The current time will be used as the initial ‘last time played’self.songTitle = title # Song title
def setTime(self):self.lastPlayed = time.time()
def getAddr(self):return self.btAddr
def getName(self):return self.name
def getTime(self):return self.lastPlayed
def getSong(self):return self.songTitle
##########################################################################
people = []jack = Person(‘Jack’, “24:E3:14:82:9C:AE”, “festivus.wav”)justen = Person(‘Justen’, “8C:29:37:10:C8:EA”, “fox.wav”)brett = Person(‘Brett’, “04:F7:E4:27:62:D7”, “snl.wav”)#cameron = Person(‘Cameron’, ” “, ” “)#stef = Person(‘Stef’, ” “, ” “)#cheryl = Person(‘Cheryl’, ” “, ” “)#nate = Person(‘Nate’, ” “, ” “)#forman = Person(‘Forman’, ” “, ” “)#jess = Person(‘Jess’, ” “, ” “)
people.append(jack)people.append(justen)people.append(brett)#people.append(cameron)#people.append(stef)#people.append(cheryl)#people.append(nate)#people.append(forman)#people.append(jess)# Continue to cycle through as long as the script is runningwhile(True):# Iterate through the list of peoplefor temp in people:# Check if the device is within range; if yes, play their songif checkDevice(temp.getAddr()):# 86400 seconds in a dayif (time.time() – temp.getTime()) > 10:# Cue entrance musicplaySong(temp.getSong())#Reset the last played time to current timetemp.setTime()else:print time.time() – temp.getTime()
time.sleep(1)
#nearby_devices = bluetooth.discover_devices()#for device in nearby_devices:# device_name = bluetooth.lookup_name( device )# if device_name == ‘Androidicus Maximus’:# print “Play music for Androidicus Maximus”# playFanfare()