Info about Eztimer

I've a simple flow where I'm using Eztimer (
It basically provides an on/off message every day of the week. The 'on' msg.payload at 07.30am and the 'off' message at 07.32am.
It can happen that for some reasons I've to temporarily suspend the 'on' payload only for a certain day and then reactivate it as per the original schedule on the next day. I've seen in the documentation that there're some options to send 'cancel' or 'on' and 'off' to the input of the Eztimer node but although I made some test, I'm still unable to get the correct result.

Can someone help me to solve this problem?

1 Like

My take on the docs:

You send an on and it turns on.
off turns it off.

But cancel only works if then on has been sent and you want to cancel that output.
From the docs:

Cancels the current run (if any) of the timer ( without emitting an off event).

Which means an on has been sent and you want it to go off before the real time.

How about you post the flow (code) and people can look at it better?

I'm still not understanding how cancel works. I'd prevent to send the 'on' at all. I mean supposing tomorrow morning I don't want Eztimer to send the 'on' event at 07.30, I'd send it a message for example at 07.28 in order to avoid it will send that 'on' event. But the day after it should again trigger the scheduled on and off normally.

This is my simple flow:

[{"id":"549011fe.913e","type":"eztimer","z":"b0466595.da9a28","name":"Abbassa tapparella salone","debug":false,"autoname":"07:30:00 - 07:32:00","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"lat":"45.06562","lon":"7.6266","timerType":"1","startupMessage":true,"ontype":"2","ontimesun":"dawn","ontimetod":"07:30:00","onpropertytype":"msg","onproperty":"payload","onvaluetype":"str","onvalue":"ON","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"07:32:00","offduration":"00:01:00","offpropertytype":"msg","offproperty":"payload","offvaluetype":"str","offvalue":"OFF","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":500,"y":200,"wires":[["be374167.10607"]],"info":"Abbassa Tapparella"}]

Yeah, interesting.

Reading the docs again I find this bit ....... interesting:

Cancels the current run (if any) of the timer ( without emitting an off event).

Particularly the (without emitting an off event).

If it is cancelling the current run and it is not emitting an off event..... what exactly is it doing?

Maybe go to the github page and ask the person who wrote the node.

So back to your question about how to "disable" the output for one day.

As I read it you want to skip the next ON event, then go back to normal.

If so, here is a small bit of code/flow that does what you want.

[{"id":"152fbddb.4484da","type":"eztimer","z":"b9924a74.4d98f8","name":"Abbassa tapparella salone","debug":false,"autoname":"07:30:00 - 07:32:00","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"lat":"45.06562","lon":"7.6266","timerType":"1","startupMessage":true,"ontype":"2","ontimesun":"dawn","ontimetod":"07:30:00","onpropertytype":"msg","onproperty":"payload","onvaluetype":"str","onvalue":"ON","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"07:32:00","offduration":"00:01:00","offpropertytype":"msg","offproperty":"payload","offvaluetype":"str","offvalue":"OFF","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":210,"y":2110,"wires":[["e09d7c3b.d296c"]],"info":"Abbassa Tapparella"},{"id":"e09d7c3b.d296c","type":"function","z":"b9924a74.4d98f8","name":"Skip","func":"let s = context.get(\"Skip\") || 0;\nif (msg.payload == \"Skip one\")\n{\n    context.set(\"SKIP\",1);\n    return;\n}\nif (msg.payload == \"ON\")\n{\n    if (s == 1)\n    {\n        context.set(\"SKIP\",0);\n        return;\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"x":430,"y":2110,"wires":[["4d784638.133888"]]},{"id":"f1abf273.25a62","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"Skip one","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":1990,"wires":[["e09d7c3b.d296c"]]},{"id":"4d784638.133888","type":"debug","z":"b9924a74.4d98f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":600,"y":2110,"wires":[]}]

The inject node can be what ever you want. So long as it sends "Skip one" as the payload.
If you understand that easily, you can change it to what ever you want - so long as it isn't ON or OFF, of course.

The debug is there only to show you what is/not happening at the next node.

If you want help with what the function node is doing ask and I will try to explain.

Instead of Easy timer - use Neil Cherry @ncherry Schedex - ```

It will allow you to suspend from the commandline and then re-enable (again from the commandline)

Maybe stack two of them

First one runs at (say) midnight each day and sends an enable to the 2nd one - the 2nd one is where your work is done - this runs the schedule you want to use. In the event you want to suspend the schedule inject into the 2nd node the suspend (from an inject node or a dashboard icon etc)

That night the first node will run again and send the enable schedule to re-enable the schedule that you paused.

I also think i remember something about Peter Scargills BigTimer node having this capability natively - but that was a long time ago and is quite a complex node - so i may be wrong on that


@Trying_to_learn I tried to use your skip function but it seems do not behaves as expected. These are the steps I followed:

  • Set on and off time
  • Deploy the flow
  • Inject the 'Skip One'

It anyway schedule the ON event. See the picture attached

An here the flow:

[{"id":"22f7eb35.b4b6e4","type":"eztimer","z":"b0466595.da9a28","name":"Abbassa tapparella salone","debug":false,"autoname":"20:04:30 - 20:05:00","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"lat":"45.06562","lon":"7.6266","timerType":"1","startupMessage":true,"ontype":"2","ontimesun":"dawn","ontimetod":"20:04:30","onpropertytype":"msg","onproperty":"payload","onvaluetype":"str","onvalue":"ON","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"20:05:00","offduration":"00:01:00","offpropertytype":"msg","offproperty":"payload","offvaluetype":"str","offvalue":"OFF","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":540,"y":500,"wires":[["d85a32ac.4204d"]],"info":"Abbassa Tapparella"}]

Alternatively, use node-red-contrib-cron-plus, which allows you to pause specific schedules and start them again later. Can be done thorough command messages going into the node. There's example flows included with the node explaining this kind of setup.

Thanks I'll give it a look tomorrow

Hi Craig,
how to inject 'suspend' message to schedex? It seems it only accept the following as Inputs (ON, OFF, Toggle, Info, Info_local, send_state). Am I wrong?


Looking, at the output it seems correct.

Let's look at what you want/asked for and what I did:

You wanted to skip an event happening. I took that is not accepting an ON signal for one time.

So: all things being normal, you would see:
ON at the desired on time. and
OFF at the desired off time.

That is what I am seeing in the right of the screen. Given you ran it twice.
The first ON was blocked.

So you have multiple events on a day and want to suspend ALL those events? Ah!
I took it as only one event.
That may be where the problem lies.

If you want that, you are a few steps ahead of your skills I feel.
And for me to show you how to do that - with my limited knowledge - will not really help either of us. Sorry.

That is a bit tricky.

It isn't you send a msg.payload which is suspend.

You have to send:
msg.suspend and have it set to true

Node example:


I believe the latest version of Node-Red you can do this in the inject node.
I don't have the latest version so can't show you how to do that.

Unfortunatelly it doesn't skip the ON event (see the picture). Can you please make a test and send your screenshot? and flow...

No, you understood correctly at the beginning, I'd suspend only one event not the entire weekly schedulling. In fact I think your approach is correct but maybe it requires some refinements of the function. Or maybe we're still not on the same page :slight_smile:

[{"id":"b0466595.da9a28","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"22f7eb35.b4b6e4","type":"eztimer","z":"b0466595.da9a28","name":"Abbassa tapparella salone","debug":false,"autoname":"23:32:00 - 23:33:00","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"lat":"45.06562","lon":"7.6266","timerType":"1","startupMessage":true,"ontype":"2","ontimesun":"dawn","ontimetod":"23:32:00","onpropertytype":"msg","onproperty":"payload","onvaluetype":"str","onvalue":"ON","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"23:33:00","offduration":"00:01:00","offpropertytype":"msg","offproperty":"payload","offvaluetype":"str","offvalue":"OFF","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":540,"y":500,"wires":[["d85a32ac.4204d"]],"info":"Abbassa Tapparella"},{"id":"d85a32ac.4204d","type":"function","z":"b0466595.da9a28","name":"Skip","func":"let s = context.get(\"Skip\") || 0;\nif (msg.payload == \"Skip one\")\n{\n    context.set(\"SKIP\",1);\n    return;\n}\nif (msg.payload == \"ON\")\n{\n    if (s == 1)\n    {\n        context.set(\"SKIP\",0);\n        return;\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"x":760,"y":500,"wires":[["796828f3.7d1418"]]},{"id":"d8492445.f0b848","type":"inject","z":"b0466595.da9a28","name":"","topic":"","payload":"Skip one","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":600,"y":380,"wires":[["d85a32ac.4204d"]]},{"id":"796828f3.7d1418","type":"debug","z":"b0466595.da9a28","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":970,"y":500,"wires":[]},{"id":"b9fdde31.6e20f","type":"change","z":"b0466595.da9a28","name":"Suspend","rules":[{"t":"set","p":"suspend","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":660,"wires":[[]]}]

Yeah, sorry. I can't say what happened.

Here is a working one.

With TEST buttons to help make it easier to test if it is (or not) blocking.

[{"id":"e09d7c3b.d296c","type":"function","z":"b9924a74.4d98f8","name":"Skip","func":"let s = context.get(\"SKIP\") || 0;\nif (msg.payload == \"Skip one\")\n{\n    context.set(\"SKIP\",1);\n    node.status({fill: \"red\",text:\"BLOCK\"});\n    return;\n}\nif (msg.payload == \"ON\")\n{\n    if (s == 1)\n    {\n        node.status({});\n        context.set(\"SKIP\",0);\n        return;\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"x":430,"y":2110,"wires":[["4d784638.133888"]]},{"id":"152fbddb.4484da","type":"eztimer","z":"b9924a74.4d98f8","name":"Abbassa tapparella salone","debug":false,"autoname":"07:41:00 - 07:42:00","tag":"eztimer","suspended":false,"sendEventsOnSuspend":false,"lat":"45.06562","lon":"7.6266","timerType":"1","startupMessage":true,"ontype":"2","ontimesun":"dawn","ontimetod":"07:41:00","onpropertytype":"msg","onproperty":"payload","onvaluetype":"str","onvalue":"ON","onoffset":0,"onrandomoffset":0,"onsuppressrepeats":false,"offtype":"2","offtimesun":"dusk","offtimetod":"07:42:00","offduration":"00:01:00","offpropertytype":"msg","offproperty":"payload","offvaluetype":"str","offvalue":"OFF","offoffset":0,"offrandomoffset":0,"offsuppressrepeats":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":170,"y":2110,"wires":[["e09d7c3b.d296c"]],"info":"Abbassa Tapparella"},{"id":"f1abf273.25a62","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"Skip one","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":2020,"wires":[["e09d7c3b.d296c"]]},{"id":"4d784638.133888","type":"debug","z":"b9924a74.4d98f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":600,"y":2110,"wires":[]},{"id":"4b1c827a.6cf4ac","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":2170,"wires":[["e09d7c3b.d296c"]]},{"id":"e3e319e6.394528","type":"inject","z":"b9924a74.4d98f8","name":"","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":2210,"wires":[["e09d7c3b.d296c"]]}]

The problem was the function node and I messed up with the SKIP name.
In one line it was SKIP and in another it wasn't. That's a no-no! (Causes problems)

This one is tested.

It is also a bit more informative to you. When you press the Skip button the function node tells you it is blocking.
After the node has blocked, it wipes the message and all things are normal.

1 Like

Or try this one

[{"id":"9cebcacf.f2a138","type":"schedex","z":"6b000f73.b47a6","name":"The Actual Worker","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"07:30","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"7:50","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":930,"y":300,"wires":[[]]},{"id":"a4dbd03.4c2a03","type":"schedex","z":"6b000f73.b47a6","name":"The Controller","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"11:59","ontopic":"","onpayload":"suspended false","onoffset":0,"onrandomoffset":0,"offtime":"12:00","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":720,"y":200,"wires":[["36e28e66.06fce2","9cebcacf.f2a138"]]},{"id":"36e28e66.06fce2","type":"debug","z":"6b000f73.b47a6","name":"Test ","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":950,"y":200,"wires":[]},{"id":"2091b0d9.db256","type":"inject","z":"6b000f73.b47a6","name":"Suspend next schedule","topic":"","payload":"suspended true","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":760,"y":440,"wires":[["9cebcacf.f2a138","36e28e66.06fce2"]]}]


1 Like

Great. It works as expected. Now I've seen at the bottom of the schedex documentation the payload you're using to suspend and resume throughsuspend true and suspend false.

Very goog job!!! Also your way works as expected now!!! Thank you a lot for your effort. You also gave me the right directions to learn how to use functions. If you've some time could you please explain me a little bit more about what and how you defined the function?

Again thanks a lot!

Ok, lets look at the code in the skip node:

let s = context.get("SKIP") || 0;
if (msg.payload == "Skip one")
    node.status({fill: "red",text:"BLOCK"});
if (msg.payload == "ON")
    if (s == 1)
return msg;

Line 1:
This gets the context variable called "SKIP". If it isn't set it is given the value 0 (Number) This is stored in variable s
Line 2:
If the incoming message has a payload of (equal to) "Skip one"
Line 3:
Line 4:
Set "SKIP" to 1
Line 5:
Set the node.status up to indicate it is blocking.
Line 6:
return. As there is nothing there it basically exits this whole bit of code.
Line 7:
end the then from line 3

That is used to configure the node and sets a context variable to 1 (number)
Now the part that is the filter part.

Line 8:
If the incoming message has a payload of "ON"
Line 9:
Line 10:
If variable s (from line 1) is 1
Line 11:
Line 12:
Wipe the node.status
Line 13:
Set the context variable SKIP to 0
Line 14:
Line line 6, return. Again, just exit from this code.
Line 15:
End then2
Line 16
End then
return the message as received.

That means that all messages are sent.
So any OFF message would never even be looked at.
Any ON message would depend is s is set to 1 or not.
If s is/was 1 the code would just exit.
If that fails (isn't true) it gets to the last line and is returned in its original state.

Hope that helps.

1 Like

Happy to help

Good luck with it


This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.