| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- package fwh_pro
- import (
- "encoding/json"
- "errors"
- "fmt"
- "fwh-toolbox-server/domain"
- "net/url"
- "strconv"
- "time"
- "go.uber.org/zap"
- )
- type EventAlarmType int
- const (
- Event EventAlarmType = iota // 0
- Alarm // 1
- )
- type EventAlarmListResponse struct {
- Code int `json:"code"`
- Message string `json:"message"`
- Result []domain.EventAlarmItem `json:"result"`
- Success bool `json:"success"`
- Total uint `json:"total"`
- }
- // 查询事件事件日志
- func queryEventAndAlarmLog(sn string, params url.Values) ([]byte, error) {
- token := getLoginToken()
- userId, _ := getUserId(token)
- // 构造 query 参数
- params.Add("userId", strconv.Itoa(userId))
- params.Add("searchName", sn)
- params.Add("timeType", strconv.Itoa(1)) // 0-通讯时间;1-设备时间
- params.Add("pageSize", strconv.FormatUint(REQ_PAGE_SIZE, 10))
- params.Add("pageNum", strconv.Itoa(1))
- params.Add("land", "ZH_CN")
- return FwhHttpGet("https://energy.franklinwh.com/hes-gateway/manage/iotDeviceRunLogs", params)
- }
- // 查询所有事件告警
- // startTime&endTime 格式 YYYY-MM-DD HH:mm:SS
- func queryAllEventAlarm(sn, startTime, endTime string) ([]byte, error) {
- // 构造 query 参数
- params := url.Values{}
- params.Add("startTime", startTime)
- params.Add("endTime", endTime)
- return queryEventAndAlarmLog(sn, params)
- }
- // 查询事件日志
- // startTime&endTime 格式 YYYY-MM-DD HH:mm:SS
- func queryEventLog(sn, startTime, endTime string) ([]byte, error) {
- // 构造 query 参数
- params := url.Values{}
- params.Add("logType", strconv.Itoa(0))
- params.Add("startTime", startTime)
- params.Add("endTime", endTime)
- return queryEventAndAlarmLog(sn, params)
- }
- // 查询告警日志
- // startTime&endTime 格式 YYYY-MM-DD HH:mm:SS
- // alarmCode - 支持多个code,用‘,’隔开,“”代表查询所有
- func queryAlarmLog(sn, startTime, endTime, alarmCode string) ([]byte, error) {
- // 构造 query 参数
- params := url.Values{}
- params.Add("logType", strconv.Itoa(1))
- params.Add("alarmCode", alarmCode)
- params.Add("startTime", startTime)
- params.Add("endTime", endTime)
- return queryEventAndAlarmLog(sn, params)
- }
- // 查询实时告警
- func queryRealtimeAlarm(sn string) ([]byte, error) {
- // 构造 query 参数
- params := url.Values{}
- params.Add("logType", strconv.Itoa(2))
- return queryEventAndAlarmLog(sn, params)
- }
- func queryEventOrAlarmListOnePage(sn string, startTime, endTime time.Time, t EventAlarmType) ([]domain.EventAlarmItem, error) {
- // 三次请求尝试
- for i := 0; i < 3; i++ {
- eventLogRes, err := queryEventOrAlarmListOnePageExec(sn, startTime, endTime, t)
- if err != nil {
- zap.L().Warn("queryEventOrAlarmListOnePageExec failed and retry", zap.String("err", err.Error()))
- continue
- }
- if eventLogRes.Code == 401 {
- // TODO 尝试重新登录
- return nil, errors.New("certification expired")
- }
- if eventLogRes.Code != 200 {
- // return nil, fmt.Errorf("查询失败 code: %d, message: %s", eventLogRes.Code, eventLogRes.Message)
- zap.L().Warn("queryEventOrAlarmListOnePage 查询失败 retry", zap.Int("code", eventLogRes.Code), zap.String("msg", eventLogRes.Message))
- time.Sleep(time.Second * 5)
- continue
- }
- return eventLogRes.Result, nil
- }
- return nil, errors.New("retry failed")
- }
- func queryEventOrAlarmListOnePageExec(sn string, startTime, endTime time.Time, t EventAlarmType) (*EventAlarmListResponse, error) {
- startTimeStr := startTime.Format(time.DateTime)
- endTimeStr := endTime.Format(time.DateTime)
- // TEST
- fmt.Printf("startTime = %s\n", startTimeStr)
- fmt.Printf("endTime = %s\n", endTimeStr)
- var resByte []byte
- var err error
- switch t {
- case Event:
- resByte, err = queryEventLog(sn, startTimeStr, endTimeStr)
- case Alarm:
- resByte, err = queryAlarmLog(sn, startTimeStr, endTimeStr, "")
- }
- if err != nil {
- return nil, err
- }
- var eventLogRes EventAlarmListResponse
- // 反序列化(unmarshal)
- jsonErr := json.Unmarshal(resByte, &eventLogRes)
- if jsonErr != nil {
- return nil, jsonErr
- }
- return &eventLogRes, nil
- }
- // 从FWH获取事件或告警log数据
- func QueryEventOrAlarmListOnTimeRange(sn string, startTime, endTime time.Time, t EventAlarmType) ([]domain.EventAlarmItem, error) {
- // 保证 startTime <= endTime
- if startTime.After(endTime) {
- return nil, errors.New("startTime > endTime")
- }
- // 按天拆分时间段
- var periods []struct{ Start, End time.Time }
- currTime := startTime
- for currTime.Before(endTime) {
- // 当天结束时间
- dayEnd := time.Date(currTime.Year(), currTime.Month(), currTime.Day(), 23, 59, 59, 0, currTime.Location())
- // 如果当天结束大于 endTime,使用 endTime
- if dayEnd.After(endTime) {
- dayEnd = endTime
- }
- periods = append(periods, struct{ Start, End time.Time }{Start: currTime, End: dayEnd})
- // 下一天开始
- currTime = dayEnd.Add(time.Second).Truncate(24 * time.Hour)
- currTime = time.Date(currTime.Year(), currTime.Month(), currTime.Day(), 0, 0, 0, 0, currTime.Location())
- }
- // 按天查询
- var eventLogList []domain.EventAlarmItem
- for _, period := range periods {
- var eventLogRes []domain.EventAlarmItem = nil
- periodEndTime := period.End
- // 检查数据是否超过1000(单次查询上限)
- for {
- var err error
- eventLogRes, err = queryEventOrAlarmListOnePage(sn, period.Start, periodEndTime, t)
- if err != nil {
- return nil, err
- }
- eventLogList = append(eventLogList, eventLogRes...)
- // 判断是否未查完
- if len(eventLogRes) < int(REQ_PAGE_SIZE) {
- // 请求完成,退出
- break
- }
- // 跳转时间段,再次请求
- // 提取最后一条数据的设备时间
- periodEndTime, err = time.Parse(time.DateTime, eventLogRes[len(eventLogRes)-1].LogTime)
- if err != nil {
- return nil, err
- }
- }
- }
- return eventLogList, nil
- }
- // 查询快照信息
- // logTime 格式 YYYY-MM-DD
- func queryAlarmSnapshotInfo(sn, logTime string, page int) ([]byte, error) {
- // 构造 query 参数
- params := url.Values{}
- params.Add("logTime", logTime)
- params.Add("linkId", sn)
- params.Add("pageSize", strconv.FormatUint(REQ_PAGE_SIZE, 10))
- params.Add("pageNum", strconv.Itoa(page))
- params.Add("land", "ZH_CN")
- return FwhHttpGet("https://energy.franklinwh.com/hes-gateway/manage/selectAlarmSnapshotList", params)
- }
- func QueryAlarmSnapshotInfo(sn, logTime string) ([]domain.AlarmSnapshotInfo, error) {
- var page int = 1
- var infoList []domain.AlarmSnapshotInfo
- for {
- // 查询告警快照数据
- resByte, err := queryAlarmSnapshotInfo(sn, logTime, page)
- if err != nil {
- return nil, fmt.Errorf("[QueryAlarmSnapshotInfo] %s", err.Error())
- }
- var alarmSnapshotRes domain.FwhPageResponse[domain.AlarmSnapshotInfo]
- // 反序列化(unmarshal)
- jsonErr := json.Unmarshal(resByte, &alarmSnapshotRes)
- if jsonErr != nil {
- return nil, fmt.Errorf("[QueryAlarmSnapshotInfo] %s", jsonErr)
- }
- if alarmSnapshotRes.Code != 200 {
- return nil, fmt.Errorf("[QueryAlarmSnapshotInfo] 查询失败 code: %d, message: %s", alarmSnapshotRes.Code, alarmSnapshotRes.Message)
- }
- if alarmSnapshotRes.Total > 10000 {
- return nil, fmt.Errorf("[QueryAlarmSnapshotInfo] 数据超过10000条")
- }
- infoList = append(infoList, alarmSnapshotRes.Result...)
- if alarmSnapshotRes.Total <= uint64(page*int(REQ_PAGE_SIZE)) {
- break
- }
- page++
- }
- return infoList, nil
- }
|