玩轉OneNET物聯網平臺之MQTT服務①

微控制器菜鳥發表於2019-06-20

1.MQTT簡介

    MQTT協議是一個面向物聯網應用的即時通訊協議,使用TCP/IP提供網路連線,能夠對負載內容實現訊息遮蔽傳輸,開銷小,可以有效降低網路流量。
    參考博主線上博文:玩轉PubSubClient MQTT庫

特點及功能

  • 長連線協議(保持心跳,keepAlive)
  • 終端資料點上報,支援的資料點型別包括

整型(int)
浮點數(float)
字串(string)
JSON格式
二進位制資料

  • 平臺訊息下發
  • 基於Topic的訂閱、釋出以及訊息推送,可以實現裝置間的訊息單播以及組播

典型應用場景
    MQTT協議適用於裝置和平臺需要保持長連線的使用場景,MQTT特點在於可以實現裝置間的訊息單播以及組播,可以不依賴於其他服務(下發命令服務,推送服務等)實現讓裝置以應用伺服器的方式對真實裝置進行管理和控制。

讀者所需知識儲備

  • 玩轉PubSubClient MQTT庫
  • 玩轉OneNET物聯網平臺之簡介

2.MQTT接入說明

    接入流程分為:

  • 平臺域(也就是OneNet平臺上的操作)
  • 裝置域(8266裝置上的SDK,我們這裡用PubSubClient)

image

    接入步驟如下:

2.1 Step1 —— 建立產品,選擇接入協議

  • 首先您需要在平臺建立一個接入協議為MQTT的產品,檢視產品建立
  • 建立產品後,記錄該產品的產品ID(ProductId)

2.2 Step2 —— 建立裝置,記錄裝置ID等資訊

建立裝置有兩種方式:

  • 第一種 可以通過頁面點選新增裝置,輸入裝置名稱鑑權資訊(即裝置編號,在8266中我們可以使用 ESP+Mac地址的方式或者ESP+ChipId的方式),具體平臺的資源模型可詳情請檢視第一章 資源模型,並記錄下該裝置編號(deviceId).
  • 第二種 可以通過呼叫建立裝置API 實現裝置的建立,輸入裝置的裝置名、接入協議、鑑權資訊以及MasterKey等資訊,即可在平臺上建立裝置(博主比較喜歡這一種,也比較靈活)。

2.3 Step3 —— 建立裝置與平臺間的協議連線

  • MQTT伺服器地址域名為:mqtt.heclouds.com

    使用Step1和Step2中的引數作為登入引數,使用SDK中的對應介面組織MQTT連線報文,傳送到平臺,與平臺建立MQTT連線

    若已經連線成功,在裝置資訊中會看到一個線上標記:
image

    對於初學者,博主建議先用OneNet提供的MQTT除錯工具來試玩一下,已親測可用。

image

2.4 Step4 —— 資料流建立,資料點上傳

  • 利用SDK中提供的介面函式,編寫程式碼將資料上傳到平臺

2.5 Step5 —— 資料流展示,檢視資料點

  • 在OneNET上的裝置管理下點選資料展示,進入資料展示頁面,點選下拉選單,檢視近期上傳的資料點;也可以選擇時間區間來檢視歷史時間

3. MQTT API

    API根據用途做了幾種分類,博主這裡不重複,請參考 玩轉OneNET物聯網平臺之簡介

    當然,OneNet為了簡單方便除錯API,也給我們提供了除錯介面,具體請參考

image

    博主在這裡不會去講解各個API的詳細用法,請大家自行去查閱官方文件(查閱官方文件也是鍛鍊能力的一種)。

3.1 新增裝置

  • 具體參考 OneNet官方文件 - 新增裝置
  • 此方法比較重要,請仔細理解

3.2 註冊裝置

3.3 更新裝置資訊

3.4 查詢裝置詳情

3.5 批量查詢裝置資訊

3.6 批量查詢裝置狀態

3.7 刪除裝置

3.8 新增資料流

3.9 更新資料流屬性

3.10 查詢資料流詳情

3.11 批量查詢資料流資訊

3.12 刪除資料流

3.13 查詢裝置歷史資料

3.14 批量查詢裝置最新資料

3.15 新增資料點

3.16 上傳檔案

3.17 獲取檔案

3.18 傳送命令

3.19 查詢命令狀態

3.20 查詢命令響應

3.21 查詢裝置歷史命令

3.22 新增觸發器

3.23 更新觸發器

3.24 查詢觸發器

3.25 刪除觸發器

3.26 新增apikey

3.27 更新apikey

