fwh_eventAlarmLog.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package fwh_pro
  2. import (
  3. "errors"
  4. "fmt"
  5. "fwh-toolbox-server/config"
  6. "fwh-toolbox-server/domain"
  7. "net/url"
  8. "strconv"
  9. "time"
  10. "go.uber.org/zap"
  11. )
  12. type EventAlarmType int
  13. const (
  14. All EventAlarmType = iota // 0
  15. Event // 1
  16. Alarm // 2
  17. )
  18. // 查询事件事件日志
  19. func queryEventAndAlarmLog(sn string, params url.Values) (*domain.FwhResponse[[]domain.EventAlarmItem], error) {
  20. userId := getUserId()
  21. // 构造 query 参数
  22. params.Add("userId", strconv.FormatUint(uint64(userId), 10))
  23. params.Add("searchName", sn)
  24. params.Add("timeType", strconv.Itoa(1)) // 0-通讯时间;1-设备时间
  25. params.Add("pageSize", strconv.FormatUint(REQ_PAGE_SIZE, 10))
  26. params.Add("pageNum", strconv.Itoa(1))
  27. params.Add("land", "ZH_CN")
  28. reqUrl := fmt.Sprintf("https://%s/hes-gateway/manage/iotDeviceRunLogs", config.FWH_ENERGY)
  29. response, err := FwhHttpGetUnmarshal[[]domain.EventAlarmItem](reqUrl, params)
  30. if err != nil {
  31. return nil, err
  32. }
  33. return response, nil
  34. }
  35. // 查询所有事件告警
  36. // startTime&endTime 格式 YYYY-MM-DD HH:mm:SS
  37. func queryAllEventAlarm(sn, startTime, endTime string) (*domain.FwhResponse[[]domain.EventAlarmItem], error) {
  38. // 构造 query 参数
  39. params := url.Values{}
  40. params.Add("startTime", startTime)
  41. params.Add("endTime", endTime)
  42. return queryEventAndAlarmLog(sn, params)
  43. }
  44. // 查询事件日志
  45. // startTime&endTime 格式 YYYY-MM-DD HH:mm:SS
  46. func queryEventLog(sn, startTime, endTime string) (*domain.FwhResponse[[]domain.EventAlarmItem], error) {
  47. // 构造 query 参数
  48. params := url.Values{}
  49. params.Add("logType", strconv.Itoa(0))
  50. params.Add("startTime", startTime)
  51. params.Add("endTime", endTime)
  52. return queryEventAndAlarmLog(sn, params)
  53. }
  54. // 查询告警日志
  55. // startTime&endTime 格式 YYYY-MM-DD HH:mm:SS
  56. // alarmCode - 支持多个code,用‘,’隔开,“”代表查询所有
  57. func queryAlarmLog(sn, startTime, endTime, alarmCode string) (*domain.FwhResponse[[]domain.EventAlarmItem], error) {
  58. // 构造 query 参数
  59. params := url.Values{}
  60. params.Add("logType", strconv.Itoa(1))
  61. params.Add("alarmCode", alarmCode)
  62. params.Add("startTime", startTime)
  63. params.Add("endTime", endTime)
  64. return queryEventAndAlarmLog(sn, params)
  65. }
  66. // 查询实时告警
  67. func queryRealtimeAlarm(sn string) (*domain.FwhResponse[[]domain.EventAlarmItem], error) {
  68. // 构造 query 参数
  69. params := url.Values{}
  70. params.Add("logType", strconv.Itoa(2))
  71. return queryEventAndAlarmLog(sn, params)
  72. }
  73. func queryEventOrAlarmListOnePage(sn string, startTime, endTime time.Time, t EventAlarmType) ([]domain.EventAlarmItem, error) {
  74. // 三次请求尝试
  75. for i := 0; i < 3; i++ {
  76. eventLogRes, err := queryEventOrAlarmListOnePageExec(sn, startTime, endTime, t)
  77. if err != nil {
  78. zap.L().Warn("queryEventOrAlarmListOnePageExec failed and retry", zap.String("err", err.Error()))
  79. continue
  80. }
  81. if eventLogRes.Code != 200 {
  82. // return nil, fmt.Errorf("查询失败 code: %d, message: %s", eventLogRes.Code, eventLogRes.Message)
  83. zap.L().Warn("queryEventOrAlarmListOnePage 查询失败 retry", zap.Int("code", eventLogRes.Code), zap.String("msg", eventLogRes.Message))
  84. time.Sleep(time.Second * 5)
  85. continue
  86. }
  87. return *eventLogRes.Result, nil
  88. }
  89. return nil, errors.New("retry failed")
  90. }
  91. func queryEventOrAlarmListOnePageExec(sn string, startTime, endTime time.Time, t EventAlarmType) (*domain.FwhResponse[[]domain.EventAlarmItem], error) {
  92. startTimeStr := startTime.Format(time.DateTime)
  93. endTimeStr := endTime.Format(time.DateTime)
  94. // TEST
  95. fmt.Printf("startTime = %s\n", startTimeStr)
  96. fmt.Printf("endTime = %s\n", endTimeStr)
  97. var eventLogRes *domain.FwhResponse[[]domain.EventAlarmItem]
  98. var err error
  99. switch t {
  100. case Event:
  101. eventLogRes, err = queryEventLog(sn, startTimeStr, endTimeStr)
  102. case Alarm:
  103. eventLogRes, err = queryAlarmLog(sn, startTimeStr, endTimeStr, "")
  104. default:
  105. eventLogRes, err = queryAllEventAlarm(sn, startTimeStr, endTimeStr)
  106. }
  107. if err != nil {
  108. return nil, err
  109. }
  110. return eventLogRes, nil
  111. }
  112. // 从FWH获取事件或告警log数据
  113. func QueryEventOrAlarmListOnTimeRange(sn string, startTime, endTime time.Time, t EventAlarmType) ([]domain.EventAlarmItem, error) {
  114. // 保证 startTime <= endTime
  115. if startTime.After(endTime) {
  116. return nil, errors.New("startTime > endTime")
  117. }
  118. // 按天拆分时间段
  119. var periods []struct{ Start, End time.Time }
  120. currTime := startTime
  121. for currTime.Before(endTime) {
  122. // 当天结束时间
  123. dayEnd := time.Date(currTime.Year(), currTime.Month(), currTime.Day(), 23, 59, 59, 0, currTime.Location())
  124. // 如果当天结束大于 endTime,使用 endTime
  125. if dayEnd.After(endTime) {
  126. dayEnd = endTime
  127. }
  128. periods = append(periods, struct{ Start, End time.Time }{Start: currTime, End: dayEnd})
  129. // 下一天开始
  130. currTime = dayEnd.Add(time.Second).Truncate(24 * time.Hour)
  131. currTime = time.Date(currTime.Year(), currTime.Month(), currTime.Day(), 0, 0, 0, 0, currTime.Location())
  132. }
  133. // 按天查询
  134. var eventLogList []domain.EventAlarmItem
  135. for _, period := range periods {
  136. var eventLogRes []domain.EventAlarmItem = nil
  137. periodEndTime := period.End
  138. // 检查数据是否超过1000(单次查询上限)
  139. for {
  140. var err error
  141. eventLogRes, err = queryEventOrAlarmListOnePage(sn, period.Start, periodEndTime, t)
  142. if err != nil {
  143. return nil, err
  144. }
  145. eventLogList = append(eventLogList, eventLogRes...)
  146. // 判断是否未查完
  147. if len(eventLogRes) < int(REQ_PAGE_SIZE) {
  148. // 请求完成,退出
  149. break
  150. }
  151. // 跳转时间段,再次请求
  152. // 提取最后一条数据的设备时间
  153. periodEndTime, err = time.Parse(time.DateTime, eventLogRes[len(eventLogRes)-1].LogTime)
  154. if err != nil {
  155. return nil, err
  156. }
  157. }
  158. }
  159. return eventLogList, nil
  160. }
  161. // 查询快照信息
  162. // logTime 格式 YYYY-MM-DD
  163. func queryAlarmSnapshotInfo(sn, logTime string, page int) (*domain.FwhPageResponse[[]domain.AlarmSnapshotInfo], error) {
  164. // 构造 query 参数
  165. params := url.Values{}
  166. params.Add("logTime", logTime)
  167. params.Add("linkId", sn)
  168. params.Add("pageSize", strconv.FormatUint(REQ_PAGE_SIZE, 10))
  169. params.Add("pageNum", strconv.Itoa(page))
  170. params.Add("land", "ZH_CN")
  171. reqUrl := fmt.Sprintf("https://%s/hes-gateway/manage/selectAlarmSnapshotList", config.FWH_ENERGY)
  172. response, err := FwhHttpGetUnmarshalPage[[]domain.AlarmSnapshotInfo](reqUrl, params)
  173. if err != nil {
  174. return nil, err
  175. }
  176. return response, nil
  177. }
  178. func QueryAlarmSnapshotInfo(sn, logTime string) ([]domain.AlarmSnapshotInfo, error) {
  179. var page int = 1
  180. var infoList []domain.AlarmSnapshotInfo
  181. for {
  182. // 查询告警快照数据
  183. alarmSnapshotRes, err := queryAlarmSnapshotInfo(sn, logTime, page)
  184. if err != nil {
  185. return nil, fmt.Errorf("[QueryAlarmSnapshotInfo] %s", err.Error())
  186. }
  187. if alarmSnapshotRes.Code != 200 {
  188. return nil, fmt.Errorf("[QueryAlarmSnapshotInfo] 查询失败 code: %d, message: %s", alarmSnapshotRes.Code, alarmSnapshotRes.Message)
  189. }
  190. if alarmSnapshotRes.Total > 10000 {
  191. return nil, fmt.Errorf("[QueryAlarmSnapshotInfo] 数据超过10000条")
  192. }
  193. infoList = append(infoList, *alarmSnapshotRes.Result...)
  194. if alarmSnapshotRes.Total <= uint64(page*int(REQ_PAGE_SIZE)) {
  195. break
  196. }
  197. page++
  198. }
  199. return infoList, nil
  200. }