2019年6月23日 星期日

Using the Node-Red Function Node- Beginners Guide

Using the Node-Red Function Node- Beginners Guide
源自於http://www.steves-internet-guide.com/node-red-functions/
node-red-function-nodeThe function node is used to run JavaScript code against the msg object.
The function node accepts a msg object as input and can return 0 or more message objects as output.
This message object must have a payload property (msg.payload), and usually has other properties depending on the proceeding nodes.


Accessing the msg Properties in The Function Node.

The message payload can be accessed using:
var payload=msg.payload;
and can be modified using:
msg.payload=payload;
Likewise the message topic can be accessed using:
var topic=msg.topic;
and can be modified using:
msg.topic= topic;
It can be extended using
var  newvalue;
msg.newproperty=newvalue;
Now the msg object has a property called msg.newproperty.

Creating a New Message Object

Inside a function you can create a new msg object using:

var newMsg = { payload: msg.payload,topic:msg.topic };
return newMsg;

Using the Function Node

When you drop a function node onto a flow , and go to edit you will see a single line of code that returns the msg object and a blank line above were you can start to enter your own code.
If you don’t return a msg object then the flow stops.

Simple Function Example 1

The flow below is uses the function node with the default code which simply returns the msg object.
The effect is simply to pass the msg object and all of it’s properties from the input node to the output node and the next node in the flow (debug).
The inject node injects a msg object into the flow with the Unix time stamp as the payload and a blank topic. It is passes through the do nothing function node and you can see that this appears on the debug node.

Function Node Example 2

Next we use the inject node to inject a payload with the string “test string”  and a topic of test.
If we pass this into our do nothing function as before we get the following output.
The output is as expected. This time we show the topic as test and the payload as test string.
Now if we modify the function to change the payload t Upper case and the topic to upper case using the following code:
var payload=msg.payload; //get payload
msg.payload=payload.toUpperCase(); //convert to uppercase
var topic=msg.payload; //get topic
msg.topic=topic.toUpperCase();//convert to uppercase
return msg;
The first line of the code retrieves the msg payload.
var payload=msg.payload; //get payload
The second line converts it to upper case and re-assign it back to the msg object.
msg.payload=payload.toUpperCase();
We then do exactly the same with the topic property before returning the complete msg object.

The output on the debug screen is shown below:
function-node-example-2-out
Notice the topic and payload have been converted to upper case.

Multiple Outputs

The function node can be configured with multiple outputs.
This is useful when the flow splits into separate paths depending on a message property.
To configure multiple outputs open the function node and use the up/down arrows to adjust the outputs.
Outputs are numbered starting with 1 at the top.
To return messages to multiple outputs you need to return an array. So the return looks like this:
return [msg1,msg2];
Msg1 will appear on output1 and msg2 on output2. To stop a flow you return null.
So to return the msg objext on output1 and nothing on output2 use:
return [msg1,null];

Example

In the example flow we use two inject nodes to inject a message on two different topics and send the message to the output based on the topic name.
Topic test1 goes to output1 and test2 goes to output2.
The following code is used in the function node to spit the message path based on the topic name.
Notice the return statement.
var topic=msg.topic;
if (topic=="test1"){
    return [msg,null];
    
}
if (topic=="test2"){
    return [null,msg];
    
}
The output on the debug screen is show below:

Multiple Messages on a Single Output

You can use an array to return multiple msg objects on a single output.
So the return would look like this
return [msg_object_array];
Important you are returning an array of objects in an array.
This is best seen with an example

Example Multiple Messages on Single Output:

In this example we use an inject node to inject a test string into the function node.
The function node takes the string and uses it for the message payload, but instead of sending 1 message it has a for loop which creates 3 messages and puts them in an array . The function returns the array as an array!
Here is the flow:
Here is the code of the function node:
var m_out=[]; //rray for message objects
var message=msg.payload;
for (i=0;i<3;i++){
    
    message=message+i; //add count to message
    var newmsg={payload:message,topic:msg.topic}
    m_out.push(newmsg);
}
return[m_out];
Important– notice the return statement returns an array.
Here is the debug screen output when run notice the debug screen shows 3 messages:


[{"id":"17702cea.6d0b43","type":"inject","z":"afe7af4b.c2261","name":"","topic":"Test","payload":"Test string","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1340,"wires":[["7fd4d728.895558","eec9d963.9e8af8"]]},{"id":"7fd4d728.895558","type":"function","z":"afe7af4b.c2261","name":"Does Nothing","func":"\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":1340,"wires":[["3bcb0572.4346da"]]},{"id":"eec9d963.9e8af8","type":"function","z":"afe7af4b.c2261","name":"To_UpperCase","func":"var payload=msg.payload; //get payload\nmsg.payload=payload.toUpperCase(); //convert to uppercase\nvar topic=msg.payload; //get topic\nmsg.topic=topic.toUpperCase();//convert to uppercase\nreturn msg;\n","outputs":1,"noerr":0,"x":350,"y":1420,"wires":[["3f8ae56a.a4788a"]]},{"id":"3bcb0572.4346da","type":"debug","z":"afe7af4b.c2261","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":1340,"wires":[]},{"id":"3f8ae56a.a4788a","type":"debug","z":"afe7af4b.c2261","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":510,"y":1420,"wires":[]},{"id":"e71db003.c8795","type":"debug","z":"afe7af4b.c2261","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":1520,"wires":[]},{"id":"61365be4.2fc744","type":"debug","z":"afe7af4b.c2261","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":1600,"wires":[]},{"id":"549f2f6c.0cc2a","type":"debug","z":"afe7af4b.c2261","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":1700,"wires":[]},{"id":"b73ed76d.7bd3b8","type":"function","z":"afe7af4b.c2261","name":"message array","func":"var m_out=[]; //rray for message objects\nvar message=msg.payload;\nfor (i=0;i<3;i++){\n    \n    message=message+i; //add count to message\n    var newmsg={payload:message,topic:msg.topic}\n    m_out.push(newmsg);\n}\nreturn[m_out];\n","outputs":1,"noerr":0,"x":340,"y":1700,"wires":[["549f2f6c.0cc2a"]]},{"id":"eb646584.7e7ae8","type":"function","z":"afe7af4b.c2261","name":" two different Topic","func":"var topic=msg.topic;\nif (topic==\"test1\"){\n    return [msg,null];\n    \n}\nif (topic==\"test2\"){\n    return [null,msg];\n    \n}\nreturn msg;","outputs":2,"noerr":0,"x":330,"y":1560,"wires":[["e71db003.c8795"],["61365be4.2fc744"]]},{"id":"2eedc7bb.354738","type":"inject","z":"afe7af4b.c2261","name":"","topic":"test1","payload":"Output1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1520,"wires":[["eb646584.7e7ae8"]]},{"id":"111eff36.6a0551","type":"inject","z":"afe7af4b.c2261","name":"","topic":"test2","payload":"Output2","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1600,"wires":[["eb646584.7e7ae8"]]},{"id":"6aee26ac.b75e48","type":"inject","z":"afe7af4b.c2261","name":"","topic":"test","payload":"test message","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1700,"wires":[["b73ed76d.7bd3b8"]]}]



Reusing Function Nodes

You can save your function nodes in the library and reuse them in other flows by importing them
To save a function to the library double click on the function to edit it and click on the bookmark icon next to the function name.
A drop down menu appears to either import or save the function to the library.

沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...