Switch Node with time

Hi
I am looking for a node that can pass or block depending on the day of week and between two times and if the week is odd or even.
A switch Node would work if it had selections for odd or even week numbers and select a time frame for example from 11Am to 1Pm.

You can always use a function node

Another alternative, instead of a function node, could be using one of the many time switches nodes available along with a gate node (that at the end of the day is just a function node). I like most the switch time node-red-contrib-timerswitch as it is easy to understand and use.

You can implement this functionality on an output port basis (a separate control for each output).

I wired together those node without an extensive testing (have to leave now). Let me know if it works.

[{"id":"cec65c7f.ec93","type":"subflow","name":"Gate Flow","info":"","in":[{"x":347,"y":297,"wires":[{"id":"53532d8.60aa2d4"}]}],"out":[{"x":605.0000019073486,"y":292,"wires":[{"id":"53532d8.60aa2d4","port":0}]}]},{"id":"53532d8.60aa2d4","type":"function","z":"cec65c7f.ec93","name":"control","func":"if (msg.topic === \"gate\") {\n    gateControl = (msg.payload === \"true\") ? true : false;\n    context.set(\"pass\", gateControl);\n    return null;  // exit out early as it's just the control\n}\nif (context.get(\"pass\")) {\n    return msg; // if enabled pass msg\n}\nreturn null; // or drop it","outputs":1,"noerr":0,"x":480,"y":298,"wires":[[]]},{"id":"ea013306.19c1f","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"64bef377.50969c","type":"comment","z":"ea013306.19c1f","name":"","info":"","x":120,"y":60,"wires":[]},{"id":"9c886940.f48148","type":"inject","z":"ea013306.19c1f","name":"","topic":"","payload":"A","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":220,"wires":[["6dcd441b.fb6c9c"]]},{"id":"6dcd441b.fb6c9c","type":"switch","z":"ea013306.19c1f","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"},{"t":"eq","v":"B","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":350,"y":240,"wires":[["f57a26e5.9f0408"],["a0a6d69e.6e8048"]]},{"id":"86de4763.d52718","type":"inject","z":"ea013306.19c1f","name":"","topic":"","payload":"B","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":260,"wires":[["6dcd441b.fb6c9c"]]},{"id":"4d896ce3.c7d654","type":"timerswitch","z":"ea013306.19c1f","name":"","ontopic":"gate","offtopic":"gate","onpayload":"true","offpayload":"false","disabled":false,"schedules":[{"on_h":"11","on_m":"00","on_s":"00","off_h":"12","off_m":"10","off_s":"00","valid":true}],"x":550,"y":160,"wires":[["f57a26e5.9f0408"]]},{"id":"9cf5afe7.227fa","type":"debug","z":"ea013306.19c1f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":710,"y":220,"wires":[]},{"id":"f57a26e5.9f0408","type":"subflow:cec65c7f.ec93","z":"ea013306.19c1f","name":"","x":550,"y":220,"wires":[["9cf5afe7.227fa"]]},{"id":"93aa887a.6051a8","type":"timerswitch","z":"ea013306.19c1f","name":"","ontopic":"gate","offtopic":"gate","onpayload":"true","offpayload":"false","disabled":false,"schedules":[{"on_h":"11","on_m":"00","on_s":"00","off_h":"12","off_m":"10","off_s":"00","valid":true}],"x":570,"y":280,"wires":[["a0a6d69e.6e8048"]]},{"id":"8993d056.940ab","type":"debug","z":"ea013306.19c1f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":730,"y":340,"wires":[]},{"id":"a0a6d69e.6e8048","type":"subflow:cec65c7f.ec93","z":"ea013306.19c1f","name":"","x":570,"y":340,"wires":[["8993d056.940ab"]]}]

This solves it partly at least. I am still searching on how to get every second Wednesday. So if it is like Wednesday every odd week then the node should pass.
Maybe need a function node here instead. Just thought it would be a neat feature on the switch node.

Indeed, I overlooked the requirement for day of week. Surely there are others timer switches available. All that is needed for the gate subflow is to receive a control message with topic = "gate" and payload = "true" or "false". I have to agree that having such functionality embedded in the switch node seems to be very appealing but it will probably overload the switch node with a functionality that is not its core. Anyway, very interesting suggestion.

There are several schedulers that might fit the bill

https://flows.nodered.org/?term=schedule&num_pages=1

Also the later node allows really complex schedules to be defined, uses later.js

Have to check them out. But a timer node is not exactly what I want (I think) since I do not want a timer node to trigger at a certain time. The trigger comes from alarm and it should be passed on if time is the time I have chosen. Also have to handle each other week (every two weeks).
I have looked at Big timer but I do not think that can be triggered by input (my alarm) and only has odd and even days and not weeks.

Hint :slight_smile: 2 weeks = 1 209 600 000 milliseconds

2 Likes

Except, for many, twice a year with an additional couple every four years.

You have to use the signal from the timer node as the control input to a gate that allows your alarm message to pass or not.

No. Turning the clock to does not change the amount of measured time units passed by. Time goes in one direction with constant speed. We just call this kind of amount of time "two weeks".

2 Likes

That depends on your use case.
The use case here is that the OP wants something to happen at the same time of day every two weeks. Normally that would imply local time, in which case the events are not always the same number of seconds apart, though they are two weeks apart.

Just to clarify. I do not want something to happen exactly the same time every two weeks. I want it to happen when my alarm sends an on signal and it is wednesday (odd week for example) and time between 10am and 1pm. So the time between the two events is not always exactly two weeks (that would have been easy) since it is the alarm on that triggers the event and that can happen between 11am and 1pm that particular day. Of course can happen many more times that day but that is not relevant for what I want to do.

Just seems like a waste of resources to have a timer counting when I could have my trigger that comes a couple of times a day and then just check if it is Wednesday odd week and time between 11am and 1pm.

Well you can write a function node to do that and pass the message on or not as appropriate. Google for javascript Date to see how to get the current time and from that the day of week, week number etc.

@Gnindit, as Colin mentioned above one of the things you will need to code your function is the week number. It is not quite trivial to do the calculation from scratch so I would recommend to rely on an existing javascript library called moment.js.

You can install it very easily after reading the paragraph " Loading additional modules " from the following link: Redirecting…

You will need to modify your seetings.js file by adding the moment statement like below:

    functionGlobalContext: {
        //uuid: "3d0ca315-aff9–4fc2-be61–3b76b9a2d798",
        jsonata:require('jsonata'),
        moment:require('moment'),
        uuidv:require('C:/Users/OCM/node_modules/uuid/v1')
        // os:require('os'),
        // octalbonescript:require('octalbonescript'),
        // jfive:require("johnny-five"),
        // j5board:require("johnny-five").Board({repl:false})
    },

and then your function node will be capable of using the hundreds of moment functions :

var moment = global.get('moment'); 
msg.payload = moment().week();
return msg;

Delivering in the output the current week number in the year (which is 43 at the time of this writing):

r-01

Or you can use the moment node to insert the week number to your msg before processing.

1 Like

How about this flow for simplicity rather than than using the "sub flow" as in one of the examples:

[{"id":"4578d4b3.eef034","type":"inject","z":"c7041248.e87fd","name":"","topic":"","payload":"A","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":930,"wires":[["e19243f6.6ecdc8"]]},{"id":"e19243f6.6ecdc8","type":"switch","z":"c7041248.e87fd","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"},{"t":"eq","v":"B","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":320,"y":950,"wires":[["fe83631c.e36f"],["cbbf854b.21011"]]},{"id":"832c9600.4153f","type":"inject","z":"c7041248.e87fd","name":"","topic":"","payload":"B","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":970,"wires":[["e19243f6.6ecdc8"]]},{"id":"a0702699.d494d","type":"debug","z":"c7041248.e87fd","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":680,"y":930,"wires":[]},{"id":"28220d98.1d9372","type":"debug","z":"c7041248.e87fd","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":700,"y":1050,"wires":[]},{"id":"996d023d.f7cc3","type":"timerswitch","z":"c7041248.e87fd","name":"","ontopic":"gate","offtopic":"gate","onpayload":"true","offpayload":"false","disabled":false,"schedules":[{"on_h":"20","on_m":"57","on_s":"00","off_h":"20","off_m":"59","off_s":"00","valid":true}],"x":530,"y":870,"wires":[["fe83631c.e36f"]]},{"id":"bcb6efcd.e31bb8","type":"timerswitch","z":"c7041248.e87fd","name":"","ontopic":"gate","offtopic":"gate","onpayload":"true","offpayload":"false","disabled":false,"schedules":[{"on_h":"11","on_m":"00","on_s":"00","off_h":"12","off_m":"10","off_s":"00","valid":true}],"x":540,"y":990,"wires":[["cbbf854b.21011"]]},{"id":"fe83631c.e36f","type":"traffic","z":"c7041248.e87fd","name":"","property_allow":"payload","filter_allow":"true","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"false","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":530,"y":930,"wires":[["a0702699.d494d"]]},{"id":"cbbf854b.21011","type":"traffic","z":"c7041248.e87fd","name":"","property_allow":"payload","filter_allow":"true","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"false","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":540,"y":1050,"wires":[["28220d98.1d9372"]]}]

This uses the TRAFFIC node (which ok, isn't standard) but does the same.

Though if you really wanted to get "smart" you could just use the function node as used in the sub-flow to do the same.

I'm not exactly sure why it was done like that.
(No offence Andrei.)

Right, it can be as simple as you mentioned. The function code would looks like:

var moment = global.get('moment'); 
let myWeek = moment().week();
let myDay  = moment().day();
let myHour = moment().hour();

// Check requirements
// myWeek%2 - check even or odd week
// myDay - Wednesday equals 3 (Sunday is 0)

let valid =  (myWeek%2 == 1 && myDay == 3 && myHour >=11 && myHour <=15);

if (valid) return msg;
return null;

Flow:

[{"id":"b8573bf.9cd2cc8","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"42ffde27.a3abc","type":"function","z":"b8573bf.9cd2cc8","name":"gate","func":"var moment = global.get('moment'); \nlet myWeek = moment().week();\nlet myDay  = moment().day();\nlet myHour = moment().hour();\n\n// Check requirements\n// myWeek%2 - check even or odd week\n// myDay - Wednesday equals 3 (Sunday is 0)\n\nlet valid =  (myWeek%2 == 1 && myDay == 3 && myHour >=11 && myHour <=15);\n\nif (valid) return msg;\nreturn null;\n","outputs":1,"noerr":0,"x":450,"y":180,"wires":[["5d64856f.68588c"]]},{"id":"5d64856f.68588c","type":"debug","z":"b8573bf.9cd2cc8","name":"","active":true,"console":false,"complete":"true","x":570,"y":180,"wires":[]},{"id":"348e315.1f5d4ce","type":"comment","z":"b8573bf.9cd2cc8","name":"moment.js in a function","info":"","x":160,"y":80,"wires":[]},{"id":"21a48172.19269e","type":"inject","z":"b8573bf.9cd2cc8","name":"","topic":"","payload":"A","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":180,"wires":[["3adf2e54.a2b1a2"]]},{"id":"3adf2e54.a2b1a2","type":"switch","z":"b8573bf.9cd2cc8","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"},{"t":"eq","v":"B","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":310,"y":200,"wires":[["42ffde27.a3abc"],["fdc1ae41.3caa"]]},{"id":"bcac78da.5fb018","type":"inject","z":"b8573bf.9cd2cc8","name":"","topic":"","payload":"B","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":220,"wires":[["3adf2e54.a2b1a2"]]},{"id":"fdc1ae41.3caa","type":"function","z":"b8573bf.9cd2cc8","name":"gate","func":"var moment = global.get('moment'); \nlet myWeek = moment().week();\nlet myDay  = moment().day();\nlet myHour = moment().hour();\n\n// Check requirements\n// myWeek%2 - check even or odd week\n// myDay - Wednesday equals 3 (Sunday is 0)\n\nlet valid =  (myWeek%2 == 1 && myDay == 3 && myHour >=11 && myHour <=15);\n\nif (valid) return msg;\nreturn null;\n//return {\"week\": myWeek, \"day\" : myDay, \"hour\":myHour, \"valid\" : valid};","outputs":1,"noerr":0,"x":450,"y":220,"wires":[["23589fc3.9bb58"]]},{"id":"23589fc3.9bb58","type":"debug","z":"b8573bf.9cd2cc8","name":"","active":true,"console":false,"complete":"true","x":570,"y":220,"wires":[]}]

Thanks, I would need to install the traffic node to test this flow.