TIme remaining on Trigger node - debug or msg.property

Guys, Suggestion to add a debug for time remaining on a trigger node to allow that to be output to the debug window or as a property

So i have a trigger node that counts down for 4 hours - i have no idea when it was set though and how much time is left until it resets or does the next action - would be nice to know - either through a property that could be output on a timed basis to the Debug window - or simply as a debug output


1 Like

I am a newbie also, but I use the BigTimer node for something similar. For observing the time remaining, I use the second output of the timer and the following function to tell me how much time remains.

Hope this helps.
Steve Mann

var myTime = msg.timer;
var hours = Math.floor(myTime / 3600);
myTime = myTime - hours * 3600; //Remaining minutes
var minutes = Math.floor(myTime / 60); //Minutes
var seconds = myTime - minutes * 60; //Remaining seconds

//Format into hh:mm:ss
msg.payload = (“0” + hours).slice(-2) + “:” + (“0” + minutes).slice(-2) + “:” + (“0” + seconds).slice(-2);
return msg;

+1… I have it also solved with bigtimer and some function but will be great to have a simple dedicated node that can handle it easier

FYI, here’s a trick I have used to convert a number of seconds into a readable time string:

var sec = +msg.payload;  // assuming the payload contains seconds
var dtm = new Date(1970, 0, 1, 0, 0, sec); // add seconds to the epoch
var hms = dtm.toTimeString().substring(0, 8); // convert to time string

This seems to work in any timezone, because this new Date(yy,mm,dd,hh,mm,ss,ms) function assumes local time. (of course, you could also pass in numeric hours or minutes)

NB: this technique won’t handle more than 1 days worth of seconds, because it will roll-over to 00:00:00. For more complex time shifting/formatting, take a look at the node-red-contrib-moment nodes.

Thanks SteveMann, will incorporate this - I had forgotten about how good Peters BigTimer was.

It would still be nice to have the option with the standard trigger also


