Mqtt協定設備接入

頁面導讀
適用場景適合透過 MQTT 接入直連設備、閘道器設備,或將固定格式設備訊息轉發到 FastBee 平台。
前置條件已建立並發佈產品,已準備設備編號、產品編號、MQTT 帳號、密碼和設備授權碼。
認證建議正式環境優先使用加密認證;簡單認證更適合聯調、展示和問題排查。
驗收點設備連線成功、認證通過、訂閱主題正常,並可完成物模型上報和指令接收。
接入入口與最小流程
- 在產品管理中建立並發佈 MQTT 產品,確認產品 ID、設備編號、MQTT 帳號、密碼和設備授權碼。
- 設備或 MQTTX 使用約定的
clientId、userName、password連線 MQTT 服務。 - 連線成功後先發佈
/info/post,再發佈/property/post或/event/post。 - 平台側透過設備詳情的運行狀態、事件日誌、指令日誌和規則場景確認鏈路閉環。
一、接入步驟
提示
- 參考的ESP8266硬體SDK原始碼 FastBee Arduino SDK
- 如果設備的Mqtt訊息格式是固定的,可以透過規則引擎進行轉發,適配到平台
- 系統內建netty-mqtt: 支援主題和內容轉發
- 使用emqx中介軟體: 支援內容轉發,主題可以透過emqx內建的規則引擎轉發
1. 設備認證
- 加密認證(推薦)
- 簡單認證
2. 設備互動
- 發佈物模型、設備資訊、時鐘同步相關Mqtt主題
- 訂閱物模型、設備升級、時鐘同步相關Mqtt主題
3. 設備AP配網(可選,僅限Wifi類設備)
- 設備偵測介面
- 設備設定介面
二、設備認證
提示
- 認證類型:S=簡單認證,E=加密認證
- 產品啟用設備授權碼後,授權碼不可為空
- 使用者ID就是登入使用者的ID,使用不同使用者ID,設備歸屬於不同使用者。可以統一使用admin帳號1,後面透過配網或者掃碼關聯設備分配給不同使用者。
- 設備編號有兩種方式取得:1.使用系統新增設備時,產生的設備編號;2.系統未新增設備,硬體端產生一個唯一編號作為設備編號,認證後系統會自動註冊一個設備實體(設備比較多時,推薦這種方式)
1. 加密認證
產品詳情中取得產品編號、Mqtt帳號、Mqtt密碼和產品金鑰,密碼透過產品金鑰進行AES加密,傳遞到後端;後端透過產品金鑰解密進行認證;連線Mqtt訊息伺服器需要提供唯一的用戶端ID、使用者名稱和密碼,具體格式如下:
ts
# 用戶端Id等於 認證類型 + 設備編號 + 產品編號 + 使用者ID
clientId = E & deviceNumber & productId & userId
# 使用者名稱
userName = fastbee
# 密碼
password = mqtt密碼 & 過期時間
password = mqtt密碼 & 過期時間 & 設備授權碼 (產品啟用設備授權時格式)- 用戶端ID等於 認證類型 + 設備編號 + 產品編號 + 使用者ID,用
&符號連接,中間無空格; - 使用者名稱直接輸入Mqtt帳號
- 密碼等於 Mqtt密碼 + 密碼過期時間 + 設備授權碼(可選),然後進行AES加密。為了安全,密碼過期時間應該在24小時以內,採用時間戳格式,精確到毫秒。
帳號設定資訊範例:
ts
clientId = "E&D68329VL588&2&1"
userName = "fastbee"
password = "/W2A/4MK+9cEGBhyBDgr2K5c62DAjAK4m0b5pvwxX6FFMzI3h1pUmaDY3BH1P2mI"2. 簡單認證
產品詳情中取得Mqtt帳號和Mqtt密碼,建議測試環境使用。Mqtt用戶端ID格式類似加密認證,其中E改為S。
ts
# 用戶端Id等於 認證類型 + 設備編號 + 產品編號 + 使用者ID
clientId = S & deviceNumber & productId & userId
# 使用者名稱
userName = fastbee
# 密碼
password = mqtt密碼
password = mqtt密碼 & 設備授權碼 (產品啟用設備授權時格式)帳號設定資訊範例:
ts
# 用戶端Id等於 認證類型 + 設備編號 + 產品編號 + 使用者ID
clientId = "S&D68329VL588&2&1"
userName = "fastbee"
password = "PHYFED93WSFF1DAS"
password = "PHYFED93WSFF1DAS&ADBFCC8934864B26B55658C66F562AC5" (產品啟用設備授權時格式)3. 設備取得目前時間
取得目前時間,可以呼叫系統的NTP時間介面,介面請求時發送設備目前運行毫秒數,回傳設備發送時間、伺服端接收時間、伺服端發送時間。然後取得設備目前運行毫秒數,作為設備接收時間。最後用公式計算出設備目前的時間,時間必須以毫秒為單位。線上時間戳工具
ts
# deviceSendTime值為設備目前運行的毫秒數
http://localhost:8080/iot/tool/ntp?deviceSendTime=35768
# 計算時間
設備目前時間 = (伺服端接收時間 + 伺服端發送時間 + 設備接收時間 - 設備發送時間) / 24. AES加密說明
採用AES的CBC加密模式,偏移量固定為 wumei-smart-open 16位元,輸出為Base64,加密使用的密碼為產品金鑰。測試可以使用:線上加解密工具
ts
加密模式: CBC
填 充: pkcs5padding
資 料 塊: 128位元
偏 移 量: wumei-smart-open
輸 出: base64
密 碼: 對應系統的產品金鑰
加密內容: mqtt密碼 & expireTime & 授權碼(可選)三、設備互動
{productId} 代表產品ID, {deviceNum} 代表設備編號。透過web端取得產品ID和設備編號,如果使用自動新增設備,設備編號可以使用唯一編碼或者使用設備MAC位址,設備認證成功後會在後端自動新增一個對應的設備實體。
1. 訂閱主題
| 主題 | 描述 |
|---|---|
| /{productId}/{deviceNum}/function/get | 訂閱平台指令 |
| /{productId}/{deviceNum}/info/get | 訂閱設備資訊(訂閱到該主題就發佈設備資訊) |
| /{productId}/{deviceNum}/monitor/get | 訂閱即時監測訊號(根據監測次數和間隔,然後發佈監測資料) |
| /{productId}/{deviceNum}/ntp/get | 訂閱時鐘同步(可選,用於同步設備的目前時間) |
| /{deviceNum}/http/upgrade/set | HTTPS方式訂閱OTA升級(新) |
| /{deviceNum}/fetch/upgrade/set | 二進位套件方式訂閱OTA升級(新) |
| /{productId}/{deviceNum}/ota/get | 訂閱設備升級(舊) |
| /{productId}/{deviceNum}/property/get | 2.x棄用 訂閱屬性(伺服端發佈,設備訂閱) |
| /{productId}/{deviceNum}/property-online/get | 2.x棄用 訂閱屬性(線上模式,使用者端發佈,設備訂閱) |
| /{productId}/{deviceNum}/function-online/get | 2.x棄用 訂閱功能(線上模式,使用者端發佈,設備訂閱) |
2. 發佈主題
| 主題 | 描述 |
|---|---|
| /{productId}/{deviceNum}/property/post | 發佈資料 (即時顯示,屬性/功能和監測資料,可定時上報監測資料) |
| /{productId}/{deviceNum}/info/post | 發佈設備資訊 |
| /{productId}/{deviceNum}/event/post | 發佈事件 |
| /{productId}/{deviceNum}/monitor/post | 發佈即時監測資料(僅用於即時監測圖表顯示,不會儲存) |
| /{productId}/{deviceNum}/ntp/post | 發佈時鐘同步(可選) |
| /{deviceNum}/http/upgrade/reply | HTTPS方式回覆OTA升級(新) |
| /{deviceNum}/fetch/upgrade/reply | 二進位套件方式回覆OTA升級(新) |
| /{productId}/{deviceNum}/upgrade/reply | 回覆OTA升級(舊) |
| /{productId}/{deviceNum}/function/post | 2.x棄用 發佈功能 (即時顯示) |
3. 資料格式
設備和系統互動使用JSON格式
- 訂閱設備資訊,對應主題:
/info/get
js
# 描述:訂閱到設備資訊後,發佈設備資訊,解決設備狀態同步問題
# 設備訊息內容為空- 發佈設備資訊,對應主題:
/info/post
ts
# 描述:1.設備通電後發佈設備資訊; 2.設備接收到設備資訊指令後發佈設備資訊
# rssi 設備訊號(訊號極佳[-55— 0],訊號佳[-70— -55],訊號普通[-85— -70],訊號差[-100— -85])
# status 設備狀態,固定為3,表示線上
# firmwareVersion 韌體版本
# userId 使用者的ID,可設定為使用者ID為1(管理員),配網時會分配設備給具體的使用者。
# longitude 可選,經度,使用設備定位時需要上傳
# latitude 可選,緯度,使用設備定位時需要上傳
# iccid 可選,物聯網卡的ICCID號,設備使用物聯網卡時上傳
# cardPlatformId 可選,對應物聯網卡管理-卡平台編號,設備上傳ICCID號時上傳,如果不上傳則預設遍歷所有卡平台查詢
# summary 可選,摘要,設備的設定資訊等,json格式,物件可自訂
{
"rssi": -43,
"firmwareVersion": 1.2,
"status": 3,
"userId": 2,
"longitude": 0,
"latitude": 0,
"iccid": 898604293620C0000970,
"cardPlatformId": 0,
"summary": {
"name": "FastBee",
"chip": "ESP8266",
"author": "fastbee",
"deliveryTime": "2023-06-06",
"activeTime": "2022-10-01"
}
}- 訂閱即時監測,對應主題:
/monitor/get
ts
# 描述:訂閱到即時監測訊息,根據數量和間隔發佈即時監測資料
# count 數量
# interval 間隔,毫秒為單位
{
"count": 60,
"interval": 1000
}- 發佈即時監測,對應主題:
/monitor/post
ts
# 描述:根據訂閱到的即時監測訊息,發佈指定數量和間隔的監測資料
# id 識別碼,即時監測是物模型中的屬性,產品詳情中查看識別碼,對應id值
# value 設備採集的值,只能是整數或者小數,以字串型別傳遞
# remark 可為空或者使用設備目前時間
[{
"id": "temperature",
"value": "27.43",
"remark": ""
}, {
"id": "humidity",
"value": "32.18",
"remark": ""
}]- 訂閱平台指令,對應主題:
/function/get
ts
# 描述:屬性、功能、事件都屬於物模型,Json定義是一樣的。例如都訂閱到訊息開啟開關,設備的處理都是把開關開啟。
# id 識別碼,產品詳情中查看物模型,對應物模型的識別碼
# value 值,對應物模型中定義,以字串型別傳遞
# remark 平台中告警、場景聯動和定時下發的指令有備註資訊
[{
"id": "gear",
"value": "1",
"remark": "設備定時"
},{
"id": "switch",
"value": "0",
"remark": "場景聯動觸發"
}]- 發佈資料和事件,對應主題:
/property/post、/event/post
ts
# 描述:屬性、功能、事件都屬於物模型,Json定義是一樣的。`value` 的值如果是布林型別,值為"0"或者"1",代表開啟/關閉;列舉型別對應列舉項的鍵值(例如 "1",代表中速檔位);陣列型別是以英文逗號分隔的字串。
# id 識別碼,產品詳情中查看物模型,對應物模型的識別碼
# value 值,對應物模型中定義,以字串型別傳遞
# remark 可以直接使用訂閱到的備註資訊,設備日誌資訊中查看到該備註
[{
"id": "gear",
"value": "1",
"remark": "檔位設定成功"
}, {
"id": "switch",
"value": "0",
"remark": "開關已關閉"
}]相關物模型說明
- 所有物模型的Id(識別碼)都是唯一的,盡量不要使用特殊字元,以字母和數字為主。
- 物件類型物模型下面子模型Id(識別碼)格式:parentId_childId,物件陣列類型同樣,子模型Id增加父級的Id以底線分隔,例如:
shell
# 父級物模型Id:power
# 子級物模型Id:power_light- 陣列類型(包括物件陣列類型)的物模型Id(識別碼)只有一個,物模型值為陣列(以英文逗號分隔的字串儲存),例如
98,100,50字串。所以上報陣列類型的屬性/功能/事件,相對特殊,Id(識別碼)必須以array_索引開頭,索引是兩位數,例如:shell# 普通陣列格式 `array_00_RGB` # 物件陣列格式 `array_00_power_switch` # 索引00代表陣列中第一個元素,02 / 03 ... 98 / 99 以此類推,陣列長度不能超過100 [{ "id": "array_01_power_switch", // array_01作為前綴,表示陣列中的第二個元素 "value": "1", "remark": "" }]
- 發佈時鐘同步,對應主題:
/ntp/post
ts
# 描述:可選,發佈時鐘同步訊息,伺服端訂閱到後下發時鐘同步訊息
# deviceSendTime 設備發送時間
{
"deviceSendTime": "1592361428000"
}- 訂閱時鐘同步,對應主題:
/ntp/get
ts
# 描述:可選,訂閱到時鐘同步訊息,計算目前時間 = (伺服端接收時間 + 伺服端發送時間 + 設備接收時間 - 設備發送時間) / 2
# deviceSendTime 設備發送時間
# serverRecvTime 伺服端接收時間
# serverSendTime 伺服端發送時間
{
"deviceSendTime": "1592361428000",
"serverSendTime": "1592366463548",
"serverRecvTime": "1592366463548"
}- 訂閱OTA升級,對應主題:
/http/upgrade/set或者/fetch/upgrade/set
ts
# 描述:訂閱到設備升級訊息後,根據韌體下載位址,Http請求下載韌體並升級
# version 版本號,可用於比對韌體版本
# downloadUrl 韌體下載位址
{
"taskId": 26,
"url": "/profile/iot/1/2024-0824-001954.bin",
"version": 1.2,
"status": 1
}四、設備配網(可選,僅限Wifi類設備)
提示
- 設備採用AP配網,配網時,設備開啟熱點,並提供web服務。行動端透過設備提供的web服務來傳遞設定資訊。
- 設備端熱點的位址設定為:192.168.4.1
- 可以參考專案SDK
1. 偵測設備介面
設備端提供偵測介面,行動端透過該介面實現發現設備功能,適用於單設備配網。
ts
# 請求方法:Get
# 介面位址:http://192.168.4.1/status
# 參數:無
# 回傳資訊:HTTP狀態碼200 表示偵測到設備2. 設定介面
設備端提供設定介面來取得資訊,行動端發送設定資訊,參數採用Url方式傳遞,其中SSID、password、userId是必傳參數。
ts
# 請求方法:Post
# 介面位址:http://192.168.4.1/config
# 參數如下:
SSID # Wifi的名稱
password # Wifi的密碼
userId # 使用者編號/ID
deviceNum # 可選,設備編號
authCode # 可選,授權碼
extra # 可選,補充資訊
# 回傳資訊:HTTP狀態碼200 表示配網成功;HTTP狀態碼500 表示配網失敗;
# 請求URL範例,設備透過該Url取得參數,儲存到設備中
http://192.168.4.1/config?SSID=mywifi&password=mywifipassword&userId=1
http://192.168.4.1/config?SSID=mywifi&password=mywifipassword&userId=1&deviceNum=D68329VL588&authCode=6688&extra=open五、聯調驗收清單
MQTT 設備接入建議依以下順序驗收,避免只看到連線成功但業務資料沒有進入平台。
| 步驟 | 驗收內容 | 成功表現 |
|---|---|---|
| 1 | 產品已發佈 | 產品狀態為已發佈 |
| 2 | MQTTX 或設備連線 | EMQX 控制台出現用戶端連線 |
| 3 | 設備狀態 | 設備詳情顯示線上或最近線上時間更新 |
| 4 | /info/post | 設備資訊、訊號、版本等欄位更新 |
| 5 | /property/post | 運行狀態顯示物模型屬性值 |
| 6 | /event/post | 事件日誌出現上報事件 |
| 7 | /function/get | 平台下發後設備端收到指令 |
| 8 | 回傳結果 | 設備依下發結果回傳,平台狀態重新整理 |
| 9 | 規則/場景 | 相關規則、場景、告警能被觸發 |
六、常見錯誤
連線被拒絕
優先檢查:
- 伺服器
1883連接埠是否開放。 - EMQX 或內建 MQTT 服務是否啟動。
clientId是否符合S&設備編號&產品ID&使用者ID或加密認證格式。- 產品是否啟用設備授權,啟用後密碼是否包含授權碼。
- 設備是否被停用。
設備線上但屬性不更新
優先檢查:
- 發佈主題是否為
/{productId}/{deviceNum}/property/post。 productId是否使用產品 ID,而不是產品編號。deviceNum是否與設備編號完全一致。- 訊息內容是否為陣列。
id是否與物模型識別碼完全一致。value是否符合資料型別。
平台下發後設備收不到
優先檢查:
- 設備是否訂閱
/{productId}/{deviceNum}/function/get。 - MQTTX 或設備連線是否仍在線上。
- 物模型是否為可寫功能或可下發屬性。
- 使用者是否有設備詳情和指令下發權限。
- 設備影子是否影響目前判斷。
規則或告警沒有觸發
優先檢查:
- 設備資料是否進入平台運行狀態。
- 場景或規則綁定的產品、設備、變數是否正確。
- 條件表達式是否與上報值型別一致。
- 告警設定是否啟用。
七、二次開發入口
| 類型 | 路徑或介面 | 說明 |
|---|---|---|
| MQTT 認證 | /iot/tool/mqtt/auth、/iot/tool/mqtt/webhook | EMQX 認證和 Webhook 入口 |
| 設備介面 | /iot/device | 設備線上、狀態、詳情 |
| 物模型介面 | /iot/model | 模型定義和對應 |
| 協定模組 | springboot/fastbee-protocol | MQTT 訊息解析和轉換 |
| 資料模組 | springboot/fastbee-iot-data | 屬性、事件、監測資料處理 |
| 前端頁面 | vue3/src/views/iot/device | 設備詳情、運行狀態、資料偵錯 |
| 前端 API | vue3/src/api/iot | 設備和物模型請求封裝 |
八、關聯文件
- 產品到設備的完整閉環(简体中文)
- 產品管理
- 設備管理(简体中文)
- 通用物模型(简体中文)
- 設備接入排錯清單(简体中文)


