Function node conditional statement output to JSON

#1

Hello everyone. I'm completely new to javascript and node red and have been trying to learn. Appologies if this has been answered in this already but i havent been able to figure it out (I found some leads but nothing with an output built over a conditional statement).

I'm building garage door controller where the door automatically closes after x minutes left open.
However, I would like to add a feature where the user can either extend the timeout before to auto close the door, or simply "pause" indefinetly the countdown.
the timer I'm using is the node-red-contrib-mytimeout. One of the inputs it accepts is a JSON packet in this format :

{
"payload": "on",
"timeout": 600,
"warning": 30
}

I would like to replace the on, 600, and 30 values with flow values set by the user through a function node. (I have verified that all the flow values are effectively going through as set by the user).
my script looks like this:

var y = flow.get('payload'); //get the payload ( i.e. keep open or close instruction : "cancel" or "closenow")

var x = flow.get('timeout'); //get the override countdown timeout value. range from 0 to 180 minutes converted to seconds

var w = flow.get('override'); //asses whether the countdown timer is suppose to run but with an extended countdown value "override" of "dissable"

if (y == "cancel") msg.payload = {"payload" : y, "timeout" : x, "warning" : 0}
else if (y == "override") msg.payload = {"payload" : "on", "timeout" : z, "warning" : 0}
else msg.payload = {"payload" : "on", "timeout" : 0, "warning" : 0}; //sets the right payloads for either pause autoclose, extend countdown, or close now commands

//{"payload": "on","timeout": 600,"warning": 30} example of the packet expected

return msg;

Any idea would be very welcome! :wink:

0 Likes

#2

can we see this is context ? what is triggering this function ?

0 Likes

#3

Hi dceejay,
here are some screenshots of the flow and code (in current state) to explain this better and I'll post the UI interface in the next post.

Please let me know if you need me to upload any other info.
Thanks!

0 Likes

#4

Since posting this morning, I've modified the code a little bit. Below is a summary of each case, with the current state of the UI and the debug node output, as well as the modified function code.



The only time I seem to get a payload that is usable by the timer is when line 11 is true, the rest of the time the output of the function defaults to line 14. I'm not sure whether it's a syntax issue or if i'm not thinking the right way...

0 Likes

#5

We can not assess the values of variables y and w so it is not possible to know why the conditional statement is not working as you expect. If you share the flow it will be easier to troubleshoot your flow.

If I understood correctly you want to select among three different objects based on the status of two variables. If this is correct then the conditional statement could be as simple as:

let select = pause ? 0 : enable ? 1 : 2;

The main function would in such case looks like:

let obj = [
    {"payload" : "a", "timeout" : "b", "warning" : "c"},
    {"payload" : "d", "timeout" : "e", "warning" : "f"},
    {"payload" : "g", "timeout" : "h", "warning" : "i"}
    ]


let enable = flow.get("enable");
let pause  = flow.get("pause");

// obj[0] => pause=true
// obj[1] => pause=false , enable=true
// obj[2] => pause=false , enable=false

let select = pause ? 0 : enable ? 1 : 2;

// show status
node.status({text:`pause=${pause} ,  enable=${enable}`});

msg.payload = obj[select];

return msg;

and the flow would be like (need however some additional nodes for the initialization)

