Trouble with function

Hi, IT guy pretending to understand how to script this function and not getting it. Below function is working. The reason I did it this way was to simply get the right output to BLYNK app.

However there are some values here I would like to group and just show that component status. For example, instead of showing status of LED Green, LED red and LED Yellow individually, I want to display " LED status : [green] '. What is the best way to do this?

The function node is as below

let var1
let var2;
let var3;
let var4;
let var5;
let var6;
let var7;
let var8;
let var9;
let var10;
let var11;
let var12;
let var13;
let var14;

var1 = msg.payload.LevelPresSensor;
var2 = msg.payload.AutoMode;
var3 = msg.payload.ManualMode;
var4 = msg.payload.CT;
var5 = msg.payload.LevelSensorRaw;
var6 = msg.payload.LEDGreen;
var7 = msg.payload.LEDRed;
var8 = msg.payload.LEDYellow;
var9 = msg.payload.FLSBLS;
var10 = msg.payload.LevelSWON;
var11 = msg.payload.LevelSWHIGH;
var12 = msg.payload.LevelSWOFF;
var13 = msg.payload.MainContactor;
var14 = msg.payload.PumpInterlock;

let msg1 = {payload: var1};
let msg2 = {payload: var2};
let msg3 = {payload: var3};
let msg4 = {payload: var4};
let msg5 = {payload: var5};
let msg6 = {payload: var6};
let msg7 = {payload: var7};
let msg8 = {payload: var8};
let msg9 = {payload: var9};
let msg10 = {payload: var10};
let msg11 = {payload: var11};
let msg12 = {payload: var12};
let msg13 = {payload: var13};
let msg14 = {payload: var14};

return [msg1, msg2, msg3, msg4,msg5, msg6,msg7,msg8,msg9,msg10,msg11,msg12,msg13,msg14];
return msg;

Screen Shot 2021-03-31 at 2.42.18 PM

What determines " LED status : [green] " ? What values would msg.payload.LEDGreen, msg.payload.LEDRed and msg.payload.LEDYellow have to have to make that string?

OBSERVATION...

Why do you bother even splitting the object? All this code is fairly unnecessary - you can simply set the ui_text to the property of interest...

image

OBSERVATION2...

I know i said you dont need to split out each message but if you must, this might be a bit more manageable...

let messages = [];
messages.push( { payload: msg.payload.LevelPresSensor } );
messages.push( { payload: msg.payload.AutoMode } );
messages.push( { payload: msg.payload.ManualMode } );
messages.push( { payload: msg.payload.CT } );
messages.push( { payload: msg.payload.LevelSensorRaw } );
messages.push( { payload: msg.payload.LEDGreen } );
messages.push( { payload: msg.payload.LEDRed } );
messages.push( { payload: msg.payload.LEDYellow } );
messages.push( { payload: msg.payload.FLSBLS } );
messages.push( { payload: msg.payload.LevelSWON } );
messages.push( { payload: msg.payload.LevelSWHIGH } );
messages.push( { payload: msg.payload.LevelSWOFF } );
messages.push( { payload: msg.payload.MainContactor } );
messages.push( { payload: msg.payload.PumpInterlock } );
return messages;
1 Like

