$ node-red
11 Jul 20:39:32 - [info] Welcome to Node-RED =================== 11 Jul 20:39:32 - [info] Node-RED version: v0.16.2 11 Jul 20:39:32 - [info] Node.js version: v6.11.0 11 Jul 20:39:32 - [info] Darwin 16.6.0 x64 LE 11 Jul 20:39:33 - [info] Loading palette nodes 11 Jul 20:39:33 - [warn] ------------------------------------------------------ 11 Jul 20:39:33 - [warn] [rpi-gpio] Info : Ignoring Raspberry Pi specific node 11 Jul 20:39:33 - [warn] ------------------------------------------------------ 11 Jul 20:39:33 - [info] Settings file : /Users/xanxus/.node-red/settings.js 11 Jul 20:39:33 - [info] User directory : /Users/xanxus/.node-red 11 Jul 20:39:33 - [info] Flows file : /Users/xanxus/.node-red/flows_XanxusMacde-MacBook-Pro.local.json 11 Jul 20:39:33 - [info] Server now running at http://127.0.0.1:1880/ 11 Jul 20:39:33 - [info] Starting flows 11 Jul 20:39:33 - [info] Started flows
http://127.0.0.1:1880/ 就是Node-RED平台的網址
Note:
- 如果Node-RED不是裝在全域的話,執行方式似乎也有所差異[1]
- Node-RED預設會儲存使用者資料在家目錄底下的.node-red,--userDir可作相關的操作
- 當在Raspberry Pi or BeagleBone Black等限制記憶體的裝置上運作時,或許需要把參數傳給node.js處理 [1]
- 在開機時啟動Node-RED,在Windows上可能要用NSSM的方案 [1]
查看Node-RED版本:
$ node-red --help
更新or升級Node-RED [2]:
$ sudo npm cache clean (npm5.x版貌似不支援)
$ sudo npm update -g --unsafe-perm node-red
可以額外安裝新的Node-RED節點 [3]
有兩種方式安裝:第一種、直接在Node-RED面板上安裝
點選面板右邊的菜單選單中的 Manage palette,切到Install這個tag,可以直接在這搜尋你要的套件,這裡會搜尋到Node-RED Library網站上有的套件,如果沒有在網站上的就搜尋不到
或者可直接在Node-RED Library網站直接搜尋,並直接用npm指令安裝,如:
$ npm install node-red-contrib-json-schema-validator
第二種、git clone安裝
假設我要OM2M,但官方函式庫沒有,如果github上有的話,可以clone下來在安裝
先到https://github.com/themaco/node-red-contrib-om2m clone下來
放到你的函式庫資料夾,並且到這套件的目錄位置,並安裝:
$ sudo npm install -g
Node-RED Library https://flows.nodered.org/
npm上的Node-REDpackage https://www.npmjs.com/browse/keyword/node-red
可到上面兩個連結找還有哪些額外的節點函式庫
建置一個簡單的Flow [4]
- 拉一個Inject節點,右鍵點擊節點,Repeat設Interval between times,every選5minutes,好了按Done
- 再拉一個HttpRequest節點,與前面節點連起來,URL填http://realtimeweb-prod.nationalgrid.com/SystemData.aspx
- 再拉一個function節點,與前面節點連起來,可以在這個節點裡面寫js程式碼,貼上以下程式碼:
// does a simple text extract parse of the http output to provide an // object containing the uk power demand, frequency and time if (~msg.payload.indexOf('<span')) { var dem = msg.payload.split('Demand:')[1].split("MW")[0]; var fre = msg.payload.split('Frequency:')[1].split("Hz")[0]; msg.payload = {}; msg.payload.demand = parseInt(dem.split(">")[1].split("<")[0]); msg.payload.frequency = parseFloat(fre.split(">")[1].split("<")[0]); msg2 = {}; msg2.payload = (msg.payload.frequency >= 50) ? true : false; return [msg,msg2]; } return null;
最後Outputs選2 - 最後拉一個debug節點,與前一個節點連起來,因為剛剛Output是2,因此要連兩條線。
- 點Deploy
- 點Inject節點前面的小區塊,就會下請求了。
- 回應結果在右邊的debug視窗。
Node-RED的一些系統設定 [5]
如在跑一些獨立的應用程式時,一些參數的屬性設定會從settings.js檔案讀取,貌似此檔案會根據放的地方來決定執行的順序。也可以設定一些系統的參數,像port、host IP等等
還可以更換佈景主題
Node-RED預設沒有被保護,只要知道Node-RED的IP和網址的人都可以隨意修改節點與部署。[6]
因此Node-RED也有提供一些安全上的設定。Node-RED的Log的功能
可以在settings.js設定log的一些功能與屬性Note:
- 可以用自行定義的logger模組,來把輸出發送到其他位置。
可以用指令模式來管理Node-RED [7]
但需要安裝node-red-adminNode-RED的Function Node [8]
Function Node有一個重要也是最主要的物件msg
msg底下有很多屬性如msg.payload
而msg.payload裡面放的東西其實就像http的body
msg.url放的就是你要請求的網址
msg.headers是你請求的標頭
輸出也可以是陣列:
[{"id":"ea46f50f.753b08","type":"inject","z":"eb44de0d.fcac1","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":186,"y":274,"wires":[["480852e1.561e6c"]]},{"id":"480852e1.561e6c","type":"function","z":"eb44de0d.fcac1","name":"","func":"msg.url = \"https://api.api.ai/v1/query?v=20150910\";\nmsg.headers = {\n \"Authorization\": \"Bearer 2b0ed04782064644b8066768bbda2fa5\",\n\"Content-Type\": \"application/json; charset=utf-8\"\n\n};\nmsg.payload = {\n \"query\": [\n \"我想去帥勁影印\"\n ],\n \"lang\": \"zh-cn\",\n \"sessionId\": \"1234567890\"\n};\n\nvar output = [msg,null];\n\nreturn output;","outputs":"2","noerr":0,"x":352,"y":274,"wires":[["395a11ef.5f572e"],["f825cd3e.6c83b"]]},{"id":"f825cd3e.6c83b","type":"debug","z":"eb44de0d.fcac1","name":"","active":true,"console":"false","complete":"payload","x":528,"y":300,"wires":[]},{"id":"395a11ef.5f572e","type":"debug","z":"eb44de0d.fcac1","name":"","active":true,"console":"false","complete":"payload","x":539,"y":229,"wires":[]}]先把這段Flow匯入,打開Function Node看程式碼
var output = [msg,null];
return output;
因為我output是一個陣列,因此我這個節點的輸出要拉兩條線,分別輸出到各別的Node,此例是上面那個節點觸發,而節點輸出的內容就是msg.payload,就是剛剛寫在裡面的
對API.AI下請求,並取得回應:
[{"id":"ea46f50f.753b08","type":"inject","z":"eb44de0d.fcac1","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":186,"y":274,"wires":[["480852e1.561e6c"]]},{"id":"480852e1.561e6c","type":"function","z":"eb44de0d.fcac1","name":"","func":"msg.url = \"https://api.api.ai/v1/query?v=20150910\";\nmsg.headers = {\n \"Authorization\": \"Bearer 2b0ed04782064644b8066768bbda2fa5\",\n\"Content-Type\": \"application/json; charset=utf-8\"\n\n};\nmsg.payload = {\n \"query\": [\n \"我想去帥勁影印\"\n ],\n \"lang\": \"zh-cn\",\n \"sessionId\": \"1234567890\"\n};\n\n\n\nreturn msg;","outputs":"2","noerr":0,"x":352,"y":274,"wires":[["97235edf.7a0cf"],[]]},{"id":"395a11ef.5f572e","type":"debug","z":"eb44de0d.fcac1","name":"","active":true,"console":"false","complete":"payload","x":718,"y":268,"wires":[]},{"id":"97235edf.7a0cf","type":"http request","z":"eb44de0d.fcac1","name":"","method":"POST","ret":"txt","url":"","tls":"","x":521,"y":269,"wires":[["395a11ef.5f572e"]]}]把節點匯入
Function Node是根據API.AI文件用POST下請求一定要的參數,最後包在msh物件裡面回傳並輸出
http request記得用POST
最後什麼都不用做,拉一個debug節點就可以取得回應了,比起用java來做省力很多
Multiple Messages的展示:以官網的範例展示
就是如果輸出有多個訊息,會依序從第一個開始輸出至最後一個
依順序,第一個先拉Inject、兩個function、兩個debug,且第二個function串兩個debug
[{"id":"480852e1.561e6c","type":"function","z":"eb44de0d.fcac1","name":"","func":"\nvar msg1 = { payload:\"first out of output 1\" };\nvar msg2 = { payload:\"second out of output 1\" };\nvar msg3 = { payload:\"third out of output 1\" };\nvar msg4 = { payload:\"only message from output 2\" };\nreturn [ [ msg1, msg2, msg3 ], msg4 ];","outputs":"1","noerr":0,"x":352,"y":274,"wires":[["383205a4.13ad7a"]]},{"id":"395a11ef.5f572e","type":"debug","z":"eb44de0d.fcac1","name":"","active":true,"console":"false","complete":"payload","x":708,"y":238,"wires":[]},{"id":"faef2961.d55798","type":"debug","z":"eb44de0d.fcac1","name":"","active":true,"console":"false","complete":"payload","x":705,"y":310,"wires":[]},{"id":"383205a4.13ad7a","type":"function","z":"eb44de0d.fcac1","name":"","func":"var outputMsgs = [];\nvar words = msg.payload.split(\" \");\nfor (var w in words) {\n outputMsgs.push({payload:words[w]});\n}\nreturn [ outputMsgs ];","outputs":"2","noerr":0,"x":515,"y":279,"wires":[["395a11ef.5f572e"],["faef2961.d55798"]]},{"id":"ea46f50f.753b08","type":"inject","z":"eb44de0d.fcac1","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":186,"y":274,"wires":[["480852e1.561e6c"]]}]結果會是這樣
其他一些Function節點提供的功能:
- 非同步傳送訊息(Sending messages asynchronously)
- Log事件(Logging events)
- 錯誤處理(Handling errors)
- 儲存資料(Storing data):可以在上下文儲存資料
- Flow context:官方是說這是整個Flow等級的Context,可以讓所有節點共享,而不是只有function節點
- 全域的Context(Global context):讓所有節點都可以存取變數的功能?
- 在節點旁附上狀態(Adding Status)
創造自定義的節點 - Creating Nodes
Node-RED除了提供內建的節點,還可以自行定義創造屬於自己獨一無二的節點
一個節點由兩個檔案組成,分別是Javascript和html檔
就來用官方範例來創創看,是一個把內容轉變為小寫的例子
創建一個目錄,裡面有以下的檔案:
package.json
lower-case.js
lower-case.html
1.先建構一個標準的package.json
打入此指令
$ npm init
會跳出一段訊息,然後會要你輸入一些資料,就是這個描述檔的內容
package name打入node-red-contrib-example-lower-case
description打入內容轉成小寫
其他enter跳過就可以
最後他會產生在家目錄底下,叫package.json
{ "name": "node-red-contrib-example-lower-case", "node-red": { "nodes": { "lower-case": "lower-case.js" } }, "version": "1.0.0", "description": "內容轉成小寫", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }並在裡面加入node-red的片段,如上
另外文件有一頁是針對打包所寫的有需要可以看看 http://bit.ly/2tPat67
lower-case.js檔的部分
lower-case.html檔
name屬性是在面板上這個Node會顯示的名稱。
接下來,把它安裝到Node-RED上
用終端機移動到package.json檔案的目錄,並下:
$ sudo npm link
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN node-red-contrib-example-lower-case@1.0.0 No repository field.
up to date in 0.099s
/Users/xanxus/.nvm/versions/node/v6.11.0/lib/node_modules/node-red-contrib-example-lower-case -> /Users/xanxus/lower-case
上面是他回應的訊息
重啟Node-RED,打開右邊的選單選Manage palette會發現node-red-contrib-example-lower-case
應該是我們剛剛建的...
回去面板,左邊列表找找看就有了
節點由建構函數所構成,並在執行時註冊。
首先要先呼叫RED.nodes.createNode來初始化所有節點都有的特徵:
並在監聽器上註冊input事件,以從Flow接收訊息
並使用send函數寄送訊息
另外還有close事件
如果節點要執行其他非同步工作,則註冊的監聽器需引入一個參數,該參數是在所有工作完成時才會被呼叫。
文件寫到,在命名節點時,最好符合官方的命名規則
例如,節點類型是sample-node,對外公開的名稱是colour,那在設定檔的名稱就要叫sampleNodeColour
如果要把設置公開給編輯器,那要像以下這樣寫:
它包含三個不同的部分,每個部分都含有<script>的標籤。
第一部分:定義節點的一些外觀屬性,如顏色、icon、類型...
第二部分:定義節點的表單
第三部分:定義輔助的文字說明
第一部分:定義節點的一些外觀屬性,如顏色、icon、類型...
必須用一個叫RED.nodes.registerType的函數來定義,此函數有兩個參數,為node-type和該函數裡面的內容(你要做的事情.....)
Note:node-type是面板上會呈現的名稱。如果是in和out,那呈現的還是原本的名稱,如內建的mqtt in、mqtt out,分別放在input和output的地方,但info的Node Type是mqtt in。
定義它給的內建的屬性值
官方的範例有這些值category、color、defaults、inputs、outputs、icon........這只是一部分
其他可以定義的屬性:
category: (string) the palette category the node appears in
defaults: (object) the editable properties for the node.
credentials: (object) the credential properties for the node.
inputs: (number) how many inputs the node has, either 0 or 1.
outputs: (number) how many outputs the node has. Can be 0 or more.
color: (string) the background colour to use.
paletteLabel: (string|function) the label to use in the palette.
label: (string|function) the label to use in the workspace.
labelStyle: (string|function) the style to apply to the label.
inputLabels: (string|function) optional label to add on hover to the input port of a node.
outputLabels: (string|function) optional labels to add on hover to the output ports of a node.
icon: (string) the icon to use.
align: (string) the alignment of the icon and label.
oneditprepare: (function) called when the edit dialog is being built. See custom edit behaviour.
oneditsave: (function) called when the edit dialog is okayed. See custom edit behaviour.
oneditcancel: (function) called when the edit dialog is cancelled. See custom edit behaviour.
oneditdelete: (function) called when the delete button in a configuration node’s edit dialog is pressed. See custom edit behaviour.
oneditresize: (function) called when the edit dialog is resized. See custom edit behaviour.
onpaletteadd: (function) called when the node type is added to the palette.
onpaletteremove: (function) called when the node type is removed from the palette.
第二部:定義節點的表單
它定義的是這個地方的介面:
官方文件裡叫做dialog(對話框)
第三部分沒什麼,不寫
這裡範例主要是示範如何在.js程式碼中用.html定義的屬性值
做完之後的結果是這樣:
像
defaults: {
name: {value:""},
prefix: {value:""}
},
除了value還有required(布林型態)、validate(function)、type
lower-case.js檔的部分
module.exports = function(RED) { function LowerCaseNode(config) { RED.nodes.createNode(this,config); var node = this; node.on('input', function(msg) { msg.payload = msg.payload.toLowerCase(); node.send(msg); }); } RED.nodes.registerType("lower-case",LowerCaseNode); }
lower-case.html檔
<script type="text/javascript"> RED.nodes.registerType('lower-case', { category: 'function', color: '#a6bbcf', defaults: { name: { value: "" } }, inputs: 1, outputs: 1, icon: "file.png", label: function() { return this.name || "lower-case"; } }); </script> <script type="text/x-red" data-template-name="lower-case"> <div class="form-row"> <label for="node-input-name"><i class="icon-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> </script> <script type="text/x-red" data-help-name="lower-case"> <p>A simple node that converts the message payloads into all lower-case characters</p> </script>這裡注意一下defaults物件,它裡面的東西是Node的屬性,name只是其中一個,所以還有其他很多屬性。
name屬性是在面板上這個Node會顯示的名稱。
接下來,把它安裝到Node-RED上
用終端機移動到package.json檔案的目錄,並下:
$ sudo npm link
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN node-red-contrib-example-lower-case@1.0.0 No repository field.
up to date in 0.099s
/Users/xanxus/.nvm/versions/node/v6.11.0/lib/node_modules/node-red-contrib-example-lower-case -> /Users/xanxus/lower-case
上面是他回應的訊息
重啟Node-RED,打開右邊的選單選Manage palette會發現node-red-contrib-example-lower-case
應該是我們剛剛建的...
回去面板,左邊列表找找看就有了
如果要更新的話,就再下一次指令就好,然後重啟Node-RED
接下來是.js檔案的細節部分:
Node的.js檔主要定義Node執行時的行為節點由建構函數所構成,並在執行時註冊。
首先要先呼叫RED.nodes.createNode來初始化所有節點都有的特徵:
function SampleNode(config) { RED.nodes.createNode(this,config); // node-specific code goes here } RED.nodes.registerType("sample",SampleNode);
並在監聽器上註冊input事件,以從Flow接收訊息
this.on('input', function(msg) { // do something with 'msg' });
並使用send函數寄送訊息
var msg = { payload:"hi" } this.send(msg);如果msg為空,則不會發送任何訊息
另外還有close事件
如果節點要執行其他非同步工作,則註冊的監聽器需引入一個參數,該參數是在所有工作完成時才會被呼叫。
文件寫到,在命名節點時,最好符合官方的命名規則
例如,節點類型是sample-node,對外公開的名稱是colour,那在設定檔的名稱就要叫sampleNodeColour
如果要把設置公開給編輯器,那要像以下這樣寫:
RED.nodes.registerType("sample",SampleNode, { settings: { sampleNodeColour: { value: "red", exportable: true } } });
再來是HTML檔的詳細:
HTML檔主要定義節點在面板上呈現的方式。它包含三個不同的部分,每個部分都含有<script>的標籤。
第一部分:定義節點的一些外觀屬性,如顏色、icon、類型...
第二部分:定義節點的表單
第三部分:定義輔助的文字說明
第一部分:定義節點的一些外觀屬性,如顏色、icon、類型...
必須用一個叫RED.nodes.registerType的函數來定義,此函數有兩個參數,為node-type和該函數裡面的內容(你要做的事情.....)
<script type="text/javascript"> RED.nodes.registerType('node-type',{ // node definition }); </script>Note:其中node-type必須與.js檔匹配。如果這個節點叫lower-case,那js檔那裡也要叫lower-case。
Note:node-type是面板上會呈現的名稱。如果是in和out,那呈現的還是原本的名稱,如內建的mqtt in、mqtt out,分別放在input和output的地方,但info的Node Type是mqtt in。
定義它給的內建的屬性值
官方的範例有這些值category、color、defaults、inputs、outputs、icon........這只是一部分
其他可以定義的屬性:
category: (string) the palette category the node appears in
defaults: (object) the editable properties for the node.
credentials: (object) the credential properties for the node.
inputs: (number) how many inputs the node has, either 0 or 1.
outputs: (number) how many outputs the node has. Can be 0 or more.
color: (string) the background colour to use.
paletteLabel: (string|function) the label to use in the palette.
label: (string|function) the label to use in the workspace.
labelStyle: (string|function) the style to apply to the label.
inputLabels: (string|function) optional label to add on hover to the input port of a node.
outputLabels: (string|function) optional labels to add on hover to the output ports of a node.
icon: (string) the icon to use.
align: (string) the alignment of the icon and label.
oneditprepare: (function) called when the edit dialog is being built. See custom edit behaviour.
oneditsave: (function) called when the edit dialog is okayed. See custom edit behaviour.
oneditcancel: (function) called when the edit dialog is cancelled. See custom edit behaviour.
oneditdelete: (function) called when the delete button in a configuration node’s edit dialog is pressed. See custom edit behaviour.
oneditresize: (function) called when the edit dialog is resized. See custom edit behaviour.
onpaletteadd: (function) called when the node type is added to the palette.
onpaletteremove: (function) called when the node type is removed from the palette.
第二部:定義節點的表單
它定義的是這個地方的介面:
官方文件裡叫做dialog(對話框)
第三部分沒什麼,不寫
Node context [11]
節點可以利用context物件儲存資料,每次重新部署、重新啟動Node-RED Context都會被重置。Node properties
defaults物件是定義在.html裡面這裡範例主要是示範如何在.js程式碼中用.html定義的屬性值
做完之後的結果是這樣:
Property definitions [12]
屬性裡面可以再定義屬性...像
defaults: {
name: {value:""},
prefix: {value:""}
},
除了value還有required(布林型態)、validate(function)、type
Node credentials [13]
有時我們有一些私密的屬性值,如帳號密碼等....不希望被匯出,可以把這些定義在這個地方這樣就不會被匯出的樣子?
官方文件上也有寫如何存取在這定義的屬性值
Node appearance [14]
主要是定義Node的外觀
Node status [15]
定義Node目前執行的狀態,狀態會顯示在這個Node底下。
Node help style guide [16]
Raspberry Pi上的NodeRED [17]
安裝完Pi的作業系統,會預設幫你裝好Node.js和NodeRED,但版本是蠻舊的,接下來我們要把這兩個升級版本:$ update-nodejs-and-nodered
過程中會把他要做的事情列一個清單,做完就打勾
更新完後,啟動NodeRED,會發現版本都更新了
Node-RED version: v0.17.5
Node.js version: v6.11.2
因為裝新的Node.js所以npm剛剛也裝好了,原本是沒有npm
$ npm --version
3.10.10
Note:npm最新版本是4,但官方不推薦使用
更新python-gpio
$ sudo apt-get update && sudo apt-get install python-rpi.gpio
NodeRED啟動的方式在Pi上有分兩種:
第一種是文件比較早提到的
$ sudo systemctl enable nodered.service
這個指令,在Pi開機的時候啟動NodeRED
第二種是SystemD,也是官方推薦的方式
他是把啟動和停止和開機就啟動寫成一個腳本,讓你可用一個指令來操作
很像已經幫你裝好了,我直接下$ node-red-start 就啟動了
停止的話還是要下$ node-red-stop 來停止
問題一:遇到找不到package.json的錯誤訊息
http://bit.ly/2xVESUn
問題二:一開啟NodeRED,上次拉的Block都不見了
有次原本辛辛苦苦拉的方塊,也部署完了,隔一陣子沒用NodeRED,再次開啟NodeRED時拉的Node(or Block)都不見了,然後Console就會出現一些訊息,說什麼Flow不存在...
至今原因未知,但有找到解決方法,經調查後並不是不見,而存在其他Flow檔,去.node-red底下發現有4個Flow的json檔,為:
flows_XXXXXMacde-MBP.json
flows_XXXXXMacde-MBP_cred.json
flows_XXXXXMacde-MacBook-Pro.local.json
flows_XXXXXMacde-MacBook-Pro.local_cred.json
首先我們一打開NodeRED,拉的Node或是說Block,他們都存放在flow裡面,當然我們可能會建立很多Flow來放Node,但她最後都會存放在同一個檔案裡面,就是像上面flows_XXXXXMacde-MBP.json或是flows_XXXXXMacde-MacBook-Pro.local.json
XXXXX就是我這台電腦的名稱
那不知為何有時打開它就沒有抓到原本的flow.json檔,而是抓到另一個,也就是說原本拉的還在!但有時他又會自己抓回原本的。
所以,請打開~/.node-red/settings.js檔案,找到flowFile這個屬性,它原本是被註解掉的,去除註解並打上你NodeRED要抓的那個Flow.json檔,像這樣:
flowFile: 'flows_XXXXXMacde-MacBook-Pro.local.json'
這樣他就會固定讀這個Flow檔了。
重啟NodeRED,成功。
Context
Context就是可以在Node與Node之間或Flow與Flow之間儲存資料。
有分三種:
- 一般的Context
- Flow等級的Context
- Global等級的Context
以下用一些簡單的範例來測試這幾種Context的特性。
Context 1與Context 2的原始碼都一樣,如下:
// initialise the counter to 0 if it doesn't exist already var count = context.get('count')||0; count += 1; // store the value back context.set('count',count); // make it part of the outgoing msg object msg.count = count; return msg;
程式很簡單,就是數字累加而已。
參考資料:
而這種一般的Context只會儲存同一個Flow的值,也就是Context 1與Context 2都是獨立的,Context 1不會儲存到Context 2的值,即使定義的變數名稱一樣也是互相獨立。
Flow Context 1和Flow Context 2原始碼都一樣,如下:
可以發現他們共用了變數的資料。
下圖為重新部署的實驗結果:
發現他們會紀錄上次的值,也就是說重新部署不會洗掉。
但是NodeRED重新啟動後就會洗掉重置了。
並且它只儲存同一個Flow頁籤,也就是說再開一個新的Flow頁籤並不會持續記錄,就會是一個新的獨立的個體物件。
下圖是Global等級的Context,位於第一個Flow頁面:
下圖位於第二個Flow頁面:
上圖是觸發Context 1兩次和觸發Context 2一次的結果,印證了上述的說明。
每次重新部署和NodeRED重新啟動後,都會重置儲存的Context值。
並且也只作用於同一個Flow頁籤。
下圖是Flow等級的Context:
// initialise the counter to 0 if it doesn't exist already //var count = context.get('count')||0; var count = flow.get('count')||0; count += 1; // store the value back flow.set('count',count); // make it part of the outgoing msg object msg.count = count; return msg;下圖是對Flow Context 1觸發兩次,Flow Context 2觸發一次的實驗:
可以發現他們共用了變數的資料。
下圖為重新部署的實驗結果:
發現他們會紀錄上次的值,也就是說重新部署不會洗掉。
但是NodeRED重新啟動後就會洗掉重置了。
並且它只儲存同一個Flow頁籤,也就是說再開一個新的Flow頁籤並不會持續記錄,就會是一個新的獨立的個體物件。
下圖是Global等級的Context,位於第一個Flow頁面:
下圖位於第二個Flow頁面:
下圖是分別觸發Global Context 1到Global Context 3的結果:
結論是,Global等級的Context可以在不同的Flow頁面之間儲存資料。
重新部署不會洗掉。
但NodeRED重新啟動就會洗掉。
Context層級\特性 | 作用範圍 | 不同條的Flow是否共用 | 不同Flow頁籤是否共用 | 重新部署是否會保留物件 | 重啟NodeRED是否會保留物件 |
Node | 只存在於設置這個Node層級變數的這個節點中 | 否 | 否 | 否 | 否 |
Flow | 可存在於多條Flow、多個節點中 | 是 | 否 | 是 | 否 |
Global | 可存在於多條Flow且不同頁籤的Flow中 | 是 | 是 | 是 | 否 |
參考資料:
- Running https://nodered.org/docs/getting-started/running
- Upgrading https://nodered.org/docs/getting-started/upgrading
- Adding Nodes https://nodered.org/docs/getting-started/adding-nodes
- Creating your second flow https://nodered.org/docs/getting-started/second-flow
- Configuration https://nodered.org/docs/configuration
- Security https://nodered.org/docs/security
- Command-line Administration https://nodered.org/docs/node-red-admin
- Writing Functions https://nodered.org/docs/writing-functions
- Creating Nodes https://nodered.org/docs/creating-nodes/
- Packaging https://nodered.org/docs/creating-nodes/packaging
- Node context https://nodered.org/docs/creating-nodes/context
- Property definitions https://nodered.org/docs/creating-nodes/properties
- Node credentials https://nodered.org/docs/creating-nodes/credentials
- Node appearance https://nodered.org/docs/creating-nodes/appearance
- Node status https://nodered.org/docs/creating-nodes/status
- Node help style guide https://nodered.org/docs/creating-nodes/help-style-guide
- Running on Raspberry Pi https://nodered.org/docs/hardware/raspberrypi.html
- 週二來一招, Node-RED 簡單講講 (Node-RED)http://bit.ly/2ey5FLu
沒有留言:
張貼留言