Node function multiple output

Hello. I started playing with this fantastic application a few days ago... I was really amazed by the simplicity of use and the power that you have under the hood.
I read a lot of things here on the forum guides and around the network, more or less I managed to set up the basis for a flow to solve problems I have on a photovoltaic home automation.
currently use openhab for this, but I needed to move the sensitive devices in a more suitable room (now in outdoor although protected), and here comes into the field NR.
I’m then trying to collect some data (to start) from an inverter (easun) to give it a formatted and send them to the mqtt broker. more or less I managed to do what I needed, at least for the first rudimentary flow, that is to interrogate the device on serial and get a response through broker mosquitto. was quite easy, now I’m at the rock... since I have no programming bases, until you had to use nodes preconstituted all ok... but in the path of growth very soon this gap is consolidated.
I should use the "function" node.
I tried to read something but I don’t have the bases to understand the code.
So I set the question hoping in some volunteer that I take the right way in writing the codes that I need to configure this node.

In practice:
I have a string:
^D03900,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1c�
containing the warning data of the inverter
D039 and c are not interesting from the point of view of info
The data is left with only two values (0 and 1) and are separated by ","
using the node "split" was easy to divide them into single messages, now I should feed the node "multi function output" to send the various data to its outputs... and here falls the ass... I have no idea what to write in the node...

I trust in a help...

flows2.json (45.1 KB)

Hey there!

Actually, with the function node you can do almost "everything", you just need to write it into javascript.

Here I leave you an example of how could you do it:

