先注册Tlink云平台帐号(网址),注册成功后找到开发者中心,查看Tlink云平台的MQTT协议说明。添加一个设备,把模块的电压,信号强度和灯状态上传云平台,Tlink提供的APP和微信控制灯开关,链接协议选MQTT。html
Air302模块与Tlink云平台通讯使用Json格式通讯。web
在Tlink云的开发者中心查看MQTT通讯格式要求,写程序会用到,以下:编程
链接域名和端口号:每一种协议的链接服务器地址和端口号都不同,请登陆平台>设备管理>进入设置链接界面查看。json
客户端ID:发布和订阅是在同一个设备进行时,客户端ID只须要一个,能够直接使用设备序列号当作客户端ID,若是存在多个设备进行订阅,须要在平台获取新的客户端ID。服务器
用户名密码:用户名(User Name):同平台的登陆账号同样。 密码(Password):同平台的登陆密码同样(注:修改登陆密码会致使设备没法链接,企业版可单独设置用户名密码)。微信
发布主题:发布主题:设备序列号,指设备发布上行数据到平台的主题。网络
订阅主题:订阅主题:设备序列号/+,指设备接收下行数据时订阅的主题。这里利用了通配符的概念,订阅该主题能够接收该设备全部传感器的下行数据(传感器下行数据所使用的主题为序列号/传感器ID)。socket
JSON格式的消息内容............tcp
main.lua以下:函数
PROJECT = "tlink_demo" VERSION = "1.0.0" -- 引入必要的库文件(lua编写), 内部库不须要require local sys = require "sys" local mqtt = require "mqtt" log.info("version", _VERSION, VERSION) -- GPIO 和 PWM 相关 ------------------------------- -- 网络灯 GPIO19/PWM5 NETLED = gpio.setup(19, 0, gpio.PULLUP) -- 初始化GPIO19, 并设置为低电平 gpio.set(19, 0) -- 设置为高电平 ----发送数据table--------------- local vPowerSwitch = 0 --数据发送的消息队列,缓冲做用 local msgQueue = {} function insertMsg( ) rssi_value = nbiot.rssi() --rgb_led = gpio.get(19) adc.open(1) -- VBAT电压 vbt = adc.read(1) local re = { sensorDatas = { { sensorsId = 200456308, flag = 'dianya', value = vbt }, { sensorsId = '200456309', flag = 'xinhao', value = rssi_value }, { sensorsId = 200456387, flag = 'deng', switcher = vPowerSwitch } } } payload = json.encode(re) table.insert(msgQueue,{topic='O5UUTBP9146XN0L5',payload=payload,qos=1}) end --循环120s执行插入数据 sys.timerLoopStart(insertMsg, 120000) --灯闪烁线程------------------------------- --[[sys.taskInit(function() while 1 do -- 一闪一闪亮晶晶 NETLED(0) sys.wait(1000) NETLED(1) sys.wait(1500) --log.info("gpio", "18", G18()) end end) ]] --接受发送函数---------------------------- --- MQTT客户端数据接收处理 -- @param mqttClient,MQTT客户端对象 -- @return 处理成功返回true,处理出错返回false -- @usage mqttInMsg.proc(mqttClient) function mqttInMsg_proc(mqttClient) local result,data while true do result,data = mqttClient:receive(5000) --接收到数据 if result then --TODO:根据需求自行处理data.payload log.info("mqttInMsg_proc",string.toHex(data.payload)) log.info("mqttc", "mqttc:receive!!!!", result or nil ,data or nil) local tjsondata,res,errinfo = json.decode(data.payload) if res then vPowerSwitch = tjsondata['sensorDatas'][1]['switcher'] gpio.set(19, vPowerSwitch) --接受数据成功后返回灯的状态,由于要更新web页面灯开关的状态 insertMsg() mqttOutMsg_proc(mqttClient) log.info("vPowerSwitch!!!!!", vPowerSwitch) else log.info("json decode faile",errinfo) end --uart.write(1,"\r\n topic = "..data.topic .. " paload = " ..data.payload) --经过串口1发送出去 --若是mqttOutMsg中有等待发送的数据,则当即退出本循环 if waitForSend() then return true end else break end end return result or data=="timeout" end --- MQTT客户端是否有数据等待发送 -- @return 有数据等待发送返回true,不然返回false -- @usage mqttOutMsg.waitForSend() function waitForSend() return #msgQueue > 0 end --- MQTT客户端数据发送处理 -- @param mqttClient,MQTT客户端对象 -- @return 处理成功返回true,处理出错返回false -- @usage mqttOutMsg.proc(mqttClient) function mqttOutMsg_proc(mqttClient) while #msgQueue>0 do local outMsg = table.remove(msgQueue,1) local result = mqttClient:publish(outMsg.topic,outMsg.payload,outMsg.qos) log.info("mqttOutMsg_proc", outMsg.topic,outMsg.payload,outMsg.qos) --if outMsg.user and outMsg.user.cb then outMsg.user.cb(result,outMsg.user.para) end if not result then return end end log.info("mqttOutMsg_proc", 'msgQueue length zero') return true end --链接mqtt线程---------------------------- local host, port, selfid = 'mq.tlink.io', 1883, 'O5UUTBP9146XN0L5' local mqttClientId = selfid local mqttUsername = '17852270083' local mqttPassword = 'chunqing0083!' sys.taskInit( function() local retryConnectCnt = 0 while true do if not socket.isReady() then retryConnectCnt = 0 --等待网络环境准备就绪,超时时间是30s log.info("net", "wait for network ready") sys.waitUntil("NET_READY",30000) end --是否获取到分配的IP(是否连上网) if socket.isReady() then log.info("net", "network ready") --建立一个MQTT客户端 local mqttClient = mqtt.client(mqttClientId, 60, mqttUsername, mqttPassword) --阻塞执行MQTT CONNECT动做,直至成功 --若是使用ssl链接,打开mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"}),根据本身的需求配置 --mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"}) if mqttClient:connect(host, port,"tcp") then --链接成功 log.info("mqttClient","Connet ok!") retryConnectCnt = 0 --失败次数清零 --ready = true --订阅主题 if mqttClient:subscribe({["O5UUTBP9146XN0L5".."/+"]=0}) then --xxx表明的是序列号 log.info("mqttClient","subscribe ok!") --订阅成功,发布第一次消息,先把消息写入table在调用发布函数 insertMsg() mqttOutMsg_proc(mqttClient) --mqttOutMsg.insertMsg("xxx","Iccid = " .. sim.getIccid(),0)--这个没啥用 --循环处理接收和发送的数据 while true do if not mqttInMsg_proc(mqttClient) then log.error("mqttTask.mqttInMsg.proc error") break end if not mqttOutMsg_proc(mqttClient) then log.error("mqttTask.mqttOutMsg proc error") break end end end --ready = false else log.info("mqttTask.mqttClient","Connet fail!") retryConnectCnt = retryConnectCnt+1 --失败次数加一 end --断开MQTT链接 mqttClient:disconnect() if retryConnectCnt>=5 then retryConnectCnt=0 end sys.wait(5000) else --进入飞行模式,5秒以后,退出飞行模式 nbiot.setCFUN(0) sys.wait(5000) log.info("net", "I am in fly mode") nbiot.setCFUN(1) end end end ) -- 用户代码已结束--------------------------------------------- -- 结尾老是这一句 sys.run() -- sys.run()以后后面不要加任何语句!!!!!
一个小细节,就是在Tlink云的控制台控制灯的开关,须要设备把接受到的值在返回给服务器,改变开关图标,这样服务器才能肯定下发数据是否成功,如图。可在程序中,当模块接收到数据后紧接着发布数据就能够了。