Is there a scheduler/timer that will tell "now" what event will be "next"?

#1

Hi everyone,

I've been pulling my hair out on this one....maybe you can help me with some insights...
For my project I am looking into using a scheduler/timer for creating daily/weekly events.
But I do not want to wait until an event fires...my project needs to be more predictive/intelligent.
So what I really need is the ability to "now" fetch/query the next future event/timer that has been configured or the length of time until the next event will happen.

Example:
an event is scheduled to fire every day at 10am.
Today/now, monday at 9am, the scheduler would enable me to learn, that the next event is scheduled for today, monday at 10am (or due in 1 hour)
Today/now, monday at 3pm, the scheduler would enable me to learn, that the next event is due tomorrow, tuesday at 10am (or due in 19 hours)

I found something like that in this node: https://flows.nodered.org/node/node-red-contrib-heater-controller but it is a UI-node, which I don't need.
Also I found this: https://github.com/bunkat/later but it is no longer maintained, so I fear to rely on it in my project (will it continue to work in future node-red versions? what's the risk?).

On my standalone hardware IoT projects, I used this: https://flyingcarsandstuff.com/projects/chronos/ but it is written in C++, not javascript.

Many thanks in advance for your ideas!

regards,
hominidae

#2

I think that node-red-contrib-schedex can do what you want. It displays its next ON and OFF times in the node status, where it can be caught by a status node, and it can be interrogated using msg.payload = 'info', reporting upcoming events as msg.payload.on and msg.payload.off.

#3

I'm using Google Calendar for this type of usage - node-red-node-google can read the next event. This has the benefit that I can change the schedule easily including exceptions to recurring events. Of course it requires Internet access, which may not suit your situation.

#4

Hello @hominidae,

I've been there myself. I do understand your pain :smile:
I started some research to find a suitable library to develop a programmable timer and I think I can provide you some insights (even though the research is not ended).

Cristal clear. You have a gift to express your thoughts in an understandable way.

I could probably list 10 reasons for you to give up from Later.js but just one is enough. As you already know the library is no longer maintained for more than 2 years now. PR´s and issues (nearly 100 altogether) are pilling up and not getting resolved. It is true that the library is good on calculating occurrences and telling you which is the next one (or the next 10 if you wish) but the poor timer capabilities will limit what you can do anyway.

Is there any hope ? Definitely yes. I could name two capable libraries.

The first one is cron.js, which by the way, is already used by Node-RED for the inject node. The API provides the method nextDates() that is required by your use case. If I am not mistaken we already shared a flow in this forum that shows the usage of the library. If you can not find it I will be glad to post the example

The other one would be the libraries moment.js + plugin moment-timer.js. I did only basic testing with these libraries and found them very capable. Unfortunately, I had to stop the testing due to some other priorities. If I recall correctly the library does not have a way to inquire about the next event but I believe that this functionality can be implemented, in an elegant way, with JavaScrip ES6 iterators/ generators.

#5

@drmibell: thank you for that information. I've looked into schedex but did miss that part....this sounds very promising.

@michaelblight: Thank you for your input. You have a good point there. I live in a rural area and already learned, that internet access is not granted....been in the dark for weeks, although already running a redundant WAN setup :wink:

@Andrei: Thank you for all the info and kind words. I'll look into cron, too ...extending an existing library is beyond my JS skills atm....I am a beginner with node-red and javascript.

Thanks you all for helping.
I'd say I would start looking into schedex first, then cron if it does not work out.

regards,
hominidae

1 Like
#6

Hmm, that sounds like it would be a nice extension to node-red-contrib-moment - possibly another node. Since that package already includes moment.js

#7

Good luck, and post here if you need help or have success. As @Andrei, @TotallyInformation, and others have said, scheduling is an essential part of many applications of Node-RED, and we still don't have exactly the tool(s) we need.

#8

I wonder if that is because we all have different needs :wink:

1 Like
#9

Good point, but see this discussion. I wasn't suggesting "all things to all people," just that I haven't found a timer/scheduler with all the features I need.

3 Likes
#10

using schedex indeed works fine.
Here is a first test flow that will create an array, holding the minutes until the next scheduled events are due in ascending order:

