package model import ( "fmt" "kpt-pasture/util" "math" "strconv" "strings" "time" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" ) const ( InitChangeFilter = -10000 DefaultChangeFilter = -99 DefaultRuminaFilter = -99 DefaultChewFilter = -99 DefaultFilterCorrect = 100 DefaultWeeklyActive = 1500 ) type NeckActiveHabit struct { Id int64 `json:"id"` PastureId int64 `json:"pastureId"` NeckRingNumber string `json:"neckRingNumber"` CowId int64 `json:"cowId"` Lact int32 `json:"lact"` CalvingAge int32 `json:"calvingAge"` ActiveTime string `json:"activeTime"` Frameid int32 `json:"frameid"` HeatDate string `json:"heatDate"` Rumina int32 `json:"rumina"` Intake int32 `json:"intake"` Inactive int32 `json:"inactive"` Gasp int32 `json:"gasp"` Other int32 `json:"other"` High int32 `json:"high"` Active int32 `json:"active"` FilterHigh int32 `json:"filterHigh"` FilterRumina int32 `json:"filterRumina"` FilterChew int32 `json:"filterChew"` WeekHigh int32 `json:"weekHigh"` WeekHighHabit int32 `json:"weekHighHabit"` WeekRuminaHabit int32 `json:"weekRuminaHabit"` WeekIntakeHabit int32 `json:"weekIntakeHabit"` WeekChewHabit int32 `json:"weekChewHabit"` WeekInactiveHabit int32 `json:"weekInactiveHabit"` WeekOtherHabit int32 `json:"weekOtherHabit"` ChangeHigh int32 `json:"changeHigh"` ChangeRumina int32 `json:"changeRumina"` ChangeChew int32 `json:"changeChew"` ChangeAdjust int32 `json:"changeAdjust"` ChangeFilter int32 `json:"changeFilter"` RuminaFilter int32 `json:"ruminaFilter"` ChewFilter int32 `json:"chewFilter"` FilterCorrect int32 `json:"filterCorrect"` SumRumina int32 `json:"sumRumina"` SumIntake int32 `json:"sumIntake"` SumInactive int32 `json:"sumInactive"` SumActive int32 `json:"sumActive"` SumMinHigh int32 `json:"sumMinHigh"` SumMaxHigh int32 `json:"sumMaxHigh"` SumMinChew int32 `json:"SumMinChew"` BeforeThreeSumRumina int32 `json:"beforeThreeSumRumina"` BeforeThreeSumIntake int32 `json:"beforeThreeSumIntake"` Score int32 `json:"score"` IsMaxTime pasturePb.IsShow_Kind `json:"isMaxTime"` IsShow pasturePb.IsShow_Kind `json:"isShow"` RecordCount int32 `json:"recordCount"` FirmwareVersion int32 `json:"firmwareVersion"` CreatedAt int64 `json:"createdAt"` UpdatedAt int64 `json:"updatedAt"` } func (n *NeckActiveHabit) TableName() string { return "neck_active_habit" } func NewNeckActiveHabit(data *NeckRingOriginalMerge) *NeckActiveHabit { return &NeckActiveHabit{ PastureId: data.PastureId, Frameid: data.XframeId, HeatDate: data.ActiveDate, NeckRingNumber: data.NeckRingNumber, Active: data.Active, Gasp: data.Gasp, High: data.High, Inactive: data.Inactive, Intake: data.Intake, Other: data.Other, Rumina: data.Rumina, IsShow: data.IsShow, WeekHigh: DefaultWeeklyActive, IsMaxTime: pasturePb.IsShow_No, ChangeFilter: InitChangeFilter, FilterCorrect: InitChangeFilter, RuminaFilter: InitChangeFilter, ChewFilter: InitChangeFilter, ActiveTime: fmt.Sprintf("%s %02d:00:00", data.ActiveDate, data.XframeId*2+1), RecordCount: data.RecordCount, FirmwareVersion: data.FirmwareVersion, } } type NeckActiveHabitSlice []*NeckActiveHabit func (n NeckActiveHabitSlice) Len() int { return len(n) } func (n NeckActiveHabitSlice) Swap(i, j int) { n[i], n[j] = n[j], n[i] } func (n NeckActiveHabitSlice) Less(i, j int) bool { if n[i].HeatDate != n[j].HeatDate { return n[i].HeatDate < n[j].HeatDate } return n[i].Frameid < n[j].Frameid } func (n NeckActiveHabitSlice) ToPB(curveName, startDateTime, endDateTime string) *CowBehaviorCurveData { res := &CowBehaviorCurveData{ OriginalDateList: make([]int32, 0), ChangeDateList: make([]int32, 0), SumDateList: make([]int32, 0), DateTimeList: make([]string, 0), EstrusList: make(map[pasturePb.EstrusLevel_Kind][]string), EventList: make(map[string][]string), EventMap: make(map[pasturePb.EventType_Kind]string), } initFrameId := int32(0) dateFrameMap := make(map[string][]int32) for _, v := range n { if dateFrameMap[v.HeatDate] == nil { initFrameId = 0 dateFrameMap[v.HeatDate] = make([]int32, 0) } // 补全结尾不够的数据 if initFrameId == 0 && len(res.DateTimeList) > 0 { lastDateTime := res.DateTimeList[len(res.DateTimeList)-1] lastDatePase := strings.Split(lastDateTime, " ") if len(lastDatePase) == 2 { lastDay := lastDatePase[0] lastHourStr := lastDatePase[1] lastHour, _ := strconv.ParseInt(lastHourStr, 10, 64) maxHour := util.ExpectedFrameIDs[len(util.ExpectedFrameIDs)-1] xframeId := int32(lastHour-1)/2 + 1 if xframeId != maxHour { for ; xframeId <= maxHour; xframeId++ { res.DateTimeList = append(res.DateTimeList, fmt.Sprintf("%s %02d", lastDay, util.ExpectedFrameIDs[xframeId]*2+1)) res.OriginalDateList = append(res.OriginalDateList, 0) res.ChangeDateList = append(res.ChangeDateList, 0) res.SumDateList = append(res.SumDateList, 0) } } } } expectedFrameId := util.ExpectedFrameIDs[initFrameId] if expectedFrameId != v.Frameid { maxFrameId := int32(math.Abs(float64(expectedFrameId - v.Frameid))) for ; expectedFrameId < maxFrameId; expectedFrameId++ { res.DateTimeList = append(res.DateTimeList, fmt.Sprintf("%s %02d", v.HeatDate, util.ExpectedFrameIDs[expectedFrameId]*2+1)) res.OriginalDateList = append(res.OriginalDateList, 0) res.ChangeDateList = append(res.ChangeDateList, 0) res.SumDateList = append(res.SumDateList, 0) } initFrameId = expectedFrameId } // 格式化为到小时的字符串 parsedTime, _ := time.Parse(LayoutTime, v.ActiveTime) hourStr := parsedTime.Format(LayoutHour) res.DateTimeList = append(res.DateTimeList, hourStr) switch curveName { case "active": // 活动量 res.OriginalDateList = append(res.OriginalDateList, v.High) res.ChangeDateList = append(res.ChangeDateList, v.ChangeFilter) case "rumina": // 反刍 res.OriginalDateList = append(res.OriginalDateList, v.Rumina) res.ChangeDateList = append(res.ChangeDateList, v.ChangeRumina) res.SumDateList = append(res.SumDateList, v.SumRumina) case "intake": // 采食 res.OriginalDateList = append(res.OriginalDateList, v.Intake) res.SumDateList = append(res.SumDateList, v.SumIntake) case "inactive": // 休息 res.OriginalDateList = append(res.OriginalDateList, v.Inactive) res.SumDateList = append(res.SumDateList, v.SumInactive) case "chew": // 咀嚼 res.OriginalDateList = append(res.OriginalDateList, v.FilterChew) res.ChangeDateList = append(res.ChangeDateList, v.ChangeChew) case "immobility": // 静止 res.OriginalDateList = append(res.OriginalDateList, 120-v.Active) res.SumDateList = append(res.SumDateList, 60*24-v.SumActive) } initFrameId++ } return res } func (n *NeckActiveHabit) SumAvg() { n.Rumina = n.Rumina / n.RecordCount * n.RecordCount n.Inactive = n.Inactive / n.RecordCount * n.RecordCount n.Active = n.Active / n.RecordCount * n.RecordCount n.Intake = n.Intake / n.RecordCount * n.RecordCount n.Other = n.Other / n.RecordCount * n.RecordCount n.Gasp = n.Gasp / n.RecordCount * n.RecordCount n.High = n.High / n.RecordCount * n.RecordCount } type MaxHabitIdModel struct { Id int64 `json:"id"` }