HomeHome AutomationA Timer in NodeRED

A Timer in NodeRED

An offline timer in IoT is priceless

You can laugh all you want at me, but I’m excited! Why? It’s Halloween and timers have been haunting me for way too long! I finally cracked it! I’d like to show you how to make infinite timers in NodeRED which can be set via Dashboard. My timer in NodeRED not only works offline, but it’s modular! What a time to be alive!

Why so serious? It’s just a timer in NodeRED!

Before I decided to play Dr Strange of JavaScript and reinvent the wheel in a function node, I was like everyone else using “bigtimer” node made by Peter Scargill. I’m in no way discouraging you from using that node, but each method has its own pros and cons.

I needed a simple Dashboard timer which I can add to any IoT device, so I could set the schedules via NodeRED Dashboard rather than hardcode the values in NodeRED.

I present you with a Timer in NodeRED:

  • Modular (as a subflow)
  • Unlimited timers per device
  • Supports “days of the week”
  • works offline
  • Dashboard interface
  • One button reset

Unlike my other flows, this one is very easy to add to your creations. This timer in NodeRED can be deployed as a single subflow configurable via NodeRED 1.0 environmental variables.

To configure the subflow, you have to provide the timer iteration (each timer should have its own number like: 1|2|…n) and values for payload on start and stop (string).

Apart from the Dashboard (obviously?), you will need the Schedex node so head to palette manager and install:

node-red-dashboard 
node-red-contrib-schedex

What’s the catch?

Nothing is perfect, and timer in NodeRED has annoyances too! The way the Dashboard works makes it impossible to simply import the subflow and hope that the widget will be added in the right place.

All elements are configured correctly, but the Dashboard will try to fill in spaces on your web interface by shifting the elements up. The result may look tragic, but everything will work fine.

To fix the layout, you will need to add a couple of spacers. There is no rule how big the spacers should be, as all this depends on your layout in the Dashboard, just make sure the elements don’t shift up.

If you want to have multiple timers on the same page, you are better off duplicating the subflow manually, then setting the values of the environmental variables yourself.

How does it work?

I tried to make this flow as simple as possible. I used the groundwork laid in articles about calculating time in Tasker (underlying maths is the same, plus Tasker supports JavaScript).

function calcTime(hh){
     var hours = ("0"+Math.floor((hh%86400)/3600)).slice(-2);
     var minutes = ("0"+Math.floor((hh%3600)/60)).slice(-2);
     return hours + ":" + minutes;
 }

“Pick time” Dashboard element generates time in milliseconds since midnight. To set a valid timer, I will need the start time and the end time. These values are converted to seconds (division by 1000) and I can use the clever JavaScript to add leading zeros and format it to HH:MM format needed for the Schedex node.

When the time is set in the picker, a function node saves it as a flow variable and sets the button labels to provide the visual feedback.

Function Node: Set T2 On/OFF
var z = flow.get("Timer1");

//if timer on is set
if(msg.topic === "Ton"){
    flow.set("timer"+z+"_on", msg.payload);
    msg.color = "red";
    msg.topic = "Press";
    return [msg, null];
    
    
}

//if timer off is set
if(msg.topic === "Toff"){
    flow.set("timer"+z+"_off", msg.payload);
    msg.color = "red";
    msg.topic = "Press";
    return [null, msg];
    
}

// reboot detected
if(msg.topic === "reboot"){
    msg.color = "grey";
    msg.topic = "Select Time";
    return [msg, msg];
    
}

I wanted this visual feedback to be clear, so not only I change the colour and labels of the buttons, but I included a text label showing that the timer had been set.

Function Node: On Button Press
var z = flow.get("Timer1");
var pon = flow.get("Payload"+z+"_on");
var poff = flow.get("Payload"+z+"_off");

function calcTime(hh){
    var hours = ("0"+Math.floor((hh%86400)/3600)).slice(-2);
    var minutes = ("0"+Math.floor((hh%3600)/60)).slice(-2);
    return hours + ":" + minutes;
}

var time = null;
var timerlabel = "Timer "+ z;


// when button on is pressed
if(msg.topic === "buttonON"){
    var t1  = flow.get("timer"+z+"_on")/1000;
    time = calcTime(t1);
    flow.set("T"+z+"on", time);
    //send to text element
    //var msg1 = {payload: "SET", topic: timerlabel, color: "green"};
    //send to schedex
    var msg1 = {payload: {ontime: "ontime " + time,
                          onpayload: pon,
                          suspended: false},
                topic: "SET",
                color:   "green"};
    return [msg1,null];
}
// when button off is pressed
if(msg.topic === "buttonOFF"){
    var t2 = flow.get("timer"+z+"_off")/1000;
    time = calcTime(t2);
    flow.set("T"+z+"off", time);
    //send to text element
    //var msg3 = {payload: "SET", topic: timerlabel, color: "green"};
    //send to schedex
    var msg2 = {payload: {offtime: "offtime " + time,
                          offpayload: poff,
                          suspended: false},
                topic: "SET",
                color:   "green"};
    return [null,msg2];
    
}

