I was really disappointed when I couldn’t use the IKEA TRADFRI remote in NodeRED or with Xiaomi MiHome ecosystem despite the promised IKEA integration. The remote has been collecting dust ever since as the Swedish company did not win my heart with their less than ideal smart home solutions. Now, I have the CC2531 USB Zigbee sniffer flashed and ready (no CC debugger flash guide) for use with Zigbee2MQTT (how to add new devices) – so all I have left is to map buttons in NodeRED to recreate the original functionality.
IKEA TRADFRI remote
If you have the IKEA’s dimmer, I already covered the transition to NodeRED here. IKEA TRADFRI remote comes with 3 basic functions:
- toggle (on/off)
- brightness (up/down)
- change device (left/right)
Thanks to NodeRED, there are 2 more actions available:
- brightness (long press)
- change device (long press)
I can use all these inputs to create the following actions:
- toggle light
- change brightness (step)
- change brightness (smooth)
- change device
- pick 2 favourite devices
IKEA TRADFRI remote in NodeRED
If you connect a debug node to IKEA TRADFRI remote in NodeRED, you will see 13 actions available. I will map almost all of them. The actions are:
- toggle
- brightness_up_click|brightness_down_click
- brightness_up_hold|brightness_up_release
- brightness_down_hold|brightness_down_release
- arrow_right_click|arrow_left_click
- arrow_right_hold|arrow_right_release
- arrow_left_hold|arrow_left_release
Preparation
Since I know I will control more than one device (there is no limit) I will create an array that stores all names of the devices. These names will correspond with the names given by Zigbee2MQTT (important). I would also encourage you to enable saving contexts in NodeRED otherwise everything written in variables will be lost on reboot.
["spotlight1","ikeabulb1","ikeabulb2"]
This will be stored as a global variable: “ZigbeeLights“. I will be able to cycle through each device using arrow buttons. Since I can toggle and change the brightness of each light, I want to store these values as well in flow contexts. I created a set of flow variables for each light I have:
var state = msg.payload.state; var brightness = msg.payload.brightness; flow.set("spotlight1_brightness", brightness); flow.set("spotlight1_state", state);
Try keeping the naming convention consistent so you could keep track of the variables.
Changing devices
Before I take care of other functions, I need to sort out how NodeRED will know which light to control. There are 2 mechanisms in place. First, I took the advantage of the “long press” option to set the favourite devices:
var x = msg.payload.action; if(x === "arrow_right_release"){ flow.set("activeDevice", "spotlight1"); } if(x === "arrow_left_release"){ flow.set("activeDevice", "ikeabulb2"); } return msg;
These will trigger only when the button is released – and action: arrow_left_release|arrow_right_release
appears. With that sorted, let’s cycle through the devices.
Cycling through lights
There are 2 different functions triggered, one to count up and one to count down. These are very similar in structure, they just iterate the variable “count” and update previously created flow variable “activeDevice“.
Each time I press the arrow button the variable count will change and pick the next device form the array stored in "ZigbeeDevices".
Toggle
Now that NodeRED knows what device I want to control, time to turn it on or off! The present state is always stored in an appropriate light context, so I just have to look up the current value, change it to the opposite one and send that to the correct light using MQTT OUT.
To pick the correct device, I have to compile the correct MQTT topic. It's easy, as I alredy know the name of the active device, which is required for this.
The message ON|OFF is sent as msg.payload.state
to the msg.topic = zigbee2mqtt/devicename/set
.
Brightness
There are 2 ways to increase/decrease the brightness. You can click the button to go up a step (up/down by 50 out of 255) or you can press and hold the button to increase it by a smaller increment (30) until the right level.
Brightness steps
I'm using mirrored functions again to increase and decrease the brightness of the light and make sure that msg.payload.brightness
where the value is stored doesn't go outside the bounds 0:255.
Each time the button is pressed, the current value is read and adjusted by 50. To update the light source, I compile the topic with the current device again and send the msg.payload.brightness
to the MQTT OUT node.
The state updates defined in the preparation section will assure that new values are set in the NodeRED.
Brightness by smaller increment
I actually wrote about this before in my Smart Dimmer article. I used a single button to change the brightness up/down based on the current values. I didn't have a second button so I had to use click and hold to control both changes.
When the button is pressed, there is a loop that keeps changing the value by 30 and sends the update to the light until the loop is stopped by the the brightness_down_release|brightness_up_release
.
When I press and hold the button down, the flow.press
value turns true
and it allows the messages in my loop to pass through the switch node. The same variable is set to false
when the button is released and the loop stops.
It's worth noting that each time I update the light with the brightness value, the same is sent as msg.feedback
to for iteration.
Buy USB Zigbee Stick CC2531
Buy it using these links to support NotEnoughTech.
Conclusion
This is a mere recreation of the original functionality of the IKEA TRADFRI remote in NodeRED. There are 13 actions available that could be used for lights, garage door controls, blinds and other connected devices. The sky is the limit! I will be posting from time to time about interesting concepts. Let me know what would be a cool use of the IKEA TRADFRI remote in NodeRED in this Reddit thread and I might write about the best concepts in details.
Project Download
Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.