I purchased the $35 Raspberry Pi 2 which worked well for this project, however, it's horribly slow from the UI. It's practically unusable for internet browsing and everything takes a painful 3-10 secs to start after you click on it. However, it turned out to be perfect for a cheerlights server, as the UI is not needed.
Another option would have been to go with the $5 Pi zero. If you go that route, you'll need to buy some micro to USB adapters to connect the peripherals and you only get two USB ports so you'll definitely need a USB hub. It only has mini HDMI so you may need an adapter for that too which may bring the price closer to $35. However, if you already have the peripherals, you could bring cheerlights to your home for $25. Once setup, you could just leave it running as a headless cheerlights server.
Pi does not have bluetooth on board (or wifi for that matter) so I purchased the Plugable USB Bluetooth 4.0 Low Energy Micro Adapter from Amazon, which I can't say I recommend given the issues. For the wifi, I purchased the KEEBOX W150NUIEEE Wireless-N 150 USB Adapter which worked well. I'm using the NOOBS distro which is already expanded, a Sandisk class 10 card, and I'm running Jessie:
uname -a Linux raspberrypi 4.1.13-v7+ #826 SMP PREEMPT Fri Nov 13 20:19:03 GMT 2015 armv7l GNU/Linux
sudo apt-get install bluetooth bluezAnd that's when I started making negative progress. I couldn't get my wireless keyboard or mouse to be identified using the hcitool:
hcitool scanThe log showed an error:
dmesg | grep -i blue [ 6.018894] Bluetooth: Core ver 2.20 [ 6.019050] Bluetooth: HCI device and connection manager initialized [ 6.019082] Bluetooth: HCI socket layer initialized [ 6.019107] Bluetooth: L2CAP socket layer initialized [ 6.019158] Bluetooth: SCO socket layer initialized [ 6.071937] Bluetooth: hci0: BCM: chip id 63 [ 6.073980] Bluetooth: hci0: BCM20702A1 (001.002.014) build 0000 [ 6.077185] bluetooth hci0: Direct firmware load for brcm/BCM20702A1-0a5c-21e8.hcd failed with error -2 [ 6.077204] Bluetooth: hci0: BCM: Patch brcm/BCM20702A1-0a5c-21e8.hcd not found [ 10.792578] Bluetooth: BNEP (Ethernet Emulation) ver 1.3 [ 10.792603] Bluetooth: BNEP filters: protocol multicast [ 10.792630] Bluetooth: BNEP socket layer initializedAfter some searching, I found a post regarding copying a new profile called fw-0a5c_21e8.hcd onto the Pi and renaming it to BCM20702A1-0a5c-21e8.hcd in the /lib/firmware/brcm folder.
That fixed the bluetooth load error but it still couldn't find my wireless keyboard or mouse so next I downloaded and built bluez 5.31 courtesy of Johnas Cukier. Thanks goes to him for that post.
sudo apt-get install libglib2.0-dev libdbus-1-dev libudev-dev libical-dev libreadline-dev wget https://www.kernel.org/pub/linux/bluetooth/bluez-5.31.tar.xz tar xvf bluez-5.31.tar.xz cd bluez-5.31 ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --disable-systemd --enable-experimental --enable-maintainer-mode make sudo make install sudo cp attrib/gatttool /usr/binThat didn't fix the keyboard and mouse issue so I decided to focus on the candle as it was now being found:
sudo hcitool lescan LE Scan ... 31:82:4B:0B:AC:E6 (unknown) 31:82:4B:0B:AC:E6 PLAYBULB CANDLEBTW, Blueman provides a UI to manage bluetooth devices:
sudo apt-get install blueman
gatttool -b 31:82:4B:0B:AC:E6 --char-write -a 0x0019 -n 00FF0000It turns out white is a separate byte which would be:
gatttool -b 31:82:4B:0B:AC:E6 --char-write -a 0x0019 -n FF000000To turn off the effects (rainbow, flash, etc.):
gatttool -b 31:82:4B:0B:AC:E6 --char-write -a 0x001b -n 00
gatttool -b 31:82:4B:0B:AC:E6 --char-read -a 0x0019
2016-02-07 11:03:37.949486> Got hex FFA500 from cheerlights API 2016-02-07 11:03:37.950130> gatttool -b 31:82:4B:0B:AC:E6 --char-write -a 0x0019 -n 00FFA500 2016-02-07 11:04:07.999003> gatttool -b 31:82:4B:0B:AC:E6 --char-read -a 0x0019 2016-02-07 11:04:08.479197> connect error: Function not implemented (38) 2016-02-07 11:04:08.479731> retrying
#This script will fetch the current color from the cheerlights API and #set the color of the playbulb candle. You need to set the candle's address #below. To get the address: # #sudo hcitool lescan addresses = ['31:82:4B:0B:AC:E6','FD:F7:4B:0D:AC:E6'] #two candles import requests import subprocess import shlex import datetime from subprocess import call from time import sleep def log(msg): if len(msg) < 1: return date = datetime.datetime.now() print str(date) + '> ' + msg #get current value to see if it has been blown out def checkBlown(address): try: cmd = 'gatttool -b ' + address + ' --char-read -a 0x0019' log(cmd) args = shlex.split(cmd) output,error = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() log(error) if 'busy' in error or 'not implement' in error or 'timed out' in error: #retry log('retrying') sleep(1) output,error = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() #if still failing, assume it was blown out if(error): log(error) return True ans = output.replace('Characteristic value/descriptor: ','') ans = ans.replace(' \n','') if str(ans) == '00 00 00 00': log('No update. Candle has been blown out.') return True return False except: return True #set the candle def setCandle(address, args): try: cmd = 'gatttool -b ' + address + ' ' + args log(cmd) args = shlex.split(cmd) output,error = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() log(output) log(error) if 'busy' in error or 'not implement' in error or 'timed out' in error: #retry log('retrying') sleep(1) output,error = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() log(output) log(error) except: pass ################################ # main logic here ################################ #default candle to red on so it doesn't appear blown out on start for address in addresses: setCandle(address, '--char-write -a 0x0019 -n 00FF0000') while 1: try: for address in addresses: ans = checkBlown(address) if(ans == False): url = 'http://api.thingspeak.com/channels/1417/field/2/last.txt' r = requests.get(url) hex = r.text.replace('#','') log('Got hex ' + hex + ' from cheerlights API') #set the color, white is a separate byte if hex == 'FFFFFF': #white? args = '--char-write -a 0x0019 -n FF000000' else: args = '--char-write -a 0x0019 -n 00' + hex setCandle(address, args) sleep(30) except: #requests.ConnectionError: pass
4280 people have been romanced by the candle since 7/16.