An alternative approach... assuming you want to monitor the remaining timeout in the edit page (not in the dashboard). How about branching your flow in the trigger node to include a function that will display a status decoration (https://nodered.org/docs/creating-nodes/status) ?

Testing flow:

[{"id":"ce1de646.75e118","type":"trigger","z":"f17da547.15ef68","op1":"start","op2":"stop","op1type":"str","op2type":"str","duration":"40","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":412.10008239746094,"y":249.00000381469727,"wires":[["bf803970.becfc8","a9a68a8c.e31a38"]]},{"id":"50e205c7.c5e3ec","type":"inject","z":"f17da547.15ef68","name":"","topic":"","payload":"start","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":251.10000228881836,"y":250.00000381469727,"wires":[["ce1de646.75e118"]]},{"id":"bf803970.becfc8","type":"debug","z":"f17da547.15ef68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":671.1000595092773,"y":214.00000381469727,"wires":[]},{"id":"a9a68a8c.e31a38","type":"function","z":"f17da547.15ef68","name":"Branch to display time remaining","func":"var counting = function () {\n  let counter = flow.get('counter');\n  counter += 1;\n  node.status({text:counter + \" seconds\"});\n  flow.set('counter',counter);\n   return counter;\n}\n\nif (msg.payload === \"start\") {\n    flow.set('counter',0);\n    node.status({text: \"Started..\"}); \n    let timer1 = setInterval(counting, 1000);\n    flow.set('timer1',timer1);\n} else if (msg.payload === \"stop\") {\n    node.status({}); // clear the status decoration\n    clearInterval(flow.get('timer1')); \n    \n}\n\nreturn msg;","outputs":1,"noerr":0,"x":683.1000595092773,"y":305.00000381469727,"wires":[["e66bad9a.b704a"]]},{"id":"e66bad9a.b704a","type":"debug","z":"f17da547.15ef68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":896.0000114440918,"y":304.00000381469727,"wires":[]}]

I know this is an old thread, but I just used @Andrei 's flow and it's good for showing the 'running' time of the trigger (thanks).

In my case, I have the trigger set for 2 minutes and "extend delay if new message arrives" is ticked. Evertime the PIR detects motion, the trigger starts again.

It would be good if the function would re-start counting from zero at every trigger.

Did anyone find a solution?

This is Andrei's function:

var counting = function () {
  let counter = flow.get('counter');
  counter += 1;
  node.status({text:counter + " seconds"});
   return counter;

if (msg.payload === "true") {
    node.status({text: "Started.."}); 
    let timer1 = setInterval(counting, 1000);
} else if (msg.payload === "false") {
    node.status({}); // clear the status decoration

return msg;

Hi , I will have a look tomorrow (going out now). There are a couple of things I dislike in this old flow. It would be better to refactor.

Check Peter Scargills blog - i am sure i remember that he has updated his Timeout node (or maybe his Big Timer) to support a function such as this.


1 Like

Here you go

https://tech.scargill.net/node-red-contrib-timeout/ - looks like it will do what you want ?


1 Like

HI @877,

Considering the flaws existing in the old flow my recommendation is to stop using it in favor of another solution. I modified the flow by adding an additional trigger node to function as a heartbeat and changing the code in the function node (more simple). This new flow will restart the counter each time the trigger node named monitor starts a new cycle. The trigger node does not provide any information on its output when the delay is extended. I can't, therefore, reset the counter when the delay is extended, only when a new cycle is started (when the blue icon appears).

The idea of a custom node for monitoring the timing is appealing but I was unaware of the timeout contrib node. Perhaps I will try it in the future.

[{"id":"f23c5499.aabc68","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"fe71ea4c.17d5c8","type":"trigger","z":"f23c5499.aabc68","op1":"trigger","op2":"newcycle","op1type":"str","op2type":"str","duration":"2","extend":true,"units":"min","reset":"stopcounting","bytopic":"all","name":"monitor","x":400,"y":160,"wires":[["8b20690f.508318","2d881ab3.88a7d6","61fec400.84239c","9756a5b6.a95ee8"]]},{"id":"8b20690f.508318","type":"debug","z":"f23c5499.aabc68","name":"Right Kitchen light","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":750,"y":160,"wires":[]},{"id":"152df4c1.e36c1b","type":"inject","z":"f23c5499.aabc68","name":"Data from PIR (MQTT)","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":160,"wires":[["fe71ea4c.17d5c8"]]},{"id":"61fec400.84239c","type":"function","z":"f23c5499.aabc68","name":"Display time","func":"if (msg.payload === \"count\") {\ncc = (flow.get('counter') || 0);\ncc = cc + 1;\nnode.status({text:cc + \" seconds\"});\nflow.set('counter', cc);\n} else {\n    if (msg.payload === \"newcycle\") {\n        flow.set('counter' , 0);\n        node.status({text:\"Stop\"});\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"x":690,"y":220,"wires":[[]]},{"id":"2d881ab3.88a7d6","type":"trigger","z":"f23c5499.aabc68","op1":"count","op2":"fail","op1type":"str","op2type":"str","duration":"-1","extend":true,"units":"s","reset":"newcycle","bytopic":"all","name":"heartbeat","x":460,"y":220,"wires":[["61fec400.84239c"]],"outputLabels":["send \"fail\" if not feeded"]},{"id":"9756a5b6.a95ee8","type":"debug","z":"f23c5499.aabc68","name":"Left Kitchen light","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":740,"y":120,"wires":[]}]

1 Like

... But the input does...


Thanks guys I will test it out when I get back from work :+1:

Indeed, in which case I would add an additional wire to the function node and do some processing on the data coming from the sensor. So, it is possible just requiring some additional thought.

Edit: in fact not much thought required...:smile:

[{"id":"760faf65.70c2b","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"be79017b.ada3b","type":"trigger","z":"760faf65.70c2b","op1":"trigger","op2":"newcycle","op1type":"str","op2type":"str","duration":"6","extend":true,"units":"s","reset":"stopcounting","bytopic":"all","name":"monitor","x":400,"y":140,"wires":[["cf8b1b07.16c518","5c274368.b7f35c","3681edac.7f5c72"]]},{"id":"cf8b1b07.16c518","type":"debug","z":"760faf65.70c2b","name":"Right Kitchen light","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":750,"y":140,"wires":[]},{"id":"57510a4d.ef00e4","type":"inject","z":"760faf65.70c2b","name":"Data from PIR (MQTT)","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":140,"wires":[["be79017b.ada3b","72817943.f6bb28"]]},{"id":"bf7c304f.8d5ec","type":"function","z":"760faf65.70c2b","name":"Display time","func":"if (msg.payload === \"count\") {\n   cc = (flow.get('counter') || 0);\n   cc = cc + 1;\n   node.status({text:cc + \" seconds\"});\n   flow.set('counter', cc);\n} else {\n        flow.set('counter' , 0);\n        node.status({text:\"Restarted\"});\n}\nreturn msg;","outputs":1,"noerr":0,"x":650,"y":200,"wires":[[]]},{"id":"5c274368.b7f35c","type":"trigger","z":"760faf65.70c2b","op1":"count","op2":"fail","op1type":"str","op2type":"str","duration":"-1","extend":true,"units":"s","reset":"newcycle","bytopic":"all","name":"heartbeat","x":460,"y":200,"wires":[["bf7c304f.8d5ec"]],"outputLabels":["send \"fail\" if not feeded"]},{"id":"3681edac.7f5c72","type":"debug","z":"760faf65.70c2b","name":"Left Kitchen light","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":740,"y":100,"wires":[]},{"id":"e5b4631e.403ca","type":"link in","z":"760faf65.70c2b","name":"","links":["72817943.f6bb28"],"x":535,"y":260,"wires":[["bf7c304f.8d5ec"]]},{"id":"72817943.f6bb28","type":"link out","z":"760faf65.70c2b","name":"","links":["e5b4631e.403ca"],"x":320,"y":260,"wires":[]}]
1 Like

Thank you, I actually already use the timeout node for detecting whether my devices are online, a very useful node. I use it to change the colour of the readings on the Blynk app. I will have a tinker and see how it fits this application :slight_smile:

@Andrei thanks for the flow, first impressions are that it works very well. I need to study it a little more, did you just use the link nodes to keep the flow tidy? First time I have seen them, as I am quite new :+1:

I am happy it works :smiley:
I have added the link nodes, as you well notes, to keep the flow tidy. They are very handy.

1 Like