Home Home Automation Smarter IKEA TRADFRI motion sensor in NodeRED

Smarter IKEA TRADFRI motion sensor in NodeRED

Turning a boring motion sensor into a smart one!

Hooking up IKEA TRADFRI motion sensor in NodeRED takes about 1 min and it would make it for a very boring and very much obvious tutorial. If you have seen my stuff before, you know I like to complicate things, mostly because I can! I’d like to introduce you to a much smarter version of the IKEA TRADFRI motion sensor – which you can control like a real IoT device!

IKEA TRADFRI motion sensor in NodeRED

If you want to use the sensor “as is” there isn’t much to it, simply read the state from msg.payload.occupancy which comes as true or false and use the change node to send the appropriate message back to the device of your choice. Simple! You will have to get a CC2531 USB Zigbee sniffer and follow this 3 min guide to flash it (no cc debugger needed!). Follow this guide to pair your sensor with cc2531.

FUNCTION NODE: Format
var x = msg.payload.occupancy;

if(x === true){
    msg.payload = {"state": "ON"};
}
if(x === false){
    msg.payload = {"state": "OFF"};
}
return msg;

I’m here to extend the features of the IKEA TRADFRI motion sensor and show you how to add the following functions:

  • dashboard access
  • extended timeout (10 min+)
  • delay mode (up to 10 min)
  • latching
  • time condition (ie day, night, 24h)

You have to admit this is pretty impressive especially, that the IKEA TRADFRI motion sensor comes with a timeout 1-10 min and night/ anytime options of operation only. Not very smart if I’m honest.

Buy USB Zigbee Stick CC2531

Buy it using these links to support NotEnoughTech.

This project uses one of my previous articles about getting sunset and sunrise information to NodeRED. Make sure you get yourself familiar with it and have the flow deployed.

Motion Sensor Dashboard & more

Unfortunately, this is one of these flows that are a bit mad to explain as there are many multiple interactions going on. I will break it down to GUI dependent elements and the NodeRED.

The design principle was simple. Set the time on/off timers (“SensorON” & “SensorOFF”) and check every minute if the light should be turned on or turned off. To make it work I need to set the IKEA TRADFRI motion sensor dials to “sun” (operating in any light conditions) and 1 min (one-minute timeout). I will use NodeRED to process that behaviour.

The Dashboard

The 3 buttons are using the global variable “TimeOfDay” to compare the value of the button payload (night, day, 24) against the value assigned to the global variable (night, day). In addition to that, I use 4 different outputs of the function node to change the colours of the buttons using {{msg.background}}.

FUNCTION NODE: Update GUI
var topic = msg.payload;

if(topic === "day"){
   var msg1 = {background: "#04a3f2"};
   var msg2 = {background: "#c3c7c9"};
   var msg3 = {background: "#c3c7c9"};
}

if(topic === "night"){
   msg1 = {background: "#c3c7c9"};
   msg2 = {background: "#055277"};
   msg3 = {background: "#c3c7c9"};
}
if(topic === "24"){
   msg1 = {background: "#c3c7c9"};
   msg2 = {background: "#c3c7c9"};
   msg3 = {background: "#1e8c26"};
}


var msg4 = {payload: msg.payload};
flow.set("24", msg.payload);

return [msg1, msg2, msg3, msg4];

An INSERT node in the repeat mode (1 min) is used to check if the day conditions has changed. If you want to, you can convert this into a time keeping system.

FUNCTION NODE: Is it night?
var x = flow.get("24");
var y = global.get("TimeOfDay");

if(x === y){
    flow.set("day", true);
}
if(x === "24"){
    flow.set("day", true);
}
if(x !== y && x !== "24"){
    flow.set("day", false);
}
return msg;

This setup controls the SWITCH node (“Day?“) in the main flow. Setting the flow context “day” to false stops the messaged from going through.

Both sliders and the latch toggle have unique topics assigned (delay, timeout, latch) which are processed by the FUNCTION node (“Set GUI vars“) and the data is saved as flow contexts.

FUNCTION NODE: Set GUI vars
var topic = msg.topic;
var payload = msg.payload;

if(topic === "latch"){
    flow.set("IKEA_motionsensor1_latch", payload);
    if(payload === true){
        flow.set("latchpass", false);
    }

    if(payload === false){
        flow.set("latchpass", true);
    }
    return msg;
}
if(topic === "delay"){
    var x = payload *60;
    flow.set("delay", x);
    return msg;
}
if(topic === "timeout"){
    var y = payload * 60;
    flow.set("timeout", y);
    return msg;
}

Lastly there is a reset button which feeds back the default values to the user interface, turns off the light and overrides all important flow variables. It is linked to a notification so you could see the feedback of your action. There is a template node there just for the good measure – it just shows the picture.

FUNCTION NODE: Reset
var msg1 = { payload: 1 };
var msg2 = { payload: 0 };
var msg3 = { payload: false };
var msg4 = { payload:"IKEA Motion Sensor has been reset" };
var msg5 = { spotlight: false};


