Setting up Homebridge on Raspberry Pi for controlling TP-Link devices with Apple Home & Siri

iPhone X with Home app

Setting up a Homebridge server on a Raspberry Pi is relatively straightforward if you follow the project’s documentation. However, there are a some considerations I discovered along the way that may be helpful for others.

Installing Homebridge

I believe it’s worth taking the time to update the Pi’s system version of NodeJS now. Since v4, NodeJS is compatible with arm CPU architectures and it only takes a few minutes to update to the latest version. I previously had installed a newer version of NodeJS via nvm but soon realized that this method wasn’t going to be compatible with running homebridge as a systemd service.

The latest version as of now is 10, and you can update by following these steps:

$ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
$ sudo apt-get install -y nodejs

Since you’ll more than likely be compiling some software from source, go ahead and install the native addons and build tools:

$ sudo apt-get install -y build-essential

It’s recommended to follow the installation instructions on the Homebridge Wiki that have specific steps for a Raspberry Pi. I’ll be sharing some issues I discovered along the way regarding running Homebridge on boot up, so feel free to stop before that step.

You can test your installation was successful and make an initial connection with your Apple Home app by running:

$ homebridge

You should see output in your terminal and a message about no plugins found, which is normal. This would be a good time to setup the pairing between the Apple Home app and the homebridge accessory by scanning the QR code visible in the terminal output.

Install and Setup the TP-Link Smarthome Plugin

The TP-Link Homebridge plugin supports their smart bulbs and plugs and they will show up as accessories in the Apple Home app once configured.

Install the plugin via npm:

$ npm i -g homebridge-tplink-smarthome

The Homebridge configuration file will need to be updated to include the newly supported TP-Link platform. The configuration file is located by default in ~/.homebridge/config.json.

Example configuration:

pi@raspberrypi:~ $ cat ~/.homebridge/config.json
{
	"bridge": {
        	"name": "HomeBridge",
        	"username": "CC:22:3D:E3:CE:30",
        	"port": 51826,
        	"pin": "031-45-154"
	},
	"description": "Personal HomeBridge project",
	"accessories": [],
	"platforms": [{
		"platform": "TplinkSmarthome",
		"name": "TplinkSmarthome"
	}]
}

Configure Homebridge to run as a Service

You’ll want to configure Homebridge to run as a service if you’d like to use it for any significant period of time. Another benefit to configuring a service with systemd is that it’ll be able to restart in the event of a crash.

The configuration files for Homebridge are located in the pi user home directory e.g. /home/pi/.homebrige and should look similar to this:

.homebridge
├── accessories
│   └── cachedAccessories
├── config.json
└── persist
    ├── AccessoryInfo.CC223DE3CE30.json
    └── IdentifierCache.CC223DE3CE30.json

When testing out new plugins and configuration settings, I’ve found it useful to leave the configuration files in their default location and leverage symlinks in the appropriate places to support the systemd service.

Start by ensuring the following directory structures exist with the correct permissions:

$ sudo mkdir -p /var/lib/homebridge/accessories
$ sudo mkdir -p /var/lib/homebridge/persist
$ sudo chmod -R 0777 /var/lib/homebridge

Create symbolic links from the default configuration into the new location:

$ sudo ln -s ~/.homebridge/config.json /var/lib/homebridge/config.json
$ sudo ln -s ~/.homebridge/accessories/cachedAccessories /var/lib/homebridge/cachedAccessories
$ sudo ln -s ~/.homebridge/persist/AccessoryInfo.CC223DE3CE30.json /var/lib/homebridge/persist/AccessoryInfo.CC223DE3CE30.json
$ sudo ln -s ~/.homebridge/persist/IdentifierCache.CC223DE3CE30.json /var/lib/homebridge/persist/IdentifierCache.CC223DE3CE30.json

Note: it’s possible your files will be named slightly different in your /persist directory.

Running $ tree /var/lib/homebridge should output similar to the following showing the symlinks:

pi@raspberrypi:~ $ tree /var/lib/homebridge/
/var/lib/homebridge/
├── accessories
│   └── cachedAccessories -> /home/pi/.homebridge/accessories/cachedAccessories
├── config.json -> /home/pi/.homebridge/config.json
└── persist
    ├── AccessoryInfo.CC223DE3CE30.json -> /home/pi/.homebridge/persist/AccessoryInfo.CC223DE3CE30.json
    └── IdentifierCache.CC223DE3CE30.json -> /home/pi/.homebridge/persist/IdentifierCache.CC223DE3CE30.json

Create a file to reference the configuration options that will be used by the service:

$ sudo nano /etc/default/homebridge

Copy/paste the following into this file, save it, and close it.

# Defaults / Configuration options for homebridge
# The following settings tells homebridge where to find the config.json file and where to persist the data (i.e. pairing and others)
HOMEBRIDGE_OPTS=-U /var/lib/homebridge

# If you uncomment the following line, homebridge will log more 
# You can display this via systemd's journalctl: journalctl -f -u homebridge
# DEBUG=*

Before creating the service, you’ll want to verify the location of the homebridge binary by running the following:

pi@raspberrypi:~ $ which homebridge
/usr/bin/homebridge

Create the service:

$ sudo nano /etc/systemd/system/homebridge.service

Copy/paste the following in this file, save it, and close it.

[Unit]
Description=Homebridge Service
After=syslog.target network-online.target

[Service]
Type=simple
User=pi
EnvironmentFile=/etc/default/homebridge
ExecStart=/usr/bin/homebridge $HOMEBRIDGE_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

That’s it. Now you should be able to run the service and verify everything is working as intended.

Reload the systemd daemon

$ sudo systemctl daemon-reload

Enable the newly created service

$ sudo systemctl enable homebridge.service

Start the homebridge service

$ sudo systemctl start homebridge

View the service status

$ sudo systemctl status homebridge

Tail the service logs

$ journalctl -f -u homebridge