For a couple of years I've been running a small automated homekit setup with the Ikea TRÅDFRI gateway. It's been a bit of a rollercoaster ride, with everything working fine to start with, a few hiccups a bit later, then getting better, and now just being almost unusable; I can't connect to the gateway from the Ikea app, even though I'm only 10 feet away from the gateway, until I power cycle it, and then it only works for about a day before I need to do it all again. Needless to say, at this point, none of the HomeKit automations work either. An exercise in frustration.
A positive point of all the Ikea stuff I have bought (actually only bulbs and 2 power adapters) is that they are all Zigbee compliant, and so any Zigbee controller could be used.
One of my colleagues at work is a bit of a home automation expert, so I asked about his setup, and decided to bit the bullet and migrate to an all new setup using the Ikea devices. It also means that I don't need to stick to Ikea in future in case I wanted to experiment with other vendors as well. I had a spare Raspberry PI 3 lying around not doing much ( well, just running Pi-Hole for ad blocker and DHCP, but mostly idle) which I could use so decided to go this route.
I used the Zigbee2MQTT page as a starting point as to what adapter to get. This was no mainly about what was available at the time, but I decided to go with the "Electrolama zig-a-zig-ah! (zzh!)" from the Zigbee2MQTT recommended devices, use a docker container on the Rasperry Pi to setup and run the Zigbee devices and use Home Assistant to act as a bridge between the devices and HomeKit on the Apple Ecosystem.
Zigbee Stick
The stick supplied doesn't come with any firmware on it at all, just code to flash the LEF when it is plugged in, so I needed first to flash the firmware. There are instructions on the Electrolama web page for this for Windows and using a python program. Also, when I ordered the stick, I didn't bother with the debug module.
Not having a windows machine around, I decided to go with the Python program which was remarkably easy on my Macbook Pro. There are instructions on the page, specifically for Macintosh:
To run cc2538-bsl.py you need to install some extra python dependencies, python3 should already be shipped with macOS (Catalina onwards?).
Download and extract cc2538-bsl: curl --output cc2538-bsl.zip https://codeload.github.com/JelmerT/cc2538-bsl/zip/master && unzip cc2538-bsl.zip
Install required dependencies: $ /usr/bin/python3 -m pip install --user pyserial intelhex
(As we cannot write to the system's location we need to install the dependencies with in the user location.)
After this, I put my stick in BSL mode by pressing the small button on the top and plugging into my USB port at the same time. The device appeared as /dev/tty.usbserial*
I needed to download the firmware for co-ordinator usage as I was wanting to use this stand alone. The link was on the main Zigbee2MQTT page, so I downloaded directly from there. At this point, it was a simple case of running:
python3 cc2538-bsl.py -p /dev/tty.usbserial* -evw CC2652R_coordinator_20210708.hex
And the firmware.
Raspberry Pi
Docker.
As mentioned, earlier, I wanted to run the Automation in a container, so it would be way to start/stop and migrate to a new machine if necessary.
The Raspberry Pi, does not come with docker or docker-compose installed by default, but they are easy to install. https://dev.to/elalemanyo/how-to-install-docker-and-docker-compose-on-raspberry-pi-1mo gives a simple tutorial on installing docker and docker-compose. It also has the benefit of restarting the containers, and hence the Homekit stuff if, for any reason, the Pi reboots. I followed steps 1-6 and made sure everything was working successfully.
Next step was to create a directory for all of the zigbee/home automation code and config.
pi@bluepi:~ $ mkdir ~/zigbee
pi@bluepi:~ $ cd ~/zigbee
pi@bluepi:~/zigbee $
Hardware
The following are modifed from https://www.zigbee2mqtt.io/guide/getting-started/ with my local changes.
First, I plugged the stick into my Raspberry Pi. I then needed to determine the device that it was assigned to.
pi@bluepi:~/zigbee $ sudo dmesg
[ deleted ]
usbcore: registered new interface driver ch341
usbserial: USB Serial support registered for ch341-uart
ch341 1-1.3:1.0: ch341-uart converter detected
usb 1-1.3: ch341-uart converter now attached to ttyUSB0
[ deleted ]
pi@bluepi:~/zigbee $ ls -lL /dev/serial/by-id/
total 0
crw-rw---- 1 root dialout 188, 0 Nov 17 17:05 usb-1a86_USB_Serial-if00-port0
pi@bluepi:~/zigbee $ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Nov 17 17:05 /dev/ttyUSB0
pi@bluepi:~/zigbee $
First I created a configuration file for docker-compose, using the device above.
pi@bluepi:~/zigbee $ cat docker-compose.yaml
version: '3.8'
services:
mqtt:
image: eclipse-mosquitto:2.0
restart: unless-stopped
volumes:
- "./mosquitto-data:/mosquitto"
ports:
- "1883:1883"
- "9001:9001"
command: "mosquitto -c /mosquitto-no-auth.conf"
zigbee2mqtt:
container_name: zigbee2mqtt
restart: unless-stopped
image: koenkk/zigbee2mqtt
volumes:
- ./zigbee2mqtt-data:/app/data
- /run/udev:/run/udev:ro
ports:
- 8080:8080
environment:
- TZ=Europe/London
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
pi@bluepi:~/zigbee $
Since I'm running as the 'pi' users, and the permissions on the USB device above don't allow me to read/write to it, and I also had to run the usermod command to add 'pi' to the dialout group:
pi@bluepi:~/zigbee $ sudo usermod -aG dialout pi
pi@bluepi:~/zigbee $
Then a configuration file is needed. Yhis should be created under zigbee2mqtt-data/configuration.yaml after creating the zigbee2mqtt-data directory. I added the homeassistant support in this file ready for later as well.
pi@bluepi:~/zigbee $ cat zigbee2mqtt-data/configuration.yaml
permit_join: true
mqtt:
base_topic: zigbee2mqtt
server: mqtt://mqtt
serial:
port: /dev/ttyUSB0
frontend:
port: 8080
homeassistant: true
advanced:
network_key: GENERATE
pi@bluepi:~/zigbee $
Connect to the devices
Now it's time to start the docker images, and pair all the devices. This is a simple case of running docker-compose.
The first time round, this may take some time as it will have to download images. Subsequent calls to the command will be much faster. The '-d' option to to disassociate from the terminal, so one they have started the shell prompt will appear. After that we can run a 'tail -f' on the logs. This can be interrupted with ^C at any time without stopping the docker image.
pi@bluepi:~/zigbee $ docker-compose up -d
[ deleted ]
# Check the logs
pi@bluepi:~/zigbee $ docker-compose logs -f
Connect to the Zigbee web
The next stage was to connect to the Raspberry-Pi on port 8080 to ensure everything was working. At this point it will be pretty much an empty page.
RePair all devices
At this point, I needed to re-pair all of the devices. For the power adapters, it's a matter of pressing a small pin into the bottom for about 5 seconds until the LED flashes. No problem. The lights needed to be turned off and on 6 times at just the right amount of time between each on/off interval. For some of the lights, this took about 5 or 6 attempts, but they all eventually went into pair mode and each appeared on the Zibgee web page.
As each was being paired, I changed the name of the device to something more reasonable. At the end, the screen looked like this:
Set up Home Assistant and Homekit
I already added the homeassistant tag to the configuration file, above, so all this is needed is to add the Home Assitant information to the docker-compose file. First, I created a directory "HA" in the zigbee directory for all of the Home Assistant configuration and storage.
Create a directory under zigbee and then add the following to the docker-compose file for HomeAssistant:
pi@bluepi:~/zigbee $ mkdir HA
pi@bluepi:~/zigbee $ cat docker-compose.yaml
[deleted]
homeassistant:
container_name: homeassistant
image: "ghcr.io/home-assistant/raspberrypi3-homeassistant:stable"
volumes:
- /home/pi/zigbee/HA:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
# Example for HomeKit setup
privileged: true
network_mode: host
pi@bluepi:~/zigbee $
- Start up the docker images again and log on to Home assistant on the default port of 8123
- Set up account for the first time.
Now, back on the Raspberry-pi close all docker images down.
pi@bluepi:~/zigbee $ docker-compose down
Stopping homeassistant ... done
Stopping zigbee_mqtt_1 ... done
Stopping zigbee2mqtt ... done
Removing homeassistant ... done
Removing zigbee_mqtt_1 ... done
Removing zigbee2mqtt ... done
Removing network zigbee_default
pi@bluepi:~/zigbee $
Add 'homekit: and mqtt broker' information to homekit configuration.yaml file.
To edit this sudo will need to be used, as it will have been created by the root user. i.e. sudo vi HA/configuration.yaml
pi@bluepi:~/zigbee $ cat HA/configuration.yaml
# Configure a default setup of Home Assistant (frontend, api, etc)
default_config:
# Text to speech
tts:
- platform: google_translate
group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
homekit:
mqtt:
broker: localhost
pi@bluepi:~/zigbee $
Start all the docker images again and then login to Home Assistant.
pi@bluepi:~/zigbee $ docker-compose up -d
Creating network "zigbee_default" with the default driver
Creating zigbee_mqtt_1 ... done
Creating homeassistant ... done
Creating zigbee2mqtt ... done
pi@bluepi:~/zigbee $
Note: Notification about new devices with barcode will appear
Note: Scan in barcode on Phone Homekit app
Note: New devices will appear automatically.
Note: Move the devices to the correct rooms and carry on as normal, but just much faster now.
Conclusion
Take Aways:
- Response from the new setup is much faster than with the original IKEA gateway. Siri integration is more responsive as well.
- A Raspberry PI 3 model B with 1G of memory is sufficient to run the Zigbee and Home Assistant software in a docker image, even with running Pi-Hole along side it.
- It did take longer that it seems above; a few false starts trying to use the native Zigbee support in Home Assistant didn't work as expected, so moving to use MQTT messages was the better option.
- Zigbee2MQTT has a net map feature that shows which devices are active and the string s of the signal between each one.
- Home Assistant has a lot of scripting and reporting which can be used on the web page and there is an associated iOS and Android app that can be used to control the devices as well as using HomeKit.
Summary for adding docker-compose.
In case the link forestalling docker-compose if offline, these are the steps.
Prerequisites
Raspberry Pi with a running Raspbian OS
1. Update and Upgrade
First of all make sure that the system runs the latest version of the software.
Run the command:
sudo apt-get update && sudo apt-get upgrade
2. Install Docker
Now is time to install Docker! Fortunately, Docker provides a handy install script for that, just run:
curl -sSL https://get.docker.com | sh
3. Add a Non-Root User to the Docker Group
By default, only users who have administrative privileges (root users) can run containers. If you are not logged in as the root, one option is to use the sudo prefix.
However, you could also add your non-root user to the Docker group which will allow it to execute docker commands.
The syntax for adding users to the Docker group is:
sudo usermod -aG docker [user_name]
To add the permissions to the current user run:
sudo usermod -aG docker ${USER}
Check it running:
Reboot the Raspberry Pi to let the changes take effect.
4. Install Docker-Compose
Docker-Compose usually gets installed using pip3. For that, we need to have python3 and pip3 installed. If you don't have it installed, you can run the following commands:
sudo apt-get install libffi-dev libssl-dev
sudo apt install python3-dev
sudo apt-get install -y python3 python3-pip
Once python3 and pip3 are installed, we can install Docker-Compose using the following command:
sudo pip3 install docker-compose
5. Enable the Docker system service to start your containers on boot
This is a very nice and important addition. With the following command you can configure your Raspberry Pi to automatically run the Docker system service, whenever it boots up.
sudo systemctl enable docker
With this in place, containers with a restart policy set to always or unless-stopped will be re-started automatically after a reboot.