Running Home Assistant with Zigbee2MQTT on Synology NAS in containers
For those of you who are following me on Twitter, you might have seen my Philips Hue bridge was acting up in the past couple of months. Major bandwith usage, automations not being triggered at the appropriate times, and even the internet connectivity wasn’t working anymore. The bridge is also about 14 years old, so it might have been its time to shut down.
A relative cheap solution would be to buy a new Philips Hue bridge and set that up. However, lots of my friends are very fond of Home Assistant to automate everything, including their Hue lights. Because everyone is so positive about it, I thought I’d look into it too.
From what I understand, Home Assistant is a platform with a nice frontend application which enables user to add devices to it, so they can be used to automate stuff. For example: when turning on an Xbox, also turn on the lights in the game room.
I’m not sure how many devices are supported, but it looks like hundreds (or thousands) can be integrated. At least most of the popular devices are supported for automation.
In the IoT world there are two major communication protocols, Zigbee & Z-Wave. For a consumer, like me, they’re pretty much the same. The protocols differ on a technical level, of course. For Home Assistant to talk to my Hue lights and accessiories it needs some kind bridge to make sure the machine where Home Assistant is running on can communicate with the Zigbee hardware. For this, I’ve bought the Zigbee 3.0 USB Dongle Plus.
The setup
A lot of people are running Home Assistant on a Raspberry Pi and for good reason. This device doesn’t has a very high power consumption and has enough compute power. It even has USB-ports, so a Zigbee dongle can be used directly.
I too have an old Raspberry Pi over here, but don’t want to use it. It’s one of the first models, so not very powerful.
Also, Home Assistant also has a container version available and my Synology NAS is able to run containers. Since the NAS is already turned on 24/7, with a couple of other containers running also, I didn’t feel like adding yet another device to the network.
What I want to use, and have set up is the following:
- Synology NAS DS918+
- Zigbee 3.0 USB Dongle Plus
- Home Assistant in a container
- Zigbee2MQTT + Mosquitto running in containers
These are used to convert the Zigbee messages to MQTT messages which can be used in Home Assistant using the MQTT integration.
And I have removed the old Philips Hue bridge from the network altogether.
Setting up your Synology NAS
This is the hardest part to get right, as you need to do quite a lot of things to get everything up and running.
Enable and install USB drivers for the dongle
As of DSM 7, USB perhipals have been disabled on your NAS. These devices can be enabled again, but you also need to install the appropriate drivers to use the devices.
First of all, getting the drivers for the dongle. The DS918+ runs with a CPU of the Apollo Lake architecture, therefore you need drivers corresponding with this architecture. The linked dongle I’m using uses the CP210 chip, so I had to download that one. Lots of other dongles use a CH341 chip, so need a different one. Both can be found in a GitHub repository by robertklep, for DSM 7.1
.
Be sure to download & store these drivers locally, or fork the project, so you’re not dependent on this specific repository. I’ve had stuff break more as once, taking up public dependencies.
Second, install the drivers, and enable USB. You can run the following script as root
on your NAS. This can also be found in the Zigbee2MQTT docs: https://www.zigbee2mqtt.io/guide/installation/02_docker.html#docker-on-synology-dsm-7-0
cd /lib/modules
# This link is mentioned in the docs, but the domain doesn't work anymore and it doesn't look like it'll be up any time soon.
# wget http://www.jadahl.com/iperf-arp-scan/DSM_7.0/apollolake/ch341.ko
wget https://github.com/robertklep/dsm7-usb-serial-drivers/raw/main/modules/apollolake/dsm-7.1/ch341.ko
insmod /lib/modules/ch341.ko
wget https://github.com/robertklep/dsm7-usb-serial-drivers/raw/main/modules/apollolake/dsm-7.1/cp210x.ko
insmod /lib/modules/cp210x.ko
wget https://github.com/robertklep/dsm7-usb-serial-drivers/raw/main/modules/apollolake/dsm-7.1/pl2303.ko
insmod /lib/modules/pl2303.ko
wget https://github.com/robertklep/dsm7-usb-serial-drivers/raw/main/modules/apollolake/dsm-7.1/rndis_host.ko
insmod /lib/modules/rndis_host.ko
/sbin/modprobe usbserial
/sbin/modprobe ftdi_sio
/sbin/modprobe cdc-acm
chmod 777 /dev/ttyUSB0
chmod 777 /dev/ttyACM0
The easiest way to do this, is to create a new Task in the Task Scheduler and run it as root
, then manually trigger it.
You can also trigger it on boot, but when an upgrade of the DSM happens, who knows what might break. So be wary of running this script on boot.
Configuring Docker
Note: you need to enable SSH on your NAS to continue. This can be enabled via Terminal & SNMP -> Terminal. To invoke the next commands, make sure you’re logged in via SSH on the NAS
First of all, install the Docker package from the Package Center. This will install all the tooling you need.
I was tempted to run the containers using the UI within DSM, but this UI doesn’t offer enough advanced options to set up the Zigbee2MQTT & Mosquitto containers. You can run the Home Assistant container using the UI if you wish. I’ve done so and it’s working like a charm.
The documentation is straightforward and can be translated to the appropriate UI elements fairly easy, if you ask me.
Second, once Docker is installed you need to configure who can communicate with it. By default, only root
is supported, but we need to add another user, to start some of the containers.
The steps to do this are described in Nataraj Basappa’s post on the matter. For reference:
# The default, only root has access.
$ ls -l /var/run/docker.sock
srw-rw---- 1 root root 0 Jan 5 22:15 /var/run/docker.sock
# Create a group named docker
$ sudo synogroup --add docker
# Change group ownership of docker.sock to newly created group
$ sudo chown root:docker /var/run/docker.sock
# Make a non-root user member of docker group
$ sudo synogroup --add docker user1
Creating a group and user didn’t work for me via the CLI, so I added them via the DSM UI.
Not doing this will give you ‘strange’ error messages when running docker compose.
Plug in the dongle
All drivers are installed and Docker is configured, so it’s time to plug in the dongle.
If you’re still logged in to a SSH session, run the following:
$ dmesg | grep tty
The output should result in something which looks like this:
[ 3164.784143] usb 1-3: cp210x converter now attached to ttyUSB0
Use Docker Compose to start Zigbee2MQTT and Mosquitto
Both Zigbee2MQTT and Mosquitto are necessary for a proper integration with Home Assistant of the Hue hardware. There are alternative solutions for this, of course.
The easiest way, in my opinion, to get both containers started is by using Docker Compose. This is installed by default on your NAS after installing the Docker package.
I have a dedicated folder on my NAS for all container-related configuration and create subfolders per container.
In a subfolder called zigbee2mqtt
, I’ve added the a docker-compose.yml
file with the following content.
version: "3.8"
services:
# Mosquitto
mqtt:
container_name: mosquitto
image: eclipse-mosquitto:2.0
network_mode: bridge
restart: unless-stopped
volumes:
- ./mosquitto-data:/mosquitto
ports:
- 1883:1883
- 9001:9001
command: "mosquitto -c /mosquitto-no-auth.conf"
# Zigbee2MQTT
zigbee2mqtt:
container_name: zigbee2mqtt
image: koenkk/zigbee2mqtt
network_mode: bridge
restart: unless-stopped
volumes:
- ./data:/app/data
- /run/udev:/run/udev:ro
ports:
# Frontend port
- 8020:8020
environment:
- TZ=Europe/Amsterdam
devices:
- /dev/ttyUSB0:/dev/ttyACM0
You can find similar files on the internet. I’ve added the network_mode: bridge
to the file, so the containers are running in the Bridge network, which allows me to access them from the network. At first I didn’t have this, so a new network was added which wasn’t accessible from the network, but does make discoverability within the network a lot easier.
As you can see, I’m mounting the ./data
folder to the Zigbee2MQTT data folder. In this folder, make sure there’s a configuration.yaml
with the content looking somewhat like the following:
homeassistant: true
permit_join: true
mqtt:
base_topic: zigbee2mqtt
server: mqtt://[The IP-address of your NAS]
serial:
port: /dev/ttyACM0
frontend:
port: 8020
advanced:
network_key: GENERATE
homeassistant_legacy_entity_attributes: false
legacy_api: false
legacy_availability_payload: false
log_level: debug
device_options:
legacy: false
This makes sure Zigbee2MQTT is able to work with Home Assistant, devices are allowed to join, the MQTT broker server address is specified & the port of the frontend system is specified.
Running a docker-compose up -d
will start both containers and you’re ready to go!
Finishing up
When all is running, and all of your devices are added, make sure to disable SSH access to your NAS again. Also set the permit_join
to false
, so no other devices can join your network.
The above sample also doesn’t use any type of authentication for Mosquitto. Needless to say, it makes sense to add this.
The documentation is quite good on the matter, so make sure to secure your environment.
Configuring Home Assistant
When all containers are running, Home Assistant, Zigbee2MQTT, and Mosquitto, you can configure the MQTT integration within Home Assistant.
Configure it by adding the IP address of your NAS, where Mosquitto is running on, and you’re ready to go!
The only thing left to do is join all of your devices. The easiest way to do this, is by doing a factory reset of the hardware. I walked around the house and reset all lights using the Dimmer switch. After a couple of seconds, the lamps are automatically added to Zigbee2MQTT list of devices, and you can start using them from within Home Assistant.
To conclude
When reading all of this, things look fairly straightforward. However, I did spend quite a lot of time on it. Reason for this, is most information is scattered across multiple sites and posts and there are a lot of moving parts.
The biggest risk in this setup are changes in DSM, because you want to be up-to-date with the version but there might be changes which break the Docker configuration or disable/break the USB drivers.
Is it all worth it?
I think using Home Assistant has great advantages compared to using the default features offered by consumer products like a Hue Bridge.
It also has some disadvantages, because the UX in the applications aren’t as rich compared to the consumer products. Lucky there is the Apple Homekit integration, which makes the UX a bit better. However, all communication is handled via a messaging system, so there is a bit of delay before messages are being handled.