[
    {
        "id": "d78489fa01061f79",
        "type": "inject",
        "z": "115848319abb5cbe",
        "name": "Test",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "^D03900,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1c",
        "payloadType": "str",
        "x": 270,
        "y": 260,
        "wires": [
            [
                "2c1d8c2379af0b87"
            ]
        ]
    },
    {
        "id": "2c1d8c2379af0b87",
        "type": "function",
        "z": "115848319abb5cbe",
        "name": "Data conversion",
        "func": "let Data = msg.payload;\n\nlet Data2Array = Data.split(\",\"); //Converts string to array using , as separator\n\nmsg.payload = Data2Array;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 460,
        "y": 260,
        "wires": [
            [
                "6f9c056be998bf59",
                "b2fcaaa290d29ca3",
                "1a1ff6672940aaf1"
            ]
        ]
    },
    {
        "id": "6f9c056be998bf59",
        "type": "debug",
        "z": "115848319abb5cbe",
        "name": "debug 5",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 505,
        "y": 300,
        "wires": [],
        "l": false
    },
    {
        "id": "93f0dc19c03ea230",
        "type": "mqtt out",
        "z": "115848319abb5cbe",
        "name": "MQTT Out",
        "topic": "",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "d1dc4d6ed7da82ef",
        "x": 1030,
        "y": 260,
        "wires": []
    },
    {
        "id": "39d6967ee81727e2",
        "type": "comment",
        "z": "115848319abb5cbe",
        "name": "Generate the MQTT messages you need here:",
        "info": "",
        "x": 770,
        "y": 220,
        "wires": [],
        "icon": "font-awesome/fa-info-circle"
    },
    {
        "id": "b2fcaaa290d29ca3",
        "type": "change",
        "z": "115848319abb5cbe",
        "name": "Error ID Conversion - 1",
        "rules": [
            {
                "t": "change",
                "p": "payload[1]",
                "pt": "msg",
                "from": "1",
                "fromt": "str",
                "to": "Rete Assente",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload[1]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "INVERTER_IGRID/Risposta_Inverter/Info_Codice_Errore",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 710,
        "y": 260,
        "wires": [
            [
                "93f0dc19c03ea230",
                "97711b68ad9449c4"
            ]
        ]
    },
    {
        "id": "97711b68ad9449c4",
        "type": "debug",
        "z": "115848319abb5cbe",
        "name": "debug 6",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 805,
        "y": 300,
        "wires": [],
        "l": false
    },
    {
        "id": "1a1ff6672940aaf1",
        "type": "change",
        "z": "115848319abb5cbe",
        "name": "Error ID Conversion - 2",
        "rules": [
            {
                "t": "change",
                "p": "payload[2]",
                "pt": "msg",
                "from": "1",
                "fromt": "str",
                "to": "Cortocircuito Uscita Inverter",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload[2]",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "INVERTER_IGRID/Risposta_Inverter/Tipo_Errore",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 710,
        "y": 340,
        "wires": [
            [
                "0650dce845f09269",
                "93f0dc19c03ea230"
            ]
        ]
    },
    {
        "id": "0650dce845f09269",
        "type": "debug",
        "z": "115848319abb5cbe",
        "name": "debug 7",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 805,
        "y": 380,
        "wires": [],
        "l": false
    },
    {
        "id": "a112b07c4c024a7b",
        "type": "comment",
        "z": "115848319abb5cbe",
        "name": "+ ADD yours",
        "info": "",
        "x": 670,
        "y": 420,
        "wires": [],
        "icon": "font-awesome/fa-info-circle"
    },
    {
        "id": "d1dc4d6ed7da82ef",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.1.89",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

Give it a try, you may find it inspiring

Plus I highly recommend the documentation of the node since you may find how does it work and best practices to use it.

You can read more info about function node (and handling of multiple outputs) here:
https://nodered.org/docs/user-guide/writing-functions

Good luck!

1 Like

Thanks for the very quick answer... I wonder how you did to create all the script in less time than I took a look at it.
Clearly I do not understand anything and I do not think I can do it even using all my mental resources.
I saw that the code you produced takes care of the whole process from the input string until the transmission of the mqtt message with attached content for the various warnings.
I didn’t understand if your script should simply paste it in the "function" node without using other blocks in the flow (since it does everything)?
Do I need to change/adapt something in the script?
Thank you.

Hi is a function node and multiple mqtt and change nodes required?

This example you add the topic and messages in the second change node. You can skip any 1 or 0 you do not wish to send mqtt messages for by adding blank objects {}.
This example outputs 1st, skips second and output 3rd. Just add the objects for each you require. The beauty of this is you just have to edit the topics object when adding or removing extra fields.

[{"id":"d78489fa01061f79","type":"inject","z":"d1395164b4eec73e","name":"Test","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^D03900,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1c�","payloadType":"str","x":130,"y":60,"wires":[["d2a6f2715590216e"]]},{"id":"d2a6f2715590216e","type":"change","z":"d1395164b4eec73e","name":"clean incoming string","rules":[{"t":"change","p":"payload","pt":"msg","from":"^D0390","fromt":"str","to":"","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"c�","fromt":"str","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":60,"wires":[["71756e6f9ba78bf8"]]},{"id":"71756e6f9ba78bf8","type":"change","z":"d1395164b4eec73e","name":"set topics and messages","rules":[{"t":"set","p":"topics","pt":"msg","to":"[{\"topic\":\"INVERTER_IGRID/Risposta_Inverter/Info_Codice_Errore\",\"message\":[\"A zero\",\"A one\"]},{},{\"topic\":\"INVERTER_IGRID/Risposta_Inverter/Tipo_Errore\",\"message\":[\"C zero\",\"C one\"]}]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":60,"wires":[["d73b7de343849366"]]},{"id":"d73b7de343849366","type":"csv","z":"d1395164b4eec73e","name":"parse csv and convert string to numbers","sep":",","hdrin":"","hdrout":"none","multi":"one","ret":"\\n","temp":"","skip":"0","strings":true,"include_empty_strings":"","include_null_values":"","x":220,"y":100,"wires":[["7b4c9e07110bece1","6f9c056be998bf59"]]},{"id":"7b4c9e07110bece1","type":"split","z":"d1395164b4eec73e","name":"split object  of numbers","splt":",","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":280,"y":140,"wires":[["8a8e1b3ddcf98845"]]},{"id":"6f9c056be998bf59","type":"debug","z":"d1395164b4eec73e","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":465,"y":120,"wires":[],"l":false},{"id":"8a8e1b3ddcf98845","type":"switch","z":"d1395164b4eec73e","name":"Is topic set for index","property":"topics[msg.parts.index]","propertyType":"msg","rules":[{"t":"hask","v":"topic","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":280,"y":180,"wires":[["b2fcaaa290d29ca3"]]},{"id":"b2fcaaa290d29ca3","type":"change","z":"d1395164b4eec73e","name":"select topic and message","rules":[{"t":"set","p":"payload","pt":"msg","to":"topics[msg.parts.index].message[msg.payload]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"topics[msg.parts.index].topic","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":180,"wires":[["97711b68ad9449c4","f239497c0d69a079"]]},{"id":"97711b68ad9449c4","type":"debug","z":"d1395164b4eec73e","name":"debug 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":845,"y":60,"wires":[],"l":false},{"id":"f239497c0d69a079","type":"mqtt out","z":"d1395164b4eec73e","name":"Only one mqtt node required","topic":"","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"e8ba3ef5.22f4a8","x":840,"y":180,"wires":[]},{"id":"e8ba3ef5.22f4a8","type":"mqtt-broker","name":"testb","broker":"192.168.1.25","port":"1883","clientid":"","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":"5","keepalive":"60","cleansession":true,"autoUnsubscribe":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

Hello,
Thank you for your availability and commitment.
I only realized after a while that those scripts were going to be "imported" in node-red... well I learned something...
I have seen and studied a little your flows and thank you very much because in this case I have also learned something...

To be able to transmit what I have in my head (which is not easy, especially remotely) I thought of representing with a kind of flow what I would like to get, actually the flow also seems to work, except for the last one that must send the mess. mqtt "No Warning", that is the part that should make an "end" of the 16 out to "0".
sure it’s a flow made by an electronic and certainly not by a programmer. but at least I think I transmit what I have in mind and would like to achieve.

Hello and thank you
finale_pulito 7.8.24.json (52.6 KB)

1 Like

I would probably use a lookup object for the messages and an array for the errors and a trigger node to send no errors.
Have a look at this, set the full messages and errors in the set messages change node. You would only need to set one mqtt node.

[{"id":"1e0c01ec4dea7859","type":"inject","z":"d1395164b4eec73e","name":"Test no errors","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^D03900,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1c�","payloadType":"str","x":170,"y":20,"wires":[["d2a6f2715590216e"]]},{"id":"d2a6f2715590216e","type":"change","z":"d1395164b4eec73e","name":"clean incoming string","rules":[{"t":"change","p":"payload","pt":"msg","from":"^D039","fromt":"str","to":"","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":".1c�","fromt":"str","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":60,"wires":[["3f2f05ca372767b6"]]},{"id":"d78489fa01061f79","type":"inject","z":"d1395164b4eec73e","name":"Test with errors","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^D03905,1,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1c�","payloadType":"str","x":180,"y":60,"wires":[["d2a6f2715590216e"]]},{"id":"3f2f05ca372767b6","type":"change","z":"d1395164b4eec73e","name":"set messages ","rules":[{"t":"set","p":"messages","pt":"msg","to":"{\"00\":\"no error\",\"01\":\"fan is locked\",\"02\":\"Over temperature\",\"03\":\"Battery voltage is too high\",\"04\":\"Battery voltage is too low\",\"05\":\"Output short circuited or Over temperature\",\"06\":\"Output voltage is too high\",\"07\":\"Over load time out\"}","tot":"json"},{"t":"set","p":"errors","pt":"msg","to":"[\"line failed\",\"output short circuit\",\"error3\",\"error4\",\"error5\",\"error6\",\"error7\",\"error8\",\"error9\",\"error10\",\"error11\",\"error12\",\"error13\",\"error14\",\"error15\",\"error16\"]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":60,"wires":[["7b4c9e07110bece1"]]},{"id":"7b4c9e07110bece1","type":"split","z":"d1395164b4eec73e","name":"split string  of numbers","splt":",","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":800,"y":60,"wires":[["08fdaa49d434e7c8"]]},{"id":"08fdaa49d434e7c8","type":"switch","z":"d1395164b4eec73e","name":"","property":"parts.index","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":true,"outputs":2,"x":190,"y":120,"wires":[["e3b8cb78b1a99462","f8867d01ab4e393b"],["abf0013bbbe7f563"]]},{"id":"e3b8cb78b1a99462","type":"change","z":"d1395164b4eec73e","name":"set messages for index 0 & topic","rules":[{"t":"set","p":"payload","pt":"msg","to":"messages[msg.payload]","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"INVERTER_IGRID/Risposta_Inverter/Fault-Warning/Codice Errore Info","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":160,"wires":[["d0c9074f6f0451c5","066b2da6fd46e71f"]]},{"id":"abf0013bbbe7f563","type":"change","z":"d1395164b4eec73e","name":"set index","rules":[{"t":"set","p":"index","pt":"msg","to":"parts.index","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":160,"y":240,"wires":[["5c00f9c480e8e29a"]]},{"id":"f8867d01ab4e393b","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"INVERTER_IGRID/Risposta_Inverter/Fault-Warning/Codice Errore","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":120,"wires":[["454ac41267df26f1","066b2da6fd46e71f"]]},{"id":"d0c9074f6f0451c5","type":"debug","z":"d1395164b4eec73e","name":"debug 2566","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":715,"y":160,"wires":[],"l":false},{"id":"066b2da6fd46e71f","type":"mqtt out","z":"d1395164b4eec73e","name":"","topic":"","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"e8ba3ef5.22f4a8","x":1010,"y":160,"wires":[]},{"id":"5c00f9c480e8e29a","type":"switch","z":"d1395164b4eec73e","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"else"}],"checkall":"true","repair":true,"outputs":2,"x":290,"y":240,"wires":[["d41cacb641ab56e5"],["6a4ff04b64d2ee6d"]]},{"id":"454ac41267df26f1","type":"debug","z":"d1395164b4eec73e","name":"debug 2565","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":715,"y":120,"wires":[],"l":false},{"id":"86f56ed6c5026cef","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"INVERTER_IGRID/Risposta_Inverter/Fault-Warning/Codice Errore Info","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":280,"wires":[["97711b68ad9449c4","066b2da6fd46e71f"]]},{"id":"d41cacb641ab56e5","type":"change","z":"d1395164b4eec73e","name":"set error","rules":[{"t":"set","p":"payload","pt":"msg","to":"errors[msg.index]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":240,"wires":[["d3e8d094ec8732eb"]]},{"id":"6a4ff04b64d2ee6d","type":"change","z":"d1395164b4eec73e","name":"set no error","rules":[{"t":"set","p":"payload","pt":"msg","to":"no errors","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":280,"wires":[["692aaf96f2f4bd4f"]]},{"id":"692aaf96f2f4bd4f","type":"trigger","z":"d1395164b4eec73e","name":"errors or no errors","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"250","extend":true,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":690,"y":280,"wires":[["86f56ed6c5026cef"]]},{"id":"97711b68ad9449c4","type":"debug","z":"d1395164b4eec73e","name":"debug 6","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1015,"y":280,"wires":[],"l":false},{"id":"d3e8d094ec8732eb","type":"join","z":"d1395164b4eec73e","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":550,"y":240,"wires":[["692aaf96f2f4bd4f"]]},{"id":"e8ba3ef5.22f4a8","type":"mqtt-broker","name":"testb","broker":"192.168.1.25","port":"1883","clientid":"","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":"5","keepalive":"60","cleansession":true,"autoUnsubscribe":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

Maybe watching the essentials videos will give you more insight into what each node type can do.