# 1 簡單介紹
樂為物聯MQTT服務支持協議: MQTT 3.1 and 3.1.1,
設備可以上傳數據接收控制命令并返回結果,完全兼容使用樂為物聯TCP服務的操作方式。
推薦MQTT客戶端:MQTT.fx
# 2 服務說明
1. 服務器: mqtt://mqtt.lewei50.com:1883
2. 連接Client Id:使用SN或者Userkey_設備標識方式
3. 連接時服務器會使用 Client Id進行校驗,只有驗證通過才允許建立連接
4. 服務限制
同一IP最多可以保持5個連接,
同一IP30秒內pub次數超過20次或者連接次數超過10次會被禁用IP10分鐘
5. 僅允許發布或者訂閱/lw/*/Client Id方式的主題
/lw/u/clientid 上傳數據
/lw/c/clientid 控制命令
/lw/r/clientid 返回控制結果
# 3 場景說明
## 3.1 上傳數據
建立連接后,定時推送主題:/lw/u/clientid
消息內容格式參照:[HTTP upload API][2]
``` javascript
[
{
"Name":"T1",
"Value":"1"
},
{
"Name":"01H1",
"Value":"96.2"
}
]
```
MQTT.FX 設置如下圖
![][3]
MQTT.FX 執行上傳操作
![][4]
樂聯網看到上傳結果
![][5]
# 3.2 接收控制命令
詳細操作步驟如下:
MQTT.FX與樂聯網設置,要使用樂聯網的控制服務,需要在設備管理中設置MQTT連接,如圖:
![][6]
然后測試一下控制命令,結果如下圖
![][7]
> 可以看到,client 訂閱到了平臺發布的消息:{"f":"hello","p1":"1","p2":"2","p3":"3","p4":"4"}
> 但是再等一會兒,發現彈出如下錯誤提示,這是因為client
> 在訂閱到平臺發布的消息以后沒有發布(subscribe)正確的回復(這個回復要求是樂聯網控制要求的,如果是設備控制設備,就沒有這個要求,可以不發布回復信息)。
![][8]
**正確的做法是,平臺點擊完成以后,再發布一個回復,如下圖所示,這樣流程就都走走通了。**
![][9]
# 4 設備端控制處理邏輯
1 建立連接后,訂閱主題:/lw/c/clientid 來接收控制命令
收到的消息格式為json:
```
{f:"方法名",p1:"xxx",p2:"xxx",p3:"xxx",p4:"xxx",p5:"xxx"}
```
其中除了f外其他是可選項,根據實際需求確定是否包含。
2 收到命令后進行業務操作,處理完成之后,需要返回執行命令的結果,發布主題:/lw/r/clientid,消息格式為
``` javascript
{
"successful": true,
"message": "xxxx",
"data":[
{
"id": "C1",
"value": "1"
},
{
"id": "C2",
"value": "2"
}
]
}
```
其中data 根據實際業務進行返回
控制設備在線測試API:
http://www.lewei50.com/dev/apitest/11
SN設備請將API地址更改成:
http://www.lewei50.com/api/V1/gateway/excuteCommandBySN/設備SN,userkey為空即可
# 5 客戶端代碼例子(JS)
**JS 代碼僅僅用于說明流程,實際客戶端推薦nodemcu 平臺lua 實現。**
``` javascript
var mqtt = require('mqtt');
//var clientId = 'xxxxC3F2'; //SN方式
var clientId = 'xxxxxxb372e484d9be1632b99227899_01'; //userkey_gatewayno方式
var settings = {
keepalive: 600,
clientId: clientId
}
var client = mqtt.connect('mqtt://mqtt.lewei50.com:1883', settings);
client.on('connect', function () {
//訂閱控制主題
client.subscribe("/lw/c/" + clientId);
//定時上傳數據
setInterval(uploadData, 5000)
})
//上傳數據
var uploadData = function () {
client.publish('/lw/u/' + clientId, '[{"Name":"T1","Value":"12"}]');
};
//收到控制消息后,返回結果
client.on('message', function (topic, message) {
if (topic == "/lw/c/" + clientId) {
var obj = JSON.parse(message);
console.log(obj.f); //輸出調用的方法
client.publish('/lw/r/' + clientId, JSON.stringify({ successful: true, message: null, data: 'testok' }));
}
})
```
[1]: https://github.com/lewei50/lua
[2]: http://www.lewei50.com/dev/apiinfo/3 "api"
[3]: http://doc-resources.lewei50.com/lewei50/img/MQTT-lewei50-20170504-1.jpg
[4]: http://doc-resources.lewei50.com/lewei50/img/MQTT-lewei50-20170504-2.jpg
[5]: http://doc-resources.lewei50.com/lewei50/img/MQTT-lewei50-20170504-3.jpg
[6]: http://doc-resources.lewei50.com/lewei50/img/MQTT-lewei50-20170504-4.jpg
[7]: http://doc-resources.lewei50.com/lewei50/img/MQTT-lewei50-20170504-5.jpg
[8]: http://doc-resources.lewei50.com/lewei50/img/MQTT-lewei50-20170504-6.jpg
[9]: http://doc-resources.lewei50.com/lewei50/img/MQTT-lewei50-20170504-7.jpg