agpsZkw.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. --- 模块功能:GPS辅助定位以及星历更新服务.
  2. -- 本功能模块只能配合Air820UX系列的模块以及Air530Z模块,中科微GPS芯片使用;
  3. -- require"agpsZkw"后,会自动开启本功能模块的任务;
  4. -- 会定期更新GPS星历,星历更新算法如下:
  5. -- 从最后一次GPS定位成功的时间算起,每隔4小时连接星历服务器下载一次星历数据(大概4K字节),写入GPS芯片。
  6. -- 例如01:00分开机后,更新了一次星历文件,截止到05:00,“一直没有开启过GPS”或者“开启过GPS,但是GPS从来没有定位成功”,在05:00就会下载星历数据然后写入GPS芯片;
  7. -- 05:00更新星历数据后,在06:00打开了GPS,并且GPS定位成功,然后在07:00关闭了GPS,关闭前GPS仍然处于定位成功状态;
  8. -- 截止到11:00,“一直没有开启过GPS”或者“开启过GPS,但是GPS从来没有定位成功”,在11:00就会下载星历数据然后写入GPS芯片;
  9. -- @module agpsZkw
  10. -- @author openLuat
  11. -- @license MIT
  12. -- @copyright openLuat
  13. -- @release 2020.10.28
  14. require"http"
  15. require"lbsLoc"
  16. require"net"
  17. local gps = require"gpsZkw"
  18. module(..., package.seeall)
  19. local EPH_TIME_FILE = "/ephTime.txt"
  20. local EPH_DATA_FILE = "/ephData.bin"
  21. local sEphData
  22. local EPH_UPDATE_INTERVAL = 4*3600
  23. local lastLbsLng,lastLbsLat = "",""
  24. local function runTimer()
  25. sys.timerStart(updateEph,EPH_UPDATE_INTERVAL*1000)
  26. end
  27. local function writeEphEnd()
  28. log.info("agpsZkw.writeEphEnd")
  29. sys.timerStart(gps.close,3000,gps.TIMER,{tag="lib.agpsZkw.lua.eph"})
  30. sEphData = nil
  31. end
  32. local function writeEph()
  33. log.info("agpsZkw.writeEph")
  34. gps.writeData(sEphData)
  35. writeEphEnd()
  36. end
  37. local function downloadEphCb(result,prompt,head,body)
  38. log.info("agpsZkw.downloadEphCb",result,prompt)
  39. runTimer()
  40. if result and prompt=="200" and body then
  41. io.writeFile(EPH_DATA_FILE,body)
  42. io.writeFile(EPH_TIME_FILE,tostring(os.time()))
  43. if gps.isFix() then
  44. else
  45. sEphData = body
  46. gps.open(gps.TIMER,{tag="lib.agpsZkw.lua.eph",val=10,cb=writeEphEnd})
  47. sys.timerStart(writeEph,2000)
  48. return
  49. end
  50. end
  51. end
  52. --连接服务器下载星历
  53. function updateEph()
  54. if gps.isFix() then runTimer() return end
  55. http.request("GET","http://download.openluat.com/9501-xingli/CASIC_data.dat",nil,nil,nil,20000,downloadEphCb)
  56. end
  57. --JWL在星历的时间范围内,如果有星历文件,重启模块就直接把本地的星历文件写入GPS芯片
  58. --在AGPS_LOCATED 的订阅事件中,调用此接口。
  59. function upd_xingli()
  60. if not gps.isFix() then
  61. local lstm = io.readFile(EPH_TIME_FILE)
  62. if not lstm or lstm=="" then return end
  63. log.info("agpsZkw.upd_xingli lstm=",lstm)
  64. if os.time()-tonumber(lstm) < EPH_UPDATE_INTERVAL then
  65. local body = io.readFile(EPH_DATA_FILE)
  66. if body and #body >0 then
  67. log.info("agpsZkw.upd_xingli length=",#body)
  68. sEphData = body
  69. gps.open(gps.TIMER,{tag="lib.agpsZkw.lua.eph",val=10,cb=writeEphEnd})
  70. sys.timerStart(writeEph,2000)
  71. else
  72. log.info("agpsZkw.upd_xingli wanto update xingli data")
  73. updateEph()
  74. end
  75. end
  76. end
  77. end
  78. --检查是否需要更新星历
  79. local function checkEph()
  80. local result
  81. if not gps.isFix() then
  82. lastTm = io.readFile(EPH_TIME_FILE)
  83. if not lastTm or lastTm=="" then return true end
  84. log.info("agpsZkw.checkEph",os.time(),tonumber(lastTm)," DELTA=",os.time()-tonumber(lastTm))
  85. result = (os.time()-tonumber(lastTm) >= EPH_UPDATE_INTERVAL)
  86. end
  87. if not result then runTimer() end
  88. return result
  89. end
  90. local function setFastFix(lng,lat,tm)
  91. gps.setFastFix(lat,lng,tm)
  92. if checkEph() then updateEph() end
  93. end
  94. local getloc = 0
  95. local lbsLocRequesting
  96. --获取到基站对应的经纬度,写到GPS芯片中
  97. local function getLocCb(result,lat,lng,addr,time)
  98. log.info("agpsZkw.getLocCb",result,lat,lng,time and time:len() or 0)
  99. lbsLocRequesting = false
  100. if result==0 then
  101. lastLbsLng,lastLbsLat = lng,lat
  102. if not gps.isFix() then
  103. local tm = {year=0,month=0,day=0,hour=0,min=0,sec=0}
  104. if time:len()==6 then
  105. tm = {year=time:byte(1)+2000,month=time:byte(2),day=time:byte(3),hour=time:byte(4),min=time:byte(5),sec=time:byte(6)}
  106. misc.setClock(tm)
  107. tm = common.timeZoneConvert(tm.year,tm.month,tm.day,tm.hour,tm.min,tm.sec,8,0)
  108. end
  109. gps.open(gps.TIMERORSUC,{tag="lib.agpsZkw.lua.fastFix",val=4})
  110. sys.timerStart(gps.setFastFix,2000,lng,lat,tm)
  111. getloc = 1
  112. end
  113. end
  114. if result~=0 or gps.isFix() then
  115. if checkEph() then updateEph() end
  116. end
  117. end
  118. --是否获取到基站对应的经纬度
  119. function isgetloc()
  120. return getloc
  121. end
  122. local function ipReady()
  123. if gps.isFix() then
  124. runTimer()
  125. else
  126. if not lbsLocRequesting then
  127. lbsLocRequesting = true
  128. lbsLoc.request(getLocCb,nil,30000,"0","bs.openluat.com","12412",true)
  129. end
  130. log.info("agpsZkw.ipready to updateEph")
  131. if checkEph() then
  132. updateEph()
  133. else
  134. sys.timerStart(upd_xingli,3000)
  135. end
  136. end
  137. end
  138. local function gpsState(evt,para)
  139. log.info("agpsZkw.GPS_STATE",evt,para)
  140. if evt=="LOCATION_SUCCESS" or (evt=="CLOSE" and para==true) then
  141. runTimer()
  142. elseif evt=="OPEN" then
  143. local lng,lat = gps.getLastLocation()
  144. if lng=="" or lat=="" then
  145. lng,lat = lastLbsLng,lastLbsLat
  146. end
  147. if lng~="" and lat~="" then
  148. gps.open(gps.TIMERORSUC,{tag="lib.agpsZkw.lua.fastFix",val=4})
  149. local tm = os.date("*t")
  150. sys.timerStart(gps.setFastFix,2000,lat,lng,common.timeZoneConvert(tm.year,tm.month,tm.day,tm.hour,tm.min,tm.sec,8,0))
  151. end
  152. end
  153. end
  154. function init()
  155. sys.subscribe("GPS_STATE",gpsState)
  156. sys.subscribe("IP_READY_IND",ipReady)
  157. log.info("agpsZkw.unInit")
  158. end
  159. function unInit()
  160. sys.unsubscribe("GPS_STATE",gpsState)
  161. sys.unsubscribe("IP_READY_IND",ipReady)
  162. log.info("agpsZkw.unInit")
  163. end
  164. init()