4 min read

Deploying a multiprotocol bridge with SkyConnect

Deploying a multiprotocol bridge with SkyConnect
Photo by Anders Jildén / Unsplash

Matter is becoming a reality! I still have a long way to go, but I wanted to give some pointers on how to achieve a Zigbee2MQTT + OpenThread Border Router with a Raspberry Pi and a SkyConnect.

Note that you may want to follow the more guided/official approach: NabuCasa (the "Home Assistant company") is streamlining the process with add-ons and easy procedures (check the SkyConnect website and Home Assistant blog posts for those). However, I needed/wanted a more modular approach and will be describing in this post how to deploy both a Zigbee2MQTT for the Zigbee network and an OpenThread Border Router for the Thread network in a single Raspberry Pi by using the SkyConnect with its multiprotocol features.

Hardware

  • SkyConnect
  • Raspberry Pi 3 or 4 (Raspberry OS Lite 64bit installed)

Firmware

Before starting, you need to make sure that your SkyConnect has the RCP MultiPAN firmware flashed, available here: https://github.com/NabuCasa/silabs-firmware

The RCP means "Radio Co-Processor". This describes a way of operation of chips in which the radio is in the chip itself while all the intelligence is located in the Raspberry. A different way of operation would be NCP or "Network Co-Processor" in which the network logic is done in the firmware and the Raspberry interacts at a higher level.

The magic of using RCP is that multiprotocol becomes much easier to implement, as both Zigbee and Thread are protocols that are "similar" from a radio point of view --but very different at the network level.

Unify software

Silicon Labs (the company that does the specific radio chip of the SkyConnect) provides the main software that we will be using. Documentation available here: https://siliconlabs.github.io/UnifySDK/doc/multiprotocol.html

I installed the following packages:

  • uic-cpcd which is the single point of communication with the USB device
  • uic-otbr for the OpenThread Border Router (i.e. otbr)
  • uic-zigbeed for the Zigbee communication

Follow the documentation and enable/start all the services. Most will fail, so keep reading to fix the issues.

The default tty devices that worked for me were:

  • /dev/ttyUSB0 for the cpcd configuration (the ACM one is typically for the internal serial, not USB connected ones such as the SkyConnect).
  • /dev/ttyZigbeeNCP for the zigbeed configuration.

Encryption and key binding

At the time of writing this blog entry, the beta firmware provided by NabuCasa doesn't have encryption enabled. However, the default configuration of cpcd tries to establish the key binding key (which is done through ECDH, a cryptographic key agreement protocol). You will see the following error in uic-cpcd-bind systemd service:

Security configuration mismatch between CPCd (enabled) and Secondary (disabled)

To solve that:

  • Disable the uic-cpcd-bind service (with systemctl mask)
  • Change the uic-cpcd service (copy it from /lib/systemd/system/uic-cpcd.service to /etc/systemd/system/uic-cpcd.service and remove both the Wants and After settings, and also remove the --key parameter in the command.
  • Disable encryption in the cpcd configuration, i.e. set disable_encryption: true in the /usr/etc/cpcd.conf
  • Restart the uic-cpcd service (with systemctl restart)

With those changes, the service should have been started properly.

Missing otbr dependencies

I saw some errors on the otbr-* services (those services are automated/managed by the uic-otbr service). It seems that the deb packages dependencies are not properly set up. The packages that I was missing were:

  • libavahi-client3
  • libjsoncpp24

Once those are installed and you restart the parent uic-otbr service, then the Border Router should start up properly and you should be able to access the web interface (port 80).

Fix socat permissions

The default uic-zigbeed installation sets up a socat but it has only root permission. That may become a problem for default user-space Zigbee2MQTT, so let's change it:

  • Copy the /lib/systemd/system/uic-zigbeed/socat.service to /etc/systemd/system
  • Change the following line:
ExecStart=socat -v pty,link=/dev/ttyZigbeeNCP,group-late=dialout,mode=660 pty,link=/tmp/ttyZigbeeNCP

After those changes, you can restart uic-zigbeed service. The pi user is, by default, a dialout member so so it will now be able to access that ZigbeeNCP virtual tty device (you can double check it with a simple cat /dev/ttyZigbeeNCP).

Installing and configuring Zigbee2MQTT

First of all, you should go to its documentation and follow the Installation instruction. However, at the time of writing this, the 1.30.2 version (the latest one) was failing mysteriously, but downgrading to 1.30.1 solved the issue; if that has not been solved yet you can downgrade to that by running the following (from the folder where Zigbee2MQTT is, typically /opt/zigbee2mqtt):

$ git fetch --tags
$ git checkout 1.30.1

You have to specify both the place of the virtual TTY and the protocol (the one that uic-zigbeed publishes) which is EZSP. The relevant lines in the configuration are:

serial:
  adapter: ezsp
  port: /dev/ttyZigbeeNCP

Once you change that in the data/configuration.yaml file, Zigbee2MQTT should be able to start. I recommend to activate the frontend and then you should be able to use the web interface that by default is published through port 8080.

Profit!

You should be able to use both networks from here on. Ideally, you should commit to a single mesh, in order to achieve stronger and better connectivity. However, having a multiprotocol capable bridge may ease the migration process. Or allow you to experiment. Be creative!