netLed.lua 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. --[[
  2. @module netLed
  3. @summary netLed 网络状态指示灯
  4. @version 1.2
  5. @date 2025.10.21
  6. @author 马亚丹
  7. @usage
  8. --注意:因使用了sys.wait()所有api需要在协程中使用
  9. ]]
  10. netLed = {}
  11. -- 引用sys库
  12. local sys = require("sys")
  13. local simError --SIM卡状态:true为异常,false或者nil为正常
  14. local flyMode --是否处于飞行模式:true为是,false或者nil为否
  15. local gprsAttached --是否附着上GPRS网络,true为是,false或者nil为否
  16. local socketConnected --是否有socket连接上后台,true为是,false或者nil为否
  17. local prevState -- 保存SIMERR触发前的状态
  18. --[[
  19. 网络指示灯表示的工作状态
  20. NULL:功能关闭状态
  21. FLYMODE:飞行模式
  22. SIMERR:未检测到SIM卡或者SIM卡锁pin码等SIM卡异常
  23. IDLE:未注册GPRS网络
  24. GPRS:已附着GPRS数据网络
  25. SCK:socket已连接上后台
  26. ]]
  27. local ledState = "NULL"
  28. local ON, OFF = 1, 2
  29. --各种工作状态下配置的点亮、熄灭时长(单位毫秒)
  30. local ledBlinkTime = {
  31. NULL = {0, 0xFFFF}, --常灭
  32. FLYMODE = {0, 0xFFFF}, --常灭
  33. SIMERR = {700, 300}, --亮300毫秒,灭5700毫秒
  34. IDLE = {300, 3700}, --亮300毫秒,灭3700毫秒
  35. GPRS = {300, 700}, --亮300毫秒,灭700毫秒
  36. SCK = {100, 100}, --亮100毫秒,灭100毫秒
  37. }
  38. local ledSwitch = false --网络指示灯开关,true为打开,false或者nil为关闭
  39. local LEDPIN = 27 --网络指示灯默认PIN脚(GPIO27)
  40. --[[
  41. 网络指示灯模块的运行任务
  42. @api netLed.taskLed(ledPinSetFunc)
  43. @return nil 无返回值
  44. @usage
  45. ]]
  46. function netLed.taskLed(ledPinSetFunc)
  47. while true do
  48. if ledSwitch then
  49. local onTime, offTime = ledBlinkTime[ledState][ON], ledBlinkTime[ledState][OFF]
  50. if onTime > 0 then
  51. ledPinSetFunc(1)
  52. if not sys.waitUntil("NET_LED_UPDATE", onTime) then
  53. if offTime > 0 then
  54. ledPinSetFunc(0)
  55. sys.waitUntil("NET_LED_UPDATE", offTime)
  56. end
  57. end
  58. elseif offTime > 0 then
  59. ledPinSetFunc(0)
  60. sys.waitUntil("NET_LED_UPDATE", offTime)
  61. end
  62. else
  63. ledPinSetFunc(0)
  64. break
  65. end
  66. end
  67. end
  68. --[[
  69. 初始化网络指示灯并且立即执行配置后的动作
  70. @api netLed.setup(flag,ledpin)
  71. @bool flag 是否打开网络指示灯功能,true为打开,false为关闭
  72. @number ledPin 控制网络指示灯闪烁的GPIO引脚,例如pio.P0_1表示GPIO1
  73. @return nil 无返回值
  74. @usage
  75. netLed.setup(true,27)
  76. ]]
  77. function netLed.setup(flag, ledPin)
  78. local oldSwitch = ledSwitch
  79. if flag ~= ledSwitch then
  80. ledSwitch = flag
  81. sys.publish("NET_LED_UPDATE")
  82. end
  83. -- 仅在首次打开时初始化并启动网络指示灯任务
  84. if flag and not oldSwitch then
  85. sys.taskInit(netLed.taskLed, gpio.setup(ledPin, 0))
  86. end
  87. end
  88. --[[
  89. 配置某种工作状态下指示灯点亮和熄灭的时长(如果用户不配置,使用netLed.lua中ledBlinkTime配置的默认值)
  90. @api netLed.setBlinkTime(state,on,off)
  91. @string state 某种工作状态,仅支持"FLYMODE"、"SIMERR"、"IDLE"、"GPRS"、"SCK"
  92. @number on 指示灯点亮时长,单位毫秒,0xFFFF表示常亮,0表示常灭
  93. @number off 指示灯熄灭时长,单位毫秒,0xFFFF表示常灭,0表示常亮
  94. @return nil 无返回值
  95. @usage
  96. netLed.setBlinkTime("FLYMODE",1000,500) --表示飞行模式工作状态下,指示灯闪烁规律为: 亮1秒,灭0.5秒
  97. ]]
  98. function netLed.setBlinkTime(state, on, off)
  99. if not ledBlinkTime[state] then
  100. log.error("netLed.setBlinkTime", "invalid state")
  101. return
  102. end
  103. local updated = false
  104. if on and ledBlinkTime[state][ON] ~= on then
  105. ledBlinkTime[state][ON] = on
  106. updated = true
  107. end
  108. if off and ledBlinkTime[state][OFF] ~= off then
  109. ledBlinkTime[state][OFF] = off
  110. updated = true
  111. end
  112. if updated then
  113. sys.publish("NET_LED_UPDATE")
  114. end
  115. end
  116. --[[
  117. 呼吸灯
  118. @api netLed.setupBreateLed(ledPin)
  119. @function ledPin 呼吸灯的ledPin用gpio.setup注册返回的方法
  120. @return nil 无返回值
  121. @usage
  122. ]]
  123. function netLed.setupBreateLed(ledPin)
  124. -- 呼吸灯的状态、PWM周期
  125. local bLighting, bDarking, LED_PWM = false, true, 18
  126. if bLighting then
  127. for i = 1, LED_PWM - 1 do
  128. ledPin(0)
  129. sys.wait(i)
  130. ledPin(1)
  131. sys.wait(LED_PWM - i)
  132. end
  133. bLighting = false
  134. bDarking = true
  135. ledPin(0)
  136. sys.wait(700)
  137. end
  138. if bDarking then
  139. for i = 1, LED_PWM - 1 do
  140. ledPin(0)
  141. sys.wait(LED_PWM - i)
  142. ledPin(1)
  143. sys.wait(i)
  144. end
  145. bLighting = true
  146. bDarking = false
  147. ledPin(1)
  148. sys.wait(700)
  149. end
  150. end
  151. -- 事件订阅回调直接处理状态更新
  152. sys.subscribe("FLYMODE", function(mode)
  153. if flyMode == mode then return end
  154. flyMode = mode
  155. local newState = "IDLE"
  156. if flyMode then
  157. newState = "FLYMODE"
  158. elseif simError then
  159. newState = "SIMERR"
  160. elseif socketConnected then
  161. newState = "SCK"
  162. elseif gprsAttached then
  163. newState = "GPRS"
  164. end
  165. if newState ~= ledState then
  166. ledState = newState
  167. sys.publish("NET_LED_UPDATE")
  168. end
  169. end)
  170. sys.subscribe("SIM_IND", function(para)
  171. local newSimError = (para ~= "RDY") and (para ~= "GET_NUMBER")
  172. if simError == newSimError then return end
  173. -- 保存SIM异常前的状态
  174. if not simError and newSimError then
  175. prevState = ledState -- 发生SIM错误时,记录当前状态
  176. end
  177. simError = newSimError
  178. local newState = "IDLE"
  179. if flyMode then
  180. newState = "FLYMODE"
  181. elseif simError then
  182. newState = "SIMERR" -- SIM错误时使用SIMERR状态
  183. else
  184. -- SIM恢复正常时,使用错误前的状态或正常计算
  185. newState = prevState or (socketConnected and "SCK" or (gprsAttached and "GPRS" or "IDLE"))
  186. end
  187. if newState ~= ledState then
  188. ledState = newState
  189. sys.publish("NET_LED_UPDATE")
  190. end
  191. log.info("sim status", para)
  192. end)
  193. sys.subscribe("IP_LOSE", function()
  194. if not gprsAttached then return end
  195. gprsAttached = false
  196. local newState = "IDLE"
  197. if flyMode then
  198. newState = "FLYMODE"
  199. elseif simError then
  200. newState = "SIMERR"
  201. elseif socketConnected then
  202. newState = "SCK"
  203. elseif gprsAttached then
  204. newState = "GPRS"
  205. end
  206. if newState ~= ledState then
  207. ledState = newState
  208. sys.publish("NET_LED_UPDATE")
  209. end
  210. log.info("mobile", "IP_LOSE", (adapter or -1) == socket.LWIP_GP)
  211. end)
  212. sys.subscribe("IP_READY", function(ip, adapter)
  213. if gprsAttached == adapter then return end
  214. gprsAttached = adapter
  215. local newState = "IDLE"
  216. if flyMode then
  217. newState = "FLYMODE"
  218. elseif simError then
  219. newState = "SIMERR"
  220. elseif socketConnected then
  221. newState = "SCK"
  222. elseif gprsAttached then
  223. newState = "GPRS"
  224. end
  225. if newState ~= ledState then
  226. ledState = newState
  227. sys.publish("NET_LED_UPDATE")
  228. end
  229. log.info("mobile", "IP_READY", ip, (adapter or -1) == socket.LWIP_GP)
  230. end)
  231. sys.subscribe("SOCKET_ACTIVE", function(active)
  232. if socketConnected == active then return end
  233. socketConnected = active
  234. local newState = "IDLE"
  235. if flyMode then
  236. newState = "FLYMODE"
  237. elseif simError then
  238. newState = "SIMERR"
  239. elseif socketConnected then
  240. newState = "SCK"
  241. elseif gprsAttached then
  242. newState = "GPRS"
  243. end
  244. if newState ~= ledState then
  245. ledState = newState
  246. sys.publish("NET_LED_UPDATE")
  247. end
  248. end)
  249. return netLed