Node-Red的全局变量
Storing Data in Node-Red Variables
Node-red nodes pass the msg object between nodes.
However this object is replaced by the next msg object. So how do you store data between node calls?
Node-Red provides three mechanisms:(注意区分以下三者作用域之间的关系)
- The context object -stores data for a node
- The Flow object – stores data for a flow
- The global object -stores data for the canvas
I will illustrate these methods using a simple flow like the one below.
The inject node is used to start the flow , then function node implements the counter and the debug node displays the result.
The idea is to count the number of times the message was injected.
The actual message that gets injected isn’t important.
Note: There is a video to accompany this tutorial as it is easy to demonstrate the interaction between variables using video. You may want to read quickly through the text and then go to the video. Here is the video
Using the Context Object
This is used for storing function variables.
The process for retrieving and storing is to use the get method of the object for retrieving value and the set method to store values.:
x =context.get(name); //to retrieve a variable
context.set(name)=x; // to store a variable
A variable stored for function 1 in the context object is not available to function 2 and vice versa.
Initialising the Variable
The standard way is to include this code at the top of the script:
var count=context.get('count') || 0;
Which means- If count doesn’t exist in the context object then make our local variable count zero; otherwise assign the stored value to our local variable count.
You can use multiple variables e.g.
var count=context.get('count') || 0;
var count2=context.get('count2') || 0;
You can also use an object e.g
var local=context.get('data') || {};
if (local.count===undefined) //test exists
{
local.count=0;
}
In the code above data is an object stored in the context object and local is our local object.
Here is an example script that uses a single variable as a counter in function 1:
var count=context.get('count') || 0;
count +=1;
msg.payload="F1 "+msg.payload+" "+count;
context.set('count',count);
return msg;
Here is an example script that uses a object variable as a counter in function 2::
var local=context.get('data') || {};
if (local.count===undefined)//test exists
{
local.count=0;
}
local.count +=1;
msg.payload="F2 "+msg.payload+" "+local.count;
context.set('data',local);
return msg;
If look at the code for function 1 and function 2 you will see that they use the same counter variable..
However when you click the inject node for function 1 you see the counter value is 1 and then the inject node for function 2 then counter is also 1.
This shows that the counters are local to each function and not shared between functions.
Note: Currently if you restart the flow the variables are reset but this is likely to change
Using the Flow Object
You use the flow object in the same way as the context object.
To retrieve values stored in the flow object use:
var count=flow.get('count') || 0;
and to store values use:
flow.set('count',count);
This time you should notice that the functions can share variables stored in flow objects. See video
Using the Global Object
You use the flow object in the same way as the context object.
To retrieve values stored in the flow object use:
var count=global.get('count') || 0;
and to store values use:
global.set('count',gcount);
This time you should notice that the functions can share variables stored in the global object even across flows.
附带源码1:
[{"id":"e5d17b06.1eb23","type":"function","z":"9b79d705.36516","name":"Function 1","func":"var count=context.get('count') || 0;\ncount +=1;\nmsg.payload=\"F1 \"+msg.payload+\" \"+count;\ncontext.set('count',count);\nreturn msg;\n//\n//","outputs":1,"noerr":0,"x":259,"y":34,"wires":[["8a701147.e5911"]]},{"id":"8a701147.e5911","type":"debug","z":"9b79d705.36516","name":"","active":true,"console":"false","complete":"false","x":409,"y":94,"wires":[]},{"id":"27f735da.096c92","type":"inject","z":"9b79d705.36516","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":119,"y":103,"wires":[["e5d17b06.1eb23"]]},{"id":"888c9d4f.3d53b","type":"inject","z":"9b79d705.36516","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":117,"y":423,"wires":[["acd1780e.a5dfa"]]},{"id":"acd1780e.a5dfa","type":"function","z":"9b79d705.36516","name":"Uses Object","func":"var local=context.get('data') || {};\nif (local.count===undefined)//test exists\n{\n local.count=0;\n}\nlocal.count +=1;\nmsg.payload=\"F2 \"+msg.payload+\" \"+local.count;\ncontext.set('data',local);\nreturn msg;\n//","outputs":1,"noerr":0,"x":280,"y":380,"wires":[["cfb44101.06c7b8"]]},{"id":"cfb44101.06c7b8","type":"debug","z":"9b79d705.36516","name":"","active":true,"console":"false","complete":"false","x":449,"y":412,"wires":[]},{"id":"7ca45479.2ff8e4","type":"inject","z":"9b79d705.36516","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":122,"y":595,"wires":[["7481cdd9.be607c"]]},{"id":"7481cdd9.be607c","type":"function","z":"9b79d705.36516","name":"With Flow","func":"//var count=context.get('count') || 0;\nvar count=flow.get('count') || 0;\n\ncount +=1;\nmsg.payload=\"F5 \"+msg.payload+\" \"+count;\nflow.set('count',count);\nreturn msg;","outputs":1,"noerr":0,"x":274,"y":507,"wires":[["b3c59ea2.ba4068"]]},{"id":"b3c59ea2.ba4068","type":"debug","z":"9b79d705.36516","name":"","active":true,"console":"false","complete":"false","x":396,"y":601,"wires":[]},{"id":"c70a28a9.3f0018","type":"inject","z":"9b79d705.36516","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":126,"y":696,"wires":[["e8f1d04c.d13e7"]]},{"id":"e8f1d04c.d13e7","type":"function","z":"9b79d705.36516","name":"With Flow","func":"var count=flow.get('count') || 0;\n\ncount +=2;\nmsg.payload=\"F6 \"+msg.payload+\" \"+count;\nflow.set('count',count);\nreturn msg;","outputs":1,"noerr":0,"x":271,"y":647,"wires":[["b7894834.f9cd18"]]},{"id":"b7894834.f9cd18","type":"debug","z":"9b79d705.36516","name":"","active":true,"console":"false","complete":"false","x":405,"y":698,"wires":[]},{"id":"3f5132b9.9a3e9e","type":"inject","z":"9b79d705.36516","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":95,"y":331,"wires":[["3088f4d0.0b0ee4"]]},{"id":"3088f4d0.0b0ee4","type":"function","z":"9b79d705.36516","name":"Multiple variables","func":"var count=context.get('count') || 0;\nvar count2=context.get('count2') || 0;\n\n//\n\ncount +=1;\ncount2 +=2;\nmsg.payload=\"F3 \"+msg.payload+\" \"+count +\" \"+count2;\ncontext.set('count',count);\ncontext.set('count2',count2);\nreturn msg;","outputs":1,"noerr":0,"x":279,"y":290,"wires":[["d697d513.62e288"]]},{"id":"d697d513.62e288","type":"debug","z":"9b79d705.36516","name":"","active":true,"console":"false","complete":"false","x":452,"y":340,"wires":[]},{"id":"6e75a3b.86afe5c","type":"inject","z":"9b79d705.36516","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":89,"y":782,"wires":[["cafe0896.b37a9"]]},{"id":"cafe0896.b37a9","type":"function","z":"9b79d705.36516","name":"Reset","func":"var count=flow.get('count') || 0;\n\ncount =0;\nflow.set('count',count);\nreturn msg;","outputs":1,"noerr":0,"x":266,"y":781,"wires":[[]]},{"id":"56e788bf.bbda5","type":"inject","z":"9b79d705.36516","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":147,"y":933,"wires":[["5457ea02.df34b4"]]},{"id":"5457ea02.df34b4","type":"function","z":"9b79d705.36516","name":"With Global","func":"\nvar count=flow.get('count') || 0;\nvar gcount=global.get('count') || 0;\n\ncount +=1;\nmsg.payload=\"F10 \"+\" flow= \"+count+ \" global= \"+gcount;\nflow.set('count',count);\nglobal.set('count',gcount);\nreturn msg;","outputs":1,"noerr":0,"x":296,"y":840,"wires":[["1cbca862.39b138"]]},{"id":"1cbca862.39b138","type":"debug","z":"9b79d705.36516","name":"","active":true,"console":"false","complete":"false","x":459,"y":921,"wires":[]},{"id":"da4f24ed.b574f8","type":"inject","z":"9b79d705.36516","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":138,"y":1046,"wires":[["544190ee.2cdd08"]]},{"id":"544190ee.2cdd08","type":"function","z":"9b79d705.36516","name":"Global Reset","func":"var count=flow.get('count') || 0;\n\ncount =0;\nflow.set('count',count);\nglobal.set('count',count);\nreturn msg;","outputs":1,"noerr":0,"x":335,"y":1045,"wires":[[]]},{"id":"42a05a43.6656c4","type":"inject","z":"9b79d705.36516","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":126,"y":211,"wires":[["29635145.d19c66"]]},{"id":"29635145.d19c66","type":"function","z":"9b79d705.36516","name":"Function 2","func":"var count=context.get('count') || 0;\nnode.log(count);\n//\n\ncount +=1;\nmsg.payload=\"F1 \"+msg.payload+\" \"+count;\ncontext.set('count',count);\nreturn msg;\n//\n//","outputs":1,"noerr":0,"x":283,"y":152,"wires":[["4d077fc.63245"]]},{"id":"4d077fc.63245","type":"debug","z":"9b79d705.36516","name":"","active":true,"console":"false","complete":"false","x":455,"y":201,"wires":[]}]
附带源码2:
[{"id":"c8fd27c.5903358","type":"inject","z":"3d8b3bc.2f4e344","name":"","topic":"sensors/sensor1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"x":117,"y":172,"wires":[["6c6c002d.2fc9d"]]},{"id":"6c6c002d.2fc9d","type":"function","z":"3d8b3bc.2f4e344","name":"With Global","func":"\nvar count=flow.get('count') || 0;\nvar gcount=global.get('count') || 0;\n\ncount +=1;\ngcount +=5;\nmsg.payload=\"F10 \"+\" flow= \"+count+ \" global= \"+gcount;\nflow.set('count',count);\nglobal.set('count',gcount);\nreturn msg;","outputs":1,"noerr":0,"x":244,"y":79,"wires":[["9df3d6c7.acb6"]]},{"id":"9df3d6c7.acb6","type":"debug","z":"3d8b3bc.2f4e344","name":"","active":true,"console":"false","complete":"false","x":407,"y":160,"wires":[]}]