|
@@ -4,6 +4,7 @@ import (
|
|
|
"fmt"
|
|
|
"kpt-pasture/model"
|
|
|
"math"
|
|
|
+ "time"
|
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
@@ -11,6 +12,13 @@ import (
|
|
|
"gitee.com/xuyiping_admin/pkg/xerr"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ DefaultLimit = 10000
|
|
|
+ DefaultChangeFilter = 0
|
|
|
+ MinChangeFilter = -99
|
|
|
+ MinChangeHigh = -99
|
|
|
+)
|
|
|
+
|
|
|
// NeckRingMergeData 把
|
|
|
func (e *Entry) NeckRingMergeData() error {
|
|
|
// 先看看上次任务有没有执行结束,结束在执行下面的任务
|
|
@@ -25,7 +33,7 @@ func (e *Entry) NeckRingMergeData() error {
|
|
|
|
|
|
limit := e.Cfg.NeckRingLimit
|
|
|
if limit <= 0 {
|
|
|
- limit = 10000
|
|
|
+ limit = DefaultLimit
|
|
|
}
|
|
|
neckRingList := make([]*model.NeckRingOriginal, 0)
|
|
|
if err := e.DB.Model(new(model.NeckRingOriginal)).
|
|
@@ -58,8 +66,16 @@ func (e *Entry) NeckRingMergeData() error {
|
|
|
v.SumAvg()
|
|
|
}
|
|
|
|
|
|
+ weeklyActive := &model.SystemConfigure{}
|
|
|
+ if err := e.DB.Model(new(model.SystemConfigure)).
|
|
|
+ Where("name = ?", model.WeeklyActive).
|
|
|
+ Where("is_show = ?", pasturePb.IsShow_Ok).
|
|
|
+ First(weeklyActive).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
// 更新脖环牛只相关信息
|
|
|
- newNeckActiveHabitList := model.NeckRingOriginalMap(originalMapData).ForMatData(e.GetCowInfoByImei)
|
|
|
+ newNeckActiveHabitList := model.NeckRingOriginalMap(originalMapData).ForMatData(weeklyActive.Value, e.GetCowInfoByImei)
|
|
|
|
|
|
if err := e.DB.Transaction(func(tx *gorm.DB) error {
|
|
|
// 更新已处理过的id
|
|
@@ -99,27 +115,66 @@ func (e *Entry) NeckRingMergeData() error {
|
|
|
}
|
|
|
|
|
|
func (e *Entry) ActiveHabit() error {
|
|
|
-
|
|
|
// 上次任务未处理完的数据
|
|
|
- minNeckActiveHabit := &model.NeckActiveHabit{}
|
|
|
+ lastNeckActiveHabit := &model.NeckActiveHabit{}
|
|
|
if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
Where("is_show = ?", pasturePb.IsShow_No).
|
|
|
- Order("id").Limit(1).First(minNeckActiveHabit).Error; err != nil {
|
|
|
+ Order("id").First(lastNeckActiveHabit).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ xToday := &XToday{}
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select(`MIN(TO_DAYS(h.heat_date)*1000 + h.frameid) as xTodaySBegFrameid, MIN(h.heat_date) as xBegDate,
|
|
|
+ MAX(TO_DAYS(h.heat_date)*1000 + h.frameid) as xTodaySMaxFrameid, MAX(h.heat_date) as xEndDate, MAX(h.id) as xEndUpdateActId`).
|
|
|
+ Where("id >= ?", lastNeckActiveHabit.Id).First(xToday).Error; err != nil {
|
|
|
return xerr.WithStack(err)
|
|
|
}
|
|
|
|
|
|
- // 更新牛只最新数据
|
|
|
+ minHeatDate := struct {
|
|
|
+ HeatDate string
|
|
|
+ }{}
|
|
|
+
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("MIN(heat_date) as heat_date").
|
|
|
+ Where("id >= ?", lastNeckActiveHabit.Id).
|
|
|
+ First(&minHeatDate).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ minHeatDateParse, _ := time.Parse(model.LayoutDate2, minHeatDate.HeatDate)
|
|
|
+ xMin2Id := struct {
|
|
|
+ Id int64
|
|
|
+ }{}
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("IFNULL(MIN(id), ?) as id", lastNeckActiveHabit.Id).
|
|
|
+ Where("heat_date = ?", minHeatDateParse.AddDate(0, 0, -1).Format(model.LayoutDate2)).
|
|
|
+ First(&xMin2Id).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ xMin7Id := struct {
|
|
|
+ Id int64
|
|
|
+ }{}
|
|
|
+ XBegDateTime, _ := time.Parse(model.LayoutDate2, xToday.XBegDate)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("MIN(id) as id").
|
|
|
+ Where("heat_date >= ?", XBegDateTime.AddDate(0, 0, -7).Format(model.LayoutDate2)).
|
|
|
+ First(&xMin7Id).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ // 更新is_max_time
|
|
|
if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
Where("is_max_time = ?", pasturePb.IsShow_Ok).
|
|
|
Update("is_max_time", pasturePb.IsShow_No).Error; err != nil {
|
|
|
return xerr.WithStack(err)
|
|
|
}
|
|
|
-
|
|
|
+ xBegDate, _ := time.Parse(model.LayoutDate2, xToday.XBegDate)
|
|
|
+ before7xBegDate := xBegDate.AddDate(0, 0, 7).Format(model.LayoutDate2)
|
|
|
sqlQuery := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
- Select("Max(id) as id").
|
|
|
- Where("id BETWEEN ? AND ?").
|
|
|
- Where("change_filter > ?", -99).
|
|
|
- Where("").Group("cow_id")
|
|
|
+ Select("MAX(id) as id").
|
|
|
+ Where("id BETWEEN ? AND ?", xMin2Id.Id, lastNeckActiveHabit.Id).
|
|
|
+ Where("change_filter > ?", MinChangeFilter).
|
|
|
+ Where("heat_date >", before7xBegDate).Group("cow_id")
|
|
|
|
|
|
if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
Joins("JOIN (?) bb ON neck_active_habit.id = bb.id", sqlQuery).
|
|
@@ -129,40 +184,364 @@ func (e *Entry) ActiveHabit() error {
|
|
|
|
|
|
activeLowest := e.GetSystemConfigure(model.ActiveLowest)
|
|
|
ruminaLowest := e.GetSystemConfigure(model.RuminaLowest)
|
|
|
+
|
|
|
+ // 更新活动滤波
|
|
|
+ if err := e.FilterUpdate(activeLowest.Value, ruminaLowest.Value); err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ // 更新周平均值
|
|
|
+ if err := e.WeeklyActiveAvgUpdate(xMin2Id.Id, activeLowest.Value, ruminaLowest.Value, xToday, lastNeckActiveHabit); err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// FilterUpdate 更新活动滤波
|
|
|
+func (e *Entry) FilterUpdate(activeLowest, ruminaLowest int32) error {
|
|
|
newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
|
|
|
if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
- Where("is_show = ?", pasturePb.IsShow_No).
|
|
|
- Where(e.DB.Where("change_filter = 0").Or("is_max_time = ?", pasturePb.IsShow_Ok)).
|
|
|
- Where(e.DB.Where("high >= ?", activeLowest.Value).Or("rumina >= ?", ruminaLowest.Value)).
|
|
|
- Order("cow_id,id").Find(&newNeckActiveHabitList).Error; err != nil {
|
|
|
+ Where(e.DB.Where("change_filter = ?", DefaultChangeFilter).Or("is_max_time = ?", pasturePb.IsShow_Ok)).
|
|
|
+ Where(e.DB.Where("high >= ?", activeLowest).Or("rumina >= ?", ruminaLowest)).
|
|
|
+ Order("cow_id,id").
|
|
|
+ Find(&newNeckActiveHabitList).Error; err != nil {
|
|
|
return xerr.WithStack(err)
|
|
|
}
|
|
|
|
|
|
- var (
|
|
|
- lastCowId = int64(0)
|
|
|
- filterValues = make(map[int64]*model.NeckActiveHabit)
|
|
|
- )
|
|
|
+ var filterValues = make(map[int64]*model.NeckActiveHabit)
|
|
|
// 活动量滤波
|
|
|
for _, v := range newNeckActiveHabitList {
|
|
|
- if v.CowId != lastCowId {
|
|
|
- lastCowId = v.CowId
|
|
|
- filterValues[v.CowId] = &model.NeckActiveHabit{CowId: v.CowId}
|
|
|
+ prev, ok := filterValues[v.CowId]
|
|
|
+ if !ok {
|
|
|
+ if v.FilterHigh <= 0 {
|
|
|
+ v.FilterHigh = v.High
|
|
|
+ }
|
|
|
+ if v.FilterRumina <= 0 {
|
|
|
+ v.FilterRumina = v.Rumina
|
|
|
+ }
|
|
|
+ if v.FilterChew <= 0 {
|
|
|
+ v.FilterChew = v.Rumina + v.Intake
|
|
|
+ }
|
|
|
+ filterValues[v.CowId] = v
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if v.FilterHigh <= 0 {
|
|
|
+ v.FilterHigh = int32(computeIfPositiveElse(float64(v.High), float64(prev.FilterHigh), 0.23, 0.77))
|
|
|
+ }
|
|
|
+ if v.FilterRumina <= 0 {
|
|
|
+ v.FilterRumina = int32(computeIfPositiveElse(float64(v.Rumina), float64(prev.FilterRumina), 0.33, 0.67))
|
|
|
+ }
|
|
|
+ if v.FilterChew <= 0 {
|
|
|
+ v.FilterChew = int32(computeIfPositiveElse(float64(v.Rumina+v.Intake), float64(prev.FilterChew), 0.33, 0.67))
|
|
|
}
|
|
|
-
|
|
|
- prev := filterValues[v.CowId]
|
|
|
- v.FilterHigh = int32(computeIfPositiveElse(float64(v.FilterHigh), float64(v.High), float64(prev.FilterHigh), 0.23, 0.77))
|
|
|
- v.FilterRumina = int32(computeIfPositiveElse(float64(v.FilterRumina), float64(v.Rumina), float64(prev.FilterRumina), 0.33, 0.67))
|
|
|
- v.FilterHigh = int32(computeIfPositiveElse(float64(v.FilterChew), float64(v.Rumina+v.Intake), float64(prev.FilterChew), 0.23, 0.77))
|
|
|
// 更新过滤值
|
|
|
filterValues[v.CowId] = v
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("filter_high", "filter_rumina", "filter_chew").
|
|
|
+ Where("id = ?", v.Id).
|
|
|
+ Updates(v).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// 辅助函数来计算过滤值
|
|
|
-func computeIfPositiveElse(filterValue, newValue, prevFilterValue float64, weightPrev, weightNew float64) float64 {
|
|
|
- if filterValue > 0 {
|
|
|
- return filterValue
|
|
|
+func (e *Entry) WeeklyActiveAvgUpdate(xMin2Id int64, activeLowest, ruminaLowest int32, xToday *XToday, lastNeckActiveHabit *model.NeckActiveHabit) error {
|
|
|
+ before7DaysMinId := struct {
|
|
|
+ Id int64 `json:"id"`
|
|
|
+ }{
|
|
|
+ Id: 0,
|
|
|
+ }
|
|
|
+ before7DayDate, _ := time.Parse(model.LayoutDate2, xToday.XBegDate)
|
|
|
+ before7DayDateStr := before7DayDate.AddDate(0, 0, -7).Format(model.LayoutDate2)
|
|
|
+ before1DayDateStr := before7DayDate.AddDate(0, 0, -1).Format(model.LayoutDate2)
|
|
|
+
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("MIN(id) as id").
|
|
|
+ Where("heat_date >= ?", before7DayDateStr).
|
|
|
+ First(&before7DaysMinId).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
}
|
|
|
- return math.Ceil(weightPrev*prevFilterValue + weightNew*newValue)
|
|
|
+
|
|
|
+ weeklyActive := e.GetSystemConfigure(model.WeeklyActive)
|
|
|
+ xframeId := int64(0)
|
|
|
+ maxXframeId := int64(11)
|
|
|
+ currDate, _ := time.Parse(model.LayoutDate2, xToday.XBegDate)
|
|
|
+ XEndDateTime, _ := time.Parse(model.LayoutDate2, xToday.XEndDate)
|
|
|
+ for currDate.Format(model.LayoutDate2) < XEndDateTime.Format(model.LayoutDate2) || (currDate == XEndDateTime && xframeId <= maxXframeId) {
|
|
|
+
|
|
|
+ // 时间点周平均
|
|
|
+ weeklyHabitList := make([]*WeeklyHabit, 0)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("cow_id").
|
|
|
+ Select("IF(COUNT(1)>=3, ROUND((SUM(filter_high) -MIN(filter_high) -MAX(filter_high))/ABS(COUNT(1) -2),0), -1) as week_avg_high_habit").
|
|
|
+ Select("IF(COUNT(1)>=3, ROUND((SUM(filter_rumina) -MIN(filter_rumina) -MAX(filter_rumina))/ABS(COUNT(1) -2),0), -1) as week_avg_rumina_habit").
|
|
|
+ Select("IF(COUNT(1)>=3, ROUND((SUM(filter_chew) -MIN(filter_chew) -MAX(filter_chew))/ABS(COUNT(1) -2),0), -1) as week_avg_chew_habit").
|
|
|
+ Select("ROUND(AVG(intake),0) as week_avg_intake_habit").
|
|
|
+ Select("ROUND(AVG(inactive),0) as week_avg_inactive_habit").
|
|
|
+ Where("id BETWEEN ? AND ?", xMin2Id, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date BETWEEN ? AND ?", before7DayDateStr, before1DayDateStr).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("change_filter = ?", DefaultChangeFilter).
|
|
|
+ Where(e.DB.Where("high > ?", activeLowest).Or("rumina > ?", ruminaLowest)).
|
|
|
+ Group("cow_id").
|
|
|
+ Find(&weeklyHabitList).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ for _, v := range weeklyHabitList {
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("week_avg_high_habit", "week_avg_rumina_habit", "week_avg_chew_habit", "week_avg_intake_habit", "week_avg_inactive_habit").
|
|
|
+ Where("cow_id = ?", v.CowId).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabit.Id, xToday.xEndUpdateActId).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("change_filter = ?", DefaultChangeFilter).
|
|
|
+ Where("heat_date = ?", currDate).
|
|
|
+ Updates(v).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 累计24小时数值
|
|
|
+ sumHabitList := make([]*SumHabit, 0)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("cow_id").
|
|
|
+ Select("IF(COUNT(1)>6, ROUND(AVG( h2.filter_rumina)*12,0), 0) as sum_rumina").
|
|
|
+ Select("IF(COUNT(1)>6, ROUND(AVG( h2.intake)*12,0), 0) as sum_intake").
|
|
|
+ Select("IF(COUNT(1)>6, ROUND(AVG( h2.inactive)*12,0), 0) as sum_inactive").
|
|
|
+ Select("IF(COUNT(1)>6, ROUND(AVG( h2.active)*12,0), 0) as sum_active").
|
|
|
+ Select("MAX(h2.change_filter) as sum_max_high").
|
|
|
+ Select("MIN(IF(change_filter > ?, change_filter, 0)) as sum_min_high", MinChangeFilter).
|
|
|
+ Select("MIN( CASE WHEN filter_chew > ? THEN filter_chew WHEN filter_rumina >= ? THEN filter_rumina ELSE 0 END) as sum_min_chew", MinChangeFilter, MinChangeFilter).
|
|
|
+ Where("id BETWEEN ? AND ?", before7DaysMinId.Id, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date BETWEEN ? AND ?", currDate.AddDate(0, 0, -1).Format(model.LayoutDate2), currDate.Format(model.LayoutDate2)).
|
|
|
+ Where("created_at BETWEEN ? AND ?", currDate.Add(-23*time.Hour), currDate.Unix()).
|
|
|
+ Where(e.DB.Where("high > ?", activeLowest).Or("rumina >= ?", ruminaLowest)).
|
|
|
+ Group("cow_id").
|
|
|
+ Find(&sumHabitList).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range sumHabitList {
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("sum_rumina", "sum_intake", "sum_inactive", "sum_active", "sum_max_high", "sum_min_high", "sum_min_chew").
|
|
|
+ Where("cow_id = ?", v.CowId).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabit.Id, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("change_filter = ?", DefaultChangeFilter).
|
|
|
+ Updates(v).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 变化百分比
|
|
|
+ changeHabitList := make([]*model.NeckActiveHabit, 0)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabit.Id, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("change_filter = ?", DefaultChangeFilter).
|
|
|
+ Where("week_avg_high_habit > ?", 0).
|
|
|
+ Where(e.DB.Where("high > ?", activeLowest).Or("rumina >= ?", ruminaLowest)).
|
|
|
+ Find(&changeHabitList).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range changeHabitList {
|
|
|
+ if v.FilterHigh-v.WeekAvgHighHabit > 0 {
|
|
|
+ v.ChangeHigh = (v.FilterHigh - v.WeekAvgHighHabit) / int32(float64(v.WeekHigh)*0.6+float64(v.WeekAvgHighHabit)*0.2+float64(weeklyActive.Value)*0.2)
|
|
|
+ } else {
|
|
|
+ v.ChangeHigh = v.FilterHigh - v.WeekAvgHighHabit/v.WeekAvgHighHabit*100
|
|
|
+ }
|
|
|
+
|
|
|
+ v.ChangeRumina = v.RuminaFilter - v.WeekAvgRuminaHabit/v.WeekAvgHighHabit*100
|
|
|
+ v.ChangeChew = v.FilterChew - v.WeekAvgChewHabit/v.WeekAvgHighHabit*100
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("change_high", "change_rumina", "change_chew").
|
|
|
+ Where("id = ?", v.Id).
|
|
|
+ Updates(v).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if xframeId == maxXframeId {
|
|
|
+ xframeId = 0
|
|
|
+ currDate = currDate.AddDate(0, 0, 1)
|
|
|
+ } else {
|
|
|
+ xframeId++
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// UpdateChangeFilter 变化趋势滤波
|
|
|
+func (e *Entry) UpdateChangeFilter(xMin2Id int64, xToday *XToday) error {
|
|
|
+ xRuminaDisc := e.GetSystemConfigure(model.XRuminaDisc)
|
|
|
+ xChangeDiscount := e.GetSystemConfigure(model.XChangeDiscount)
|
|
|
+ newChangeFilterList := make([]*ChangeFilterData, 0)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("id,cow_id,change_high,change_filter,rumina_filter,change_rumina,chew_filter,change_chew").
|
|
|
+ Select("IF(lact=0,0.8,1) as xlc_dis_count").
|
|
|
+ Where("id BETWEEN ? AND ?", xMin2Id, xToday.xEndUpdateActId).
|
|
|
+ Where(e.DB.Where("change_filter = ?", DefaultChangeFilter).Or("is_max_time = ?", pasturePb.IsShow_Ok)).
|
|
|
+ Where("change_high > ?", MinChangeHigh).
|
|
|
+ Order("cow_id,heat_date,frameid").
|
|
|
+ Find(&newChangeFilterList).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ var filterValues = make(map[int64]*ChangeFilterData)
|
|
|
+ for _, v := range newChangeFilterList {
|
|
|
+ prev, ok := filterValues[v.CowId]
|
|
|
+ if v.ChangeFilter <= MinChangeFilter {
|
|
|
+ prefChangeFilter := int32(0)
|
|
|
+ if ok {
|
|
|
+ prefChangeFilter = prev.ChangeFilter
|
|
|
+ }
|
|
|
+ leastValue := v.HighChange
|
|
|
+ if prefChangeFilter < v.HighChange {
|
|
|
+ leastValue = prefChangeFilter
|
|
|
+ }
|
|
|
+ v.ChangeFilter = int32(float64(prefChangeFilter)*(1-(float64(xChangeDiscount.Value)/10)*v.XlcDisCount) +
|
|
|
+ float64(leastValue)*(float64(xChangeDiscount.Value)/10)*v.XlcDisCount)
|
|
|
+ }
|
|
|
+
|
|
|
+ if v.RuminaFilter <= MinChangeFilter {
|
|
|
+ prefRuminaFilter := int32(0)
|
|
|
+ if ok {
|
|
|
+ prefRuminaFilter = prev.RuminaFilter
|
|
|
+ }
|
|
|
+
|
|
|
+ factor := float64(1)
|
|
|
+ if math.Abs(float64(v.ChangeRumina)) > 60 {
|
|
|
+ factor = 0.5
|
|
|
+ }
|
|
|
+
|
|
|
+ v.RuminaFilter = int32(float64(prefRuminaFilter)*(1-float64(xRuminaDisc.Value/10)*v.XlcDisCount*factor) +
|
|
|
+ float64(v.ChangeRumina)*float64(xRuminaDisc.Value)/10*v.XlcDisCount*factor)
|
|
|
+
|
|
|
+ }
|
|
|
+ if v.RuminaFilter > 50 {
|
|
|
+ v.RuminaFilter = 50
|
|
|
+ }
|
|
|
+
|
|
|
+ if v.ChewFilter <= MinChangeFilter {
|
|
|
+ prefChewFilter := int32(0)
|
|
|
+ if ok {
|
|
|
+ prefChewFilter = prev.ChewFilter
|
|
|
+ }
|
|
|
+ factor := float64(1)
|
|
|
+ if math.Abs(float64(v.ChangeChew)) > 60 {
|
|
|
+ factor = 0.5
|
|
|
+ }
|
|
|
+
|
|
|
+ v.ChewFilter = int32(float64(prefChewFilter)*(1-float64(xRuminaDisc.Value)/10*factor) +
|
|
|
+ float64(v.ChangeChew)*float64(xRuminaDisc.Value)/10*factor)
|
|
|
+ }
|
|
|
+
|
|
|
+ if v.ChewFilter > 50 {
|
|
|
+ v.ChangeChew = 50
|
|
|
+ }
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("change_filter", "rumina_filter", "chew_filter").
|
|
|
+ Where("id = ?", v.Id).Where("cow_id = ?", v.CowId).
|
|
|
+ Updates(v).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ filterValues[v.CowId] = v
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// ActivityVolumeChanges 计算活动量变化趋势校正值(活跃度校正)
|
|
|
+func (e *Entry) ActivityVolumeChanges(xMin7Id int64, activeLowest, ruminaLowest int32, xToday *XToday, lastNeckActiveHabitId int64) error {
|
|
|
+ currDate, _ := time.Parse(model.LayoutDate2, xToday.XBegDate)
|
|
|
+ XEndDateTime, _ := time.Parse(model.LayoutDate2, xToday.XEndDate)
|
|
|
+ xframeId := int64(0)
|
|
|
+ maxXframeId := int64(11)
|
|
|
+ dayTimes := int64(1)
|
|
|
+ for currDate.Format(model.LayoutDate2) < XEndDateTime.Format(model.LayoutDate2) || (currDate == XEndDateTime && xframeId <= maxXframeId) {
|
|
|
+ if dayTimes == 1 {
|
|
|
+ ActivityVolumeList := make([]*ActivityVolume, 0)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Select("cow_id").
|
|
|
+ Where("id BETWEEN ? AND ?", xMin7Id, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date BETWEEN ? AND ?", currDate.AddDate(0, 0, -7).Format(model.LayoutDate2), currDate.AddDate(0, 0, -1).Format(model.LayoutDate2)).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where(e.DB.Where("high > ?", activeLowest).Or("rumina >= ?", ruminaLowest)).
|
|
|
+ Where("created_at <= ?", currDate.Add(-12*time.Hour).Unix()).
|
|
|
+ Group("cow_id").
|
|
|
+ Having("nb > ?", 30).
|
|
|
+ Find(&ActivityVolumeList).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ for _, v := range ActivityVolumeList {
|
|
|
+ filterCorrect := 100 - math.Floor(float64(v.AvgFilter)/3+float64(v.StdFilter)/2)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Where("cow_id = ?", v.CowId).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabitId, xToday.xEndUpdateActId). // todo: 待完善
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("head_date = ?", currDate.Format(model.LayoutDate2)).
|
|
|
+ Update("filter_correct", filterCorrect).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ n := 0
|
|
|
+ if n <= 10 {
|
|
|
+
|
|
|
+ // todo
|
|
|
+
|
|
|
+ n += 2
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabitId, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("change_filter = ?", 0).
|
|
|
+ Update("change_filter", MinChangeHigh).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabitId, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("rumina_filter = ?", 0).
|
|
|
+ Update("rumina_filter", MinChangeHigh).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabitId, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("filter_correct < ?", 100).
|
|
|
+ Where("change_filter < ?", 0).
|
|
|
+ Update("filter_correct", 100).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新评分
|
|
|
+ newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
|
|
|
+ if err := e.DB.Model(new(model.NeckActiveHabit)).
|
|
|
+ Where("id BETWEEN ? AND ?", lastNeckActiveHabitId, xToday.xEndUpdateActId).
|
|
|
+ Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
|
|
|
+ Where("frameid = ?", xframeId).
|
|
|
+ Where("score = ?", 0).
|
|
|
+ Find(&newNeckActiveHabitList).Error; err != nil {
|
|
|
+ return xerr.WithStack(err)
|
|
|
+ }
|
|
|
+ /*for _, v := range newNeckActiveHabitList {
|
|
|
+
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// 辅助函数来计算过滤值
|
|
|
+func computeIfPositiveElse(newValue, prevFilterValue float64, weightPrev, weightNew float64) float64 {
|
|
|
+ return math.Ceil((prevFilterValue * weightPrev) + (weightNew * newValue))
|
|
|
}
|