If you’ve used the Echo Button, you may have been disappointed like I was to find out that it’s a one-way switch. You can only use it to trigger a routine, and last I checked there isn’t a “toggle the light” routine. Well if you have one sitting around, you might be able to make use of it like I did. With Node-RED, you can use a flow to automate toggle switch functionality (and more!) for your Echo button. If you’re doing this you’ll need to make sure you have sudo/admin access to emulate an Echo device on port 80. For example with Docker you could just map an arbitrary container port to host port 80 (just like with iptables). This is the flow that I had working already, but I’ll be walking through step by step building it from scratch. For my setup I have two buttons: one on either end of my living space (bedroom connected to a home office upstairs), controlling both a Domoticz controlled device and an Alexa powered device.
The most important thing for this to work are
the node modules that both emulate/control echo devices. With Node-RED
installed, click the menu icon at the top right, and select Manage palette
Drag and drop the controller node and the home
node to the flow, and configure each.
The controller configuration doesn’t need to be
modified. If you are running as root/admin, and don’t have port 80 in use, you can set it to port 80 here.
Otherwise you will need to forward the firewall port, for example in Linux.
iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 60000
sudo apt install iptables-persistant
sudo apt install iptables-save > /etc/iptables/rules.v4
Name the device, especially if you have multiple
buttons. Helps to also write a number on the bottom of the button. The type
does not matter as we are not using the light features (but with this node, you
could do something else neat like “turn my minecraft lights red”).
6. You can output to the debug node to see the output at any point of the flow. Connect the node by clicking and dragging the connector icon from one node to another. Configuring the debug node can help when default debugging doesn’t quite cut it. Using complete message object is useful for capturing test payloads for writing JSONata functions (and other useful information). Debugging with msg.payload is usually fine. Using JSONata expressions you can filter the logs and format the output. Click Deploy at the top right to start the flow (and to update any time you’ve made a change). Node connection and deployment moving forward for documentation purposes is implied (you won’t be prompted to).
Discover the device by saying “Alexa, discover
devices” (or using the app like I prefer when I shouldn’t have any reason to).
Then in the app, toggle the newly discovered device. Here even though it shows “on”
triggered true twice in a row, it seems there was a little bit of a lag for the
callback to kick in after starting the flow (it later updated a lot quicker)
To properly manage states a value needs to be
stored. Create an inject node, and
configure it to run once when the flow is started. Here, I am using
payload.nvalue, which Domoticz also uses for control (but this guide does not
cover that). One of the devices I am controlling with this flow uses Domoticz,
so I can track the state of that device if it’s changed elsewhere. I picked the
value of 1 as the default because I’m likely to be working on this stuff during
the day when the lights are already on.
Create a change
node. Create a rule to set a flow value to the value specified in the inject
node. This value is referenced later in the flow.
10. On the Domoticz side, we have an MQTT node subscribing to the domoticz/out topic, a JSON node to convert the payload into an object, and a switch node, which only passes through the payload if it’s the Domoticz device specified. That completes the “initialization” part of the flow. One could feasibly include some nodes to manage the callback state of the virtual device on the Alexa side, but if you’re going to do that you may as well track the state of that light you’re controlling as well (playing better with voice commands). Otherwise, it’s no more than a couple button presses to sync the lights back to a given state.
Create a change
node. This is where *it* happens. You know, the thing. JSONata, what did
you think I was talking about? I went into writing JSONata functions in one of my earlier entries. For ease of use an inject button is added to the flow to allow easy development. Also,
being that not everyone uses Domoticz, I’ve adapted the flow by disconnecting
my MQTT node, and adding a rule to update the flow value. 1) Delete
msg.payload. This has to happen a lot of times because errors or other
unexpected things can happen. If you need to work with the data from the
payload in the same change node, just store it in msg.tmp or something, delete
the payload, then do the thing. 2) The IDX is configured but this is for
Domoticz only. 3) This JSONata function is used to invert the flow value. 3)
The flow value is updated with the inverted value and passed to the next
For Domoticz all that is needed is to package up
the payload into JSON format, and zap it over to MQTT. The device status gets
updated on the Domoticz switch page. To toggle an Alexa controlled device, we
are almost ready to call the node for that, but we need another change node
(this could be consolidated into the same change node if you’re not using
Domoticz). 1) The payload is stored in msg.tmp like previously mentioned, then
deleted. 2) The remote control node expects a payload array, so make a rule for
msg.payload.entity and leave it blank for now. 3) The JSONata conditional function
needing to convert the boolean value to the control commands.
tmp.nvalue=1 ? "turnOn" : "turnOff"
Add an Alexa
Smarthome node to the flow
Add an account, configuring as such that the
authorization cookie can be stored in the text file. You may have to
troubleshoot permissions if you don’t see the cookie data being stored in the
Select one of the devices from your account and
select a command so that we can fetch the ID.
Use an inject node to trigger the remote node,
and pipe that to your debug mode (complete message object). You now have your
entityID. Paste it into the change node from earlier.
17. Delete the command you used to fetch the ID, and deploy
Your final product should now be an Alexa device
that when triggered by a routine that is triggered by your Echo button, will
toggle your Alexa powered light, even though it’s not technically supported.
My Domoticz logs for the device show the
activity, and the Alexa powered device I selected seems to reliably trigger
when using an Echo button to trigger the routine
The takeaway: at a minimum, the Echo button can be used as a toggle button if you want it to. In reality, it could be used for a lot of things. Using a message router node (round robin) you could have a set of lights cycle through RGB colors (I didn’t have the ability to control Alexa powered devices years ago when I set this up). Instead of using the message router node, you could also use an array and a JSONata function to cycle through the values (I did both of these a while back with some AiLight custom firmware powered bulbs but did not save the flows). Also you could feasibly set up a rainbow mode, but if you’re triggering your lights to change with the Amazon API many times per minute, hours on end, I can’t speak towards that (rate limiting of the lambda functions behind the scenes; high usage may draw attention). In that case I would recommend getting some smart bulbs with the “rainbow mode” feature.
Don't forget to backup your flows! Menu -> Export -> All flows -> Download