合宙NB-IOT模块Air302连接Tlink云平台,APP和微信控制灯开关

3 篇文章 1 订阅

 

先注册Tlink云平台账号(网址),注册成功后找到开发者中心,查看Tlink云平台的MQTT协议说明。添加一个设备,把模块的电压,信号强度和灯状态上传云平台,Tlink提供的APP和微信控制灯开关,连接协议选MQTT。

Air302模块与Tlink云平台通信使用Json格式通信。

在Tlink云的开发者中心查看MQTT通信格式要求,写程序会用到,如下:

连接域名和端口号:每一种协议的连接服务器地址和端口号都不一样,请登录平台>设备管理>进入设置连接界面查看。

客户端ID:发布和订阅是在同一个设备进行时,客户端ID只需要一个,可以直接使用设备序列号当做客户端ID,如果存在多个设备进行订阅,需要在平台获取新的客户端ID。

用户名密码:用户名(User Name):同平台的登录帐号一样。 密码(Password):同平台的登录密码一样(注:修改登录密码会导致设备无法连接,企业版可单独设置用户名密码)。

发布主题:发布主题:设备序列号,指设备发布上行数据到平台的主题。

订阅主题:订阅主题:设备序列号/+,指设备接收下行数据时订阅的主题。这里利用了通配符的概念,订阅该主题可以接收该设备所有传感器的下行数据(传感器下行数据所使用的主题为序列号/传感器ID)。

JSON格式的消息内容............

main.lua如下,程序的思路见下方参考链接。程序连接MQTT平台收发数据还稳定,在时间长不发数据,云平台下发数据会有四五秒的延迟。之后在研究一下。

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 = 'xxxxxxxxxxx'  --换成自己的Tlink登录名
        local mqttPassword = 'xxxxxxxxxxx'   --Tlink登录密码


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云的控制台控制灯的开关,需要设备把接受到的值在返回给服务器,改变开关图标,这样服务器才能确定下发数据是否成功,如图。可在程序中,当模块接收到数据后紧接着发布数据就可以了。

 


参考:【2G模组Air202开发】Lua脚本编程实现MQTT协议连接Tlink平台

             NB-IOT(Air302) Lua开发

             稍微了解一下(需要知道的关于Lua的一些基本的知识) 

             合宙Luat / LuatOS@Air302 V0003 正式版

         

 

 

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值