1 -- LuaTools需要PROJECT和VERSION这两个信息
6 _G
.sys
= require("sys")
7 --[[特别注意, 使用mqtt库需要下列语句]]
8 _G
.sysplus
= require("sysplus")
11 -- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
12 if rtos
.bsp() == "EC618" and pm
and pm
.PWK_MODE
then
13 pm
.power(pm
.PWK_MODE
, false)
18 -- https://console.cloud.tencent.com/iotexplorer
19 -- 要在项目详情里启用 "动态注册配置", "动态注册"和"自动创建设备"都需要启用
21 local ProductId
= "T7ASGCON0H"
22 local ProductSecret
= "cAnsvBBNquvTWYIihUPoxkp2"
24 local mqtt_isssl
= false
26 -- 这个demo属于纯手写, 还可以参考 iotcloud 库及其demo/iotcloud获取更一致的云服务体验
34 local function getDeviceName()
35 --默认使用设备的IMEI作为设备名称,用户可以根据项目需求自行修改
41 function device_enrol()
42 local deviceName
= getDeviceName()
43 local nonce
= math
.random(1, 100)
44 local timestamp
= os
.time()
45 local data
= "deviceName=" .. deviceName
.. "&nonce=" .. nonce
.. "&productId=" ..
46 ProductId
.. "×tamp=" .. timestamp
47 local hmac_sha1_data
= crypto
.hmac_sha1(data
, ProductSecret
):lower()
48 local signature
= crypto
.base64_encode(hmac_sha1_data
)
50 productId
= ProductId
,
51 deviceName
= deviceName
,
53 timestamp
= timestamp
,
54 signature
= signature
,
56 local tx_body_json
= json
.encode(tx_body
)
57 local code
, headers
, body
= http
.request("POST", "https://ap-guangzhou.gateway.tencentdevices.com/register/dev",
59 ["Content-Type"] = "application/json; charset=UTF-8",
60 ["X-TC-Version"] = "2019-04-23",
61 ["X-TC-Region"] = "ap-guangzhou"
62 }, tx_body_json
, { timeout
= 30000 }).wait()
63 log.info("http.post", code
, headers
, body
)
65 local m
, result
, err
= json
.decode(body
)
66 log.info(" m,result,err", m
, result
, err
)
68 log.info("json解析失败", err
)
71 if m
.message
== "success" then
72 log.info("腾讯云注册设备成功:", body
)
73 log.info("http.body.message", m
.message
)
74 local result
= io
.writeFile("/txiot.dat", body
)
75 log.info("密钥写入结果", result
)
77 log.info("腾讯云注册设备失败:失败原因", m
.message
)
80 log.info("http请求失败:", body
)
84 sys
.subscribe("MQTT_SIGN_AUTH", function(clientid
, username
, password
)
85 sys
.taskInit(function()
86 log.info("clientid,username,password", result
, clientid
, username
, password
, payload
)
88 local mqtt_host
= ProductId
.. ".iotcloud.tencentdevices.com"
89 mqttc
= mqtt
.create(nil, mqtt_host
, 1883, mqtt_isssl
)
90 mqttc
:auth(clientid
, username
, password
, false) -- client_id必填,其余选填
91 mqttc
:keepalive(300) -- 默认300s
92 mqttc
:autoreconn(true, 3000) -- 自动重连机制
93 mqttc
:on(function(mqtt_client
, event
, data
, payload
)
95 log.info("mqtt", "event", event
, mqtt_client
, data
, payload
)
96 if event
== "conack" then
97 log.info("mqtt", "sent", "pkgid", data
)
99 sys
.publish("mqtt_conack")
100 local txiot_subscribetopic
= {
101 ["$thing/down/property/" .. ProductId
.. "/" .. getDeviceName()] = 0
103 mqtt_client
:subscribe(txiot_subscribetopic
)
104 elseif event
== "recv" then
105 log.info("mqtt", "downlink", "topic", data
, "payload", payload
)
106 --TODO:根据需求自行处理data.payload
107 --sys.publish("mqtt_payload", data, payload)
108 mqttc
:publish("$thing/up/property/" .. ProductId
.. "/" .. getDeviceName(),
109 "publish from luat mqtt client",
111 elseif event
== "sent" then
112 log.info("mqtt", "sent", "pkgid", data
)
113 elseif event
== "disconnect" then
115 -- --非自动重连时,按需重启mqttc
116 -- mqtt_client:connect()
120 sys
.waitUntil("mqtt_conack")
122 -- 如果没有其他task上报, 可以写个空等待
129 sys
.subscribe("MQTT_CERT_AUTH", function() ---证书认证连接
130 sys
.taskInit(function()
131 local clientid
= ProductId
.. getDeviceName()
132 local connid
= math
.random(10000, 99999)
133 log.info("connid类型", type(connid
))
134 local expiry
= "32472115200"
135 local username
= string.format("%s;12010126;%s;%s", clientid
, connid
, expiry
) --生成 MQTT 的 username 部分, 格式为 ${clientid};${sdkappid};${connid};${expiry}
136 local password
= 123 --证书认证不会验证password
137 log.info("clientid1,username1,password1", clientid
, username
, password
)
138 local mqtt_host
= ProductId
.. ".iotcloud.tencentdevices.com"
139 mqttc
= mqtt
.create(nil, mqtt_host
, 8883,
140 { server_cert
= io
.readFile("/luadb/ca.crt"),
141 client_cert
= io
.readFile("/client.crt"),
142 client_key
= io
.readFile("/client.key") })
143 mqttc
:auth(clientid
, username
, password
) -- client_id必填,其余选填
144 mqttc
:keepalive(300) -- 默认值300s
145 mqttc
:autoreconn(true, 20000) -- 自动重连机制
148 mqttc
:on(function(mqtt_client
, event
, data
, payload
)
150 log.info("mqtt", "event", event
, mqtt_client
, data
, payload
)
151 if event
== "conack" then
152 log.info("mqtt", "sent", "pkgid", data
)
154 sys
.publish("mqtt_conack")
155 local txiot_subscribetopic
= {
156 ["$thing/down/property/" .. ProductId
.. "/" .. getDeviceName()] = 0
158 mqtt_client
:subscribe(txiot_subscribetopic
)
159 elseif event
== "recv" then
160 log.info("mqtt", "downlink", "topic", data
, "payload", payload
)
161 --TODO:根据需求自行处理data.payload
162 --sys.publish("mqtt_payload", data, payload)
163 mqttc
:publish("$thing/up/property/" .. ProductId
.. "/" .. getDeviceName(),
164 "publish from luat mqtt client",
166 elseif event
== "sent" then
167 log.info("mqtt", "sent", "pkgid", data
)
168 elseif event
== "disconnect" then
170 -- --非自动重连时,按需重启mqttc
171 -- mqtt_client:connect()
174 local result
= mqttc
:connect()
175 log.info("connect.result", result
)
176 sys
.waitUntil("mqtt_conack")
179 -- 如果没有其他task上报, 可以写个空等待
185 sys
.taskInit(function()
186 if mobile
.status() ~= 1 and not sys
.waitUntil("IP_READY", 600000) then
189 log.info("io.exists", io
.exists("/txiot.dat"))
190 if not io
.exists("/txiot.dat") then
193 if not io
.exists("/txiot.dat") then
194 log.info("txiot", "注册失败")
197 local dat
, result
, err
= json
.decode(io
.readFile("/txiot.dat"))
198 log.info("dat,result,err", dat
, result
, err
)
200 log.info("json解码失败", err
)
201 device_enrol() --解析失败重新下载文件
202 local dat
, result
, err
= json
.decode(io
.readFile("/txiot.dat"))
204 local payload
= json
.decode(crypto
.cipher_decrypt("AES-128-CBC", "ZERO", crypto
.base64_decode(dat
.payload
),
205 string.sub(ProductSecret
, 1, 16), "0000000000000000"))
206 log.info("payload[encryptionType]", payload
.encryptionType
)
207 log.info("payload[psk]", payload
.psk
)
208 if payload
.encryptionType
== 2 then
209 local clientid
, username
, password
= iotauth
.qcloud(ProductId
, getDeviceName(), payload
.psk
)
210 sys
.publish("MQTT_SIGN_AUTH", clientid
, username
, password
) --签名认证
211 elseif payload
.encryptionType
== 1 then
212 log.info("payload date ", payload
.encryptionType
, payload
.psk
, payload
.clientCert
, payload
.clientKey
)
213 io
.writeFile("/client.crt", payload
.clientCert
)
214 io
.writeFile("/client.key", payload
.clientKey
)
215 sys
.publish("MQTT_CERT_AUTH") --证书认证
222 -- 用户代码已结束---------------------------------------------
225 -- sys.run()之后后面不要加任何语句!!!!!