flow.set("SensorOFF", 0);
flow.set("latchpass", true);
flow.set("state", false);
flow.set("timeout", 1);
flow.set("delay", 0);
flow.set("SensorON", 0);

return [msg1, msg2, msg3, msg4, msg5];

The main flow

IKEA TRADFRI motion sensor in NodeRED reports true or false – I’m only interested in true value coming from msg.payload.occupancy as I will set the timing programmatically. I mentioned before, that the flow is interrupted by “day” variable, but also by “latch“.

Latching stops the subsequent variables from being sent further, as only the initial variable should set the timer.

The first function node uses all GUI flow contexts to set the correct times for “SensorON” and “SensorOFF”. These values will control when the light should toggle. These values are updated each time the motion sensor triggers if the latching is disabled.

FUNCTION NODE: Set Sensor ON
var delay = flow.get("delay");
var timeout = flow.get("timeout");
var latch = flow.get("IKEA_motionsensor1_latch");
var latchpass = flow.get("latchpass");

var x = new Date();
var time = Math.round( x.getTime() / 1000);

//check if values are set
var y = isNaN(delay);
var z = isNaN(timeout);

if(y === true ){
    delay = 0;
    flow.set("delay", delay);
}

if(z === true ){
    timeout = 1;
    flow.set("timeout", timeout);
}

//set timers
if(delay => 0){
    var mod = time + delay
    flow.set("SensorON", mod);
    
    }

if(timeout => 0){
    var timer = time + timeout + delay;
    flow.set("SensorOFF", timer);
    }
    
//latching behaviour    
    
if(latch === true ){
    flow.set("latchpass", false);
}
if(latch === false ){
    flow.set("latchpass", true);
}
return msg;

I can get the time in milliseconds in the function node, but since I need the time in seconds, I used Math.round(time/1000) to get the time in seconds. The timers are set using the offsets from “delay” and “timeout“. It’s worth noting that the “SensorOFF” is the combination of time, delay and timeout – so it would never be set to a value smaller than “SensorON“.

There is one more flow control measure – flow “state” which will interrupt messages going forward when the alarm is set. This is done to prevent the non-latching signals causing issues.

Every minute NodeRED is checking if the lights should be set on or off. The script is comparing the current time vs the time in seconds set in flow variables “SensorON” and “SensorOFF”. If the conditions match, a correct message is being sent further to compose the payload and topic controlling my Zemismart Downlight.

FUNCTION NODE: Turn OFF
if(msg.spotlight === false){
    msg.topic = "zigbee2mqtt/spotlight1/set";
    msg.payload = {
        "state": "OFF"
    };
    
    flow.set("SensorOFF", 0);
    flow.set("latchpass", true);
    flow.set("state", false);
    flow.set("timeout", 1);
    flow.set("delay", 0);
    flow.set("SensorON", 0);
return msg;
}
FUNCTION NODE: Turn ON
if(msg.spotlight === true){
    msg.topic = "zigbee2mqtt/spotlight1/set";
    msg.payload = {
        "state": "ON"
    };
    return msg;
}

Conclusion

While it’s easy to use IKEA TRADFRI motion sensor in NodeRED as is, making an extra effort enables more options and real IoT approach to sensors. After all, is it a truly connected device if we have to take it off the wall and use a screwdriver to change its settings? Let me know what do you think about this project in this Reddit thread.

Project Download

Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.

PayPal

Nothing says "Thank you" better than keeping my coffee jar topped up!

Patreon

Support me on Patreon and get an early access to tutorial files and videos.

image/svg+xml

Bitcoin (BTC)

Use this QR to keep me caffeinated in style with crypto-currency

Smart Ideas with

Automate your space in with these ecosystems and integrate it with other automation services

Learn NodeRED

NodeRED for beginners: 1. Why do you need a NodeRED server?

0
To server or not to server? That's a very silly question!

Best Automation Projects

ESP8266 WIFI lights under $5

0
Your Sonoff device can't do this!

Free wireless doorbell (Amazon Dash button hack)

0
The most terrifying situation I can imagine* is missing a parcel

New Amazon Dash Buttons

0
You can teach new buttons old tricks!

ESP8266 ceiling light – demo

0
Testing the ESP8266 as a WIFI light controller

Try Tasker and Raspberry Pi for your home automation needs!

0
Raspberry Pi can help you with your Tasker profiles

Smart Home

IFTTT Pro Alternative: Alexa ed.

0
Bypass IFTTT Pro restrictions for Alexa voice actions with this IFTTT Pro Alternative

The answer to almost all Echo needs: Alexa-remote2

0
Alexaremote2 is a Swiss army knife for Amazon Echo devices. Connect, control and listen to all Alexa enabled gadget at home.

This ESP32 is on FIRE! – M5Stack Core

0
This ESP kit is on fire! M5Stack Core merges IoT platform and learning in a very polished stackable module.

From KettleBot to ANY-Bot – SwitchBot

0
Switching anything on and of with SwitchBot -an insanely cute robot that does all the finger pressing for you

NodeRED – multiple payloads

0
Mastering multiple payloads in the function node in NodeRED