testALiYun.lua 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. --- 模块功能:阿里云功能测试.
  2. -- 支持数据传输和OTA功能
  3. -- @author openLuat
  4. -- @module aLiYun.testALiYun
  5. -- @license MIT
  6. -- @copyright openLuat
  7. -- @release 2018.04.14
  8. module(...,package.seeall)
  9. require"aLiYun"
  10. require"misc"
  11. require"pm"
  12. --采用一机一密认证方案时:
  13. --PRODUCT_KEY为阿里云华东2站点上创建的产品的ProductKey,用户根据实际值自行修改
  14. local PRODUCT_KEY = "b0FMK1Ga5cp"
  15. --除了上面的PRODUCT_KEY外,还需要提供获取DeviceName的函数、获取DeviceSecret的函数
  16. --设备名称使用函数getDeviceName的返回值,默认为设备的IMEI
  17. --设备密钥使用函数getDeviceSecret的返回值,默认为设备的SN
  18. --单体测试时,可以直接修改getDeviceName和getDeviceSecret的返回值
  19. --批量量产时,使用设备的IMEI和SN;合宙生产的模块,都有唯一的IMEI,用户可以在自己的产线批量写入跟IMEI(设备名称)对应的SN(设备密钥)
  20. --或者用户自建一个服务器,设备上报IMEI给服务器,服务器返回对应的设备密钥,然后调用misc.setSn接口写到设备的SN中
  21. --采用一型一密认证方案时:
  22. --PRODUCT_KEY和PRODUCE_SECRET为阿里云华东2站点上创建的产品的ProductKey和ProductSecret,用户根据实际值自行修改
  23. --local PRODUCT_KEY = "b1KCi45LcCP"
  24. --local PRODUCE_SECRET = "VWll9fiYWKiwraBk"
  25. --除了上面的PRODUCT_KEY和PRODUCE_SECRET外,还需要提供获取DeviceName的函数、获取DeviceSecret的函数、设置DeviceSecret的函数
  26. --设备第一次在某个product下使用时,会先去云端动态注册,获取到DeviceSecret后,调用设置DeviceSecret的函数保存DeviceSecret
  27. --[[
  28. 函数名:getDeviceName
  29. 功能 :获取设备名称
  30. 参数 :无
  31. 返回值:设备名称
  32. ]]
  33. local function getDeviceName()
  34. --默认使用设备的IMEI作为设备名称,用户可以根据项目需求自行修改
  35. return misc.getImei()
  36. --用户单体测试时,可以在此处直接返回阿里云的iot控制台上注册的设备名称,例如return "862991419835241"
  37. --return "862991419835241"
  38. end
  39. --[[
  40. 函数名:setDeviceSecret
  41. 功能 :修改设备密钥
  42. 参数 :设备密钥
  43. 返回值:无
  44. ]]
  45. local function setDeviceSecret(s)
  46. --默认使用设备的SN作为设备密钥,用户可以根据项目需求自行修改
  47. misc.setSn(s)
  48. end
  49. --[[
  50. 函数名:getDeviceSecret
  51. 功能 :获取设备密钥
  52. 参数 :无
  53. 返回值:设备密钥
  54. ]]
  55. local function getDeviceSecret()
  56. --默认使用设备的SN作为设备密钥,用户可以根据项目需求自行修改
  57. return misc.getSn()
  58. --用户单体测试时,可以在此处直接返回阿里云的iot控制台上生成的设备密钥,例如return "y7MTCG6Gk33Ux26bbWSpANl4OaI0bg5Q"
  59. --return "y7MTCG6Gk33Ux26bbWSpANl4OaI0bg5Q"
  60. end
  61. --阿里云客户端是否处于连接状态
  62. local sConnected
  63. local publishCnt = 1
  64. --[[
  65. 函数名:pubqos1testackcb
  66. 功能 :发布1条qos为1的消息后收到PUBACK的回调函数
  67. 参数 :
  68. usertag:调用mqttclient:publish时传入的usertag
  69. result:true表示发布成功,false或者nil表示失败
  70. 返回值:无
  71. ]]
  72. local function publishTestCb(result,para)
  73. log.info("testALiYun.publishTestCb",result,para)
  74. sys.timerStart(publishTest,20000)
  75. publishCnt = publishCnt+1
  76. end
  77. --发布一条QOS为1的消息
  78. function publishTest()
  79. if sConnected then
  80. --注意:在此处自己去控制payload的内容编码,aLiYun库中不会对payload的内容做任何编码转换
  81. aLiYun.publish("/"..PRODUCT_KEY.."/"..getDeviceName().."/update","qos1data",1,publishTestCb,"publishTest_"..publishCnt)
  82. end
  83. end
  84. ---数据接收的处理函数
  85. -- @string topic,UTF8编码的消息主题
  86. -- @number qos,消息质量等级
  87. -- @string payload,原始编码的消息负载
  88. local function rcvCbFnc(topic,qos,payload)
  89. log.info("testALiYun.rcvCbFnc",topic,qos,payload)
  90. end
  91. --- 连接结果的处理函数
  92. -- @bool result,连接结果,true表示连接成功,false或者nil表示连接失败
  93. local function connectCbFnc(result)
  94. log.info("testALiYun.connectCbFnc",result)
  95. sConnected = result
  96. if result then
  97. --订阅主题,不需要考虑订阅结果,如果订阅失败,aLiYun库中会自动重连
  98. aLiYun.subscribe({["/"..PRODUCT_KEY.."/"..getDeviceName().."/get"]=0, ["/"..PRODUCT_KEY.."/"..getDeviceName().."/get"]=1})
  99. --注册数据接收的处理函数
  100. aLiYun.on("receive",rcvCbFnc)
  101. --PUBLISH消息测试
  102. publishTest()
  103. end
  104. end
  105. -- 认证结果的处理函数
  106. -- @bool result,认证结果,true表示认证成功,false或者nil表示认证失败
  107. local function authCbFnc(result)
  108. log.info("testALiYun.authCbFnc",result)
  109. end
  110. --采用一机一密认证方案时:
  111. --配置:ProductKey、获取DeviceName的函数、获取DeviceSecret的函数;其中aLiYun.setup中的第二个参数必须传入nil
  112. aLiYun.setup(PRODUCT_KEY,nil,getDeviceName,getDeviceSecret)
  113. --采用一型一密认证方案时:
  114. --配置:ProductKey、ProductSecret、获取DeviceName的函数、获取DeviceSecret的函数、设置DeviceSecret的函数
  115. --aLiYun.setup(PRODUCT_KEY,PRODUCE_SECRET,getDeviceName,getDeviceSecret,setDeviceSecret)
  116. --setMqtt接口不是必须的,aLiYun.lua中有这个接口设置的参数默认值,如果默认值满足不了需求,参考下面注释掉的代码,去设置参数
  117. --aLiYun.setMqtt(0)
  118. aLiYun.on("auth",authCbFnc)
  119. aLiYun.on("connect",connectCbFnc)
  120. --要使用阿里云OTA功能,必须参考本文件124或者126行aLiYun.setup去配置参数
  121. --然后加载阿里云OTA功能模块(打开下面的代码注释)
  122. require"aLiYunOta"
  123. --如果利用阿里云OTA功能去下载升级合宙模块的新固件,默认的固件版本号格式为:_G.PROJECT.."_".._G.VERSION.."_"..sys.getcorever(),下载结束后,直接重启,则到此为止,不需要再看下文说明
  124. --如果下载升级合宙模块的新固件,下载结束后,自己控制是否重启
  125. --如果利用阿里云OTA功能去下载其他升级包,例如模块外接的MCU升级包,则根据实际情况,打开下面的代码注释,调用设置接口进行配置和处理
  126. --设置MCU当前运行的固件版本号
  127. --aLiYunOta.setVer("MCU_VERSION_1.0.0")
  128. --设置新固件下载后保存的文件名
  129. --aLiYunOta.setName("MCU_FIRMWARE.bin")
  130. --[[
  131. 函数名:otaCb
  132. 功能 :新固件文件下载结束后的回调函数
  133. 通过uart1(115200,8,uart.PAR_NONE,uart.STOP_1)把下载成功的文件,发送到MCU,发送成功后,删除此文件
  134. 参数 :
  135. result:下载结果,true为成功,false为失败
  136. filePath:新固件文件保存的完整路径,只有result为true时,此参数才有意义
  137. 返回值:无
  138. ]]
  139. local function otaCb(result,filePath)
  140. log.info("testALiYun.otaCb",result,filePath)
  141. if result then
  142. local uartID = 1
  143. sys.taskInit(
  144. function()
  145. local fileHandle = io.open(filePath,"rb")
  146. if not fileHandle then
  147. log.error("testALiYun.otaCb open file error")
  148. if filePath then os.remove(filePath) end
  149. return
  150. end
  151. pm.wake("UART_SENT2MCU")
  152. uart.on(uartID,"sent",function() sys.publish("UART_SENT2MCU_OK") end)
  153. uart.setup(uartID,115200,8,uart.PAR_NONE,uart.STOP_1,nil,1)
  154. while true do
  155. local data = fileHandle:read(1460)
  156. if not data then break end
  157. uart.write(uartID,data)
  158. sys.waitUntil("UART_SENT2MCU_OK")
  159. end
  160. --此处上报新固件版本号(仅供测试使用)
  161. --用户开发自己的程序时,根据下载下来的新固件,执行升级动作
  162. --升级成功后,调用aLiYunOta.setVer上报新固件版本号
  163. --如果升级失败,调用aLiYunOta.setVer上报旧固件版本号
  164. aLiYunOta.setVer("MCU_VERSION_1.0.1")
  165. uart.close(uartID)
  166. pm.sleep("UART_SENT2MCU")
  167. fileHandle:close()
  168. if filePath then os.remove(filePath) end
  169. end
  170. )
  171. else
  172. --文件使用完之后,如果以后不再需求,需要自行删除
  173. if filePath then os.remove(filePath) end
  174. end
  175. end
  176. --设置新固件下载结果的回调函数
  177. --aLiYunOta.setCb(otaCb)