return msg;

My work on the timer has been interrupted once because of unexpected Raspberry Pi shutdown. Inspired by this failure, I have promptly added a couple of inject nodes with Started! which triggers on reboot.

To use this, make sure your context|flow|global variables are saved by NodeRED – you can learn how here.

Function Node: Apply stored values
var z = flow.get("Timer1");
var pon = flow.get("Payload"+z+"_on");
var poff = flow.get("Payload"+z+"_off");


// restore days
var mon = flow.get("Monday"+z);
var tue = flow.get("Tuesday"+z);
var wed = flow.get("Wednesday"+z);
var thu = flow.get("Thursday"+z);
var fri = flow.get("Friday"+z);
var sat = flow.get("Saturday"+z);
var sun = flow.get("Sunday"+z);

//restore timers
var timeON = flow.get("T"+z+"on");
var timeOFF = flow.get("T"+z+"off");
var timerlabel = "Timer "+ z;


msg.payload = { "ontime": "ontime " + timeON, "onpayload": pon,
                "offtime": "offtime " + timeOFF, "offpayload": poff,
                "mon": mon,
                "tue": tue,
                "wed": wed,
                "thu": thu,
                "fri": fri,
                "sat": sat,
                "sun": sun
}

    
return msg;

Now your timer can survive reboots, saving time ON|OFF and the days of the week.

Lastly, schedex node supports days of the week, so there is no reason not to drop in 7 switches and name it accordingly! Unfortunately, implementation is a bit clunky, so I don’t know an easy way of combining it in a single function node, but it’s workable:

var z = flow.get("Timer1");
 var x = msg.payload;
 flow.set("Monday"+z, x);
 msg.payload = {mon: x};
 return msg;

Settings

I promised the node to be simple to deploy and use. To use it in your NodeRED flow, deploy the subflow and edit the environmental variables. The node will create the following Flow Variables for you to use:

  • Timer[ID]_on – time on in seconds from midnight
  • Timer[ID]_off – time off in seconds from midnight
  • T[ID]on – HH:MM time on
  • T[ID]off – HH:MM time off
Timer #

You will need to provide the timer number (as int 0,1,2,3 etc keep this easy to track). Each flow can have unlimited timers, providing each comes with a unique number. Practically, the limit will come from hardware specification like heap memory available to NodeRED.

ON|OFF Payload

You can also assign a custom payload. It’s an afterthought really, as I quickly realised that you don’t have to litter your Flow with another switch node. The payload is configured as a “string“, so if you want something more specific like bool or a number, you will need to convert it yourself.

Conclusion

Free timers for everyone! This timer has been made specifically for IKEA Smart Socket write up (soon), but I will be incorporating this also into my Nest alike smart heating (check it out, it works with old thermostats!) and probably other systems that use schedules. I may consider adding reboot behaviour so you could decide how the node reacts if power is restored (sending missed schedules vs ignoring it). Let me know what would you use if for and what other functions would be useful 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 with BTC: 1FwFqqh71mUTENcRe9q4s9AWFgoc8BA9ZU

Smart Ideas with

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

client-image
client-image
client-image
client-image
client-image
client-image
client-image
client-image
client-image

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

Tuya SDK for beginners: Intro to Tuya Cloud API

0
Working with Tuya Cloud API. A guide to Cloud automation for beginners, get started with REST!

NEST your old thermostat under $5

0
Nest-ing up your older thermostat under $5

Sonoff Zigbee Bridge – review

0
Sonoff line up will soon include Sonoff Zigbee Bridge and more Zigbee sensors - here is the first look

DIY Smart Washing Machine – for about 15 bucks!

0
Learn how to add washing machine notifications to your Google Home on the cheap

Nora – Google Assistant in NodeRED

0
Integrate Google Assistant with NodeRED thanks to Nora - NodeRED home automation

Smart Home

I damaged the cheapest Smart Socket with power metering for you

0
Sonoff S60 has an exeptional price for a smart socket with a power meter - I decided to check it out and see how flashable it is

The end of Tasmota? Sonoff SwitchMan M5 Matter

0
These are one of the least expensive Matter devices to automate your lights. Will Sonoff SwitchMan M5 Matter put an end to Tasmota?

Meros TRV to the rescue?

0
I got my hands on another TRV - this time from Meross. I heard good things about the brand so I wanted to see if Meross TRV would be good to manage smart heating.

Aqara brings Thread sensors but…

0
Aqara brings new Thread sensors to their ecosystem. First sensors to support Matter this way are Aqara Motion and Light Sensor P2 and Aqara Contact Sensor P2

Multi-lights for your ceiling from Aqara

0
This is the biggest light I held in my hands so far. It's ZigBee and it comes from Aqara - meet Aqara Ceiling Light T1M