3.28 查詢apikey

3.29 刪除apikey

3.30 釋出訊息

3.31 查詢訂閱topic的裝置

3.32 查詢裝置訂閱的topic

3.33 查詢產品的topic

4.裝置端接入MQTT流程

前提

  • 讀者已經瞭解MQTT協議
  • 讀者已經在OneNet上建立了Mqtt協議產品,比如博主這裡建立了彩燈-MQTT專案

4.1 連線鑑權

    在 2.3 Step3 —— 建立裝置與平臺間的協議連線中說到,我們第一步就是和OneNet平臺建立連線鑑權:

image

  • 裝置向平臺發起 connect 請求.connect 中攜帶鑑權資訊
  • 平臺拿到鑑權資訊進行鑑權
  • 鑑權通過後,如果 cleansession=0, 平臺將會載入儲存的裝置的一些資訊.如訂閱列表; 如果 cleansession=1, 裝置沒有儲存資訊在平臺,則不載入裝置相關資訊
  • 返回鑑權結果 ConnAck 報文

4.2 訊息釋出

4.2.1 資料點上報協議說明

    裝置使用publish報文來上傳資料點, 報文格式如下:

  • VariableHeader
欄位 Field名稱 說明 格式
Field1 TopicName=”$dp” $dp為系統上傳資料點的指令 2位元組字串長度 + utf8字串
  • Payload
    Payload包含真正的資料點內容,支援的格式如下:

image

資料型別 1(type == 1)格式說明:
image

資料型別 2(type == 2)格式說明:
image

資料型別 3(type == 3)格式說明:
image

資料型別 4(type ==4)格式說明:
image

資料型別 5(type ==5)格式說明:
image

資料型別 6(type ==6)格式說明:
image

資料型別 7(type == 7)格式說明:(每次最多 500 個資料流的浮點數):
image

4.2.2 資料點上報 —— 質量等級Qos0(Client->Server)

image

  • 裝置釋出 Qos0 訊息(上報資料點)
  • 平臺收到上報資料點後儲存起來.

4.2.3 資料點上報 —— 質量等級Qos1(Client->Server)

image

  • 裝置釋出 Qos1 訊息(上報資料點)
  • 平臺收到上報資料點後儲存起來.
  • 平臺給裝置回覆相應的 PubAck報文

4.2.4 資料點上報 —— 質量等級Qos2(Client->Server)

image

  • 裝置釋出 Qos2 訊息(上報資料點)
  • 平臺收到上報資料點後儲存起來
  • 平臺給裝置回覆相應的 PubRec 報文
  • 裝置需回覆平臺 PubRel 報文,如超時不回平臺則會斷開相應連線
  • 平臺給裝置回覆 PubComp 報文

注意

  • 資料點上報功能不支援 Retain 特性

4.2.5 下發平臺命令協議說明

    平臺使用publish 報文來下發平臺指令, 報文格式如下:

FixHeader

  • 參考MQTT篇關於固定頭的說明

VariableHeader

欄位 Field名稱 說明 格式
Field1 TopicName=”$creq/cmduuid” $creq 為系統下發Cmd 的指令,cmduuid 為該條指令的uuid 2 位元組字串長度+ utf8 字串

Payload:

  • Payload 包含真正的指令內容

注意點

  • 因為這裡的cmduuid為某條指令的uuid,所以我們可以考慮正規表示式的topic

4.2.6 下發平臺命令 —— 質量等級Qos0(Server->Client)

image

  • 平臺向裝置傳送topic 為$creq 的訊息(該topic 為平臺命令).
    裝置收到topic 為$creq 的topic 時,需將其作為平臺下發的指令來處理.

注意

  • 目前命令下發以Qos0 級別進行推送

4.2.7 命令回覆協議說明

    平臺使用publish 報文來回復平臺指令, 報文格式如下:

FixHeader

  • 參考MQTT篇關於固定頭的說明

VariableHeader
欄位 | Field名稱 | 說明 | 格式
---|---|---|---
Field1 | TopicName=”$crsp/cmduuid” | $crsp為系統處理裝置回覆cmd 的指令,cmduuid 為該條指令的uuid | 2 位元組字串長度+ utf8 字串

Payload:

  • Payload 包含真正的指令內容

注意點

  • 因為這裡的cmduuid為某條指令的uuid,所以我們可以考慮正規表示式的topic

4.2.8 命令回覆 —— 質量等級Qos0(Client->Server)

image

4.2.9 命令回覆 —— 質量等級Qos1(Client<-> Server)

image

  • 如果裝置回覆響應時以Qos1 回覆,則平臺需要給裝置回覆一個Puback 報文

