Homebridge plugin for exposing services and characteristics of nearby Bluetooth Low Energy (BLE) peripherals as HomeKit accesories. Ideal for wireless DIY home automation projects if you'd like to control them comfortably with Siri on any Apple device.
Homebridge runs on top of Node.js server and is an open-source implementation of the Apple HomeKit protocol. HomeKit provides the API between your Apple device (i.e. Watch) and your home automation server (i.e. Raspberry Pi). This Homebridge plugin relays the communication from the home automation server to the BLE peripheral device (i.e. Arduino 101). Take a peek into the examples folder for inspiration.
Make sure your systems matches the prerequisites. You need to have a C compiler, Node.js server and if you're running on Linux the libbluez-dev
library.
Homebridge is a lightweight framework built on top of Node.js server that provides the HomeKit bridge for your Apple devices to connect to. Noble is BLE central module library for Node.js that abstracts away intricacies of each OS BLE stack implementation and provides a nice universal high-level API.
[sudo] npm install -g noble
[sudo] npm install -g --unsafe-perm homebridge node-gyp
[sudo] npm install -g homebridge-bluetooth
Note Depending on your privileges -g
flag may need root permissions to install to the global npm
module directory.
Homebridge is setup via config.json
file sitting in the ~/.homebridge/
directory. The example config included in the repository has lots of comments and is a good starting point. Each BLE peripheral device is uniquely identified by it's address. Services and characteristics are identified by UUID. Also, each of the examples comes with it's own config.json
file.
The easiest way to find the address of a BLE device is to start the plugin with a random/default address and then check the output for Ignored | MyDevice - 01:23:45:67:89:ab
message. Alternatively you can run [sudo] hcitool lescan
to discover available BLE devices.
Mapping of services and characteristics from Bluetooth to HomeKit relies on two things - matching read/write/nofity permissions and matching data type. To see what is available, take a look at the very long list here. Services are towards the bottom of the file. Each characteristic has pre-defined permissions that represent the expected way to use it - i.e. it doesn't make sense to write (set) the current temperature. These permissions must match the corresponding permissions of the Bluetooth characteristic. All data are assumed to use little endian encoding for multi-byte values.
The following table summarizes permission matching for a very popular BLEPeripheral library that can run on most Arduino boards:
HomeKit Characteristic.Perms[...] |
BLEPeripheral BLECharacteristic(...) |
---|---|
READ |
BLEWrite |
WRITE |
BLERead |
NOTIFY |
BLENotify |
Similar to permissions, matching of the exchanged data type for BLEPeripheral is summarized here:
HomeKit Characteristic.Formats[...] |
BLEPeripheral BLETypedCharacteristic<...> |
---|---|
BOOL |
BLECharCharacteristic |
INT |
BLEIntCharacteristic |
FLOAT |
BLEFloatCharacteristic |
STRING |
BLECharacteristic |
UINT8 |
BLEUnsignedCharCharacteristic |
UINT16 |
BLEUnsignedShortCharacteristic |
UINT32 |
BLEUnsignedIntCharacteristic |
UINT64 |
BLEUnsignedLongCharacteristic |
For instance if you'd like create a HomeKit thermometer, you have to implement the TemperatureSensor
service. According to the list of available services and characteristics the service has one mandatory characteristic - CurrentTemperature
and a handful of optional ones.
The CurrentTemperature
characteristic communicates a FLOAT
value and needs READ
and NOTIFY
permissions. Using the BLEPeripheral library, the characteristic would be implemented as:
BLEService temperatureSensorService("SERVICE-UUID-HERE");
BLEFloatCharacteristic currentTemperatureCharacteristic("CHARACTERISTIC-UUID-HERE", BLERead | BLENotify);
The corresponding entry in the config.json
file that connects to the characteristic above is:
"services" : [ {
"name": "The Best HomeKit Thermometer",
"type": "TemperatureSensor",
"UUID": "SERVICE-UUID-HERE",
"characteristics": [ {
"type": "CurrentTemperature",
"UUID": "CHARACTERISTIC-UUID-HERE"
} ]
} ]
Note All UUIDs should be randomly generated to prevent collisions. This page is a good place to get your own.
Depending on your privileges, accessing the BLE kernel subsystem may need root permissions.
[sudo] homebridge -D
Note Running with -D
turns on additional debugging output that is very helpful for getting addresses and UUIDs of your BLE devices that needs to match with the config.json
file.
Note See this section of Noble readme for more details about running without sudo
.
If you encouter a different problem, please, open an issue.
Make sure the Apple device and the Homebridge server are on the same subnet and connected to the same wifi router.
Sometimes, homebridge server might think that, it has successfully paired with iOS, but iOS doesn't agree. Try to delete the persist/
directory in the ~/.homebridge/
configuration folder. This removes all pairings that normally persist from session to session.
rm -rf ~/.homebridge/persist/
From time to time it looks like iOS ignores HomeKit bridges with username
that it has already paired with. Try to change the username
in the bridge
section of config.json
to a new value never used before.
"username": "CC:22:3D:E3:CE:30" -> "username": "DD:33:4E:F4:DF:41"
This isssue seems to be happening on some versions of Raspbian running on the Pi 3. Resetting the BLE adapter seems to resolve the issue:
[sudo] hciconfig hci0 reset
Obviously, the solution is not really addressing the core of the problem, but it seems to help.
Sure thing! All contributions are welcome. Just do a pull-request or open a new issue if you see something broken.
No. Not even close. Connection from your Apple device to Homebridge server is encrypted. However, all BLE communication is currently unencrypted and anyone with the right spoofing equipment can listen to it. Moreover, once the attacker has figured out what devices you have, he can also connect to any of your peripherals and control them directly. So don't use this if you're paranoid or if NSA is after you. You wouldn't sleep well.
MFi certified HomeKit BLE encryption uses quite-strong Ed25519 elliptic cypher. BLE has built-in support for encryption, but it seems that Apple has decided to build their own thing as usual. It makes some sense in this case since a lot is at stake - once HomeKit becomes widespread a security bug literally means open doors to your house. Hooray - let's connect billions of unsecured IoT devices to the internet! What could possibly go wrong??
Moreover, from bits and pieces available on the Internet, it seems that Apple has changed the specs several times and caused a lot of trouble for the manufacturers, since slower microprocessors tend to have a hard time doing all the involved encryption math. Initial pairing can take literally minutes. Pairing procedure uses SRP (Secure Remote Password (3072-bit) protocol with an 8-digit code (the number you have to type in when first pairing with Homebridge). After pairing, per session communication always uses unique keys derived by HKDF-SHA-512 and encrypted by the ChaCha20-Poly1305.
Theoretically, one should be able to get rid of the Homebridge 'middle-man' since HomeKit over BLE allows direct connection to any Apple device. While there are many good HomeKit IP stacks around BLE implementations are few and far between. There's only one implementation I'm aware of here, but it can't be easily ported to other boards.
BTW, I think it might be possible to re-write the BLE implementation above with BLEPeripheral library instead of Nordic Semi's SoftDevice to make it run essentially everywhere. If anyone is interested in this project, please, let me know and maybe we can figure a plan and come up with something useful and fun to use.
Implementing a HomeKit over BLE stack correctly requires access to MFi internal documentation, which isn't publicly available, unless you're a registered developer at a company with big $$$. Making BLE accessories is simple, but making them secure seems to be very, very hard.
A supported BLE (Bluetooth 4.0) USB dongle is required, if your device doesn't have it built-in.
-
Install Node.js
Node.js is an asynchronous event driven JavaScript server, ideal for building scalable, low-latency network applications. Homebridge is built on top of this server. It is being developed so quickly that package repositories of most distributions contain a very old version. Getting latest from the official website is recommended.
-
Install
libbluetooth-dev
andlibavahi-compat-libdnssd-dev
These libraries and their dependencies are required by Noble package and provide access to the kernel Bluetooth subsystem.
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev libavahi-compat-libdnssd-dev
Check this link to see if your mac has built-in BLE (Bluetooth 4.0) support. All macs from 2012 and newer are generally fine.
-
Install Node.js
Node.js is an asynchronous event driven JavaScript server, ideal for building scalable, low-latency network applications. Homebridge is built on top of this server. It is being developed so quickly that package repositories of most distributions contain a very old version. Getting latest from the official website is recommended.
-
Install XCode
XCode comes with a C compiler that is needed to compile the JavaScript to C bindings required by Noble package.
Pull request is welcomed here... Both Homebridge and Noble should run on Windows, but I don't have a machine to test.
Here's a list of testing devices. The list is by no means exhaustive and the plugin will work with many more.
-
Apple Device
-
Homebridge Server
- Raspberry Pi 3 & 2 (with USB dongle) running Raspbian Jessie Lite
- Macbook Air (2015) & iMac (2012) running macOS 10.12
-
Bluetooth Peripheral
- nRF51 Based Boards
- nRF8001 Based Boards
This work is licensed under the MIT license. See license for more details.