一、接入步驟
Tips
- 參考的硬件SDK源碼 https://gitee.com/kerwincui/fastbee/tree/master/sdk/
- 如果設(shè)備的Mqtt消息格式是固定的,可以通過(guò)EMQX的規(guī)則引擎進(jìn)行轉(zhuǎn)發(fā),適配到平臺(tái)
設(shè)備認(rèn)證
- 加密認(rèn)證(推薦)
- 簡(jiǎn)單認(rèn)證
設(shè)備交互
- 發(fā)布物模型、設(shè)備信息、時(shí)鐘同步相關(guān)Mqtt主題
- 訂閱物模型、設(shè)備升級(jí)、時(shí)鐘同步相關(guān)Mqtt主題
設(shè)備AP配網(wǎng)(可選,僅限Wifi類(lèi)設(shè)備)
- 設(shè)備檢測(cè)接口
- 設(shè)備配置接口
二、設(shè)備認(rèn)證
Tips
- 認(rèn)證類(lèi)型:S=簡(jiǎn)單認(rèn)證,E=加密認(rèn)證
- 產(chǎn)品啟用設(shè)備授權(quán)碼后,授權(quán)碼不能為空
- 用戶(hù)ID就是登陸用戶(hù)的ID,使用不同用戶(hù)ID,設(shè)備歸屬于不同用戶(hù)??梢越y(tǒng)一使用admin賬號(hào)1,后面通過(guò)配網(wǎng)或者掃碼關(guān)聯(lián)設(shè)備分配給不同用戶(hù)。
- 設(shè)備編號(hào)有兩種方式獲?。?.使用系統(tǒng)新建設(shè)備時(shí),生成的設(shè)備編號(hào);2.系統(tǒng)未新建設(shè)備,硬件端生成一個(gè)唯一編號(hào)作為設(shè)備編號(hào),認(rèn)證后系統(tǒng)會(huì)自動(dòng)注冊(cè)一個(gè)設(shè)備實(shí)體(設(shè)備比較多時(shí),推薦這種方式)
1. 加密認(rèn)證
產(chǎn)品詳情中獲取產(chǎn)品編號(hào)、Mqtt賬號(hào)、Mqtt密碼和產(chǎn)品秘鑰,密碼通過(guò)產(chǎn)品秘鑰進(jìn)行AES加密,傳遞到后端;后端通過(guò)產(chǎn)品秘鑰解密進(jìn)行認(rèn)證;連接Mqtt消息服務(wù)器需要提供唯一的客戶(hù)端ID、用戶(hù)名和密碼,具體格式如下:
# 客戶(hù)端Id等于 認(rèn)證類(lèi)型 + 設(shè)備編號(hào) + 產(chǎn)品編號(hào) + 用戶(hù)ID
clientId = E & deviceNumber & productId & userId
# 用戶(hù)名
userName = fastbee
# 密碼
password = mqtt密碼 & 過(guò)期時(shí)間
password = mqtt密碼 & 過(guò)期時(shí)間 & 設(shè)備授權(quán)碼 (產(chǎn)品啟用設(shè)備授權(quán)時(shí)格式)
- 客戶(hù)端ID等于 認(rèn)證類(lèi)型 + 設(shè)備編號(hào) + 產(chǎn)品編號(hào) + 用戶(hù)ID,用
&
符號(hào)連接,中間無(wú)空格; - 用戶(hù)名直接輸入Mqtt賬號(hào)
- 密碼等于 Mqtt密碼 + 密碼過(guò)期時(shí)間 + 設(shè)備授權(quán)碼(可選),然后進(jìn)行AES加密。為了安全,密碼過(guò)期時(shí)間應(yīng)該在24小時(shí)以?xún)?nèi),采用時(shí)間戳格式,精確到毫秒。
賬號(hào)配置信息示例:
clientId = "E&D68329VL588&2&1"
userName = "fastbee"
password = "/W2A/4MK+9cEGBhyBDgr2K5c62DAjAK4m0b5pvwxX6FFMzI3h1pUmaDY3BH1P2mI"
2. 簡(jiǎn)單認(rèn)證
產(chǎn)品詳情中獲取Mqtt賬號(hào)和Mqtt密碼,建議測(cè)試環(huán)境使用。Mqtt客戶(hù)端ID格式類(lèi)似加密認(rèn)證,其中E改為S。
# 客戶(hù)端Id等于 認(rèn)證類(lèi)型 + 設(shè)備編號(hào) + 產(chǎn)品編號(hào) + 用戶(hù)ID
clientId = S & deviceNumber & productId & userId
# 用戶(hù)名
userName = fastbee
# 密碼
password = mqtt密碼
password = mqtt密碼 & 設(shè)備授權(quán)碼 (產(chǎn)品啟用設(shè)備授權(quán)時(shí)格式)
賬號(hào)配置信息示例:
# 客戶(hù)端Id等于 認(rèn)證類(lèi)型 + 設(shè)備編號(hào) + 產(chǎn)品編號(hào) + 用戶(hù)ID
clientId = "S&D68329VL588&2&1"
userName = "fastbee"
password = "PHYFED93WSFF1DAS"
password = "PHYFED93WSFF1DAS&ADBFCC8934864B26B55658C66F562AC5" (產(chǎn)品啟用設(shè)備授權(quán)時(shí)格式)
3. 設(shè)備獲取當(dāng)前時(shí)間
獲取當(dāng)前時(shí)間,可以調(diào)用系統(tǒng)的NTP時(shí)間接口,接口請(qǐng)求時(shí)發(fā)送設(shè)備當(dāng)前運(yùn)行毫秒數(shù),返回設(shè)備發(fā)送時(shí)間、服務(wù)端接收時(shí)間、服務(wù)端發(fā)送時(shí)間。然后獲取設(shè)備當(dāng)前運(yùn)行毫秒數(shù),作為設(shè)備接收間。最后用公式計(jì)算出設(shè)備當(dāng)前的時(shí)間,時(shí)間必須以毫秒為單位。在線時(shí)間戳工具
# deviceSendTime值為設(shè)備當(dāng)前運(yùn)行的毫秒數(shù)
http://localhost:8080/iot/tool/ntp?deviceSendTime=35768
# 計(jì)算時(shí)間
設(shè)備當(dāng)前時(shí)間 = (服務(wù)端接收時(shí)間 + 服務(wù)端發(fā)送時(shí)間 + 設(shè)備接收時(shí)間 - 設(shè)備發(fā)送時(shí)間) / 2
4. AES加密說(shuō)明
采用AES的CBC加密模式,偏移量固定為 wumei-smart-open
16位,輸出為Base64,加密使用的密碼為產(chǎn)品密鑰。測(cè)試可以使用:在線加解密工具
加密模式: CBC
填 充: pkcs5padding
數(shù) 據(jù) 塊: 128位
偏 移 量: wumei-smart-open
輸 出: base64
密 碼: 對(duì)應(yīng)系統(tǒng)的產(chǎn)品秘鑰
加密內(nèi)容: mqtt密碼 & expireTime & 授權(quán)碼(可選)
三、設(shè)備交互
{productId}
代表產(chǎn)品ID, {deviceNum}
代表設(shè)備編號(hào)。通過(guò)web端獲取產(chǎn)品ID和設(shè)備編號(hào),如果使用自動(dòng)添加設(shè)備,設(shè)備編號(hào)可以使用唯一編碼或者使用設(shè)備MAC地址,設(shè)備認(rèn)證成功后會(huì)在后端自動(dòng)添加一個(gè)對(duì)應(yīng)的設(shè)備實(shí)體。
1. 訂閱主題
主題 | 描述 |
---|---|
/{productId}/{deviceNum}/function/get | 訂閱平臺(tái)指令 |
/{productId}/{deviceNum}/info/get | 訂閱設(shè)備信息(訂閱到該主題就發(fā)布設(shè)備信息) |
/{productId}/{deviceNum}/ota/get | 訂閱設(shè)備升級(jí)(舊) |
/{productId}/{deviceNum}/upgrade/get | 訂閱OTA升級(jí)(新) |
/{productId}/{deviceNum}/monitor/get | 訂閱實(shí)時(shí)監(jiān)測(cè)信號(hào)(根據(jù)監(jiān)測(cè)次數(shù)和間隔,然后發(fā)布監(jiān)測(cè)數(shù)據(jù)) |
/{productId}/{deviceNum}/ntp/get | 訂閱時(shí)鐘同步(可選,用于同步設(shè)備的當(dāng)前時(shí)間) |
/{productId}/{deviceNum}/property/get | 2.x棄用 訂閱屬性(服務(wù)端發(fā)布,設(shè)備訂閱) |
/{productId}/{deviceNum}/property-online/get | 2.x棄用 訂閱屬性(在線模式,用戶(hù)端發(fā)布,設(shè)備訂閱) |
/{productId}/{deviceNum}/function-online/get | 2.x棄用 訂閱功能(在線模式,用戶(hù)端發(fā)布,設(shè)備訂閱) |
2. 發(fā)布主題
主題 | 描述 |
---|---|
/{productId}/{deviceNum}/property/post | 發(fā)布數(shù)據(jù) (實(shí)時(shí)顯示,屬性/功能和監(jiān)測(cè)數(shù)據(jù),可定時(shí)上報(bào)監(jiān)測(cè)數(shù)據(jù)) |
/{productId}/{deviceNum}/info/post | 發(fā)布設(shè)備信息 |
/{productId}/{deviceNum}/event/post | 發(fā)布事件 |
/{productId}/{deviceNum}/monitor/post | 發(fā)布實(shí)時(shí)監(jiān)測(cè)數(shù)據(jù)(僅用于實(shí)時(shí)監(jiān)測(cè)圖表顯示,不會(huì)存儲(chǔ)) |
/{productId}/{deviceNum}/ntp/post | 發(fā)布時(shí)鐘同步(可選) |
/{productId}/{deviceNum}/upgrade/reply | 回復(fù)OTA升級(jí)(新) |
/{productId}/{deviceNum}/function/post | 2.x棄用 發(fā)布功能 (實(shí)時(shí)顯示) |
3. 數(shù)據(jù)格式
設(shè)備和系統(tǒng)交互使用JSON格式
- 訂閱設(shè)備信息,對(duì)應(yīng)主題:
/info/get
# 描述:訂閱到設(shè)備信息后,發(fā)布設(shè)備信息,解決設(shè)備狀態(tài)同步問(wèn)題
# 設(shè)備消息內(nèi)容為空
- 發(fā)布設(shè)備信息,對(duì)應(yīng)主題:
/info/post
# 描述:1.設(shè)備上電后發(fā)布設(shè)備信息; 2.設(shè)備接收到設(shè)備信息指令后發(fā)布設(shè)備信息
# rssi 設(shè)備信號(hào)(信號(hào)極好[-55— 0],信號(hào)好[-70— -55],信號(hào)一般[-85— -70],信號(hào)差[-100— -85])
# status 設(shè)備狀態(tài),固定為3,表示在線
# firmwareVersion 固件版本
# userId 用戶(hù)的ID,可設(shè)置為用戶(hù)ID為1(管理員),配網(wǎng)時(shí)會(huì)分配設(shè)備給具體的用戶(hù)。
# longitude 可選,經(jīng)度,使用設(shè)備定位時(shí)需要上傳
# latitude 可選,緯度,使用設(shè)備定位時(shí)需要上傳
# summary 可選,摘要,設(shè)備的配置信息等,json格式,對(duì)象可自定義
{
"rssi": -43,
"firmwareVersion": 1.2,
"status": 3,
"userId": 2,
"longitude": 0,
"latitude": 0,
"summary": {
"name": "FastBee",
"chip": "ESP8266",
"author": "kerwincui",
"deliveryTime": "2023-06-06",
"activeTime": "2022-10-01"
}
}
- 訂閱實(shí)時(shí)監(jiān)測(cè),對(duì)應(yīng)主題:
/monitor/get
# 描述:訂閱到實(shí)時(shí)監(jiān)測(cè)消息,根據(jù)數(shù)量和間隔發(fā)布實(shí)時(shí)監(jiān)測(cè)數(shù)據(jù)
# count 數(shù)量
# interval 間隔,毫秒為單位
{
"count": 60,
"interval": 1000
}
- 發(fā)布實(shí)時(shí)監(jiān)測(cè),對(duì)應(yīng)主題:
/monitor/post
# 描述:根據(jù)訂閱到的實(shí)時(shí)監(jiān)測(cè)消息,發(fā)布指定數(shù)量和間隔的監(jiān)測(cè)數(shù)據(jù)
# id 標(biāo)識(shí)符,實(shí)時(shí)監(jiān)測(cè)是物模型中的屬性,產(chǎn)品詳情中查看標(biāo)識(shí)符,對(duì)應(yīng)id值
# value 設(shè)備采集的值,只能是整數(shù)或者小數(shù),以字符串類(lèi)型傳遞
# remark 可為空或者使用設(shè)備當(dāng)前時(shí)間
[{
"id": "temperature",
"value": "27.43",
"remark": ""
}, {
"id": "humidity",
"value": "32.18",
"remark": ""
}]
- 訂閱平臺(tái)指令,對(duì)應(yīng)主題:
/function/get
# 描述:屬性、功能、事件都屬于物模型,Json定義是一樣的。例如都訂閱到消息打開(kāi)開(kāi)關(guān),設(shè)備的處理都是把開(kāi)關(guān)打開(kāi)。
# id 標(biāo)識(shí)符,產(chǎn)品詳情中查看物模型,對(duì)應(yīng)物模型的標(biāo)識(shí)符
# value 值,對(duì)應(yīng)物模型中定義,以字符串類(lèi)型傳遞
# remark 平臺(tái)中告警、場(chǎng)景聯(lián)動(dòng)和定時(shí)下發(fā)的指令有備注信息
[{
"id": "gear",
"value": "1",
"remark": "設(shè)備定時(shí)"
},{
"id": "switch",
"value": "0",
"remark": "場(chǎng)景聯(lián)動(dòng)觸發(fā)"
}]
- 發(fā)布數(shù)據(jù)和事件,對(duì)應(yīng)主題:
/property/post
、/event/post
# 描述:屬性、功能、事件都屬于物模型,Json定義是一樣的。`value` 的值如果是布爾類(lèi)型,值為"0"或者"1",代表打開(kāi)/關(guān)閉;枚舉類(lèi)型對(duì)應(yīng)枚舉項(xiàng)的鍵值(例如 "1",代表中速檔位);數(shù)組類(lèi)型是以英文逗號(hào)分隔的字符串。
# id 標(biāo)識(shí)符,產(chǎn)品詳情中查看物模型,對(duì)應(yīng)物模型的標(biāo)識(shí)符
# value 值,對(duì)應(yīng)物模型中定義,以字符串類(lèi)型傳遞
# remark 可以直接使用訂閱到的備注信息,設(shè)備日志信息中查看到該備注
[{
"id": "gear",
"value": "1",
"remark": "檔位設(shè)置成功"
}, {
"id": "switch",
"value": "0",
"remark": "開(kāi)關(guān)已關(guān)閉"
}]
相關(guān)物模型說(shuō)明
- 所有物模型的Id(標(biāo)識(shí)符)都是唯一的,盡量不要使用特殊字符,以字母和數(shù)字為主。
- 對(duì)象類(lèi)型物模型下面子模型Id(標(biāo)識(shí)符)格式:parentId_childId,對(duì)象數(shù)組類(lèi)型同樣,子模型Id增加父級(jí)的Id以下劃線分隔,例如:
# 父級(jí)物模型Id:power
# 子級(jí)物模型Id:power_light
- 數(shù)組類(lèi)型(包括對(duì)象數(shù)組類(lèi)型)的物模型Id(標(biāo)識(shí)符)只有一個(gè),物模型值為數(shù)組(以英文逗號(hào)分隔的字符串存儲(chǔ)),例如
98,100,50
字符串。所以上報(bào)數(shù)組類(lèi)型的屬性/功能/事件,相對(duì)特殊,Id(標(biāo)識(shí)符)必須以array_索引
開(kāi)頭,索引是兩位數(shù),例如:# 普通數(shù)組格式 `array_00_RGB` # 對(duì)象數(shù)組格式 `array_00_power_switch` # 索引00代表數(shù)組中第一個(gè)元素,02 / 03 ... 98 / 99 以此類(lèi)推,數(shù)組長(zhǎng)度不能超過(guò)100 [{ "id": "array_01_power_switch", // array_01作為前綴,表示數(shù)組中的第二個(gè)元素 "value": "1", "remark": "" }]
- 發(fā)布時(shí)鐘同步,對(duì)應(yīng)主題:
/ntp/post
# 描述:可選,發(fā)布時(shí)鐘同步消息,服務(wù)端訂閱到后下發(fā)時(shí)鐘同步消息
# deviceSendTime 設(shè)備發(fā)送時(shí)間
{
"deviceSendTime": "1592361428000"
}
- 訂閱時(shí)鐘同步,對(duì)應(yīng)主題:
/ntp/get
# 描述:可選,訂閱到時(shí)鐘同步消息,計(jì)算當(dāng)前時(shí)間 = (服務(wù)端接收時(shí)間 + 服務(wù)端發(fā)送時(shí)間 + 設(shè)備接收時(shí)間 - 設(shè)備發(fā)送時(shí)間) / 2
# deviceSendTime 設(shè)備發(fā)送時(shí)間
# serverRecvTime 服務(wù)端接收時(shí)間
# serverSendTime 服務(wù)端發(fā)送時(shí)間
{
"deviceSendTime": "1592361428000",
"serverSendTime": "1592366463548",
"serverRecvTime": "1592366463548"
}
- 訂閱OTA升級(jí),對(duì)應(yīng)主題:
/ota/get
# 描述:訂閱到設(shè)備升級(jí)消息后,根據(jù)固件下載地址,Http請(qǐng)求下載固件并升級(jí)
# version 版本號(hào),可用于匹配固件版本
# downloadUrl 固件下載地址
{
"version": 1.1,
"downloadUrl": "https://iot.m.btsdy.com/prod-api/profile/iot/6/2022-0616-140539.bin"
}
四、設(shè)備配網(wǎng)(可選,僅限Wifi類(lèi)設(shè)備)
Tips
- 設(shè)備采用AP配網(wǎng),配網(wǎng)時(shí),設(shè)備開(kāi)啟熱點(diǎn),并提供web服務(wù)。移動(dòng)端通過(guò)設(shè)備提供的web服務(wù)來(lái)傳遞配置信息。
- 設(shè)備端熱點(diǎn)的地址設(shè)置為:192.168.4.1
- 可以參考項(xiàng)目SDK
1. 檢測(cè)設(shè)備接口
設(shè)備端提供檢測(cè)接口,移動(dòng)端通過(guò)該接口實(shí)現(xiàn)發(fā)現(xiàn)設(shè)備功能,適用于單設(shè)備配網(wǎng)。
# 請(qǐng)求方法:Get
# 接口地址:http://192.168.4.1/status
# 參數(shù):無(wú)
# 返回信息:HTTP狀態(tài)碼200 表示檢測(cè)到設(shè)備
2. 配置接口
設(shè)備端提供配置接口來(lái)獲取信息,移動(dòng)端發(fā)送配置信息,參數(shù)采用Url方式傳遞,其中SSID、password、userId是必傳參數(shù)。
# 請(qǐng)求方法:Post
# 接口地址:http://192.168.4.1/config
# 參數(shù)如下:
SSID # Wifi的名稱(chēng)
password # Wifi的密碼
userId # 用戶(hù)編號(hào)/ID
deviceNum # 可選,設(shè)備編號(hào)
authCode # 可選,授權(quán)碼
extra # 可選,補(bǔ)充信息
# 返回信息:HTTP狀態(tài)碼200 表示配網(wǎng)成功;HTTP狀態(tài)碼500 表示配網(wǎng)失?。?/span>
# 請(qǐng)求URL例子,設(shè)備通過(guò)該Url獲取參數(shù),保存到設(shè)備中
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