Monday, August 12, 2013

Bluetooth Household

For my home automation project, I chose to go with a fully-wired approach since I'm building from scratch. I get to run wires wherever needed, providing (hopefully) more reliability and an ability to troubleshoot problems. Certainly, the parts cost will be much lower than an RF solution.

But with that said, I met Eric Migicovsky a couple weeks ago (Founder/CEO of Pebble). He came up with a great idea: use a Pebble watch as a control mechanism. Sure, I'll have phones, tablets, infrared remotes, and various sensors... but something on my wrist? Always handy? Very cool idea! With multiple Bluetooth base stations, I can even detect signal strength and triangulate a user's position in the house, in order to provide context-sensitive menus and button controls. If you're in the home theater, then "Pause" is going to be a handy watch button, when that drink needs a refill! Given that I'm writing the app, I can even provide Wifey with her own customized watch experience.

To that end, I started doing some research on Bluetooth, and on the Pebble SDK. The first thing to pop up was the need to use Bluetooth Low Energy (aka Bluetooth 4.0, BLE, or Bluetooth Smart [Ready]) rather than the older Bluetooth 2.x or 3.x protocols. BLE allows for interactions without pairing, which is important for roaming about the house, with multiple base stations. The Pebble hardware supports BLE, but it seems that the SDK doesn't (yet) allow for applications to deliver messages to one/more/available base stations. My hope is to work with the Pebble guys to see where/how to make that available to (my) home automation application.

The second part of the problem is the development of the base stations for my house. There are inexpensive Bluetooth/USB dongles (about US$11) that can speak BLE. I've got a few Raspberry Pi boards around the house, with previously-unused USB ports. A little searching seems to indicate the dongles are supported under Linux.

These dongles seem to present themselves as an HID device (eg. keyboard, mouse, etc), and can be switched to a [Bluetooth] Host Controller Interface (HCI). I haven't dug in deeply on this stuff yet, but I do have a Fitbit dongle on my Mac OS. The Fitbit (Flex) speaks BLE, so it seemed appropriate to experiment with.

Working with HID seemed harsh, until I found hidapi. The API is very clean and simple. As a Python programmer, bindings were the next step. Ran across Cython-HIDAPI, which sucks: forked copy of HIDAPI and heavyweight Cython-based bindings (given the ugly, I'm not gonna provide link-love).

Answer: I wrote a ctypes-based binding for hidapi. My first, undocumented draft landed at just 143 lines of Python. Of course, I've checked it in, along with a sample script.

And after all that, my Fitbit dongle is purely a USB device (calling hid_open() fails). Sigh.

I've got more research to do, and maybe ordering a dongle for experimentation (see Adafruit, or various on Amazon). Maybe I can interact with the Fitbit dongle through USB rather than HID. Who knows. But once I figure the base station thing out, I can track Pebble watches, Fitbits, and other Bluetooth devices throughout my house.