# 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