Switch Node with time

Another flow but this time using the context to store a "semaphore"

r-02

[{"id":"2da73fb3.09bad","type":"tab","label":"Flow 5","disabled":false,"info":""},{"id":"88636e86.ec34a","type":"function","z":"2da73fb3.09bad","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 - Tuesday equals 2 (Sunday is 0)\n\nlet valid =  (myWeek%2 == 1 && myDay == 2 && myHour >=10 && myHour <=19);\nif (valid) {\n    node.status({fill:\"green\",shape:\"ring\",text:\"opened\"})} else {\n    node.status({fill:\"red\",  shape:\"ring\",text:\"closed\"})\n}\nflow.set(\"gateA\", valid);\nreturn null;","outputs":1,"noerr":0,"x":290,"y":180,"wires":[[]]},{"id":"97da6559.995e08","type":"comment","z":"2da73fb3.09bad","name":"moment.js in a function","info":"","x":200,"y":100,"wires":[]},{"id":"4fc38fc5.f059f","type":"inject","z":"2da73fb3.09bad","name":"","topic":"","payload":"A","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":260,"wires":[["186c4438.ee69dc"]]},{"id":"186c4438.ee69dc","type":"switch","z":"2da73fb3.09bad","name":"","property":"gateA","propertyType":"flow","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":330,"y":280,"wires":[["aa6f8e2e.0b122"]]},{"id":"ac7b2c4e.0e0ef","type":"inject","z":"2da73fb3.09bad","name":"","topic":"","payload":"B","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":300,"wires":[["186c4438.ee69dc"]]},{"id":"aa6f8e2e.0b122","type":"debug","z":"2da73fb3.09bad","name":"","active":true,"console":false,"complete":"true","x":510,"y":280,"wires":[]},{"id":"ef0902f7.74b66","type":"inject","z":"2da73fb3.09bad","name":"Set gateA","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":140,"y":180,"wires":[["88636e86.ec34a"]]}]

The switch rule is very simple:

r-03

Andrei,

I didn't mean the post in a bad way.

But really, you could just put in the FUNCTION node and do what the SUB-FLOW did anyway.

As I said: I am not sure exactly why there is/was a sub-flow used anyway, other than to give the node a better name. But really that is not true either, as all you would do is just rename the node anyway.

Icon? Shrug. Not sure. But I was just wanting to show there are a few different ways of doing it.

As I am sure you already know. Again: Just saying. Not blaming.

LET..... That takes me back a long time to I think a very early version of BASIC, where you had to prefix variables with the LET command.

Interesting how I have never seen it mentioned here before.

I'm going to go off now and look at what the LET command does because it has sort of spiked my interest.

Hmmmmmm.... Interesting.

To me that is a bit like the Arduino code and how variables are handled there.
But that may just be me.

let (not LET) is a fairly recent addition to javascript, and earlier versions of node.js did not support it which is why it has only recently started to be used with node red. Basically it is what var should have been in the first place but initially javascript was a very simple language and I imagine the developers did not realise the extent of how it would eventually be used so thought that var would be sufficient.
I recommend using let unless you have a good reason not to.

Andrei/Colin, why is moment declared as a variable, why not use 'let', the same as myWeek, myDay, etc.

No reason that I know of, in that bit of code.

1 Like

If you are using newer versions of NodeJS, you should use const rather than let or var wherever you have something that shouldn't change. In fact, you can use const with objects and arrays and still change them, you just can't replace a const.

const x = {};

x = "Hello"; // will give an error, trying to replace the object.

x.payload = "Hello"; // will be fine, we are only adding a property to the existing object

The reason for using let is that it is locally scoped.

let x = "Hello";

if ( x === "Hello" ) {
    let x = "Boo";
    console.log( x );  // outputs "Boo"
}

console.log( x );  // outputs "Hello"

We're drifting OT here, but...
So although global.get('moment') will return changing values, const moment is always equal to global.get('moment') so it is a constant reference to a value.
So for example, it could be used when parsing an api;

const summary = (msg.data.minutely.summary);
node.send({payload:summary});

Is that correct?

Yes, because moment is actually a reference to a NodeJS module (e.g. code), it cannot change and therefore it is a constant. This is best practice because, as you can imagine, if you do accidentally change it, bad things would happen!

In your second example, the summary variable does not change within the function node. It only changes outside the node. So, as far as the function node is concerned, it is a constant.

One other small point, I much prefer to always put quotes around my object property names when creating an object so that there can be never any possiblility that it could be misinterpreted as a variable.

const summary = 25;
const urm = "payload";
node.send({urm:summary});
// Is the sent object {"urm":25} or is it {"payload":25} ?

In case, you can't work it out, the answer is:

{"urm":25}

But it is confusing.

2 Likes

Hi Paul,

My sloppiness, :innocent:

I try to educate myself by using let and const but many times end up using var instead.

I endorse / agree with Colin and JulianĀ“s remarks.

1 Like

and in case you want {"payload":25} you could use instead:

const summary = 25;
const urm = "payload";
// Is the sent object {"urm":25} or is it {"payload":25} ?
return {[urm]:summary};

Haha, even more confusing! But thanks, I didn't know that.

I've always done something like:

const summary = 25;
const urm = "payload";
const myMsg = {};
myMsg[urm] = summary;
return myMsg;

Hi
Thanks for all the input.
I also found this. It depends on an url. Of course it is always nice to have it local like in other examples, but it depends on how important it is for it to work. For more important stuff I would use moment.js.
Answer will be in Sweidhs since it is an Swedish URL. It returns Date, Weekday, if it is a Swedish holiday, week number, day of week.

[{"id":"c9e1d06c.dd771","type":"http request","z":"1c6379e4.a98eb6","name":"","method":"use","ret":"txt","url":"","tls":"","x":490,"y":3740,"wires":[["927231d9.a56e3"]]},{"id":"d21cdda2.78356","type":"inject","z":"1c6379e4.a98eb6","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":200,"y":3740,"wires":[["d305bf25.5b131"]]},{"id":"56fb0e1b.7b8e8","type":"debug","z":"1c6379e4.a98eb6","name":"","active":false,"console":"false","complete":"false","x":790,"y":3740,"wires":[]},{"id":"927231d9.a56e3","type":"json","z":"1c6379e4.a98eb6","name":"","pretty":false,"x":630,"y":3740,"wires":[["56fb0e1b.7b8e8","630c8635.bfefe8"]]},{"id":"d305bf25.5b131","type":"function","z":"1c6379e4.a98eb6","name":"","func":"var today = new Date();\nvar dd = today.getDate();\nvar mm = today.getMonth();\nvar yyyy = today.getFullYear();\nmsg.url = \"http://api.dryg.net/dagar/v2.1/\"+yyyy+\"/\"+mm+\"/\"+dd;\nmsg.method = \"GET\";\nreturn msg;\n\n//http://api.dryg.net/dagar/v2.1/2015/01/06","outputs":1,"noerr":0,"x":350,"y":3740,"wires":[["c9e1d06c.dd771"]]}]

Just one thing. It needs to be adjusted since this gives the month one month off. Since month are counted from 0 to 11. So basically mm = mm + 1;

please see How to share code or flow json