deviceMgr.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package tcp
  2. import (
  3. "encoding/hex"
  4. "errors"
  5. "fmt"
  6. "go.uber.org/zap"
  7. "gorm.io/gorm"
  8. "net"
  9. Dev "server/dao/devices"
  10. deviceDao "server/dao/devices"
  11. promodel "server/model/common/devices"
  12. "server/protocol"
  13. "server/utils/logger"
  14. "strings"
  15. "time"
  16. )
  17. var (
  18. Devices = make(map[string]*Device) // 存储连接的全局 map
  19. )
  20. type Device struct {
  21. Info deviceDao.Screens
  22. Conn net.Conn
  23. LastTime time.Time
  24. }
  25. // 实例所有设备
  26. func InitDevices() {
  27. // 将数据库中的设备全部离线
  28. devs, _ := deviceDao.QueryAllScreens()
  29. for _, screen := range devs {
  30. if screen.Status != 0 {
  31. screen.Status = 0
  32. screen.LastOfflineTime = time.Now()
  33. }
  34. Devices[screen.Sn] = &Device{Info: screen}
  35. }
  36. }
  37. func (s *Device) Start(conn net.Conn) {
  38. s.Conn = conn
  39. go s.Process()
  40. }
  41. func (s *Device) Process() {
  42. // 函数执行完之后关闭连接
  43. defer s.Conn.Close()
  44. for {
  45. buf := make([]byte, 256)
  46. // 将tcp连接读取到的数据读取到byte数组中, 返回读取到的byte的数目
  47. n, err := s.Conn.Read(buf)
  48. if err != nil {
  49. // 从客户端读取数据的过程中发生错误 这里如果没读到可以视为设备离线了
  50. logger.Logger.Errorf("read from client failed [离线了], err:%v", err)
  51. break
  52. }
  53. data := hex.EncodeToString(buf[:n])
  54. if !strings.Contains(strings.ToLower(data), "fe5c4b89") {
  55. continue
  56. }
  57. switch data[16:18] {
  58. case "61":
  59. // fe5c4b89 2a000000 62 00000000 17000000 31 23 32303233(年) 3035(月) 3135(日) 3031(星期) 3038(时) 3334(分) 3135(秒) 23 303630(心跳包时间) 23 ffff
  60. buffer := protocol.AuthDataPack{}.AuthLogin()
  61. // 通过sn 查设备是否存在 不存在return 存在就保存con 和 info
  62. screens, err := deviceDao.QueryScreenBySn(data[34:50])
  63. if errors.Is(err, gorm.ErrRecordNotFound) {
  64. logger.Logger.Errorf("Process[case '61'] SN not found \n")
  65. break
  66. }
  67. s.Info = screens
  68. Devices[s.Info.Sn] = s
  69. s.Conn.Write(buffer.Bytes())
  70. logger.Logger.Debugf("设备 [%v] 登录", s.Info.ScreensName)
  71. case "91":
  72. dev := Devices[data[34:50]]
  73. if dev.Info.Status == 0 {
  74. state := 1
  75. //上线 则修改数据库上线时间
  76. err := Dev.UpdateScreensStatusAndOnline(dev.Info.ScreensCode, state)
  77. if err != nil {
  78. logger.Logger.Error("Process[case '91'] UpdateScreensStatusAndOnline err", zap.Error(err))
  79. continue
  80. }
  81. dev.Info.Status = 1
  82. dev.Info.LastOnlineTime = time.Now()
  83. logger.Logger.Debugf("设备 [%v] 上线", dev.Info.ScreensName)
  84. }
  85. dev.Conn = s.Conn
  86. dev.LastTime = time.Now()
  87. logger.Logger.Debugf("设备 [%v] 心跳", dev.Info.ScreensName)
  88. default:
  89. fmt.Println("读取:", data)
  90. }
  91. }
  92. }
  93. func IsOnline() {
  94. t := time.NewTicker(1 * time.Minute) //每分钟
  95. for {
  96. select {
  97. case <-t.C:
  98. for _, device := range Devices {
  99. //符合条件
  100. if (time.Now().Add(-5*time.Minute).After(device.LastTime) || device.LastTime.IsZero()) && device.Info.Status != 0 {
  101. //修改数据库和内存
  102. //离线
  103. state := 0
  104. err := Dev.UpdateScreensStatusAndOffline(device.Info.ScreensCode, state)
  105. if err != nil {
  106. logger.Logger.Error("[Handle] UpdateScreensStatus err", zap.Error(err))
  107. continue
  108. }
  109. device.Info.Status = 0
  110. device.Info.LastOfflineTime = time.Now()
  111. logger.Logger.Debugf("设备 [%v] 离线了...", device.Info.ScreensName)
  112. }
  113. }
  114. }
  115. }
  116. }
  117. func (s *Device) SwitchScreen(onOff int) error {
  118. if s.Conn == nil {
  119. return errors.New("connection is nil")
  120. }
  121. pack := protocol.SwitchDataPack{Type: 0x52} //熄屏
  122. if onOff == 1 {
  123. pack = protocol.SwitchDataPack{Type: 0x51} //亮屏
  124. }
  125. buf := pack.SwitchScreens() //获取开关屏指令
  126. _, err := s.Conn.Write(buf.Bytes())
  127. if err != nil {
  128. logger.Logger.Errorf("SwitchScreen write failed, err:%v", err)
  129. return err
  130. }
  131. return nil
  132. }
  133. func (s *Device) SendInternalCode(content []promodel.InternalCodeContent) error {
  134. if s.Conn == nil {
  135. return errors.New("connection is nil")
  136. }
  137. pack := protocol.InternalCodeDataPack{}
  138. //获取要写入连接的字节数组
  139. buf := pack.SendInternalCode(content)
  140. _, err := s.Conn.Write(buf.Bytes())
  141. if err != nil {
  142. logger.Logger.Errorf("SendInternalCode write failed, err:%v", err)
  143. return err
  144. }
  145. return nil
  146. }
  147. func (s *Device) VoiceBroad(broad string) error {
  148. if s.Conn == nil {
  149. return errors.New("connection is nil")
  150. }
  151. pack := protocol.VoiceBroadDataPack{}
  152. buf := pack.VoiceBroad(broad)
  153. _, err := s.Conn.Write(buf.Bytes())
  154. if err != nil {
  155. logger.Logger.Errorf("VoiceBroad write failed, err:%v", err)
  156. return err
  157. }
  158. return nil
  159. }
  160. func (s *Device) SetBrightness(bright byte) error {
  161. if s.Conn == nil {
  162. return errors.New("connection is nil")
  163. }
  164. pack := protocol.SetBrightnessDataPack{}
  165. buf := pack.SetBrightness(bright)
  166. _, err := s.Conn.Write(buf.Bytes())
  167. if err != nil {
  168. logger.Logger.Errorf("SetBrightness write failed, err:%v", err)
  169. return err
  170. }
  171. return nil
  172. }
  173. func SwitchScreen(sn string, onOff int) error {
  174. device := Devices[sn]
  175. err := device.SwitchScreen(onOff)
  176. if err != nil {
  177. return err
  178. }
  179. return nil
  180. }
  181. func SendInternalCode(sn string, content []promodel.InternalCodeContent) error {
  182. device := Devices[sn]
  183. err := device.SendInternalCode(content)
  184. if err != nil {
  185. return err
  186. }
  187. return nil
  188. }
  189. func VoiceBroad(sn string, broad string) error {
  190. device := Devices[sn]
  191. err := device.VoiceBroad(broad)
  192. if err != nil {
  193. return err
  194. }
  195. return nil
  196. }
  197. func SetBrightness(sn string, bright int) error {
  198. device := Devices[sn]
  199. err := device.SetBrightness(brightnessMap[bright])
  200. if err != nil {
  201. return err
  202. }
  203. return nil
  204. }
  205. var brightnessMap = map[int]byte{
  206. 0: 0x19,
  207. 10: 0x18,
  208. 20: 0x16,
  209. 30: 0x14,
  210. 40: 0x12,
  211. 50: 0x10,
  212. 60: 0x08,
  213. 70: 0x06,
  214. 80: 0x04,
  215. 90: 0x02,
  216. 100: 0x00,
  217. }