digiRunner Composer node-red

Composer function 節點的基本介紹

顏綸 Lun Yan 2023/12/19 18:34:57
945

前言

如果還不知道什麼是 Composer 的朋友們,可以先參考這篇 DigiRunnerAPI組合與設計 。

該篇範例會用到 debug 節點與 inject 節點,如果想深入了解這兩個節點的朋友,也可以參考以下這兩篇:

Composer debug 節點的完整介紹

Composer inject 節點的完整介紹

 

當遇到複雜邏輯處理且現有節點無法滿足需求時,我們會使用 function 節點來解決這些問題,

其節點內部提供使用者去撰寫 JavaScript,並在流經 function 節點時執行。

此篇將會分享設定介面如何使用以及提供一些範例給大家參考。

 

 

一、基本介紹

function 節點是屬於 Node-RED 的功能節點並且內部執行的語言皆為 JavaScript。

以下是節點設定介面的介紹:

(一) 函數介面:該介面是資訊流 (msg) 流經 function 節點時,會觸發此介面的程式碼。

 

(二) 設置介面:每次部署節點後都會執行設置介面內的程式碼。

 

(三) 關閉介面:每次重新部署節點或是節點停止後都會執行關閉介面內的程式碼。第一次部署該節點關閉介面內的程式碼不會執行

 

(四) Setup 介面:

(1) 輸出如果是 2 ,就會如下圖所示有兩個輸出點。

這邊要注意的是輸出要為陣列,如果不是陣列,則默認從上面第一個輸出點輸出資訊,

而陣列第一個元素對應由上往下數第一個輸出點,第二個元素對應第二個輸出點,以此類推。

(2) 設定逾時。是執行階段允許 function 節點運作的時間,如超過時間則引發錯誤,並中斷流程。

此值以秒為單位,如果設定為 0(預設值),則不套用逾時。

(3) 可以在其中添加其他第三方模組並用於此 function 節點,其他所有的 function 節點也能引用此模組。

 

(五) 打開 library 介面:左邊介面為已儲存的 function 列表,並在選取時顯示節點資訊於右下方和右上方的函數介面。

讀取後會完全覆蓋並取代目前的 function 節點。

 

(六) 保存到 library 介面:保存該 function 節點內的所有資訊至 library,並在"匯出為"那邊自訂名稱。

 

 

二、節點效果與特性

在 function 節點中 coding 會如 IDE 一樣提示是否用現有的物件或方法,如下圖所示:

該節點除了有 JavaScript 內的原生方法外,還有 node-red 提供的一些物件做工具使用,

以下將會介紹 node-red 提供的物件:

(1) 一般項:

node.id :function 節點的 id

node.name :function 節點的名稱

node.outputCount:設定 function 節點的輸出數量

 

(2) log:紀錄

node.log(..)

node.warn(..)

node.error(..)

node.debug(..)

node.trace(..)

依造使用方法的等級,顯示 log 至右方的除錯面板和 dgR 的 online console 上,如下圖所示:

我在函數的地方使用 node.error("錯誤 LOG 測試"),當觸發並執行後會如以下顯示:

除錯面板:

online console:

 

(3) 節點狀態相關

node.on(..) :註冊事件處理程序

node.status(..) : 更新節點狀態

e.g. node.status({fill:"red",shape:"ring",text:"disconnected"});

 

node.send(..):非同步傳送訊息,使用此方法可以在 function 節點執行完畢 (output msg) 之前輸出訊息

node.done() : 以訊息結束,通常用於非同步情境

 

(4) context:節點範圍內的屬性

context.get(..):取得節點範圍的上下文屬性

context.set(..):設定節點範圍的上下文屬性

context.keys(..):傳回所有節點範圍的上下文屬性鍵的列表

context.flow: 與...一樣flow

context.global: 與...一樣global

 

(5) flow:API 流程範圍內的屬性

flow.get(..):取得流範圍的上下文屬性

flow.set(..):設定流範圍的上下文屬性

flow.keys(..):傳回所有流範圍上下文屬性鍵的列表

 

(6) global:全域屬性

global.get(..):取得全域範圍的上下文屬性

global.set(..):設定全域範圍的上下文屬性

global.keys(..):傳回所有全域範圍上下文屬性鍵的列表

 

(7) RED

RED.util.cloneMessage(..):安全地複製訊息對象,以便可以重複使用它,

相當於 deep copy 的作用。

 

(8) env

env.get(..): 取得環境變數

例如我在環境變量面板設置了 { "ssd": "159" },那當我呼叫 env.get("ssd") 則會得到 "159"。

 

 

三、簡單範例

這邊做了一個範例並用到一些剛剛介紹的 node-red 物件與方法來實現 HTTP 的請求,流程如下:

Setup 方面把輸出變為 2,設定如下:

其 function 節點內部程式碼如下圖所示:

我們在全域參數取得引用方法(註1),並引用了 JavaScript 內建的 http 模組,

const _require = global.get("require");

const http = _require('https');

 

接下來對 hello world api 進行請求,

回應後,我們使用了 node.send([msg, null]) 來發送得到的回應至 debug 34 節點,debug 35 節點不會收到任何東西

最後使用 node.done() 宣告此節點執行完畢。

 

而關於錯誤處理的部分,我們使用 http 模組的 on 來監聽 error 事件,當請求出錯時,

會發送錯誤訊息至 debug 35 節點,debug 34 節點不會收到任何東西。

 

註1:關於引用的方法 "require",雖然在 IDE 內會出現有此方法可以使用,如下圖所示:

但是實際上並無此方法,所以在 Composer 中可以使用 const _require = global.get("require") 來得到 "require" 模組。

 

 

四、結語

function 節點是個極度便利且能滿足大部分需求的節點,可以說只要懂 JavaScript 的工程師,都愛用它,

像是寧可使用 function 節點置換參數也不要用 converter 節點來置換,

但其實以小弟觀點來說,function 節點屬於解決需求的最後手段,因為 Composer 本質屬於可視化流程,可讀性、偵錯性與靈活性高,

如果將大量流程塞入 function 節點中,那這個黑盒子會降低可讀性、偵錯性與靈活性,所以建議小心服用。

 

 

五、參考文獻

(1) node-red 官方

(2) 自己

 

 

 

 

 

顏綸 Lun Yan