起因
作為Python開發者,其實很羨慕JavaScript一種天生的開發能力:可視化編程。這不僅僅是指GUI,Web前端,還包括一些建模和原型規劃方面的能力。其中包括基于Node.js的Node-RED,是IoT原型開發的利器。這種設計可以追溯到Yahoo的Pipe服務。作為一種基于Web的可視化編輯器,Node-RED可以定義IoT、Web開發中所需的各類組件。
在IoT日常開發中, 經常使用代碼來實現的工作,有相當一部分設計可以用該工具完成。可是試用之后,我發現該工具是面向流的設計工具,如果前端的接入協議需要定制,或者需要復雜的狀態機,那么這種設計可能無法替代人工編碼。
加上,我的JavaScript編程能力不如Python熟悉,且Node-RED的文檔,至少教程部分并不齊全。所以我并沒有將其投入到實際的工程設計中。而且Node-RED是一個容易被遺忘的工具,一旦設計完成后,基本上也不會老是去修改。
Python與Node-RED
Node-RED與其他IoT所需組件的配合可以加快系統的開發速度:
- 消息隊列,包括MQ和MQTT,甚至Redis中的PubSub都可以作為Node-RED與其他服務進程之間的耦合組件;
- 數據庫,除了SQL RDBS,還有Redis/MongoDB和InfluxDB等;
- 云計算API,各類云計算都是通過API整合的,那么HTTP request就可以幫上忙了。
- 操作系統,包括調用操作系統的crontab和服務進程、腳本、文件系統、串口和服務等。
相對多數的IoT設計中,二進制協議是占據主體的。包括CoAP/MQTT都是如此。雖然ECMAScript 2015規定了JavaScript處理二進制的對象和方法,但大多數早期設計中JavaScript處理二進制數據比較麻煩。這些定制協議的數據處理和狀態機,可以使用Python來做處理,并轉換成JSON推送給Node-RED,更加方便使用。
Node.js早期的版本依賴項中甚至包含Python。所以Node.js其實和Python有一定相關性。這兩種是可以互相依賴的。所以我在Nodest-RED里找到了一個很重要的Node:Python function。開發者可以用Node-RED設計合適的流,并使用Python Function Node來實現其中對于流的解析、轉發和處理。
Node-RED的角色定位
原理上說,即使是類似于Xively的IoT設備云,也需要切割為:
- Connector,各類協議的轉換和狀態機,以及認證等;
- Web,管理界面,RBAC,API管理等;
- Data,包括緩存和持久保存等。
Node-RED可以作為三者間的連接設計器,也可以用過HTTP endpoint來充任部分的Web功能,不過我覺得在復雜系統中,在版本控制系統的協助下,用代碼實現更加合理。用鼠標來產生三位數的URL,管理起來很有難度。或者至少需要另外的工具來一口氣產生100多個endpoint nodes。但是查看起來,需要很大的顯示器可視面積。
Node-RED感覺像是一個任何工作都可以實現的復合工具,但是它也不是萬能的,在某些方面效率設置不如人工編碼。
典型的IoT接入云平臺需要包括:
- MQTT over TLS,可以使用mosquitto和許多MQ實現;
- CoAP over D-TLS,可以使用Python Twisted/Tornado實現;
- HTTP over TLS, 即HTTPS,標準化實現;
- WebSocket,標準化實現;
- 定制二進制協議,傾向于Twisted實現。
所以,Node-RED可以用于1/3/4三種協議實現,其他的可以交由Twisted/Tornado實現。
功能重合的選擇
雖然,使用Twisted/Tornado可以實現大多數的協議,但是我個人越來越傾向于將應用層協議從Twisted Connector中剝離出來,所以Twisted雖然從Connector中可以直接訪問各類數據庫,但是數據庫視圖本質上是設備建模,直接的后果就是一旦協議或者設備建模任何一方發生變化,都不得不重新啟動,且有版本失控的風險。
Client --> Twisted_Connector --> RBDS/TSDB --> WebAPI --> MobileAPP
所以,我現在的方式是將Twisted Connector獨立運行,將與設備連接有關的部分保留在Connector,數據在Connector中變化為JSON對象,通過mosquitoo推送。Node-RED處理后,保存在數據庫中。這樣處理的好處,還有一個就是可以通過mosquitoo直接通過Web API推送給API的利用者,比如第三方網站和移動應用。
Client --> Twisted_Connector --> mosquitoo --> RBDS/TSDB --> DataAnalyst
|
+--> WebAPI --> MobileAPP
此圖中看不出Node-RED的位置,但實際上,mosquitto --> DB
以及mosquitto-->WebAPI
可以用來實現粘合。當然,Python/Node.js里本來就可以用來實現MQTT client。
價值所在
利用PubSub/MQ/API是實現許多微服務的基礎,那么Node-RED就是這種微服務的縫紉針和膠水。在此基礎上,利用Python/Node.js開發一些基于Web和MQ的標準化API,即使單個API功能簡單,但是通過Node-RED整合,就足夠支撐一些復雜系統。