eventServer.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package eventServer
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. "github.com/sirupsen/logrus"
  6. mail "github.com/xhit/go-simple-mail/v2"
  7. "io"
  8. "io/ioutil"
  9. "lc-fangdaosha/global"
  10. "lc-fangdaosha/model/app"
  11. "lc-fangdaosha/service"
  12. "log"
  13. "math"
  14. "mime/multipart"
  15. "net/http"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. // MQDEvent (MQTT Data Event) 用于mqtt传输事件
  21. type MQDEvent struct {
  22. EventCode string `json:"eventCode"`
  23. EId int `json:"eId"`
  24. Ip string `json:"ip"`
  25. Type string `json:"type"`
  26. StartTime string `json:"startTime"`
  27. Name string `json:"name"`
  28. Data []byte `json:"data"`
  29. }
  30. func StartEventServer() {
  31. //记录长宽高
  32. go func() {
  33. for {
  34. l, w, h := CalcCap()
  35. time.Sleep(500 * time.Millisecond)
  36. //todo 根据长宽高估计车厢体积
  37. fmt.Println("长", l, "宽", w, "高", h)
  38. }
  39. }()
  40. http.HandleFunc("/event", handler)
  41. logrus.Fatal("事件监听服务启动失败", http.ListenAndServe(":8850", nil))
  42. }
  43. func handler(w http.ResponseWriter, r *http.Request) {
  44. go func() {
  45. //监听主机应答固定,直接先应答
  46. w.WriteHeader(200)
  47. w.Header().Add("Date", time.Now().String())
  48. w.Header().Add("Connection", "close")
  49. }()
  50. logRequest(r)
  51. contentType := r.Header.Get("Content-Type")
  52. if strings.Contains(contentType, "application/xml") {
  53. bytes, err := ioutil.ReadAll(r.Body)
  54. if err != nil {
  55. logrus.Error("事件处理-读取错误:", err)
  56. return
  57. }
  58. var event EventNotificationAlert
  59. err = xml.Unmarshal(bytes, &event)
  60. if err != nil {
  61. logrus.Error("事件处理-解析错误:", err)
  62. return
  63. }
  64. //处理事件 todo 邮箱
  65. handleEvent_(event)
  66. } else if strings.Contains(contentType, "multipart/form-data") {
  67. handleMultipart(r)
  68. } else {
  69. logrus.WithField("Content-Type", contentType).Error("该Content-Type没有写处理逻辑")
  70. return
  71. }
  72. }
  73. //TODO 限制事件重复触发,一段时间内不重复发送邮件,但保持报警状态
  74. var eventService = service.ServiceGroupApp.AppServiceGroup.EventService
  75. var carInfoService = service.ServiceGroupApp.AppServiceGroup.CarInfoService
  76. // 保留小数
  77. func round(num float64, places int) float64 {
  78. shift := math.Pow(10, float64(places))
  79. return math.Round(num*shift) / shift
  80. }
  81. // 保存摄像机获取到的长度,高度,宽度以及时间
  82. var bulk = make(map[string][]float64)
  83. // 处理多文件事件
  84. func handleMultipart(r *http.Request) {
  85. // todo 远程联动
  86. multipartReader := multipart.NewReader(r.Body, "boundary")
  87. var msg string //邮件消息
  88. // 循环读取每个 part
  89. var eventAlert EventNotificationAlert
  90. for {
  91. part, err := multipartReader.NextPart()
  92. if err == io.EOF {
  93. break
  94. }
  95. if err != nil {
  96. log.Println("Failed to read part:", err)
  97. continue
  98. }
  99. // 检查 part 的 Content-Disposition
  100. formName := part.FormName()
  101. //if formName != "intrusionImage" {
  102. if !strings.Contains(formName, "Image") {
  103. //不含图片的xml部分数据
  104. xmlData, err := ioutil.ReadAll(part)
  105. if err != nil {
  106. return
  107. }
  108. xml.Unmarshal(xmlData, &eventAlert)
  109. msg = handleEvent_(eventAlert)
  110. continue
  111. }
  112. //处理图片部分数据
  113. contentType := part.Header.Get("Content-Type")
  114. eventCode := part.Header.Get("Content-ID")
  115. picName := timeFmt(eventAlert.DateTime) + ".jpeg"
  116. data, _ := ioutil.ReadAll(part)
  117. if strings.Contains(eventAlert.ChannelName, "plateNumber") {
  118. // 识别车牌,记录次数
  119. number, err := CallLicensePlateRecognitionAPI(data)
  120. if err != nil {
  121. fmt.Println("车牌识别失败:", err)
  122. //time.Sleep(1000)
  123. }
  124. //todo 处理车牌号
  125. carInfoService.ProcessPlateNumber(number)
  126. return
  127. }
  128. if strings.Contains(eventAlert.ChannelName, "metering1") {
  129. //测量车的长度和高度
  130. targetRect := eventAlert.DetectionRegionList.DetectionRegionEntry[0].TargetRect
  131. //x, _ := strconv.ParseFloat(targetRect.X, 64)
  132. y, _ := strconv.ParseFloat(targetRect.Y, 64)
  133. h, _ := strconv.ParseFloat(targetRect.Height, 64)
  134. w, _ := strconv.ParseFloat(targetRect.Width, 64)
  135. n := int(round(y+h, 1) * 10)
  136. b := float64(global.Config.Metering.Camera1.B[n])
  137. a := float64(global.Config.Metering.Camera1.A[n])
  138. rh := h / (y + h) * b
  139. rl := w * a
  140. //dateTime := eventAlert.DateTime
  141. //bulk[dateTime] = append(bulk[dateTime], rh, rl)
  142. LhChan <- [2]float64{rl, rh}
  143. return
  144. }
  145. if strings.Contains(eventAlert.ChannelName, "metering2") {
  146. //todo 测量车的宽度
  147. targetRect := eventAlert.DetectionRegionList.DetectionRegionEntry[0].TargetRect
  148. //x, _ := strconv.ParseFloat(targetRect.X, 64)
  149. y, _ := strconv.ParseFloat(targetRect.Y, 64)
  150. h, _ := strconv.ParseFloat(targetRect.Height, 64)
  151. w, _ := strconv.ParseFloat(targetRect.Width, 64)
  152. n := int(round(y+h, 1) * 10)
  153. a := float64(global.Config.Metering.Camera2.A[n])
  154. rw := w * a
  155. WChan <- rw
  156. //dateTime := eventAlert.DateTime
  157. //bulk[dateTime] = append(bulk[dateTime], rw)
  158. //// 识别车牌,记录次数
  159. //number, err := CallLicensePlateRecognitionAPI(data)
  160. //if err != nil {
  161. // fmt.Println("车牌识别失败:", err)
  162. // //time.Sleep(1000)
  163. //}
  164. //// 处理车牌号
  165. //carInfoService.ProcessPlateNumber(number)
  166. return
  167. }
  168. f := &mail.File{
  169. Name: picName,
  170. MimeType: contentType,
  171. Data: data,
  172. Inline: true,
  173. }
  174. picture := &app.Picture{
  175. Name: picName,
  176. Time: time.Now(),
  177. Mime: contentType,
  178. Size: len(data),
  179. }
  180. pictureData := &app.PictureData{
  181. Data: data,
  182. }
  183. event := &app.Event{
  184. EventCode: eventCode,
  185. MacAddress: eventAlert.MacAddress,
  186. EventType: eventAlert.EventType,
  187. }
  188. //保存图片
  189. go eventService.Save(event, picture, pictureData)
  190. //邮件通知
  191. SendAlarmEmail(eventAlert.MacAddress, msg, f)
  192. }
  193. }
  194. func handleEvent_(event EventNotificationAlert) string {
  195. var eType string
  196. if event.EventType == "duration" {
  197. eType = event.DurationList.Duration[0].RelationEvent
  198. } else {
  199. eType = event.EventType
  200. }
  201. return fmt.Sprintf("事件类型:%s,时间:%s", sMap[eType], timeFmt(event.DateTime))
  202. }
  203. func timeFmt(str string) string {
  204. s := strings.Split(str, "T")
  205. t := s[0]
  206. s1 := strings.Split(s[1], ".")
  207. s2 := strings.Split(s1[0], "+")
  208. return t + " " + s2[0]
  209. }
  210. func logRequest(req *http.Request) {
  211. // 打印请求行
  212. fmt.Printf("%s %s %s\n", req.Method, req.URL.Path, req.Proto)
  213. // 打印请求头
  214. for name, headers := range req.Header {
  215. for _, h := range headers {
  216. fmt.Printf("%v: %v\n", name, h)
  217. }
  218. }
  219. // 打印请求体
  220. body, _ := ioutil.ReadAll(req.Body)
  221. fmt.Printf("%s\n", body)
  222. }