物聯(lián)網(wǎng)網(wǎng)關(guān)開發(fā):基于MQTT消息總線的設(shè)計過程
MQTT網(wǎng)關(guān)的作用
MQTT物聯(lián)網(wǎng)這個詞語的范疇太廣,似乎所有的硬件設(shè)備,只要能夠接入網(wǎng)絡(luò),就可以稱之為物聯(lián)網(wǎng)產(chǎn)品,似乎物聯(lián)網(wǎng)這個詞可以把一切都納入到其中。
這么空洞的詞語不利于我們的講解,因此我們就用一個可以感知、想象的場景來代替,那就是智能家居系統(tǒng),這是物聯(lián)網(wǎng)時代的典型產(chǎn)品了。
1.指令轉(zhuǎn)發(fā)
在一個智能家居系統(tǒng)中,假設(shè)有這么幾個設(shè)備:紅外感應(yīng)、門磁、插座、排插、聲光報警器、燈泡。
這些設(shè)備的通信模塊,如果是 WiFi 或者是藍牙,那么一般都可以直接通過手機來控制(當然,需要廠家提供相應(yīng)的手機 APP),手機就相當于一個中心節(jié)點,控制著所有的設(shè)備。
目前市面上的一些智能設(shè)備單品都是這樣的通信方式,例如:空調(diào)、吸塵器、空氣凈化器、冰箱等等。只要在這些設(shè)備中加一個無線通信模塊即可(例如:ESP8266模塊)。
如果通信模塊是其它的通信模塊,例如:RF433、ZigBee、ZWave等,由于手機沒有這些通信模塊,因此就需要一個網(wǎng)關(guān)來“轉(zhuǎn)發(fā)”指令。
手機和網(wǎng)關(guān)都連接到家中的路由器,處于同一個局域網(wǎng)中,手機把控制指令發(fā)送給網(wǎng)關(guān),網(wǎng)關(guān)再把指令轉(zhuǎn)發(fā)給相應(yīng)的設(shè)備。
2.外網(wǎng)通信
在上面的通信模型中,手機和網(wǎng)關(guān)由于處于同一個局域網(wǎng)中,因此可以直接通信。如果手機不在局域網(wǎng)中呢?那么就要通過云端的服務(wù)器來轉(zhuǎn)發(fā)了,通信模型如下:
手機把指令發(fā)到服務(wù)器;
服務(wù)器把指令轉(zhuǎn)發(fā)給網(wǎng)關(guān);
網(wǎng)關(guān)把指令發(fā)給指定的設(shè)備;
以上是控制指令的流程,如果是設(shè)備發(fā)出的報警信息呢,數(shù)據(jù)的流向就是反向進行的。
可以看出,網(wǎng)關(guān)是所有設(shè)備之間通信的中心節(jié)點,也是內(nèi)網(wǎng)與外網(wǎng)之間通信的中轉(zhuǎn)節(jié)點,也就是把各種智能設(shè)備連接到互聯(lián)網(wǎng)的中轉(zhuǎn)器。
3.協(xié)議轉(zhuǎn)換
上面已經(jīng)提到,硬件設(shè)備上的通信模塊都是確定的(RF,ZigBee,ZWave等等),一般來說,可以把這些通信模塊稱呼為無線通信協(xié)議。在一套智能家居系統(tǒng)中,所有設(shè)備的無線通信協(xié)議大部分都是相同的。
那么,不同類型的無線通信協(xié)議設(shè)備是否可以共存在同一個系統(tǒng)中呢?
答案是:可以。只要在網(wǎng)關(guān)中,集成了相應(yīng)的無線通信協(xié)議模塊就可以達到這個目的!
從手機APP上看,所有的設(shè)備都是相同的,不會關(guān)心設(shè)備的無線通信協(xié)議是什么,因此,發(fā)出的控制指令都是協(xié)議無關(guān)的。
當網(wǎng)關(guān)接收到控制指令時,首先根據(jù)指令內(nèi)容查找出目標設(shè)備,然后確定目標設(shè)備的無線通信協(xié)議,后把指令發(fā)送給對應(yīng)的硬件通信模塊,由該通信模塊通過無線電信號把控制指令發(fā)送到設(shè)備。
從這個指令的傳輸過程來看,網(wǎng)關(guān)就充當著協(xié)議轉(zhuǎn)換的角色。
另外還有一種通信場景:當系統(tǒng)中的一個“輸入”設(shè)備與一個“輸出”設(shè)備進行綁定/關(guān)聯(lián)時,例如:
(1)紅外感應(yīng)器與聲光報警器綁定:當紅外感應(yīng)器監(jiān)測到人體時,發(fā)出信號,然后控制聲光報警器發(fā)出報警;
(2)門磁與燈綁定:當開門時,門磁發(fā)出信號,自動打開燈光;
如果“輸入”設(shè)備與“輸出”設(shè)備是不同類型的無線通信協(xié)議,也需要網(wǎng)關(guān)來進行協(xié)議轉(zhuǎn)換。
4.設(shè)備管理
在一個智能家居系統(tǒng)中,設(shè)備可多可少,對這些設(shè)備進行管理也是很重要的事情。網(wǎng)關(guān)作為系統(tǒng)的中心節(jié)點,對設(shè)備進行管理的重任理所當然就由網(wǎng)關(guān)來承擔(dān)。
設(shè)備管理功能包括:
設(shè)備的添加和刪除;
設(shè)備狀態(tài)的管理(電量、設(shè)備斷網(wǎng)、失聯(lián)等等);設(shè)備樹的管理;
邊沿計算(自動化控制)
在正常的情況下,網(wǎng)關(guān)是可以通過路由器,與服務(wù)器保持著長連接的。如果服務(wù)器的處理能力比較強大,智能家居系統(tǒng)中所有需要處理的事情都可以丟給服務(wù)器來計算、處理,服務(wù)器在計算之后把處理結(jié)果再發(fā)送給網(wǎng)關(guān)??雌饋硐敕ê芡昝?!
但是,考慮下面這 2 種情況:
路由器出現(xiàn)問題了,網(wǎng)關(guān)無法連接到服務(wù)器,因此就無法把本地數(shù)據(jù)及時上報;
系統(tǒng)中出現(xiàn)了異常情況,需要緊急處理,如果把信息上報到服務(wù)器,由服務(wù)器計算之后再回傳給網(wǎng)關(guān),耗費的時間可能超過了可容忍時間,該如何處理?(可以用車聯(lián)網(wǎng)系統(tǒng)來腦補一下這個場景:自動駕駛中的汽車遇到緊急情況,如果把所有信息上傳給服務(wù)器,然后等待服務(wù)器的下一步指令?)
對于上面的這些場景,把一些計算、處理操作放在網(wǎng)關(guān)這一端來處理也許更合適!這也是近幾年比較流行的邊沿計算。
(1)邊緣計算,是指在靠近物或數(shù)據(jù)源頭的一側(cè),采用網(wǎng)絡(luò)、計算、存儲、應(yīng)用能力為一體的開放平臺,就近提供近端服務(wù)。
(2)其應(yīng)用程序在邊緣側(cè)發(fā)起,產(chǎn)生更快的網(wǎng)絡(luò)服務(wù)響應(yīng),滿足行業(yè)在實時業(yè)務(wù)、應(yīng)用智能、安全與隱私保護等方面的基本需求。
(3)邊緣計算處于物理實體和工業(yè)連接之間,或處于物理實體的頂端。而云端計算,仍然可以訪問邊緣計算的歷史數(shù)據(jù)
網(wǎng)關(guān)內(nèi)部進程之間的通信
在設(shè)計一個應(yīng)用程序的架構(gòu)時,可以通過多線程來實現(xiàn),也可以通過多進程來實現(xiàn),每個人的習(xí)慣都不一樣,各有各的好處。我們這里不去討論孰優(yōu)孰劣,因為我對多進程這樣的設(shè)計思想比較偏愛,所以就直接按照多進程的程序架構(gòu)來討論。
5.網(wǎng)關(guān)中需要哪些進程
網(wǎng)關(guān)中需要執(zhí)行的所有進程,是根據(jù)網(wǎng)關(guān)的功能來決定的,假設(shè)包括如下的功能:
(1)連接外網(wǎng)的進程 Proc_Bridge
網(wǎng)關(guān)需要連接到云端的服務(wù)器,需要一個進程與服務(wù)器之間保持長連接,這樣就可以及時接收到服務(wù)器發(fā)來的控制指令,以及把系統(tǒng)內(nèi)部數(shù)據(jù)及時上報給服務(wù)器。
這個進程需要把從服務(wù)器接收到的指令轉(zhuǎn)發(fā)到網(wǎng)關(guān)系統(tǒng)內(nèi)部,把從系統(tǒng)內(nèi)部接收到的信息轉(zhuǎn)發(fā)給服務(wù)器,類似于橋接的功能,因此命名為 Proc_Bridge。
(2)設(shè)備管理進程 Proc_DevMgr
這個進程用來執(zhí)行設(shè)備管理功能,設(shè)備的添加(入網(wǎng))、刪除(退網(wǎng)),都由此進程來管理。
(3)協(xié)議轉(zhuǎn)換進程 Proc_Protocol
下行:把應(yīng)用層的統(tǒng)一通信協(xié)議,轉(zhuǎn)換成不同類型無線通信協(xié)議,發(fā)送給相應(yīng)的無線模塊。
上行:把設(shè)備上報的、不同類型的無線通信協(xié)議,轉(zhuǎn)換成應(yīng)用層的統(tǒng)一通信協(xié)議。
(4)邊沿計算進程(自動化控制) Proc_Auto
很明顯,這需要一個進程來處理各種計算,這個進程就相當于系統(tǒng)的大腦。
(5)無線通信協(xié)議相關(guān)的進程 Proc_ZigBee, Proc_RF, Proc_ZWave
在硬件上,每一種無線通信模塊通過串口或其他硬件連接方式與到網(wǎng)關(guān)的 CPU 進行通信,因此,每一種無線通信模塊都需要一個相應(yīng)的進程來處理。
(6)其他“軟設(shè)備”進程 Proc_Xxx
在之前的項目中,還遇到一些硬件設(shè)備,它們與門磁、插座等設(shè)備在邏輯上處于同一個層次,但是與網(wǎng)關(guān)之間是通過 TCP 來連接。對于這樣的設(shè)備,也可以使用一個進程來進行管理。
MQTT消息總線
以上這些進程之間需要相互通信,不是簡單的點對點通信,而是一個網(wǎng)狀的通信模型。比如:
設(shè)備管理進程 Proc_DevMgr:當任何一種設(shè)備被添加到系統(tǒng)中時,都需要處進行處理,因此它需要與 Proc_ZigBee, Proc_RF, Proc_ZWave 這些進程進行通信;
當某個設(shè)備上報數(shù)據(jù)時(例如:Proc_ZigBee),Proc_Protocol 進程需要把數(shù)據(jù)進行協(xié)議轉(zhuǎn)換,然后 Proc_Bridge 進程把轉(zhuǎn)換后的數(shù)據(jù)上報給服務(wù)器,同時 Proc_Auto 進程需要檢查這個設(shè)備上報的數(shù)據(jù)是否觸發(fā)了其他相關(guān)聯(lián)的設(shè)備;
也就是說,這些進程中間的通信是相互交叉的,如果通過傳統(tǒng)的 IPC 方式(共享內(nèi)存、命名管道、消息隊列、Socket)等,處理起來比較復(fù)雜。
引入了 MQTT 消息總線之后,每個進程只需要掛載到總線上。每個進程只需要聽自己感興趣的 topic,就可以接收到相應(yīng)的數(shù)據(jù)。
6.網(wǎng)關(guān)與云平臺之間的通信
上面講解的設(shè)計過程,是網(wǎng)關(guān)內(nèi)部的各功能模塊之間通信方式,這也是我們作為嵌入式開發(fā)者能充分發(fā)揮的部分。
網(wǎng)關(guān)與云平臺之間的通信方式一般都是客戶指定的,就那么幾種(阿里云、華為云、騰訊云、亞馬遜AWS平臺)。一般都要求網(wǎng)關(guān)與云平臺之間處于長連接的狀態(tài),這樣云端的各種指令就可以隨時發(fā)送到網(wǎng)關(guān)。
當然了,這些云平臺都會提供相應(yīng)的 SDK 開發(fā)包,一般使用的 MQTT 協(xié)議來連接云平臺更多一些。在一些文檔中,會把位于云端的 MQTT 服務(wù)器稱作 Broker,其實就是一個服務(wù)器。
進程 Proc_Bridge 的功能主要有 2 點:
(1)與云平臺的數(shù)據(jù)傳輸通道;
(2)協(xié)議轉(zhuǎn)換:把云平臺相關(guān)的協(xié)議轉(zhuǎn)換成網(wǎng)關(guān)內(nèi)部的協(xié)議,以及相反的轉(zhuǎn)換。
也就是說:Proc_Bridge 進程需要同時連接到云平臺的 MQTT Broker 和網(wǎng)關(guān)內(nèi)部的 MQTT 消息總線。在下一篇文章中,我們來專門講解這部分的內(nèi)容,并提供一個實現(xiàn)橋接功能的代碼模板。