Alexa-Home, Node-Red and Docker

How do you add new virtual devices/commands in Node-Red so that Alexa can control them? There are great Node-Red extensions but things get more complicated if Node-Red is running in a docker container. In this blog post I share my take-aways from setting this up.

Voice assistants and smart home applications go together really well. For several years now we have an Echo Dot with Alexa running at home and I have connected more and more devices to it. Another important factor in my smart home setup is a Node-Red instance running in a docker container on a RaspberryPi 4.

Why Running Node-Red in Docker?

I probably could save myself some trouble if I would just install Node-Red as regular service on the base system on my Raspberry Pi. Especially where Node-Red needs direct access to RPi hardware resources. It took me quite some time to figure out how I can use the RPi Bluetooth device from within the docker container. In a nutshell: you have to use network_mode: host to share the BLE hardware between host and container.

But I believe that the benefits of running such applications like Node-Red in a docker container outweigh the trouble. Updating or trying out different configurations is super easy. And all the resources are cleanly separated from other containers running on the same machine.

The Alexa-Home Node

I have a couple of Tasmota powered Shelly devices, allowing me to control lights either with a regular light switch over WiFi. You can set up Tasmota devices to be discoverable by Alexa. Then with a simple “Alexa, turn on the corridor” you can control the lights in your corridor. But what if you want to make a new command accessible to Alexa that is not represented by a physical device?

This is where the Alexa-Home node comes in. The official name is node-red-contrib-alexa-home and this extension comes with two nodes: a controller and a device node. The controller lets you do some basic settings like the network port used for discovery while the device node lets you setup a virtual device.

So for instance I created a node called “Everything” and now I can turn off all lights by calling “Alexa, turn off Everything”. Nice, eh? But sadly this didn’t work right away. Once more I suspected the docker setup and I was correct.

The Solution

No matter what I tried, the virtual devices from Node-Red did not show up in Alexa’s device list. So I assumed some kind of networking issue. According to this github project the device needs to listen on a certain port, for generation 3 devices this has to be port 80. Alexa must be able to download the file /alexa-home/setup.xml from the RPi. This file contains the device description.

That means we have to make sure that a request to the RPi is forwarded to our Node-Red container. Now the next steps depends on your setup. I’m running Node-Red together with MQTT from a docker-compose command. And as mentioned earlier this setup is using “network_mode: host”:

Setting network_mode to host allows the container to share the same network namespace as the host OS. When this is set, any ports exposed on the container will be exposed locally on the device. This is necessary for features such as bluetooth.

Source: https://www.balena.io/docs/learn/develop/multicontainer/

This means that I cannot do port mapping in the docker-compose file because host-mode together with port-mapping is not allowed. That means that the port which uses Alexa-Home to publish it’s setup.xml must be exposed from the Dockerfile.

I set my Alexa-Home controller node to port 80:

Alexa Home Controller Node, set to port 80

And in the Dockerfile I added

EXPOSE 80

And that’s it! Rebuild the docker container and restart both containers with docker-compose. Now add an Alexa-Home node in your Node-Red web interface and set the device name in the node configuration. This is the name you will use to give commands for that virtual device. Then tell Alexa to “Discover devices”. After about 20 seconds she will tell you that she discovered your new device.

Now you can create nodes just like this one:

The “Everything” node allows you to tell “Alexa, turn off everything”

Summary

Alexa and Node-Red can be a powerful team. You can create powerful commands in Node-Red which Alexa can understand. While you are limited to simple commands like “Turn On XXX” or “Dim XXX to 50%” you can get a long way with this.

Running Node-Red in a container is a powerful thing and has many benefits. But it also complicates things every once in a while. And connecting Alexa and Node-Red over the device discovery is such a thing. But if you are in this situation you’ll hopefully find this blog post and have it up and running in no time!

blank
Posted by Daniel Eichhorn

Daniel Eichhorn is a software engineer and an enthusiastic maker. He loves working on projects related to the Internet of Things, electronics, and embedded software. He owns two 3D printers: a Creality Ender 3 V2 and an Elegoo Mars 3. In 2018, he co-founded ThingPulse along with Marcel Stör. Together, they develop IoT hardware and distribute it to various locations around the world.

Leave a Reply