analysisSiteData.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 logData domain.MqttLogContent[domain.MqttLogType_357]
  59. err = json.Unmarshal([]byte(log.LogData), &logData)
  60. if err != nil {
  61. zap.L().Error("357日志JSON数据格式错误", zap.String("err", err.Error()), zap.String("data", log.LogData))
  62. return err
  63. }
  64. // 判断操作类型 1-增加/编辑 2-删除 3-修改当前工作序列
  65. log_357 := logData.DataArea
  66. opt := log_357.Opt
  67. var modeInfo *string
  68. var modeData *string
  69. switch opt {
  70. case 1:
  71. // 记录策略ID对应的策略信息,用于关联切换的模式
  72. if log_357.Data != nil {
  73. scheduleDataList[log_357.Data.ID] = *log_357.Data
  74. }
  75. case 2:
  76. // 删除不做处理
  77. case 3:
  78. if log_357.CurrentId != nil && *log_357.CurrentId >= 0 {
  79. val, ok := scheduleDataList[uint(*log_357.CurrentId)]
  80. if ok {
  81. modeInfo = &val.Name
  82. // 转成 JSON 字符串
  83. jsonModeData, err := json.Marshal(val)
  84. if err != nil {
  85. fmt.Println("序列化失败:", err)
  86. zap.L().Error("357日志策略信息JSON数据序列化失败", zap.String("err", err.Error()), zap.Any("data", val))
  87. } else {
  88. dataStr := string(jsonModeData)
  89. modeData = &dataStr
  90. }
  91. } else {
  92. infoStr := fmt.Sprintf("未知模式(%d)", log_357.CurrentId)
  93. modeInfo = &infoStr
  94. }
  95. }
  96. default:
  97. zap.L().Error("357日志不支持的操作类型", zap.String("opt", strconv.Itoa(log_357.Opt)), zap.Any("log_357", log_357))
  98. return err
  99. }
  100. timelineItem := domain.TimelineItem{
  101. Time: log.LogTime,
  102. Type: domain.TimelineModeChange,
  103. Info: modeInfo,
  104. Data: modeData,
  105. }
  106. timelineItemList = append(timelineItemList, timelineItem)
  107. }
  108. // 分析Event
  109. for _, log := range data.EventLog {
  110. _, err := time.Parse(time.DateTime, log.LogTime)
  111. if err != nil {
  112. zap.L().Error("Event日志时间格式错误", zap.String("time", log.LogTime))
  113. return err
  114. }
  115. timelineItem := domain.TimelineItem{
  116. Time: log.LogTime,
  117. Type: domain.TimelineEvent,
  118. Info: &log.LogName,
  119. }
  120. timelineItemList = append(timelineItemList, timelineItem)
  121. }
  122. // 分析Alarm
  123. for _, log := range data.AlarmLog {
  124. _, err := time.Parse(time.DateTime, log.LogTime)
  125. if err != nil {
  126. zap.L().Error("Alarm日志时间格式错误", zap.String("time", log.LogTime))
  127. return err
  128. }
  129. alarmCode := []byte(log.AlarmCode)
  130. var alarmName string
  131. if len(alarmCode) < 4 {
  132. alarmName = fmt.Sprintf("#? %s", log.LogName)
  133. } else {
  134. if alarmCode[1] == '0' {
  135. alarmName = log.LogName
  136. } else {
  137. alarmName = fmt.Sprintf("#%s %s", string(alarmCode[1]), log.LogName)
  138. }
  139. }
  140. timelineItem := domain.TimelineItem{
  141. Time: log.LogTime,
  142. Type: domain.TimelineAlarm,
  143. Info: &alarmName,
  144. }
  145. timelineItemList = append(timelineItemList, timelineItem)
  146. }
  147. // 数据时间排序
  148. timelineSort(&timelineItemList)
  149. // 最后将时间线数据存入数据库
  150. if err := repositories.InsertSiteAnalysisTimeline(id, timelineItemList); err != nil {
  151. zap.L().Error("插入站点分析timeline数据失败", zap.String("id", id.String()))
  152. return err
  153. }
  154. return nil
  155. }
  156. func timelineSort(list *[]domain.TimelineItem) {
  157. if list == nil {
  158. return
  159. }
  160. // 排序
  161. sort.Slice(*list, func(i, j int) bool {
  162. ti, _ := time.Parse(time.DateTime, (*list)[i].Time)
  163. tj, _ := time.Parse(time.DateTime, (*list)[j].Time)
  164. return ti.Before(tj)
  165. })
  166. }
  167. // 分析站点运行实时数据
  168. func AnalysisSiteRuntime(id primitive.ObjectID, data SiteDataSet) error {
  169. var runtimeItemList []domain.RuntimeItem
  170. // 分析offline
  171. for _, log := range data.Log_201 {
  172. _, err := time.Parse(time.DateTime, log.LogTime)
  173. if err != nil {
  174. zap.L().Error("201日志时间格式错误", zap.String("time", log.LogTime))
  175. return err
  176. }
  177. runtimeItem := domain.RuntimeItem{
  178. Time: log.LogTime,
  179. Data_201: log.LogData,
  180. }
  181. runtimeItemList = append(runtimeItemList, runtimeItem)
  182. }
  183. // 数据时间排序
  184. runtimeSort(&runtimeItemList)
  185. // 将运行时数据存入数据库
  186. if err := repositories.InsertSiteAnalysisRuntime(id, runtimeItemList); err != nil {
  187. zap.L().Error("插入站点分析runtime数据失败", zap.String("id", id.String()))
  188. return err
  189. }
  190. return nil
  191. }
  192. func runtimeSort(list *[]domain.RuntimeItem) {
  193. if list == nil {
  194. return
  195. }
  196. // 排序
  197. sort.Slice(*list, func(i, j int) bool {
  198. ti, _ := time.Parse(time.DateTime, (*list)[i].Time)
  199. tj, _ := time.Parse(time.DateTime, (*list)[j].Time)
  200. return ti.Before(tj)
  201. })
  202. }