Function returns undefined - not sure how to pass it through

I have a function which extracts a value from a msg.status.text. The msg.status.text consists of for example Warm White Level 76. The same for red, green, and blue. The function then sends the value (76 in this case to output 4) to 4 different outputs, depending on colour. That all works. But, when the colour is set to 0, the inputting device sends a msg.status.text "Off". With the function as is, the output then is undefined. I need the output of the function msg.status.text to be "Off" in this case.
So a example of a complete incoming debug:

This is in my function node

var stairsred = flow.get('stairsred') || 0;
var stairsgreen = flow.get('stairsgreen') || 0;
var stairsblue = flow.get('stairsblue') || 0;
var stairswhite = flow.get('stairswhite') || 0;

var name;

name = msg.status.source.name;

let match = msg.status.text.match(/([\d]+)/);
if (match && match.length > 1) {
    msg.payload = Number(match[1])
}

if (name == "Red Channel") {
    stairsred = msg.payload;
    flow.set('stairsred', stairsred);
    var msg1 = { payload: msg.payload };

} else if (name == "Green Channel") {
    stairsgreen = msg.payload;
    flow.set('stairsgreen', stairsgreen);
    var msg2 = { payload: msg.payload };

} else if (name == "Blue Channel") {
    stairsblue = msg.payload;
    flow.set('stairsblue', stairsblue);
    var msg3 = { payload: msg.payload };

} else if (name == "White Channel") {
    stairswhite = msg.payload;
    flow.set('stairswhite', stairswhite);
    var msg4 = { payload: msg.payload };
}

return [msg1, msg2, msg3, msg4];

I am trying to a learn and b simplyfy a working solution, with a switch node and 4 function nodes (one for each colour) containing

let match = msg.status.text.match(/([\d]+)/)
if (match && match.length > 1) {
msg.payload = Number(match[1])
return msg;
}

this does return msg.status.text "Off". I am not sure I understand why my new function doesnt..

The new function only write payload to the returned object, while the old function left the original properties intact and only overwrites payload.

try something like this

[{"id":"2bad623877da81fd","type":"inject","z":"452103ea51141731","name":"","props":[{"p":"status","v":"{\"text\":\"Warm White level 76\", \"jill\": \"yellow\", \"shape\": \"dot\"}","vt":"json"},{"p":"status.source.name","v":"Red Channel","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":3660,"wires":[["56037b3e7e9b1ae3"]]},{"id":"56037b3e7e9b1ae3","type":"function","z":"452103ea51141731","name":"function 18","func":"var stairsred = flow.get('stairsred') || 0;\nvar stairsgreen = flow.get('stairsgreen') || 0;\nvar stairsblue = flow.get('stairsblue') || 0;\nvar stairswhite = flow.get('stairswhite') || 0;\n\nvar name;\nlet output = [null,null,null,null];\n\nname = msg.status.source.name;\n\nlet match = msg.status.text.match(/([\\d]+)/);\nif (match && match.length > 1) {\n    msg.payload = Number(match[1])\n}\n\nif (name == \"Red Channel\") {\n    stairsred = msg.payload;\n    flow.set('stairsred', stairsred);\n    output[0] = msg;\n    output[0].payload = msg.payload;\n} else if (name == \"Green Channel\") {\n    stairsgreen = msg.payload;\n    flow.set('stairsgreen', stairsgreen);\n    output[1] = msg;\n    output[1].payload = msg.payload;\n\n} else if (name == \"Blue Channel\") {\n    stairsblue = msg.payload;\n    flow.set('stairsblue', stairsblue);\n    output[2] = msg;\n    output[2].payload = msg.payload;\n\n} else if (name == \"White Channel\") {\n    stairswhite = msg.payload;\n    flow.set('stairswhite', stairswhite);\n    output[3] = msg;\n    output[3].payload = msg.payload;\n}\n\nreturn output;","outputs":4,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":3720,"wires":[["1ed7b575b8922ee8"],["1ed7b575b8922ee8"],["1ed7b575b8922ee8"],["1ed7b575b8922ee8"]]},{"id":"8c883efde5214b53","type":"inject","z":"452103ea51141731","name":"","props":[{"p":"status","v":"{\"text\":\"off\", \"jill\": \"yellow\", \"shape\": \"dot\"}","vt":"json"},{"p":"status.source.name","v":"Red Channel","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":3720,"wires":[["56037b3e7e9b1ae3"]]},{"id":"1ed7b575b8922ee8","type":"debug","z":"452103ea51141731","name":"debug 107","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":690,"y":3600,"wires":[]}]

Even though I have the status.text "Off" its still causing issues when I turn them off. As its only when I set them to off, I think the undefined payload must be the issue. With your function I get this in the debug node

image

If you want msg.payload to be off if status.text is off try this

let match = msg.status.text.match(/([\d]+)/);
if (match && match.length > 1) {
    msg.payload = Number(match[1])
}else{
    msg.payload = msg.status.text
}

Yes, thats done it. Great. Now, I'd like to learn..

In the if statement

if (name == "Red Channel") {
stairsred = msg.payload;
flow.set('stairsred', stairsred);
output[0] = msg;
output[0].payload = msg.payload;

I'd like to understand what output[0] sends. The first line sends what ? The second line sends msg.payload ?

The first line set output[0] to the original msg, that contains the status etc.
The second over writes the payload property

Add a node.warn(output[0]) after each line to see the contents of the output[0].

Thinking about it the second line is not needed as msg.payload is all ready overwritten in the msg, by the

let match = msg.status.text.match(/([\d]+)/);
if (match && match.length > 1) {
    msg.payload = Number(match[1])
}else{
    msg.payload = msg.status.text
}

Ok that all makes sense. And your return output at the end, thats basically the same as return [output[0], etc]; , correct ?

1 Like