devicetimer.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package busmodels
  2. import (
  3. "device-manage/common/log"
  4. model "device-manage/common/mqttcli/flatbuffer/models"
  5. "device-manage/pkg/ws"
  6. tools "device-manage/tools"
  7. "encoding/json"
  8. "fmt"
  9. "time"
  10. "github.com/muesli/cache2go"
  11. )
  12. /*
  13. DeviceSn 设备序列号
  14. TimerFinishType 定时结束类型
  15. */
  16. const (
  17. cacheName = "devicetimer"
  18. )
  19. type DeviceTimer struct {
  20. DeviceSn string `json:"deviceSn" gorm:"size:128;"`
  21. }
  22. func DeviceTimerSetup() {
  23. cache := cache2go.Cache(cacheName)
  24. // cache2go supports a few handy callbacks and loading mechanisms.
  25. cache.SetAboutToDeleteItemCallback(func(e *cache2go.CacheItem) {
  26. fmt.Println("Deleting:", e.Key(), e.Data().(*DeviceTimer).DeviceSn, e.CreatedOn())
  27. //todo delete media source
  28. fmt.Println(e.LifeSpan().Seconds())
  29. fmt.Println(e.CreatedOn().Unix())
  30. fmt.Println(time.Now().Unix())
  31. //要区分手动删除设备和超时删除设备. 超时删除要更新数据库,
  32. if time.Now().Unix()-e.CreatedOn().Unix() >= int64(e.LifeSpan().Seconds()) {
  33. fmt.Println("heartbeat timeout device offline:", e.Data().(*DeviceTimer).DeviceSn)
  34. var dev BusDevice
  35. dev.DeviceSn = e.Data().(*DeviceTimer).DeviceSn
  36. dev, _ = dev.GetDeviceByDeviceSn()
  37. devId := dev.DeviceId
  38. dev.DeviceId = 0
  39. dev.Status = DeviceStatusOffline
  40. dev.OnlineTime = DeviceInitTime
  41. if _, err := dev.UpdateByMap(devId); err != nil {
  42. log.Info(err)
  43. }
  44. devArry, _ := json.Marshal(dev)
  45. ws.WebsocketManager.SendAll(devArry)
  46. } else {
  47. fmt.Println("手动删除缓存.")
  48. }
  49. })
  50. initDevices()
  51. }
  52. //启动时, 初始化检查当前设备状态,如果历史上设备在线,给设备重新添加超时,检测设备是否离线.
  53. func initDevices() {
  54. var dev BusDevice
  55. var devtimer DeviceTimer
  56. devs, err := dev.GetOnlineDevices()
  57. if err != nil {
  58. return
  59. }
  60. for _, devInfo := range devs {
  61. devtimer.DeviceSn = devInfo.DeviceSn
  62. devtimer.AddDevice()
  63. fmt.Println("init device:", devInfo.DeviceSn)
  64. }
  65. }
  66. //查询缓存是否存在.
  67. func (e *DeviceTimer) GetDevice() error {
  68. //添加数据
  69. cache := cache2go.Cache(cacheName)
  70. res, err := cache.Value(e.DeviceSn)
  71. if err == nil {
  72. fmt.Println("Found Device in cache:", res.Data().(*DeviceTimer).DeviceSn)
  73. } else {
  74. fmt.Println("Error retrieving value from cache:", err)
  75. return err
  76. }
  77. return nil
  78. }
  79. func (e *DeviceTimer) AddDevice() (err error) {
  80. //添加数据
  81. cache := cache2go.Cache(cacheName)
  82. //如果有先清除历史
  83. if cache.Exists(e.DeviceSn) {
  84. cache.Delete(e.DeviceSn)
  85. }
  86. //添加 超时时间
  87. cache.Add(e.DeviceSn, 3*time.Minute, e)
  88. return nil
  89. }
  90. //delete device
  91. func (e *DeviceTimer) DeleteDevice() (err error) {
  92. cache := cache2go.Cache(cacheName)
  93. if _, err := cache.Delete(e.DeviceSn); err != nil {
  94. return err
  95. }
  96. fmt.Println("delete device:", e.DeviceSn)
  97. return nil
  98. }
  99. //设备在线心跳,更新设备信息
  100. func DevicesHeartBeat(devInfo *model.Heartbeat) {
  101. var err error
  102. var dev BusDevice
  103. var devtimer DeviceTimer
  104. dev.DeviceSn = devInfo.Serial
  105. //设备不存在, 设备上线也直接抛弃数据,不能接入系统.
  106. if !dev.IsExist() {
  107. return
  108. }
  109. //history db data
  110. dbDevice, _ := dev.Get()
  111. dev.DeviceIp = devInfo.DeviceIp
  112. dev.ServerIp = devInfo.ServerIp
  113. dev.Status = devInfo.Status
  114. dev.Gps = devInfo.Gps
  115. dev.Nettype = devInfo.Nettype
  116. dev.DeviceType = devInfo.Devtype
  117. //设备存在,有两种状态, a. 已经注册状态 b. 未注册状态
  118. //先判断当前设备是否已经完成注册
  119. //a. 设备未注册, 先进行设备注册,在更新设备状态信息
  120. time := time.Now()
  121. if !dev.IsRegist() {
  122. dev.DeviceName = devInfo.Serial
  123. dev.Status = DeviceStatusOnline
  124. dev.IsRegister = 1
  125. dev.RegisterTime = time
  126. dev.OnlineTime = DeviceInitTime
  127. dev.TotallTime = DeviceInitTime
  128. dev.LastTime = time
  129. if _, err = dev.Update(dbDevice.DeviceId); err != nil {
  130. log.Info(dev.DeviceSn + " error")
  131. return
  132. }
  133. fmt.Println("device register.")
  134. } else {
  135. //deviceInfo.TotallTime
  136. //b. 设备已注册, 更新设备状态信息
  137. //设备状态又分为 status:1 在线 status:0 离线.
  138. //1. 设备在线信息上报.
  139. if dev.Status == DeviceStatusOnline {
  140. devtimer.DeviceSn = dbDevice.DeviceSn
  141. devtimer.AddDevice()
  142. dev.LastTime = time
  143. //设备在线又分为设备启动首次上线(history last status:0)和正常在线(history last status:1).
  144. //设备上一次在线
  145. if dbDevice.Status == DeviceStatusOnline {
  146. updateTime := dev.LastTime.Unix() - dbDevice.LastTime.Unix()
  147. //当前在线时间加上最近一次更新的时间长度(当前LastTime减去历史LastTime的时间差)
  148. dev.OnlineTime = tools.TimeStamp2Time(tools.Time2TimeStamp(dbDevice.OnlineTime) + int(updateTime))
  149. //历史在线总时间加上最近一次更新时间长度(当前LastTime减去历史LastTime的时间差)
  150. dev.TotallTime = tools.TimeStamp2Time(tools.Time2TimeStamp(dbDevice.TotallTime) + int(updateTime))
  151. } else {
  152. //设备上一次离线
  153. dev.OnlineTime = DeviceInitTime
  154. }
  155. if _, err = dev.Update(dbDevice.DeviceId); err != nil {
  156. log.Info(dev.DeviceSn + " error")
  157. return
  158. }
  159. dev, _ := json.Marshal(dev)
  160. ws.WebsocketManager.SendAll(dev)
  161. }
  162. //使用cache2go, 设备主动报离线暂时处理不了, 先只做超时离线.
  163. /* else {
  164. //设备主动上报离线.
  165. dev.Status = 0
  166. dev.OnlineTime = "00:00:00"
  167. if _, err = dev.Update(dbDevice.DeviceId); err != nil {
  168. log.Info(dev.DeviceSn + " error")
  169. return
  170. }
  171. } */
  172. }
  173. //1. 设备存在,设备上线完成注册
  174. /* //todo get device log
  175. for _, devid := range IDS {
  176. fmt.Println(devid)
  177. dev.DeviceId = devid
  178. if devInfo, err = dev.Get(); err != nil {
  179. continue
  180. }
  181. if devInfo.Status > 0 {
  182. if _, ok := mqtthandler.MqttClientList[devInfo.ServerIp]; ok {
  183. mqtthandler.MqttClientList[devInfo.ServerIp].Reboot(devInfo.DeviceSn, "")
  184. }
  185. } else {
  186. log.Info("cmd reboot offline [%s]", devInfo.DeviceSn)
  187. }
  188. } */
  189. //app.OK(c, "", "重启成功.")
  190. }