4.2.10 命令回覆 —— 質量等級Qos2(Client<-> Server)

image

如果裝置回覆響應時以Qos2 回覆,則:

  • 1.平臺需回覆裝置一個PubRec 報文
  • 2.裝置在收到PubRec 後需向平臺回覆PubRel 報文
  • 3.平臺收到PubRel 報文後,向裝置回覆PubComp 報文

4.3 建立Topic

image

  • 裝置通過傳送HTTP 請求進行topic 的建立操作.
  • 平臺收到請求後建立topic 並返回結果.

請求及響應定義如下

image

4.4 訂閱

image

  • 裝置發起訂閱請求報文
  • 平臺收到請求後更新topic 列表
  • 平臺給裝置回覆SubAck報文

注意

  • subscribe 的request qos 級別可以為0、1、2

4.5 取消訂閱

image

  • 裝置發起取消訂閱請求
  • 平臺收到請求後更新topic 列表
  • 平臺給裝置回覆UnSubAck

4.6 推送裝置Topic

4.6.1 Publish 報文推送協議說明

FixHeader

  • 參考MQTT篇關於固定頭的說明

VariableHeader
欄位 | Field名稱 | 說明 | 格式
---|---|---|---
Field1 | TopicName | 填寫裝置訂閱的topic | 2 位元組字串長度+ utf8 字串

Payload:

  • Payload 為裝置自定義內容

4.6.2 Publish 報文推送 —— 質量等級Qos0

image

  • 裝置發起推送topic 請求(以Qos0 級別)
  • 平臺收到請求後,將topic 以Qos0 級別推送到相關訂閱裝置(支援離線裝置推送)
  • 平臺不返回PubAck 或PubRec 等報文

4.6.3 Publish 報文推送 —— 質量等級Qos1

image

  • 裝置發起推送topic 請求(以Qos1 級別)
  • 平臺收到請求後,將topic 以Qos1 級別推送到相關訂閱裝置(支援離線裝置推送)
  • 平臺返回PubAck 報文

4.6.4 Publish 報文推送 —— 質量等級Qos2

image

  • 裝置發起推送topic 請求(以Qos2 級別)
  • 平臺收到請求後,回覆PubRec 報文
  • 裝置收到PubRec 後需回覆PubRel 報文(如超時不回覆,平臺會斷開與裝置的連線)
  • 平臺收到PubRel 報文後,回覆PubComp 給裝置
  • 平臺在回覆PubComp 後會以Qos2 級別推送到相關訂閱裝置(支援離線裝置推送)
  • 裝置需回覆PubRec 報文(如超時不回覆,平臺會斷開與裝置的連線)
  • 平臺傳送PubRel 報文給裝置
  • 裝置需回覆PubComp(釋出完成)

4.6.5 HTTP 請求推送

image

  • 裝置以HTTP 的方式發起推送topic 請求
  • 平臺收到請求後,將topic 推送到相關訂閱裝置.(目前只支援線上推送)
  • 平臺返回推送結果

請求及響應定義如下

image

4.7 離線Topic

    普通推送(上面的推送裝置Topic)只針對線上裝置進行topic訊息的推送,離線裝置不會收到訂閱的topic 的訊息。

    離線Topic則會將該訊息推送給線上以及離線裝置。

注意點

  • 如果裝置在上線時設定了clean session flag,服務端會刪除其訂閱的topic 及相關的離線topic 訊息。
  • 如果裝置沒有設定clean session flag,如果有與該裝置相關的離線topic 訊息,則在鑑權成功後將離線訊息
    推送給裝置。
  • 遺囑訊息(will msg)只會推送給訂閱了該will topic 的線上的裝置,離線裝置不會收到。
  • 離線訊息的有效期預設為2 天(暫不支援使用者設定有效期),伺服器只會推送在2 天內的最近10 條訊息。

4.8 資料點訂閱

含義

  • 同一產品下的裝置可以訂閱其他裝置的資料點,訂閱的topic 格式為:/deviceid/資料流名稱。即
    被關注的裝置在上傳了該資料流名稱的資料點後,訂閱了該topic 的其他裝置都會收到上傳的資料點。

例子

  • A、B 裝置的deviceid 分別為9277、9278。
  • A 裝置訂閱了名為/9278/9527 的topic(9278 為裝置B 的id,9527 為B 裝置上傳的資料流名稱)。
  • B 裝置上傳了名為9527 的資料流(資料點為11; 15;78…)。
  • A 裝置會收到多條(取決於裝置B 上傳的資料點的個數)推送的topic 名為/9278/9527 的publish 訊息,訊息的
    payload 中則包含裝置B 上傳的資料點。