[{"id":"2e301f7e.715e6","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"d00582c1.eec9b","type":"ui_switch","z":"2e301f7e.715e6","name":"Enable Timeout","label":"Enable Timeout","tooltip":"","group":"7fae6457.6b198c","order":2,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":260,"y":80,"wires":[["48f39e0d.4fc42"]]},{"id":"a04ab26a.bd971","type":"ui_switch","z":"2e301f7e.715e6","name":"Pause countdown","label":"Pause countdown","tooltip":"","group":"7fae6457.6b198c","order":3,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":270,"y":180,"wires":[["d14a3ab4.3cac08"]]},{"id":"46eae271.15603c","type":"ui_slider","z":"2e301f7e.715e6","name":"Timeout","label":"Timeout","tooltip":"","group":"7fae6457.6b198c","order":2,"width":0,"height":0,"passthru":true,"outs":"all","topic":"","min":0,"max":10,"step":1,"x":240,"y":260,"wires":[["53ea1b5b.a10704"]]},{"id":"48f39e0d.4fc42","type":"change","z":"2e301f7e.715e6","name":"Enable","rules":[{"t":"set","p":"enable","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":80,"wires":[["aee265d0.cd2c88"]]},{"id":"d14a3ab4.3cac08","type":"change","z":"2e301f7e.715e6","name":"Pause","rules":[{"t":"set","p":"pause","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":180,"wires":[["aee265d0.cd2c88"]]},{"id":"53ea1b5b.a10704","type":"change","z":"2e301f7e.715e6","name":"Timeout","rules":[{"t":"set","p":"timeout","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":260,"wires":[["aee265d0.cd2c88"]]},{"id":"a2967531.5d67a8","type":"comment","z":"2e301f7e.715e6","name":"obj[0] => pause=true ,  obj[1] => pause=false , enable=true ,  obj[2] => pause=false , enable=false","info":"","x":390,"y":460,"wires":[]},{"id":"bec74d96.58821","type":"comment","z":"2e301f7e.715e6","name":"obj[0] = {\"payload\" : \"a\", \"timeout\" : \"b\", \"warning\" : \"c\"}","info":"","x":520,"y":500,"wires":[]},{"id":"ef8b295d.ff0aa8","type":"comment","z":"2e301f7e.715e6","name":"obj[1] = {\"payload\" : \"d\", \"timeout\" : \"e\", \"warning\" : \"f\"}","info":"","x":520,"y":540,"wires":[]},{"id":"d69e98e4.f1d158","type":"comment","z":"2e301f7e.715e6","name":"obj[2] = {\"payload\" : \"g\", \"timeout\" : \"h\", \"warning\" : \"i\"}","info":"","x":520,"y":580,"wires":[]},{"id":"18310a37.45dab6","type":"function","z":"2e301f7e.715e6","name":"Select Object","func":"let obj = [\n    {\"payload\" : \"a\", \"timeout\" : \"b\", \"warning\" : \"c\"},\n    {\"payload\" : \"d\", \"timeout\" : \"e\", \"warning\" : \"f\"},\n    {\"payload\" : \"g\", \"timeout\" : \"h\", \"warning\" : \"i\"}\n    ]\n\n\nlet enable = flow.get(\"enable\");\nlet pause  = flow.get(\"pause\");\n\n// obj[0] => pause=true\n// obj[1] => pause=false , enable=true\n// obj[2] => pause=false , enable=false\n\nlet select = pause ? 0 : enable ? 1 : 2;\n\n// show status\nnode.status({text:`pause=${pause} ,  enable=${enable}`});\n\nmsg.payload = obj[select];\n\nreturn msg;","outputs":1,"noerr":0,"x":510,"y":360,"wires":[["2c537433.6c97cc"]]},{"id":"2c537433.6c97cc","type":"debug","z":"2e301f7e.715e6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":690,"y":360,"wires":[]},{"id":"aee265d0.cd2c88","type":"link out","z":"2e301f7e.715e6","name":"","links":["52b163.b4590e9c"],"x":655,"y":180,"wires":[]},{"id":"52b163.b4590e9c","type":"link in","z":"2e301f7e.715e6","name":"","links":["aee265d0.cd2c88"],"x":395,"y":360,"wires":[["18310a37.45dab6"]]},{"id":"fcdf7959.8ddc38","type":"inject","z":"2e301f7e.715e6","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":60,"wires":[["d00582c1.eec9b"]]},{"id":"717fa7e9.18a008","type":"inject","z":"2e301f7e.715e6","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":160,"wires":[["a04ab26a.bd971"]]},{"id":"b6e32029.b8eca","type":"inject","z":"2e301f7e.715e6","name":"","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":100,"wires":[["d00582c1.eec9b"]]},{"id":"48cc07b0.0d13a8","type":"inject","z":"2e301f7e.715e6","name":"","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":200,"wires":[["a04ab26a.bd971"]]},{"id":"7fae6457.6b198c","type":"ui_group","z":"","name":"G1","tab":"d12a40ce.f7ebd","disp":true,"width":"12","collapse":false},{"id":"d12a40ce.f7ebd","type":"ui_tab","z":"","name":"T1","icon":"dashboard","disabled":false,"hidden":false}]
0 Likes

#6

Hello Andrei
Thank you for your response. Your understanding is correct, I did not realize I could handle this like you described but it looks like it does exactly what I need it to do. I will report back soon. Thank you very much!

below is my original flow. I am still curious to understand why the conditional statement was not working as expected if someone has time to look at it, but now I can keep going using your alternate! thanks for getting me unstuck :wink:

[{"id":"561f45a1.98340c","type":"tab","label":"Door Close Timer","disabled":false,"info":""},{"id":"e4c418e5.91c2b8","type":"debug","z":"561f45a1.98340c","name":"complete Object","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1800,"y":380,"wires":[]},{"id":"1774a635.0f88da","type":"mytimeout","z":"561f45a1.98340c","name":"OpenDoor(300s)Timeout(200s)Warning","outtopic":"","outsafe":"2","outwarning":"4","outunsafe":"5","warning":"200","timer":"300","debug":false,"ndebug":false,"ignoreCase":false,"repeat":false,"again":false,"x":1760,"y":220,"wires":[[],[]],"outputLabels":["Timer on, warning, off","Countdown Seconds Remaining"]},{"id":"ef74b794.aeb288","type":"debug","z":"561f45a1.98340c","name":"msg.payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1790,"y":320,"wires":[]},{"id":"f565e92f.f12748","type":"ui_slider","z":"561f45a1.98340c","name":"SnoozeTimer","label":"Timeout","tooltip":"Delay Auto-Close (up to 3 hours)","group":"2f18d7ac.e2d638","order":2,"width":"4","height":"1","passthru":false,"outs":"end","topic":"","min":"0","max":"180","step":"15","x":450,"y":240,"wires":[["a48e856a.e7bb28"]]},{"id":"a48e856a.e7bb28","type":"function","z":"561f45a1.98340c","name":"convert to seconds","func":"var x = msg.payload;\nvar y = 60;\nvar timeout = x*y;\nmsg.timeout = timeout;\nflow.set('timeout',msg.timeout);     // to store a variable (YourVariable)\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":240,"wires":[[]]},{"id":"b727b586.4b4378","type":"inject","z":"561f45a1.98340c","name":"\"on\"","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1270,"y":340,"wires":[["d4cc16f7.d51388"]]},{"id":"cba077e3.dfbc18","type":"ui_switch","z":"561f45a1.98340c","name":"","label":"PauseCountdown","tooltip":"Pauses Auto-Close (Closer activates on release)","group":"2f18d7ac.e2d638","order":5,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"cancel","onvalueType":"str","onicon":"","oncolor":"","offvalue":"closenow","offvalueType":"str","officon":"","offcolor":"","x":470,"y":380,"wires":[["1ca81281.a6c82d"]]},{"id":"1ca81281.a6c82d","type":"function","z":"561f45a1.98340c","name":"SetFlowPayload","func":"flow.set('payload', msg.payload);     // to store a variable (YourVariable)\nreturn msg;","outputs":1,"noerr":0,"x":940,"y":380,"wires":[[]]},{"id":"7985fd6b.546434","type":"ui_switch","z":"561f45a1.98340c","name":"EnableExtendedTimeout","label":"Enable","tooltip":"","group":"2f18d7ac.e2d638","order":1,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"override","onvalueType":"str","onicon":"","oncolor":"","offvalue":"dissable","offvalueType":"str","officon":"","offcolor":"","x":490,"y":140,"wires":[["5c611174.150ec"]]},{"id":"5c611174.150ec","type":"function","z":"561f45a1.98340c","name":"SetFlowOverride","func":"var override = msg.payload;\nflow.set('override',msg.override);     // to store a variable (YourVariable)\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":140,"wires":[[]]},{"id":"d1141a14.a11b58","type":"comment","z":"561f45a1.98340c","name":"Enable or Dissable Extended Tiomout","info":"","x":530,"y":100,"wires":[]},{"id":"f6a75d12.a8994","type":"comment","z":"561f45a1.98340c","name":"User Adjuste Setting for Extended Timeout in Min.","info":"","x":560,"y":200,"wires":[]},{"id":"62917cdc.571dc4","type":"comment","z":"561f45a1.98340c","name":"Converts Min. to Sec. & Set \"timeout\" Value to Flow","info":"","x":1050,"y":200,"wires":[]},{"id":"c7e10d5b.c7476","type":"comment","z":"561f45a1.98340c","name":"Set \"override\" value to Flow","info":"","x":980,"y":100,"wires":[]},{"id":"4992e660.4c7da8","type":"comment","z":"561f45a1.98340c","name":"Sends Pause Command to the Counter","info":"","x":530,"y":340,"wires":[]},{"id":"31fa547f.b474cc","type":"comment","z":"561f45a1.98340c","name":"Set \"payload\" Value to Flow","info":"","x":980,"y":340,"wires":[]},{"id":"d4cc16f7.d51388","type":"function","z":"561f45a1.98340c","name":"TimeoutOverrider","func":"var y = flow.get('payload');    //get the payload ( i.e. keep open or close instruction : \"cancel\" or \"closenow\")\nvar x = flow.get('timeout');    //get the override countdown timeout value. range from 0 to 180 minutes converted to seconds\nvar w = flow.get('override');   //asses whether the countdown timer is suppose to run but with an extended countdown value \"override\" of \"dissable\"\n\nvar payload1 = {\"payload\" : y, \"timeout\" : 0, \"warning\" : 0};           //cancel\nvar payload2 = {\"payload\" : \"on\", \"timeout\" : x, \"warning\" : 0};        //adjusted timeout\nvar payload3 = {\"payload\" : \"on\", \"timeout\" : 0, \"warning\" : 0};        //closenow\n\n//msg.payload = payload2;\n\nif (y == \"cancel\") {msg.payload = payload1;}\nelse if (y == \"closenow\" && w == \"override\") {msg.payload = payload2;}\nelse if (y == \"closenow\" && w == \"dissable\") {msg.payload = payload3;}\nelse {msg.payload = \"not working\";}\nreturn msg;","outputs":1,"noerr":0,"x":1470,"y":340,"wires":[["ef74b794.aeb288","e4c418e5.91c2b8"]]},{"id":"2f18d7ac.e2d638","type":"ui_group","z":"","name":"Commands","tab":"5e6cc32a.65a53c","order":1,"disp":true,"width":"6","collapse":true},{"id":"5e6cc32a.65a53c","type":"ui_tab","z":"","name":"Door#1","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
1 Like

#7

Thanks Andrei, this did sole my issue! I only had to declare "e" using get.flow(). and everything works in all configurations! thanks for you time!

2 Likes