| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- PROJECT = "aliyundemo"
- VERSION = "1.0.0"
- local sys = require "sys"
- local libfota = require("libfota")
- local aliyun = require "aliyun"
- --根据自己的服务器修改以下参数
- --新版已经合并, 没有了地域, 1883同时兼容加密和非加密通信,非加密会下线
- -- 阿里云资料:https://help.aliyun.com/document_detail/147356.htm?spm=a2c4g.73742.0.0.4782214ch6jkXb#section-rtu-6kn-kru
- tPara = {
- -- 是否为一型一密, true为一型一密, false为一机一密(预注册)
- Registration = false,
- -- 设备名名称, 必须唯一
- DeviceName = (mobile and mobile.imei() or (wlan and wlan.mac() or mcu.unique_id():toHex())),
- -- 产品key, 在产品详情页面
- ProductKey = "k0ti3QNOFaH", --产品key
- --产品secret,一型一密就需要填, 一机一密(预注册)不填
- ProductSecret = "",
- --设备密钥,一型一密就不填, 一机一密(预注册)必须填
- DeviceSecret = "62a17dfe2192526f90bc5fad7cd951fc", --设备secret
- -- 填写实例id,在实例详情页面
- InstanceId = "iot-06z00hmbog1v175",
- -- 固定值, 不要修改
- mqtt_port = 1883, -- mqtt端口
- --是否使用ssl加密连接,注意: 如果使用一型一密,则必须使用ssl加密
- mqtt_isssl = false,
- }
- -- 低功耗测试, 打开之后, 连接阿里云后5秒请求低功耗
- local PM_TEST = false
- -- 统一联网函数
- sys.taskInit(function()
- -----------------------------
- -- 统一联网函数, 可自行删减
- ----------------------------
- if wlan and wlan.connect then
- -- wifi 联网, ESP32系列均支持
- local ssid = "luatos1234"
- local password = "12341234"
- log.info("wifi", ssid, password)
- -- TODO 改成自动配网
- wlan.init()
- wlan.setMode(wlan.STATION) -- 默认也是这个模式,不调用也可以
- wlan.connect(ssid, password, 1)
- elseif mobile then
- -- Air780E/Air600E系列
- --mobile.simid(2) -- 自动切换SIM卡
- -- LED = gpio.setup(27, 0, gpio.PULLUP)
- -- device_id = mobile.imei()
- elseif w5500 then
- -- w5500 以太网, 当前仅Air105支持
- w5500.init(spi.HSPI_0, 24000000, pin.PC14, pin.PC01, pin.PC00)
- w5500.config() --默认是DHCP模式
- w5500.bind(socket.ETH0)
- -- LED = gpio.setup(62, 0, gpio.PULLUP)
- elseif socket or mqtt then
- -- 适配的socket库也OK
- -- 没有其他操作, 单纯给个注释说明
- else
- -- 其他不认识的bsp, 循环提示一下吧
- while 1 do
- sys.wait(1000)
- log.info("bsp", "本bsp可能未适配网络层, 请查证")
- end
- end
- -- 默认都等到联网成功
- sys.waitUntil("IP_READY")
- sys.publish("net_ready")
- end)
- --阿里云客户端是否处于连接状态
- local sConnected
- local publishCnt = 1
- --[[
- 函数名:pubqos1testackcb
- 功能 :发布1条qos为1的消息后收到PUBACK的回调函数
- 参数 :
- usertag:调用mqttclient:publish时传入的usertag
- result:任意数字表示发布成功,nil表示失败
- 返回值:无
- ]]
- local function publishTestCb(result,para)
- log.info("aliyun", "发布后的反馈", result,para)
- sys.timerStart(publishTest,20000)
- publishCnt = publishCnt+1
- end
- --发布一条QOS为1的消息
- function publishTest()
- if sConnected then
- --注意:在此处自己去控制payload的内容编码,aLiYun库中不会对payload的内容做任何编码转换
- -- aliyun.publish(topic,qos,payload,cbFnc,cbPara)
- log.info("aliyun", "上行数据")
- aliyun.publish("/"..tPara.ProductKey.."/"..tPara.DeviceName.."/user/get",1,"LUATOS_CESHI",publishTestCb,"publishTest_"..publishCnt)
- end
- end
- ---数据接收的处理函数
- -- @string topic,UTF8编码的消息主题
- -- @string payload,原始编码的消息负载
- local function rcvCbFnc(topic,payload,qos,retain,dup)
- log.info("aliyun", "收到下行数据", topic,payload,qos,retain,dup)
- end
- --- 连接结果的处理函数
- -- @bool result,连接结果,true表示连接成功,false或者nil表示连接失败
- local function connectCbFnc(result)
- log.info("aliyun","连接结果", result)
- sConnected = result
- if result then
- sys.publish("aliyun_ready")
- log.info("aliyun", "连接成功")
- --订阅主题
- --根据自己的项目需要订阅主题,下面注释掉的一行代码中的主题是非法的,所以不能打开,一旦打开,会导致订阅失败
- --订阅OTA主题
- aliyun.subscribe("/ota/device/upgrade/"..tPara.ProductKey.."/"..tPara.DeviceName,1)
- if not verRpted then
- --上报固件版本号给云端
- verRpt()
- end
- --上报固件版本号给云端
- sys.timerStart(verRpt,10000)
- -- aliyun.subscribe(topic,qos)
- -- aliyun.subscribe("/"..tPara.ProductKey.."/"..tPara.DeviceName.."/user/ceshi",1)
-
- --使用掉电不消失的kv文件区来储存的deviceSecret,deviceToken
- local used = fskv.get("deviceSecret")
- local total = fskv.get("deviceToken")
- local cid = fskv.get("clientid")
- --储存到kv分区的返回值
- -- log.info("kv分区的返回值",used,total,cid)
- local Secret = aliyun.getDeviceSecret()
- local Token = aliyun.getDeviceToken()
- local Clid = aliyun.getClientid()
- --如果三元组不为空,就把三元组写入到kv区
- if tPara.DeviceName and tPara.ProductKey then
- fskv.set("DeviceName",tPara.DeviceName)
- fskv.set("ProductKey",tPara.ProductKey)
- end
- if not tPara.Registration then
- if Secret == nil then
- log.info("aliyun","掉线重连")
- else
- fskv.set("deviceSecret",aliyun.getDeviceSecret())
- end
- else
- if Token == nil and Clid == nil then
- log.info("aliyun","掉线重连")
- else
- fskv.set("deviceToken",aliyun.getDeviceToken())
- fskv.set("clientid",aliyun.getClientid())
- end
- end
- --注册数据接收的处理函数
- aliyun.on("receive",rcvCbFnc)
- --PUBLISH消息测试
- publishTest()
- else
- log.warn("aliyun", "连接失败")
- end
- end
- aliyun.on("connect",connectCbFnc)
- --根据掉电不消失的kv文件区来储存的deviceSecret,clientid,deviceToken来判断是进行正常连接还是掉电重连
- sys.taskInit(function()
- sys.waitUntil("net_ready")
- socket.sntp()
- sys.waitUntil("NTP_UPDATE", 2000)
- log.info("已联网", "开始初始化aliyun库")
- fskv.init()
- local name = fskv.get("DeviceName")
- local key = fskv.get("ProductKey")
- local used = fskv.get("deviceSecret")
- local total = fskv.get("deviceToken")
- local cid = fskv.get("clientid")
- local host = tPara.InstanceId..".mqtt.iothub.aliyuncs.com"
- --判断是否是同一三元组,不是的话就重新连接
- if name == tPara.DeviceName and key == tPara.ProductKey then
- if not tPara.Registration then
- if used == nil then
- aliyun.setup(tPara)
- else
- aliyun.clientGetDirectDataTask(name,tPara.ProductKey,host,tPara.mqtt_port,tPara.mqtt_isssl,tPara.Registration,used,total,cid)
- end
- else
- if total == nil and cid == nil then
- aliyun.setup(tPara)
- else
- aliyun.clientGetDirectDataTask(name,tPara.ProductKey,host,tPara.mqtt_port,tPara.mqtt_isssl,tPara.Registration,used,total,cid)
- end
- end
- else
- fskv.del("deviceToken")
- fskv.del("clientid")
- fskv.del("DeviceName")
- fskv.del("deviceSecret")
- fskv.del("ProductKey")
- --删除kv区的数据,重新建立连接
- aliyun.setup(tPara)
- end
- end)
- function verRpt()
- log.info("aliyun", "上报版本信息", _G.VERSION)
- aliyun.publish("/ota/device/inform/"..tPara.ProductKey.."/"..tPara.DeviceName,1,"{\"id\":1,\"params\":{\"version\":\"".._G.VERSION.."\"}}")
- end
- -- 低功耗演示
- sys.taskInit(function()
- if not PM_TEST then
- return
- end
- sys.waitUntil("aliyun_ready")
- log.info("aliyun.pm", "阿里云已经连接成功, 5秒后请求进入低功耗模式, USB功能会断开")
- sys.wait(5000)
- local bsp = rtos.bsp():upper()
- -- 进入低功耗模式
- if bsp == "EC618" then
- log.info("aliyun.pm", "EC618方案进入低功耗模式")
- -- gpio.setup(23,nil)
- -- gpio.close(33)
- -- mobile.rtime(2) -- RRC快速释放减少connect时间能大幅降低功耗,但是会带来可能得离线风险,可选择延迟时间或者不用
- pm.power(pm.USB, false)
- pm.force(pm.LIGHT)
- elseif bsp == "EC718P" or bsp == "EC718PV" then
- log.info("aliyun.pm", "EC718P/EC718PV方案进入低功耗模式")
- -- mobile.rtime(2) -- RRC快速释放减少connect时间能大幅降低功耗,但是会带来可能得离线风险,可选择延迟时间或者不用
- pm.power(pm.USB, false)
- pm.force(pm.LIGHT)
- elseif bsp == "AIR101" or bsp == "AIR601" or bsp == "AIR103" then
- log.info("aliyun.pm", "XT804方案进入低功耗模式")
- while 1 do
- pm.dtimerStart(0, 30000)
- pm.request(pm.LIGHT)
- sys.wait(30000)
- end
- end
-
- end)
- -- 用户代码已结束---------------------------------------------
- -- 结尾总是这一句
- sys.run()
- -- sys.run()之后后面不要加任何语句!!!!!
|