[{"id":"11539364.f00b2d","type":"tab","label":"WW Control","disabled":false,"info":""},{"id":"4e2f82c9.62ac8c","type":"schedex","z":"11539364.f00b2d","name":"Mo-Fr am","suspended":false,"lat":"","lon":"","ontime":"05:15","ontopic":"auto","onpayload":"ON","onoffset":0,"onrandomoffset":0,"offtime":"07:00","offtopic":"auto","offpayload":"OFF","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":false,"sun":false,"x":300,"y":100,"wires":[["9ecf00b2.2c6ce"]]},{"id":"ea56c399.577b6","type":"schedex","z":"11539364.f00b2d","name":"Mo-Fr pm","suspended":false,"lat":"","lon":"","ontime":"16:00","ontopic":"auto","onpayload":"ON","onoffset":0,"onrandomoffset":0,"offtime":"20:30","offtopic":"auto","offpayload":"OFF","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":false,"sun":false,"x":300,"y":180,"wires":[["9ecf00b2.2c6ce"]]},{"id":"6223587.1ffc8a8","type":"debug","z":"11539364.f00b2d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1350,"y":520,"wires":[]},{"id":"f728513.8f5dfb","type":"inject","z":"11539364.f00b2d","name":"query","topic":"auto","payload":"info","payloadType":"str","repeat":"60","crontab":"","once":true,"onceDelay":"60","x":90,"y":220,"wires":[["4e2f82c9.62ac8c","ea56c399.577b6","abb14b6a.52b4a8","e6626e84.453cc"]]},{"id":"c3439273.20413","type":"moment","z":"11539364.f00b2d","name":"","topic":"next","input":"payload","inputType":"msg","inTz":"Europe/Berlin","adjAmount":0,"adjType":"days","adjDir":"add","format":"x","locale":"POSIX","output":"payload","outputType":"msg","outTz":"Europe/Berlin","x":870,"y":180,"wires":[["da3d1ecc.4c09f"]]},{"id":"8c2a2b0b.fddc58","type":"switch","z":"11539364.f00b2d","name":"ON Events ","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"}],"checkall":"false","repair":false,"outputs":1,"x":710,"y":180,"wires":[["c3439273.20413"]]},{"id":"9ecf00b2.2c6ce","type":"split","z":"11539364.f00b2d","name":"split Objects","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"topic","x":530,"y":180,"wires":[["8c2a2b0b.fddc58"]]},{"id":"da3d1ecc.4c09f","type":"function","z":"11539364.f00b2d","name":"Minutes-til-next-Event","func":"var Next = msg.payload;\nvar Now = Date.now();\n// msg.topic = \"next\";\nmsg.payload = Math.floor((Next - Now)/1000/60);\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":280,"wires":[["e59df72d.03f858"]]},{"id":"e59df72d.03f858","type":"batch","z":"11539364.f00b2d","name":"Collect Next Events","mode":"interval","count":10,"overlap":0,"interval":"15","allowEmptySequence":false,"topics":[],"x":1090,"y":280,"wires":[["7da40a09.795fd4"]]},{"id":"7da40a09.795fd4","type":"sort","z":"11539364.f00b2d","name":"Sort Next Events","order":"ascending","as_num":true,"target":"","targetType":"seq","msgKey":"","msgKeyType":"elem","seqKey":"payload","seqKeyType":"msg","x":1090,"y":400,"wires":[["cf6b318e.51dc2"]]},{"id":"cf6b318e.51dc2","type":"join","z":"11539364.f00b2d","name":"Array of Next Events","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":1100,"y":520,"wires":[["6223587.1ffc8a8"]]},{"id":"abb14b6a.52b4a8","type":"schedex","z":"11539364.f00b2d","name":"Sa-So am","suspended":false,"lat":"","lon":"","ontime":"07:30","ontopic":"auto","onpayload":"ON","onoffset":0,"onrandomoffset":0,"offtime":"10:00","offtopic":"auto","offpayload":"OFF","offoffset":0,"offrandomoffset":0,"mon":false,"tue":false,"wed":false,"thu":false,"fri":false,"sat":true,"sun":true,"x":300,"y":260,"wires":[["9ecf00b2.2c6ce"]]},{"id":"e6626e84.453cc","type":"schedex","z":"11539364.f00b2d","name":"Sa-So pm","suspended":false,"lat":"","lon":"","ontime":"18:00","ontopic":"auto","onpayload":"ON","onoffset":0,"onrandomoffset":0,"offtime":"21:00","offtopic":"auto","offpayload":"OFF","offoffset":0,"offrandomoffset":0,"mon":false,"tue":false,"wed":false,"thu":false,"fri":false,"sat":true,"sun":true,"x":300,"y":320,"wires":[["9ecf00b2.2c6ce"]]}]

thanks again for your help!

1 Like
#11

No problem. Glad I could help.