analysisSiteData.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package jobs
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "fwh-toolbox-server/domain"
  6. "fwh-toolbox-server/repositories"
  7. "sort"
  8. "strconv"
  9. "time"
  10. "go.mongodb.org/mongo-driver/bson/primitive"
  11. "go.uber.org/zap"
  12. )
  13. type SiteDataSet struct {
  14. Log_0 []domain.MqttLogItem
  15. Log_101 []domain.MqttLogItem
  16. Log_201 []domain.MqttLogItem
  17. Log_357 []domain.MqttLogItem
  18. EventLog []domain.EventAlarmItem
  19. AlarmLog []domain.EventAlarmItem
  20. }
  21. // 分析站点时间线数据
  22. func AnalysisSiteTimeline(id primitive.ObjectID, data SiteDataSet) error {
  23. var timelineItemList []domain.TimelineItem
  24. // 分析offline
  25. for _, log := range data.Log_0 {
  26. _, err := time.Parse(time.DateTime, log.LogTime)
  27. if err != nil {
  28. zap.L().Error("0日志时间格式错误", zap.String("time", log.LogTime))
  29. return err
  30. }
  31. timelineItem := domain.TimelineItem{
  32. Time: log.LogTime,
  33. Type: domain.TimelineOffline,
  34. }
  35. timelineItemList = append(timelineItemList, timelineItem)
  36. }
  37. // 分析online
  38. for _, log := range data.Log_101 {
  39. _, err := time.Parse(time.DateTime, log.LogTime)
  40. if err != nil {
  41. zap.L().Error("101日志时间格式错误", zap.String("time", log.LogTime))
  42. return err
  43. }
  44. timelineItem := domain.TimelineItem{
  45. Time: log.LogTime,
  46. Type: domain.TimelineOnline,
  47. }
  48. timelineItemList = append(timelineItemList, timelineItem)
  49. }
  50. // 分析套餐&模式日志
  51. scheduleDataList := make(map[uint]domain.ScheduleData)
  52. for _, log := range data.Log_357 {
  53. _, err := time.Parse(time.DateTime, log.LogTime)
  54. if err != nil {
  55. zap.L().Error("357日志时间格式错误", zap.String("time", log.LogTime))
  56. return err
  57. }
  58. var log_357 domain.MqttLogType_357
  59. err = json.Unmarshal([]byte(log.LogData), &log_357)
  60. if err != nil {
  61. zap.L().Error("357日志JSON数据格式错误", zap.String("data", log.LogData))
  62. return err
  63. }
  64. // 判断操作类型 1-增加/编辑 2-删除 3-修改当前工作序列
  65. opt := log_357.Opt
  66. var modeInfo *string
  67. var modeData *string
  68. switch opt {
  69. case 1:
  70. // 记录策略ID对应的策略信息,用于关联切换的模式
  71. if log_357.Data != nil {
  72. scheduleDataList[log_357.Data.ID] = *log_357.Data
  73. }
  74. case 2:
  75. // 删除不做处理
  76. case 3:
  77. if log_357.CurrentId != nil && *log_357.CurrentId >= 0 {
  78. val, ok := scheduleDataList[uint(*log_357.CurrentId)]
  79. if ok {
  80. modeInfo = &val.Name
  81. // 转成 JSON 字符串
  82. jsonModeData, err := json.Marshal(val)
  83. if err != nil {
  84. fmt.Println("序列化失败:", err)
  85. zap.L().Error("357日志策略信息JSON数据序列化失败", zap.String("err", err.Error()), zap.Any("data", val))
  86. } else {
  87. dataStr := string(jsonModeData)
  88. modeData = &dataStr
  89. }
  90. } else {
  91. infoStr := fmt.Sprintf("未知模式(%d)", log_357.CurrentId)
  92. modeInfo = &infoStr
  93. }
  94. }
  95. default:
  96. zap.L().Error("357日志不支持的操作类型", zap.String("opt", strconv.Itoa(log_357.Opt)))
  97. return err
  98. }
  99. timelineItem := domain.TimelineItem{
  100. Time: log.LogTime,
  101. Type: domain.TimelineModeChange,
  102. Info: modeInfo,
  103. Data: modeData,
  104. }
  105. timelineItemList = append(timelineItemList, timelineItem)
  106. }
  107. // 分析Event
  108. for _, log := range data.EventLog {
  109. _, err := time.Parse(time.DateTime, log.LogTime)
  110. if err != nil {
  111. zap.L().Error("Event日志时间格式错误", zap.String("time", log.LogTime))
  112. return err
  113. }
  114. timelineItem := domain.TimelineItem{
  115. Time: log.LogTime,
  116. Type: domain.TimelineEvent,
  117. Info: &log.LogName,
  118. }
  119. timelineItemList = append(timelineItemList, timelineItem)
  120. }
  121. // 分析Alarm
  122. for _, log := range data.AlarmLog {
  123. _, err := time.Parse(time.DateTime, log.LogTime)
  124. if err != nil {
  125. zap.L().Error("Alarm日志时间格式错误", zap.String("time", log.LogTime))
  126. return err
  127. }
  128. alarmCode := []byte(log.AlarmCode)
  129. var alarmName string
  130. if len(alarmCode) < 4 {
  131. alarmName = fmt.Sprintf("#? %s", log.LogName)
  132. } else {
  133. if alarmCode[1] == '0' {
  134. alarmName = log.LogName
  135. } else {
  136. alarmName = fmt.Sprintf("#%s %s", string(alarmCode[1]), log.LogName)
  137. }
  138. }
  139. timelineItem := domain.TimelineItem{
  140. Time: log.LogTime,
  141. Type: domain.TimelineAlarm,
  142. Info: &alarmName,
  143. }
  144. timelineItemList = append(timelineItemList, timelineItem)
  145. }
  146. // 数据时间排序
  147. timelineSlice(&timelineItemList)
  148. // 最后将时间线数据存入数据库
  149. if err := repositories.InsertSiteAnalysisTimeline(id, timelineItemList); err != nil {
  150. zap.L().Error("插入站点分析timeline数据失败", zap.String("id", id.String()))
  151. return err
  152. }
  153. return nil
  154. }
  155. func timelineSlice(list *[]domain.TimelineItem) {
  156. if list == nil {
  157. return
  158. }
  159. // 排序
  160. sort.Slice(*list, func(i, j int) bool {
  161. ti, _ := time.Parse(time.DateTime, (*list)[i].Time)
  162. tj, _ := time.Parse(time.DateTime, (*list)[j].Time)
  163. return ti.Before(tj)
  164. })
  165. }
  166. // 分析站点运行实时数据
  167. func AnalysisSiteRuntime(id primitive.ObjectID, data SiteDataSet) error {
  168. var runtimeItemList []domain.RuntimeItem
  169. // 分析offline
  170. for _, log := range data.Log_201 {
  171. _, err := time.Parse(time.DateTime, log.LogTime)
  172. if err != nil {
  173. zap.L().Error("201日志时间格式错误", zap.String("time", log.LogTime))
  174. return err
  175. }
  176. runtimeItem := domain.RuntimeItem{
  177. Time: log.LogTime,
  178. Data_201: log.LogData,
  179. }
  180. runtimeItemList = append(runtimeItemList, runtimeItem)
  181. }
  182. // 将运行时数据存入数据库
  183. if err := repositories.InsertSiteAnalysisRuntime(id, runtimeItemList); err != nil {
  184. zap.L().Error("插入站点分析runtime数据失败", zap.String("id", id.String()))
  185. return err
  186. }
  187. return nil
  188. }