main.lua 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. -- LuaTools需要PROJECT和VERSION这两个信息
  2. PROJECT = "aliyun_autoreg_demo"
  3. VERSION = "1.0.0"
  4. --[[
  5. 本demo 为 "一型一密' 的替代方案:
  6. 1. 通过regproxy服务获取阿里云物联网平台的设备密钥,并保存到文件
  7. 2. 使用mqtt连接到阿里云物联网平台
  8. regproxy服务的源码 https://gitee.com/openLuat/iot-regproxy
  9. ]]
  10. -- 引入必要的库文件(lua编写), 内部库不需要require
  11. local sys = require "sys"
  12. local mqtt = require "mqtt"
  13. log.info("version", _VERSION, VERSION)
  14. --- UART 相关------------------------------
  15. -- 配置uart2, 115200 8 N 1
  16. --uart.on(2, "receive", function(id, len)
  17. -- log.info("uart", "receive", uart.read(id, 1024))
  18. --end)
  19. --uart.setup(2, 115200)
  20. -- GPIO 和 PWM 相关 -------------------------------
  21. -- 网络灯 GPIO19/PWM5
  22. gpio.setup(19, 0) -- 初始化GPIO19, 并设置为低电平
  23. gpio.set(19, 1) -- 设置为高电平
  24. -- pwm.open(5, 1000, 50) -- 初始化PWM5, 频率1000hz, 占空比50%
  25. -- GPIO18/PWM4
  26. -- GPIO17/PWM3
  27. -- 低功耗sleep2模式下依然能输出电平的AON系列GPIO
  28. -- AON_GPIO2 --> GPIO22
  29. -- AON_GPIO3 --> GPIO23
  30. -- ADC相关---------------------------------------
  31. -- 通道 0-内部温度, 1-供电电压, 2-5 外部ADC管脚
  32. -- adc.open(5)
  33. -- adc.read(5)
  34. -- adc.close(5)
  35. local aliyun_msgid = 1
  36. local vPowerSwitch = 1
  37. function aliyun_params_post()
  38. --[[
  39. {
  40. "id": "123",
  41. "version": "1.0",
  42. "params": {
  43. "Power": {
  44. "value": "on",
  45. "time": 1524448722000
  46. },
  47. "WF": {
  48. "value": 23.6,
  49. "time": 1524448722000
  50. }
  51. },
  52. "method": "thing.event.property.post"
  53. }
  54. ]]
  55. aliyun_msgid = aliyun_msgid + 1
  56. local re = {
  57. id = tostring(aliyun_msgid),
  58. version = "1.0",
  59. params = {
  60. PowerSwitch = {
  61. value = vPowerSwitch,
  62. time = os.time() * 1000
  63. }
  64. -- ,RSSI = {
  65. -- value = nbiot.rssi(),
  66. -- time = os.time() * 1000
  67. -- },
  68. },
  69. method = "thing.event.property.post"
  70. }
  71. return json.encode(re)
  72. end
  73. -- 连接到阿里云物联网的Task
  74. sys.taskInit(function()
  75. sys.wait(2000)
  76. while not socket.isReady() do
  77. log.info("net", "wait for network ready")
  78. sys.waitUntil("NET_READY", 1000)
  79. end
  80. -- 阿里云物联网的设备信息
  81. -- https://help.aliyun.com/document_detail/73742.html?spm=a2c4g.11186623.6.593.11a22cf0rGX1bC
  82. -- deviceName 是imei
  83. local productKey,deviceName,deviceSecret = "a1UTvQkICk9",nbiot.imei(), nil
  84. -- 从文件读取设备密钥
  85. local f = io.open("aliyun_secret.txt")
  86. if f then
  87. -- 读取全部数据,应该是32字节
  88. deviceSecret = f:read("*a")
  89. f:close()
  90. end
  91. -- 判断一下deviceSecret是否合法
  92. if deviceSecret == nil or deviceSecret == "" or #deviceSecret ~= 32 then
  93. deviceSecret = nil
  94. log.info("aliyun", "miss deviceSecret")
  95. local c = 3
  96. -- 通过http请求regproxy
  97. -- regproxy服务的源码 https://gitee.com/openLuat/iot-regproxy
  98. -- ============================================================================================================
  99. while c > 0 and deviceSecret == nil do
  100. sys.wait(2000) -- 稍等一会
  101. c = c - 1
  102. local tmpl = "http://regproxy.luatos.com/reg/aliyun?dev=%s&key=%s&sign=%s"
  103. local url = string.format(tmpl, deviceName,productKey, crypto.md5(deviceName .. productKey .. "123"))
  104. http.get(url, nil, function(code,headers,body)
  105. log.info("http", code, body)
  106. if code == 200 then
  107. local jdata,result = json.decode(body)
  108. if jdata and jdata.secret then
  109. log.info("aliyun", "GOT secret", jdata.secret)
  110. local f_aliyun_secret = io.open("aliyun_secret.txt", "wb")
  111. f_aliyun_secret:write(jdata.secret)
  112. f_aliyun_secret:close()
  113. deviceSecret = jdata.secret
  114. end
  115. end
  116. sys.publish("HTTP_RESP")
  117. end)
  118. sys.waitUntil("HTTP_RESP", 120000) -- 等服务器响应
  119. end
  120. -- ============================================================================================================
  121. end
  122. -- 往下的代码, 与demo/aliyun一致
  123. local host, port, selfid = productKey .. ".iot-as-mqtt.cn-shanghai.aliyuncs.com", 1883, deviceName
  124. local mqttClientId = selfid .. "|securemode=3,signmethod=hmacsha1,timestamp=132323232|"
  125. local mqttUsername = deviceName .. "&" .. productKey
  126. local signstr = "clientId"..selfid.."deviceName"..deviceName.."productKey"..productKey.."timestamp".."132323232"
  127. local mqttPassword = crypto.hmac_sha1(signstr, deviceSecret)
  128. --log.info("aliiot", "mqttClientId", mqttClientId)
  129. --log.info("aliiot", "mqttUsername", mqttUsername)
  130. --log.info("aliiot", "signstr", signstr)
  131. --log.info("aliiot", "mqttPassword", mqttPassword)
  132. local topic_post = string.format("/sys/%s/%s/thing/event/property/post", productKey, deviceName)
  133. local topic_post_reply = string.format("/sys/%s/%s/thing/event/property/post_reply", productKey, deviceName)
  134. local topic_set = string.format("/sys/%s/%s/thing/service/property/set", productKey, deviceName)
  135. local topic_user_get = string.format("/%s/%s/user/get", productKey, deviceName)
  136. log.info("mqtt", "topic_post", topic_post)
  137. log.info("mqtt", "topic_set", topic_set)
  138. log.info("mqtt", "topic_user_get", topic_user_get)
  139. while true do
  140. -- 等待联网成功
  141. while not socket.isReady() do
  142. log.info("net", "wait for network ready")
  143. sys.waitUntil("NET_READY", 1000)
  144. end
  145. log.info("main", "net is ready!!")
  146. sys.wait(1000) -- 稍等一会
  147. -- 开始连接到阿里云物联网
  148. local mqttc = mqtt.client(mqttClientId, 240, mqttUsername, mqttPassword)
  149. -- 等待底层tcp连接完成
  150. while not mqttc:connect(host, port) do sys.wait(15000) end
  151. -- 连接成功, 开始订阅
  152. log.info("mqttc", "mqtt seem ok", "try subscribe", topic_set)
  153. if mqttc:subscribe(topic_set) then
  154. mqttc:subscribe(topic_post_reply)
  155. mqttc:subscribe(topic_user_get)
  156. -- 订阅完成, 发布业务数据
  157. log.info("mqttc", "mqtt subscribe ok", "try publish", topic_post)
  158. if mqttc:publish(topic_post, aliyun_params_post(), 1) then
  159. -- 发布也ok了, 等待数据下发或数据上传
  160. while true do
  161. log.info("mqttc", "wait for new msg")
  162. local r, data, param = mqttc:receive(120000, "pub_msg")
  163. log.info("mqttc", "mqttc:receive", r, data, param)
  164. if r then -- 有下发的数据
  165. log.info("mqttc", "get message from server", data.payload or "nil", data.topic)
  166. local tjsondata,result,errinfo = json.decode(data.payload)
  167. if result then
  168. log.info("mqtt", tjsondata.id, tjsondata.method)
  169. if tjsondata.method == "thing.service.property.set" and tjsondata.params then
  170. vPowerSwitch = tjsondata.params.PowerSwitch
  171. log.info("mqtt", "vPowerSwitch", "set as", vPowerSwitch)
  172. end
  173. else
  174. log.info("mqtt", "json.decode error",errinfo)
  175. end
  176. elseif data == "pub_msg" then -- 需要上报数据
  177. log.info("mqttc", "send message to server", data, param)
  178. mqttc:publish(topic_post, param, 1)
  179. elseif data == "timeout" then -- 无交互,发个定时report也行
  180. log.info("mqttc", "wait timeout, send custom report")
  181. mqttc:publish(topic_post, aliyun_params_post(), 1)
  182. else -- 其他情况不太可能,退出连接吧
  183. log.info("mqttc", "ok, something happen", "close connetion")
  184. break
  185. end
  186. end
  187. end
  188. end
  189. -- 关掉连接,清理资源
  190. mqttc:disconnect()
  191. -- 避免频繁重连, 必须加延时
  192. sys.wait(30000)
  193. end
  194. end)
  195. -- 用户代码已结束---------------------------------------------
  196. -- 结尾总是这一句
  197. sys.run()
  198. -- sys.run()之后后面不要加任何语句!!!!!