| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- -- LuaTools需要PROJECT和VERSION这两个信息
- PROJECT = "txiot_demo"
- VERSION = "1.0.0"
- -- sys库是标配
- _G.sys = require("sys")
- --[[特别注意, 使用http库需要下列语句]]
- _G.sysplus = require("sysplus")
- -- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
- if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
- pm.power(pm.PWK_MODE, false)
- end
- -- 产品ID和产品动态注册秘钥
- -- https://console.cloud.tencent.com/iotexplorer
- -- 要在项目详情里启用 "动态注册配置", "动态注册"和"自动创建设备"都需要启用
- -- 下列参数是测试用的,要改成自己的值
- local ProductId = "T7ASGCON0H"
- local ProductSecret = "cAnsvBBNquvTWYIihUPoxkp2"
- local mqttc
- local mqtt_isssl = false
- -- 这个demo属于纯手写, 还可以参考 iotcloud 库及其demo/iotcloud获取更一致的云服务体验
- --[[
- 函数名:getDeviceName
- 功能 :获取设备名称
- 参数 :无
- 返回值:设备名称
- ]]
- local function getDeviceName()
- --默认使用设备的IMEI作为设备名称,用户可以根据项目需求自行修改
- return mobile.imei()
- end
- function device_enrol()
- local deviceName = getDeviceName()
- local nonce = math.random(1, 100)
- local timestamp = os.time()
- local data = "deviceName=" .. deviceName .. "&nonce=" .. nonce .. "&productId=" ..
- ProductId .. "×tamp=" .. timestamp
- local hmac_sha1_data = crypto.hmac_sha1(data, ProductSecret):lower()
- local signature = crypto.base64_encode(hmac_sha1_data)
- local tx_body = {
- productId = ProductId,
- deviceName = deviceName,
- nonce = nonce,
- timestamp = timestamp,
- signature = signature,
- }
- local tx_body_json = json.encode(tx_body)
- local code, headers, body = http.request("POST", "https://ap-guangzhou.gateway.tencentdevices.com/register/dev",
- {
- ["Content-Type"] = "application/json; charset=UTF-8",
- ["X-TC-Version"] = "2019-04-23",
- ["X-TC-Region"] = "ap-guangzhou"
- }, tx_body_json, { timeout = 30000 }).wait()
- log.info("http.post", code, headers, body)
- if code == 200 then
- local m, result, err = json.decode(body)
- log.info(" m,result,err", m, result, err)
- if result == 0 then
- log.info("json解析失败", err)
- device_enrol()
- end
- if m.message == "success" then
- log.info("腾讯云注册设备成功:", body)
- log.info("http.body.message", m.message)
- local result = io.writeFile("/txiot.dat", body)
- log.info("密钥写入结果", result)
- else
- log.info("腾讯云注册设备失败:失败原因", m.message)
- end
- else
- log.info("http请求失败:", body)
- end
- end
- sys.subscribe("MQTT_SIGN_AUTH", function(clientid, username, password)
- sys.taskInit(function()
- log.info("clientid,username,password", result, clientid, username, password, payload)
- local mqtt_host = ProductId .. ".iotcloud.tencentdevices.com"
- mqttc = mqtt.create(nil, mqtt_host, 1883, mqtt_isssl)
- mqttc:auth(clientid, username, password, false) -- client_id必填,其余选填
- mqttc:keepalive(300) -- 默认300s
- mqttc:autoreconn(true, 3000) -- 自动重连机制
- mqttc:on(function(mqtt_client, event, data, payload)
- -- 用户自定义代码
- log.info("mqtt", "event", event, mqtt_client, data, payload)
- if event == "conack" then
- log.info("mqtt", "sent", "pkgid", data)
- --连上了
- sys.publish("mqtt_conack")
- local txiot_subscribetopic = {
- ["$thing/down/property/" .. ProductId .. "/" .. getDeviceName()] = 0
- }
- mqtt_client:subscribe(txiot_subscribetopic)
- elseif event == "recv" then
- log.info("mqtt", "downlink", "topic", data, "payload", payload)
- --TODO:根据需求自行处理data.payload
- --sys.publish("mqtt_payload", data, payload)
- mqttc:publish("$thing/up/property/" .. ProductId .. "/" .. getDeviceName(),
- "publish from luat mqtt client",
- 0)
- elseif event == "sent" then
- log.info("mqtt", "sent", "pkgid", data)
- elseif event == "disconnect" then
- log.info("连接失败")
- -- --非自动重连时,按需重启mqttc
- -- mqtt_client:connect()
- end
- end)
- mqttc:connect()
- sys.waitUntil("mqtt_conack")
- while true do
- -- 如果没有其他task上报, 可以写个空等待
- sys.wait(60000000)
- end
- end)
- end)
- sys.subscribe("MQTT_CERT_AUTH", function() ---证书认证连接
- sys.taskInit(function()
- local clientid = ProductId .. getDeviceName()
- local connid = math.random(10000, 99999)
- log.info("connid类型", type(connid))
- local expiry = "32472115200"
- local username = string.format("%s;12010126;%s;%s", clientid, connid, expiry) --生成 MQTT 的 username 部分, 格式为 ${clientid};${sdkappid};${connid};${expiry}
- local password = 123 --证书认证不会验证password
- log.info("clientid1,username1,password1", clientid, username, password)
- local mqtt_host = ProductId .. ".iotcloud.tencentdevices.com"
- mqttc = mqtt.create(nil, mqtt_host, 8883,
- { server_cert = io.readFile("/luadb/ca.crt"),
- client_cert = io.readFile("/client.crt"),
- client_key = io.readFile("/client.key") })
- mqttc:auth(clientid, username, password) -- client_id必填,其余选填
- mqttc:keepalive(300) -- 默认值300s
- mqttc:autoreconn(true, 20000) -- 自动重连机制
- mqttc:on(function(mqtt_client, event, data, payload)
- -- 用户自定义代码
- log.info("mqtt", "event", event, mqtt_client, data, payload)
- if event == "conack" then
- log.info("mqtt", "sent", "pkgid", data)
- --连上了
- sys.publish("mqtt_conack")
- local txiot_subscribetopic = {
- ["$thing/down/property/" .. ProductId .. "/" .. getDeviceName()] = 0
- }
- mqtt_client:subscribe(txiot_subscribetopic)
- elseif event == "recv" then
- log.info("mqtt", "downlink", "topic", data, "payload", payload)
- --TODO:根据需求自行处理data.payload
- --sys.publish("mqtt_payload", data, payload)
- mqttc:publish("$thing/up/property/" .. ProductId .. "/" .. getDeviceName(),
- "publish from luat mqtt client",
- 0)
- elseif event == "sent" then
- log.info("mqtt", "sent", "pkgid", data)
- elseif event == "disconnect" then
- log.info("连接失败")
- -- --非自动重连时,按需重启mqttc
- -- mqtt_client:connect()
- end
- end)
- local result = mqttc:connect()
- log.info("connect.result", result)
- sys.waitUntil("mqtt_conack")
- while true do
- -- 如果没有其他task上报, 可以写个空等待
- sys.wait(60000000)
- end
- end)
- end)
- sys.taskInit(function()
- if mobile.status() ~= 1 and not sys.waitUntil("IP_READY", 600000) then
- log.info("网络初始化失败!")
- end
- log.info("io.exists", io.exists("/txiot.dat"))
- if not io.exists("/txiot.dat") then
- device_enrol()
- end
- if not io.exists("/txiot.dat") then
- log.info("txiot", "注册失败")
- return
- end
- local dat, result, err = json.decode(io.readFile("/txiot.dat"))
- log.info("dat,result,err", dat, result, err)
- if result == 0 then
- log.info("json解码失败", err)
- device_enrol() --解析失败重新下载文件
- local dat, result, err = json.decode(io.readFile("/txiot.dat"))
- end
- local payload = json.decode(crypto.cipher_decrypt("AES-128-CBC", "ZERO", crypto.base64_decode(dat.payload),
- string.sub(ProductSecret, 1, 16), "0000000000000000"))
- log.info("payload[encryptionType]", payload.encryptionType)
- log.info("payload[psk]", payload.psk)
- if payload.encryptionType == 2 then
- local clientid, username, password = iotauth.qcloud(ProductId, getDeviceName(), payload.psk)
- sys.publish("MQTT_SIGN_AUTH", clientid, username, password) --签名认证
- elseif payload.encryptionType == 1 then
- log.info("payload date ", payload.encryptionType, payload.psk, payload.clientCert, payload.clientKey)
- io.writeFile("/client.crt", payload.clientCert)
- io.writeFile("/client.key", payload.clientKey)
- sys.publish("MQTT_CERT_AUTH") --证书认证
- end
- end)
- -- 用户代码已结束---------------------------------------------
- -- 结尾总是这一句
- sys.run()
- -- sys.run()之后后面不要加任何语句!!!!!
|