fwh_eventAlarmLog.go 6.5 KB

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