Thanks Steve.

  • msg.payload.LEDGreen, red, yellow are all true or false values. The fun thing is that I realized in certain conditions both green and red can both be true. When I initially posted I was assuming only one would be true at a time. Having said that there are other payloads (not shown) with similar true or false value I would want the same logic for, just unsure how to do it (example, system is either in auto mode or manual mode, so which ever of those is TRUE I want to have that reflect as running status AUTO or MANUAL

  • why bother splitting the object? Because my skills and experience usually end at 'copy/paste/edit' someone else's code lol. This was the first way I did it that actually worked. thanks for the other example, will play around with that and see if that makes more sense to me.

As I mentioned briefly, end goal is to use BLYNK / to reflect the system current status in the most efficient way possible. Right now I have node-red (on a PI) polling the Siemens S7-1200 PLC every 30 seconds. This will be a remote location connected over cellular, and I may end up pushing the data up to a cloud repository of sorts over MQTT and then on to Blynk from there, haven't gotten that far to think about it too much yet. Past that, future phase would also be ability to push changes back down to the PLC remotely via Blynk or at that point a custom app, React Native possibly.

much appreciated
Matt

So there are 2 approaches. I will keep them simple (no fancy code as you said you are just getting to grips with node-red / JS)

Function way...

Since you are already inside a function node you can simply do if/else...

if (msg.payload.MANUAL == true && msg.payload.AUTO == false) {
    msg.machineMode = "Manual";
} else if (msg.payload.MANUAL == false && msg.payload.AUTO == true) {
    msg.machineMode = "Auto";
} else {
    msg.machineMode = "Unknown";
}

A more node-red way...

Demo of both...
OPvJ110PKR

Demo flow...

[{"id":"393f78cb.ed7e58","type":"function","z":"b872cb4b.5a6448","name":"S7 PLC (fake) (manual)","func":"msg.payload = {\n    MANUAL: true,\n    AUTO: false,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":890,"y":280,"wires":[["ced85643.0314c8"]]},{"id":"a3aa891c.5b2ca8","type":"function","z":"b872cb4b.5a6448","name":"S7 PLC (fake) (auto)","func":"msg.payload = {\n    MANUAL: false,\n    AUTO: true,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":320,"wires":[["ced85643.0314c8"]]},{"id":"fa9cdc.86742328","type":"inject","z":"b872cb4b.5a6448","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":755,"y":280,"wires":[["393f78cb.ed7e58"]],"l":false},{"id":"f44129fd.a23878","type":"inject","z":"b872cb4b.5a6448","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":755,"y":320,"wires":[["a3aa891c.5b2ca8"]],"l":false},{"id":"ced85643.0314c8","type":"function","z":"b872cb4b.5a6448","name":"","func":"if (msg.payload.MANUAL == true && msg.payload.AUTO == false) {\n    msg.payload.machineMode = \"Manual\";\n} else if (msg.payload.MANUAL == false && msg.payload.AUTO == true) {\n    msg.payload.machineMode = \"Auto\";\n} else {\n    msg.payload.machineMode = \"Unknown\";\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1120,"y":300,"wires":[["82809d34.a04fa"]]},{"id":"82809d34.a04fa","type":"debug","z":"b872cb4b.5a6448","name":"machineMode","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload.machineMode","statusType":"msg","x":1320,"y":300,"wires":[]},{"id":"f8030946.4129e8","type":"switch","z":"b872cb4b.5a6448","name":"isAuto","property":"payload.AUTO","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":1250,"y":480,"wires":[["81e07c0a.46cd8"]]},{"id":"f4db3db6.a75d1","type":"switch","z":"b872cb4b.5a6448","name":"isManual","property":"payload.MANUAL","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":1260,"y":520,"wires":[["29cefbe1.d43184"]]},{"id":"6494cc3d.8e0584","type":"function","z":"b872cb4b.5a6448","name":"S7 PLC (fake) (manual)","func":"msg.payload = {\n    MANUAL: true,\n    AUTO: false,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":890,"y":480,"wires":[["b1301efc.c5e24"]]},{"id":"4c3e74f4.0e586c","type":"function","z":"b872cb4b.5a6448","name":"S7 PLC (fake) (auto)","func":"msg.payload = {\n    MANUAL: false,\n    AUTO: true,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":520,"wires":[["b1301efc.c5e24"]]},{"id":"31308634.0324ea","type":"inject","z":"b872cb4b.5a6448","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":755,"y":480,"wires":[["6494cc3d.8e0584"]],"l":false},{"id":"b434ef92.c012c","type":"inject","z":"b872cb4b.5a6448","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":755,"y":520,"wires":[["4c3e74f4.0e586c"]],"l":false},{"id":"81e07c0a.46cd8","type":"change","z":"b872cb4b.5a6448","name":"set machineMode \"Auto\"","rules":[{"t":"set","p":"payload.machineMode","pt":"msg","to":"Auto","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1450,"y":480,"wires":[["359af566.3c09ca"]]},{"id":"29cefbe1.d43184","type":"change","z":"b872cb4b.5a6448","name":"set machineMode \"Manual\"","rules":[{"t":"set","p":"payload.machineMode","pt":"msg","to":"Manual","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1460,"y":520,"wires":[["359af566.3c09ca"]]},{"id":"c3edfb86.8bd388","type":"change","z":"b872cb4b.5a6448","name":"set machineMode Unknown","rules":[{"t":"set","p":"payload.machineMode","pt":"msg","to":"Unknown","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1320,"y":560,"wires":[["359af566.3c09ca"]]},{"id":"359af566.3c09ca","type":"debug","z":"b872cb4b.5a6448","name":"machineMode","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload.machineMode","statusType":"msg","x":1720,"y":520,"wires":[]},{"id":"1b045b94.5ade34","type":"function","z":"b872cb4b.5a6448","name":"S7 PLC (fake) (bad data)","func":"msg.payload = {\n    MANUAL: false,\n    AUTO: false,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":890,"y":360,"wires":[["ced85643.0314c8"]]},{"id":"c8eead49.84593","type":"inject","z":"b872cb4b.5a6448","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":755,"y":360,"wires":[["1b045b94.5ade34"]],"l":false},{"id":"b1301efc.c5e24","type":"switch","z":"b872cb4b.5a6448","name":"Is Normal","property":"payload.AUTO","propertyType":"msg","rules":[{"t":"neq","v":"payload.MANUAL","vt":"msg"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":1100,"y":500,"wires":[["f8030946.4129e8","f4db3db6.a75d1"],["c3edfb86.8bd388"]]},{"id":"165d06ac.345379","type":"function","z":"b872cb4b.5a6448","name":"S7 PLC (fake) (bad data)","func":"msg.payload = {\n    MANUAL: false,\n    AUTO: false,\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":890,"y":560,"wires":[["b1301efc.c5e24"]]},{"id":"d46a9b7.4703068","type":"inject","z":"b872cb4b.5a6448","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":755,"y":560,"wires":[["165d06ac.345379"]],"l":false}]

Output...

image

NOTE: with both of these solutions, I add to the payload a property named "machineMode". This can be used in your ui elements by accessing msg.payload.machineMode


There’s a great page in the docs that will explain how to use the debug panel to find the right path to any data item. Worth the 5 mins read (especially the bit about using the "copy" buttons that appear under your mouse when you hover over a debug output in the sidebar). Working with messages : Node-RED

1 Like

This is great, thank you so much. Will review those docs you linked as well.

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