注意點

  • 目前支援訂閱的資料點的型別為Type1~Type7

5.常見問題

5.1 MQTT連線鑑權時,Payload中ClientIdentifier;UserName;UserPassword分別填寫什麼?

  • ClientIdentifier: 建立裝置時得到的裝置ID,為數字字串;
  • UserName: 註冊產品時,平臺分配的產品ID,為數字字串;
  • UserPassword: 為裝置的鑑權資訊(即唯一裝置編號,SN),或者為apiKey,為字串。

5.2 MQTT需要在連線鑑權通過後才能傳送其它報文嗎?

  • 是的,MQTT協議必須在鑑權通過後(收到ConnAck後),才能傳送後續報文進行互動,不然伺服器會直接丟棄報文。

5.3 MQTT可以訂閱Topic有什麼限制?

  • OneNET不支援訂閱$開頭的系統Topic。

5.4 如何利用MQTT協議上傳資料到雲平臺?

  • 裝置完成連線鑑權之後,將資料按照一定的格式(見協議文件說明)打包,將資料釋出到$dp系統Topic上即可。

5.5 訂閱之前是否需要建立Topic?

  • 裝置在執行訂閱時,OneNET會自動判斷該Topic是否存在,若不存在則自動建立該Topic。

5.6 裝置可否通過訂閱的方式,獲取其他裝置的資料流資訊?

  • 可以,可以通過訂閱 /device_id/資料流名 的方式,及時獲取到某裝置最新的資料點資訊。

5.7 裝置釋出訊息(Publish)有什麼限制??

  • 釋出訊息只能在同一產品ID下進行,不能進行跨產品間的Publish訊息推送。

6. 新手手把手感受OneNet MQTT案例

    博主這裡認為大家已經註冊了OneNet賬號。接下來請按照下面步驟進行:

6.1 建立 ESP8266智慧燈系統 產品(MQTT協議)

image

注意點

  • 務必選擇MQTT協議

    建立完畢後,我們點選檢視具體的產品資訊:

image

注意點

  • 需要記錄產品ID,其用來區分產品唯一識別符號
  • Master-APIkey,網路請求鑑權資訊,介面呼叫需要帶入

6.2 API除錯建立 deviceA和deviceB兩個裝置

API介面定義

操作步驟

  • 通過API除錯工具建立deviceA

image

http body

{
    "title": "mqtt_device_A",
    "desc": "mqtt_device_A",
    "tags": ["china", "mobile"],
    "location": {
        "lon": 109,
        "lat": 23.54
    },
    "auth_info": "mqtt_device_A",
    "other": {
        "version": "1.0.0",
        "manufacturer": "china mobile"
    }
}
  • 通過API除錯工具建立deviceB

image

http body

{
    "title": "mqtt_device_B",
    "desc": "mqtt_device_B",
    "tags": ["china", "mobile"],
    "location": {
        "lon": 109,
        "lat": 23.54
    },
    "auth_info": "mqtt_device_B",
    "other": {
        "version": "1.0.0",
        "manufacturer": "china mobile"
    }
}
  • 檢視裝置列表

image

6.3 官方工具除錯deviceA和deviceB

    讀者請自行下載 MQTT-device 工具。下載完工具之後請複製出兩份,一個工具代表deviceA,一個工具代表deviceB,我們模擬Mqtt操作。

6.3.1 配置deviceA

image

注意點

  • 重點關注博主標紅的地方,DeviceID和ProductID、AuthInfo需要填寫讀者自身建立的
  • 配置完畢連線伺服器

6.3.2 配置deviceB

image

注意點

  • 重點關注博主標紅的地方,DeviceID和ProductID、AuthInfo需要填寫讀者自身建立的
  • 配置完畢連線伺服器

6.3.3 deviceA訂閱主題“deviceB_to_A”

image

注意點

  • 主題名為“deviceB_to_A”

6.3.4 deviceB訂閱主題“deviceA_to_B”

image

注意點

  • 主題名為“deviceA_to_B”

6.3.5 deviceB釋出資訊給deviceA

image

6.3.6 deviceA釋出資訊給deviceB

image

6.3.7 平臺下發命令給deviceA

image

image

6.3.8 deviceA上傳資料點到平臺

image

image

7.總結

本篇作為OneNet Mqtt篇的開頭篇,主要講解了Mqtt的使用注意事項,並且在除錯工具下模擬Mqtt的常用操作,請關注接下來的篇章。

相關文章