serialmgr.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package service
  2. import (
  3. "encoding/hex"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "github.com/tarm/serial"
  8. "log"
  9. "smart_tunnel_edge/util/config"
  10. "smart_tunnel_edge/util/logger"
  11. "strconv"
  12. "time"
  13. )
  14. var (
  15. parity = map[string]serial.Parity{
  16. "N": serial.ParityNone, // 无校验
  17. "E": serial.ParityEven, // 偶校验
  18. "O": serial.ParityOdd, // 奇校验
  19. "M": serial.ParityMark, // 标记校验
  20. "S": serial.ParitySpace, // 空格校验
  21. }
  22. serialPort = make(map[int8]*serial.Port)
  23. env = make(map[string]int64) //存储环境传感器光照的切片
  24. opt = make(map[string]int64) //存储光照传感器光照的切片
  25. )
  26. var (
  27. isLightOperate bool // 标记是否进行开灯或调节亮度操作
  28. timer *time.Timer // 用于延时关闭灯的计时器
  29. lastCarTime time.Time // 记录上次来车的时间
  30. lightDuration = 2 * time.Minute // 灯亮的持续时间(2分钟)
  31. )
  32. func GetSerialPort(serialID int8) (*serial.Port, error) {
  33. port, exists := serialPort[serialID]
  34. if !exists {
  35. return nil, errors.New("serial port not found")
  36. }
  37. return port, nil
  38. }
  39. func OpenSerialPort(portMap map[int8]*config.SerialPort) error {
  40. fmt.Println("打开串口...")
  41. var lastError error
  42. // 遍历串口配置
  43. for _, port := range portMap {
  44. // 串口配置
  45. c := &serial.Config{
  46. Name: port.Address,
  47. Baud: port.BaudRate,
  48. Size: port.DataBits,
  49. StopBits: serial.StopBits(port.StopBits),
  50. Parity: parity[port.Parity],
  51. ReadTimeout: time.Duration(port.Timeout),
  52. }
  53. // 打开串口
  54. pt, err := serial.OpenPort(c)
  55. serialPort[port.Code] = pt
  56. if err != nil {
  57. logger.Logger.Errorf("无法打开串口 %s: %v", port.Address, err)
  58. if lastError == nil {
  59. lastError = err
  60. }
  61. continue
  62. }
  63. go listenPort(port.Code, pt) //开启线程监听串口
  64. }
  65. return lastError
  66. }
  67. func listenPort(portCode int8, port *serial.Port) {
  68. fmt.Println("监听串口...")
  69. buf := make([]byte, 128)
  70. for {
  71. // 读取数据
  72. n, err := port.Read(buf)
  73. if err != nil {
  74. log.Printf("读取串口数据失败: %v", err)
  75. return
  76. }
  77. if n > 0 {
  78. dataString := hex.EncodeToString(buf[:n])
  79. //fmt.Println("数据:", dataString)
  80. switch {
  81. case len(dataString) == 42 && dataString[2:6] == "0310": //环境传感器数据
  82. //fmt.Print("环境传感:")
  83. shiDu, _ := strconv.ParseInt(dataString[6:10], 16, 0)
  84. wenDu, _ := strconv.ParseInt(dataString[10:14], 16, 0)
  85. gz, _ := strconv.ParseInt(dataString[30:38], 16, 0)
  86. if _, exists := env[dataString[0:2]]; !exists {
  87. env[dataString[0:2]] = gz
  88. }
  89. data := EnvData{Temperature: float64(wenDu) / 10.0, Humidity: float64(shiDu) / 10.0, Illuminance: gz}
  90. for _, dev := range config.DevConfig.EnvDevs {
  91. if dev.Address == dataString[0:2] {
  92. data.Sn = dev.Sn
  93. break
  94. }
  95. }
  96. jsonData, _ := json.Marshal(data)
  97. topic := MqttService.GetTopic(TopicGatherDataEnv)
  98. err := MqttService.Publish(topic, jsonData)
  99. if err != nil {
  100. logger.Logger.Errorf("MQTT Publish err = %s", err.Error())
  101. continue
  102. }
  103. case len(dataString) == 14 && dataString[2:6] == "0302": //光照传感器数据
  104. //fmt.Printf("光传感:")
  105. gz, _ := strconv.ParseInt(dataString[6:10], 16, 0)
  106. if _, exists := env[dataString[0:2]]; !exists {
  107. opt[dataString[0:2]] = gz
  108. }
  109. data := OpticalData{Illuminance: gz}
  110. for _, dev := range config.DevConfig.EnvDevs {
  111. if dev.Address == dataString[0:2] {
  112. data.Sn = dev.Sn
  113. break
  114. }
  115. }
  116. jsonData, _ := json.Marshal(data)
  117. topic := MqttService.GetTopic(TopicGatherDataOpt)
  118. err := MqttService.Publish(topic, jsonData)
  119. if err != nil {
  120. logger.Logger.Errorf("MQTT Publish err = %s", err.Error())
  121. continue
  122. }
  123. case len(dataString) == 16 && dataString[0:2] == "78" && dataString[8:16] == "40790d0a": //雷达数据
  124. dataBytes, _ := hex.DecodeString(dataString)
  125. speed, _ := strconv.Atoi(string(dataBytes)[1:4])
  126. // 配置实例
  127. policy := config.Instance().Policy
  128. if speed > 5 && policy.Id == 2 { // 速度大于5且策略为根据来车调光(2代表根据来车改变光照)
  129. now := time.Now() // 记录来车时间
  130. // 如果已经操作过灯
  131. if isLightOperate {
  132. // 如果在两分钟内再来车,延长计时
  133. if now.Sub(lastCarTime) <= lightDuration {
  134. timer.Reset(lightDuration)
  135. }
  136. } else {
  137. OperationLampSwitchJudge(portCode, HighLightLevel, 2, 1) //brightness代表亮度,way代表开关继电器回路数,turnOf代表开还是关,1代表开,0代表关
  138. isLightOperate = true
  139. timer = time.AfterFunc(lightDuration, func() {
  140. OperationLampSwitchJudge(portCode, LowLightLevel, 2, 0)
  141. isLightOperate = false
  142. })
  143. }
  144. // 更新最后来车时间
  145. lastCarTime = now
  146. }
  147. continue
  148. //default:
  149. // // 其他情况可以处理默认数据
  150. // fmt.Printf("错误数据: %s \n", dataString)
  151. }
  152. if config.Instance().Policy.Id == 1 && config.Instance().Nums.EnvNum == len(env) && config.Instance().Nums.OptNum == len(opt) {
  153. envAverage := calculateAverage(env)
  154. optAverage := calculateAverage(opt)
  155. control := config.Instance().Policy.Control
  156. if envAverage-optAverage >= 20000 { //如果相差20000Lux开两路或者调节亮度为90%
  157. if control == RegulateLight {
  158. go SetLampBright(1, 90)
  159. go SetLampBright(2, 90)
  160. } else if control == RegulateSwitch {
  161. go SetSwitchMultiRelay(1, 1, []int{1, 2, 3}) //int[]{}表达控制的回路
  162. go SetSwitchMultiRelay(2, 1, []int{1, 2, 3})
  163. }
  164. } else if envAverage-optAverage >= 10000 { //如果相差10000Lux开两路或者调节亮度为60%
  165. if control == RegulateLight {
  166. go SetLampBright(1, 60)
  167. go SetLampBright(2, 60)
  168. } else if control == RegulateSwitch {
  169. go SetSwitchRelay(1, 3, 0) //不管如何先将第三路关闭
  170. go SetSwitchRelay(2, 3, 0)
  171. go SetSwitchMultiRelay(1, 1, []int{1, 2})
  172. go SetSwitchMultiRelay(2, 1, []int{1, 2})
  173. }
  174. } else {
  175. if control == RegulateLight {
  176. go SetLampBright(1, 30)
  177. go SetLampBright(2, 30)
  178. } else if control == RegulateSwitch {
  179. go SetSwitchMultiRelay(1, 0, []int{2, 3})
  180. go SetSwitchMultiRelay(2, 0, []int{2, 3})
  181. }
  182. }
  183. env = make(map[string]int64)
  184. opt = make(map[string]int64)
  185. }
  186. }
  187. time.Sleep(100 * time.Millisecond) // 设置延迟,避免CPU占用过高
  188. }
  189. }
  190. func calculateAverage(data map[string]int64) float64 {
  191. var sum int64
  192. for _, value := range data {
  193. sum += value
  194. }
  195. if len(data) == 0 {
  196. return 0 // 防止除以零
  197. }
  198. return float64(sum) / float64(len(data))
  199. }