-- LuaTools需要PROJECT和VERSION这两个信息 PROJECT = "aliyun_autoreg_demo" VERSION = "1.0.0" --[[ 本demo 为 "一型一密' 的替代方案: 1. 通过regproxy服务获取阿里云物联网平台的设备密钥,并保存到文件 2. 使用mqtt连接到阿里云物联网平台 regproxy服务的源码 https://gitee.com/openLuat/iot-regproxy ]] -- 引入必要的库文件(lua编写), 内部库不需要require local sys = require "sys" local mqtt = require "mqtt" log.info("version", _VERSION, VERSION) --- UART 相关------------------------------ -- 配置uart2, 115200 8 N 1 --uart.on(2, "receive", function(id, len) -- log.info("uart", "receive", uart.read(id, 1024)) --end) --uart.setup(2, 115200) -- GPIO 和 PWM 相关 ------------------------------- -- 网络灯 GPIO19/PWM5 gpio.setup(19, 0) -- 初始化GPIO19, 并设置为低电平 gpio.set(19, 1) -- 设置为高电平 -- pwm.open(5, 1000, 50) -- 初始化PWM5, 频率1000hz, 占空比50% -- GPIO18/PWM4 -- GPIO17/PWM3 -- 低功耗sleep2模式下依然能输出电平的AON系列GPIO -- AON_GPIO2 --> GPIO22 -- AON_GPIO3 --> GPIO23 -- ADC相关--------------------------------------- -- 通道 0-内部温度, 1-供电电压, 2-5 外部ADC管脚 -- adc.open(5) -- adc.read(5) -- adc.close(5) local aliyun_msgid = 1 local vPowerSwitch = 1 function aliyun_params_post() --[[ { "id": "123", "version": "1.0", "params": { "Power": { "value": "on", "time": 1524448722000 }, "WF": { "value": 23.6, "time": 1524448722000 } }, "method": "thing.event.property.post" } ]] aliyun_msgid = aliyun_msgid + 1 local re = { id = tostring(aliyun_msgid), version = "1.0", params = { PowerSwitch = { value = vPowerSwitch, time = os.time() * 1000 } -- ,RSSI = { -- value = nbiot.rssi(), -- time = os.time() * 1000 -- }, }, method = "thing.event.property.post" } return json.encode(re) end -- 连接到阿里云物联网的Task sys.taskInit(function() sys.wait(2000) while not socket.isReady() do log.info("net", "wait for network ready") sys.waitUntil("NET_READY", 1000) end -- 阿里云物联网的设备信息 -- https://help.aliyun.com/document_detail/73742.html?spm=a2c4g.11186623.6.593.11a22cf0rGX1bC -- deviceName 是imei local productKey,deviceName,deviceSecret = "a1UTvQkICk9",nbiot.imei(), nil -- 从文件读取设备密钥 local f = io.open("aliyun_secret.txt") if f then -- 读取全部数据,应该是32字节 deviceSecret = f:read("*a") f:close() end -- 判断一下deviceSecret是否合法 if deviceSecret == nil or deviceSecret == "" or #deviceSecret ~= 32 then deviceSecret = nil log.info("aliyun", "miss deviceSecret") local c = 3 -- 通过http请求regproxy -- regproxy服务的源码 https://gitee.com/openLuat/iot-regproxy -- ============================================================================================================ while c > 0 and deviceSecret == nil do sys.wait(2000) -- 稍等一会 c = c - 1 local tmpl = "http://regproxy.luatos.com/reg/aliyun?dev=%s&key=%s&sign=%s" local url = string.format(tmpl, deviceName,productKey, crypto.md5(deviceName .. productKey .. "123")) http.get(url, nil, function(code,headers,body) log.info("http", code, body) if code == 200 then local jdata,result = json.decode(body) if jdata and jdata.secret then log.info("aliyun", "GOT secret", jdata.secret) local f_aliyun_secret = io.open("aliyun_secret.txt", "wb") f_aliyun_secret:write(jdata.secret) f_aliyun_secret:close() deviceSecret = jdata.secret end end sys.publish("HTTP_RESP") end) sys.waitUntil("HTTP_RESP", 120000) -- 等服务器响应 end -- ============================================================================================================ end -- 往下的代码, 与demo/aliyun一致 local host, port, selfid = productKey .. ".iot-as-mqtt.cn-shanghai.aliyuncs.com", 1883, deviceName local mqttClientId = selfid .. "|securemode=3,signmethod=hmacsha1,timestamp=132323232|" local mqttUsername = deviceName .. "&" .. productKey local signstr = "clientId"..selfid.."deviceName"..deviceName.."productKey"..productKey.."timestamp".."132323232" local mqttPassword = crypto.hmac_sha1(signstr, deviceSecret) --log.info("aliiot", "mqttClientId", mqttClientId) --log.info("aliiot", "mqttUsername", mqttUsername) --log.info("aliiot", "signstr", signstr) --log.info("aliiot", "mqttPassword", mqttPassword) local topic_post = string.format("/sys/%s/%s/thing/event/property/post", productKey, deviceName) local topic_post_reply = string.format("/sys/%s/%s/thing/event/property/post_reply", productKey, deviceName) local topic_set = string.format("/sys/%s/%s/thing/service/property/set", productKey, deviceName) local topic_user_get = string.format("/%s/%s/user/get", productKey, deviceName) log.info("mqtt", "topic_post", topic_post) log.info("mqtt", "topic_set", topic_set) log.info("mqtt", "topic_user_get", topic_user_get) while true do -- 等待联网成功 while not socket.isReady() do log.info("net", "wait for network ready") sys.waitUntil("NET_READY", 1000) end log.info("main", "net is ready!!") sys.wait(1000) -- 稍等一会 -- 开始连接到阿里云物联网 local mqttc = mqtt.client(mqttClientId, 240, mqttUsername, mqttPassword) -- 等待底层tcp连接完成 while not mqttc:connect(host, port) do sys.wait(15000) end -- 连接成功, 开始订阅 log.info("mqttc", "mqtt seem ok", "try subscribe", topic_set) if mqttc:subscribe(topic_set) then mqttc:subscribe(topic_post_reply) mqttc:subscribe(topic_user_get) -- 订阅完成, 发布业务数据 log.info("mqttc", "mqtt subscribe ok", "try publish", topic_post) if mqttc:publish(topic_post, aliyun_params_post(), 1) then -- 发布也ok了, 等待数据下发或数据上传 while true do log.info("mqttc", "wait for new msg") local r, data, param = mqttc:receive(120000, "pub_msg") log.info("mqttc", "mqttc:receive", r, data, param) if r then -- 有下发的数据 log.info("mqttc", "get message from server", data.payload or "nil", data.topic) local tjsondata,result,errinfo = json.decode(data.payload) if result then log.info("mqtt", tjsondata.id, tjsondata.method) if tjsondata.method == "thing.service.property.set" and tjsondata.params then vPowerSwitch = tjsondata.params.PowerSwitch log.info("mqtt", "vPowerSwitch", "set as", vPowerSwitch) end else log.info("mqtt", "json.decode error",errinfo) end elseif data == "pub_msg" then -- 需要上报数据 log.info("mqttc", "send message to server", data, param) mqttc:publish(topic_post, param, 1) elseif data == "timeout" then -- 无交互,发个定时report也行 log.info("mqttc", "wait timeout, send custom report") mqttc:publish(topic_post, aliyun_params_post(), 1) else -- 其他情况不太可能,退出连接吧 log.info("mqttc", "ok, something happen", "close connetion") break end end end end -- 关掉连接,清理资源 mqttc:disconnect() -- 避免频繁重连, 必须加延时 sys.wait(30000) end end) -- 用户代码已结束--------------------------------------------- -- 结尾总是这一句 sys.run() -- sys.run()之后后面不要加任何语句!!!!!