main.lua 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. -- LuaTools需要PROJECT和VERSION这两个信息
  2. PROJECT = "air640w_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. wlan.connect("uiot", "12345678") -- wifi的密钥
  15. local aliyun_msgid = 1
  16. local vPowerSwitch = 1
  17. function aliyun_params_post()
  18. --[[
  19. {
  20. "id": "123",
  21. "version": "1.0",
  22. "params": {
  23. "Power": {
  24. "value": "on",
  25. "time": 1524448722000
  26. },
  27. "WF": {
  28. "value": 23.6,
  29. "time": 1524448722000
  30. }
  31. },
  32. "method": "thing.event.property.post"
  33. }
  34. ]]
  35. aliyun_msgid = aliyun_msgid + 1
  36. local re = {
  37. id = tostring(aliyun_msgid),
  38. version = "1.0",
  39. params = {
  40. PowerSwitch = {
  41. value = vPowerSwitch,
  42. time = os.time() * 1000
  43. }
  44. -- ,RSSI = {
  45. -- value = nbiot.rssi(),
  46. -- time = os.time() * 1000
  47. -- },
  48. },
  49. method = "thing.event.property.post"
  50. }
  51. return json.encode(re)
  52. end
  53. -- 连接到阿里云物联网的Task
  54. sys.taskInit(function()
  55. sys.wait(2000)
  56. while not socket.isReady() do
  57. log.info("net", "wait for network ready")
  58. sys.waitUntil("NET_READY", 1000)
  59. end
  60. -- 阿里云物联网的设备信息
  61. -- https://help.aliyun.com/document_detail/73742.html?spm=a2c4g.11186623.6.593.11a22cf0rGX1bC
  62. -- deviceName 是imei
  63. local productKey,deviceName,deviceSecret = "a1UTvQkICk9",wlan.getMac(), nil
  64. -- 从文件读取设备密钥
  65. local f = io.open("aliyun_secret.txt")
  66. if f then
  67. -- 读取全部数据,应该是32字节
  68. deviceSecret = f:read("*a")
  69. f:close()
  70. end
  71. -- 判断一下deviceSecret是否合法
  72. if deviceSecret == nil or deviceSecret == "" or #deviceSecret ~= 32 then
  73. deviceSecret = nil
  74. log.info("aliyun", "miss deviceSecret")
  75. local c = 3
  76. -- 通过http请求regproxy
  77. -- regproxy服务的源码 https://gitee.com/openLuat/iot-regproxy
  78. -- ============================================================================================================
  79. while c > 0 and deviceSecret == nil do
  80. sys.wait(2000) -- 稍等一会
  81. c = c - 1
  82. local tmpl = "http://regproxy.vue2.cn:8384/reg/aliyun?dev=%s&key=%s&sign=%s"
  83. local url = string.format(tmpl, deviceName,productKey, crypto.md5(deviceName .. productKey .. "123"))
  84. http.get(url, nil, function(code,headers,body)
  85. log.info("http", code, body)
  86. if code == 200 then
  87. local jdata,result = json.decode(body)
  88. if jdata and jdata.secret then
  89. log.info("aliyun", "GOT secret", jdata.secret)
  90. local f_aliyun_secret = io.open("aliyun_secret.txt", "wb")
  91. f_aliyun_secret:write(jdata.secret)
  92. f_aliyun_secret:close()
  93. deviceSecret = jdata.secret
  94. end
  95. end
  96. sys.publish("HTTP_RESP")
  97. end)
  98. sys.waitUntil("HTTP_RESP", 120000) -- 等服务器响应
  99. end
  100. -- ============================================================================================================
  101. end
  102. -- 往下的代码, 与demo/aliyun一致
  103. local host, port, selfid = productKey .. ".iot-as-mqtt.cn-shanghai.aliyuncs.com", 1883, deviceName
  104. local mqttClientId = selfid .. "|securemode=3,signmethod=hmacsha1,timestamp=132323232|"
  105. local mqttUsername = deviceName .. "&" .. productKey
  106. local signstr = "clientId"..selfid.."deviceName"..deviceName.."productKey"..productKey.."timestamp".."132323232"
  107. local mqttPassword = crypto.hmac_sha1(signstr, deviceSecret)
  108. --log.info("aliiot", "mqttClientId", mqttClientId)
  109. --log.info("aliiot", "mqttUsername", mqttUsername)
  110. --log.info("aliiot", "signstr", signstr)
  111. --log.info("aliiot", "mqttPassword", mqttPassword)
  112. local topic_post = string.format("/sys/%s/%s/thing/event/property/post", productKey, deviceName)
  113. local topic_post_reply = string.format("/sys/%s/%s/thing/event/property/post_reply", productKey, deviceName)
  114. local topic_set = string.format("/sys/%s/%s/thing/service/property/set", productKey, deviceName)
  115. local topic_user_get = string.format("/%s/%s/user/get", productKey, deviceName)
  116. log.info("mqtt", "topic_post", topic_post)
  117. log.info("mqtt", "topic_set", topic_set)
  118. log.info("mqtt", "topic_user_get", topic_user_get)
  119. while true do
  120. -- 等待联网成功
  121. while not socket.isReady() do
  122. log.info("net", "wait for network ready")
  123. sys.waitUntil("NET_READY", 1000)
  124. end
  125. log.info("main", "net is ready!!")
  126. sys.wait(1000) -- 稍等一会
  127. -- 开始连接到阿里云物联网
  128. local mqttc = mqtt.client(mqttClientId, 240, mqttUsername, mqttPassword)
  129. -- 等待底层tcp连接完成
  130. while not mqttc:connect(host, port) do sys.wait(15000) end
  131. -- 连接成功, 开始订阅
  132. log.info("mqttc", "mqtt seem ok", "try subscribe", topic_set)
  133. if mqttc:subscribe(topic_set) then
  134. mqttc:subscribe(topic_post_reply)
  135. mqttc:subscribe(topic_user_get)
  136. -- 订阅完成, 发布业务数据
  137. log.info("mqttc", "mqtt subscribe ok", "try publish", topic_post)
  138. if mqttc:publish(topic_post, aliyun_params_post(), 1) then
  139. -- 发布也ok了, 等待数据下发或数据上传
  140. while true do
  141. log.info("mqttc", "wait for new msg")
  142. local r, data, param = mqttc:receive(120000, "pub_msg")
  143. log.info("mqttc", "mqttc:receive", r, data, param)
  144. if r then -- 有下发的数据
  145. log.info("mqttc", "get message from server", data.payload or "nil", data.topic)
  146. local tjsondata,result,errinfo = json.decode(data.payload)
  147. if result then
  148. log.info("mqtt", tjsondata.id, tjsondata.method)
  149. if tjsondata.method == "thing.service.property.set" and tjsondata.params then
  150. vPowerSwitch = tjsondata.params.PowerSwitch
  151. log.info("mqtt", "vPowerSwitch", "set as", vPowerSwitch)
  152. end
  153. else
  154. log.info("mqtt", "json.decode error",errinfo)
  155. end
  156. elseif data == "pub_msg" then -- 需要上报数据
  157. log.info("mqttc", "send message to server", data, param)
  158. mqttc:publish(topic_post, param, 1)
  159. elseif data == "timeout" then -- 无交互,发个定时report也行
  160. log.info("mqttc", "wait timeout, send custom report")
  161. mqttc:publish(topic_post, aliyun_params_post(), 1)
  162. else -- 其他情况不太可能,退出连接吧
  163. log.info("mqttc", "ok, something happen", "close connetion")
  164. break
  165. end
  166. end
  167. end
  168. end
  169. -- 关掉连接,清理资源
  170. mqttc:disconnect()
  171. -- 避免频繁重连, 必须加延时
  172. sys.wait(30000)
  173. end
  174. end)
  175. -- 用户代码已结束---------------------------------------------
  176. -- 结尾总是这一句
  177. sys.run()
  178. -- sys.run()之后后面不要加任何语句!!!!!