123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- package crontab
- import (
- "kpt-pasture/model"
- "kpt-pasture/util"
- "time"
- pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
- "gitee.com/xuyiping_admin/pkg/logger/zaplog"
- "go.uber.org/zap"
- )
- // CowNeckRingErrorEnter 异常脖环监控 create_jbq_tj
- func (e *Entry) CowNeckRingErrorEnter() (err error) {
- pastureList := e.FindPastureList()
- if pastureList == nil || len(pastureList) == 0 {
- return nil
- }
- for _, pasture := range pastureList {
- e.CowNeckRingError(pasture.Id)
- zaplog.Error("CowNeckRingErrorEnter-Success", zap.Any("pasture", pasture))
- }
- return nil
- }
- func (e *Entry) CowNeckRingError(pastureId int64) {
- yesterday := time.Now().Local().AddDate(0, 0, -1).Format(model.LayoutDate2)
- habitMinId, originalMinId := 0, 0
- if err := e.DB.Model(new(model.NeckActiveHabit)).
- Select("IFNULL(MIN(id),0) as id").
- Where("pasture_id = ?", pastureId).
- Where("heat_date = ?", yesterday).
- Scan(&habitMinId).Error; err != nil {
- zaplog.Error("CowNeckRingError-Error", zap.Any("pastureId", pastureId), zap.Any("err", err))
- return
- }
- if err := e.DB.Model(new(model.NeckRingOriginal)).
- Select("IFNULL(MIN(id),0) as id").
- Where("pasture_id = ?", pastureId).
- Where("active_date = ?", yesterday).
- Scan(&originalMinId).Error; err != nil {
- zaplog.Error("CowNeckRingError-Error", zap.Any("pastureId", pastureId), zap.Any("err", err))
- return
- }
- minIsBindDate := util.TimeParseLocalUnix(yesterday)
- neckRingList := make([]*model.NeckRing, 0)
- if err := e.DB.Model(new(model.NeckRing)).
- Where("pasture_id = ?", pastureId).
- Where("is_bind = ?", pasturePb.IsShow_Ok).
- Where("wear_at <= ?", minIsBindDate).
- Find(&neckRingList).Error; err != nil {
- zaplog.Error("NeckRingErrorOfNoSignal", zap.Any("err", err), zap.Any("pastureId", pastureId))
- }
- updateNeckRingMap := make(map[int64]*model.NeckRingStats)
- errorMap := e.NeckRingErrorMap()
- for _, neckRing := range neckRingList {
- var info bool
- // 佩戴后无信号
- c1 := e.NeckRingErrorOfNoSignal(pastureId, neckRing, int64(habitMinId), yesterday)
- if c1 > 0 {
- updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
- Status: pasturePb.IsShow_No,
- ErrorKind: c1,
- ErrorReason: errorMap[c1],
- Describe: "",
- }
- }
- // '疑似脱落', '电量低','接收少'
- c2 := e.NeckRingErrorOfSuspectedFallOffAndLowBattery(pastureId, neckRing, int64(habitMinId), yesterday)
- if c2 > 0 {
- updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
- Status: pasturePb.IsShow_No,
- ErrorKind: c2,
- ErrorReason: errorMap[c2],
- Describe: "",
- }
- }
- // 接收少
- c3 := e.NeckRingErrorOfReceivingLess(pastureId, neckRing, int64(habitMinId), int64(originalMinId), yesterday)
- if c3 > 0 {
- updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
- Status: pasturePb.IsShow_No,
- ErrorKind: c3,
- ErrorReason: errorMap[c3],
- Describe: "",
- }
- }
- // 数据延迟
- c4 := e.NeckRingErrorOfDataLatency(pastureId, neckRing, int64(habitMinId), yesterday)
- if c4 > 0 {
- updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
- Status: pasturePb.IsShow_No,
- ErrorKind: c4,
- ErrorReason: errorMap[c4],
- Describe: "",
- }
- }
- if c1 > 0 || c2 > 0 || c3 > 0 || c4 > 0 {
- info = true
- }
- if !info {
- updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
- Status: pasturePb.IsShow_Ok,
- ErrorKind: 0,
- ErrorReason: "",
- Describe: "",
- }
- }
- }
- if len(updateNeckRingMap) > 0 {
- for id, v := range updateNeckRingMap {
- if err := e.DB.Model(new(model.NeckRing)).
- Where("id = ?", id).
- Updates(map[string]interface{}{
- "status": v.Status,
- "error_kind": v.ErrorKind,
- "error_reason": v.ErrorReason,
- "describe": v.Describe,
- }).Error; err != nil {
- zaplog.Error("CowNeckRingError", zap.Any("err", err), zap.Any("id", id), zap.Any("v", v))
- }
- }
- }
- }
- // NeckRingErrorOfNoSignal 佩戴后无信号
- func (e *Entry) NeckRingErrorOfNoSignal(pastureId int64, neckRing *model.NeckRing, minId int64, dateTime string) pasturePb.NeckRingNumberError_Kind {
- var count int64
- if err := e.DB.Model(new(model.NeckActiveHabit)).
- Where("id >= ?", minId).
- Where("neck_ring_number = ?", neckRing.NeckRingNumber).
- Where("pasture_id = ?", pastureId).
- Where("heat_date >= ?", dateTime).
- Count(&count).Error; err != nil {
- zaplog.Error("NeckRingErrorOfNoSignal", zap.Any("err", err), zap.Any("pastureId", pastureId))
- }
- if count <= 0 {
- return pasturePb.NeckRingNumberError_No_Signal
- }
- return pasturePb.NeckRingNumberError_Invalid
- }
- // NeckRingErrorOfSuspectedFallOffAndLowBattery '疑似脱落', '电量低','接收少'
- func (e *Entry) NeckRingErrorOfSuspectedFallOffAndLowBattery(pastureId int64, neckRing *model.NeckRing, minId int64, dateTime string) pasturePb.NeckRingNumberError_Kind {
- nowTime := time.Now().Local()
- neckRingHabitList := make([]*model.NeckActiveHabit, 0)
- if err := e.DB.Model(new(model.NeckActiveHabit)).
- Where("id >= ?", minId).
- Where("neck_ring_number = ?", neckRing.NeckRingNumber).
- Where("pasture_id = ?", pastureId).
- Where("heat_date >= ?", dateTime).
- Find(&neckRingHabitList).Error; err != nil {
- zaplog.Error("suspectedFallOffAndLowBattery", zap.Any("err", err), zap.Any("pastureId", pastureId))
- return pasturePb.NeckRingNumberError_Invalid
- }
- nba, nb1, nbHh, nbh, voltage := 0, 0, 0, 0, int32(0)
- for _, v := range neckRingHabitList {
- nba++
- if v.High <= 50 && v.Rumina <= 5 {
- nb1 += 1
- }
- at := util.DateTimeParseLocalUnix(v.ActiveTime)
- nowTimeUnix := nowTime.Unix()
- hoursDiff := (nowTimeUnix - at) / 3600
- sumRuminaIntake := v.SumRumina + v.SumIntake
- if hoursDiff <= 8 && (v.High > 0 || sumRuminaIntake > 20) {
- nbHh++
- }
- if v.High > 100 || v.Rumina > 5 {
- nbh++
- }
- voltage += v.Voltage
- }
- svgVoltage := int32(float32(voltage) / float32(nba))
- errorKind := pasturePb.NeckRingNumberError_Invalid
- switch {
- case svgVoltage <= 275:
- errorKind = pasturePb.NeckRingNumberError_Low_Battery
- case nb1 >= 4:
- errorKind = pasturePb.NeckRingNumberError_Suspected_Fall_Off
- default:
- errorKind = pasturePb.NeckRingNumberError_Receiving_Less
- }
- if (nb1 >= 4 && nbHh <= 1) || svgVoltage <= 275 || nba <= (5+nowTime.Hour()/4-1) {
- return errorKind
- }
- return pasturePb.NeckRingNumberError_Invalid
- }
- // NeckRingErrorOfReceivingLess '接收少'
- func (e *Entry) NeckRingErrorOfReceivingLess(pastureId int64, neckRing *model.NeckRing, habitMinId, originalMinId int64, dateTime string) pasturePb.NeckRingNumberError_Kind {
- var count int64
- if err := e.DB.Model(new(model.NeckRing)).
- Where("pasture_id = ?", pastureId).
- Where("neck_ring_number = ?", neckRing.NeckRingNumber).
- Where("status = ?", pasturePb.IsShow_No).
- Count(&count).Error; err != nil {
- zaplog.Error("NeckRingErrorOfReceivingLess", zap.Any("err", err), zap.Any("pastureId", pastureId))
- return pasturePb.NeckRingNumberError_Invalid
- }
- // 已存在就不再处理
- if count > 0 {
- return pasturePb.NeckRingNumberError_Invalid
- }
- if err := e.DB.Model(new(model.NeckActiveHabit)).
- Where("id >= ?", habitMinId).
- Where("neck_ring_number = ?", neckRing.NeckRingNumber).
- Where("pasture_id = ?", pastureId).
- Where("heat_date >= ?", dateTime).
- Count(&count).Error; err != nil {
- zaplog.Error("NeckRingErrorOfReceivingLess", zap.Any("err", err), zap.Any("pastureId", pastureId))
- }
- // 已存在就不再处理
- if count > 0 {
- return pasturePb.NeckRingNumberError_Invalid
- }
- // 查询原始活动数据统计信息
- var originalStats struct {
- Count int64
- AvgVoltage float64
- }
- if err := e.DB.Model(new(model.NeckRingOriginal)).
- Select("COUNT(*) as count, ROUND(AVG(voltage)) as avg_voltage").
- Where("id >= ?", originalMinId).
- Where("neck_ring_number = ?", neckRing.NeckRingNumber).
- Where("pasture_id = ?", pastureId).
- Where("heat_date >= ?", dateTime).
- First(&originalStats).Error; err != nil {
- zaplog.Error("NeckRingOriginal", zap.Any("err", err), zap.Any("pasture_id", pastureId))
- return pasturePb.NeckRingNumberError_Invalid
- }
- // 创建错误记录
- errorKind := pasturePb.NeckRingNumberError_Receiving_Less
- if originalStats.AvgVoltage <= 285 {
- errorKind = pasturePb.NeckRingNumberError_Low_Battery
- }
- // 限制最大显示数量为99
- displayCount := originalStats.Count
- if displayCount > 99 {
- displayCount = 99
- }
- if displayCount > 0 {
- return errorKind
- }
- return pasturePb.NeckRingNumberError_Invalid
- }
- // NeckRingErrorOfDataLatency 数据延迟
- func (e *Entry) NeckRingErrorOfDataLatency(pastureId int64, neckRing *model.NeckRing, habitMinId int64, dateTime string) pasturePb.NeckRingNumberError_Kind {
- res := make([]*model.NeckRingErrorModel, 0)
- if err := e.DB.Model(new(model.NeckActiveHabit)).
- Select(`cow_id,ear_number, SUM(IF(TIMESTAMPDIFF(HOUR, UNIX_TIMESTAMP(active_time), created_at)>9, 1, 0)) AS nb, COUNT(1) AS nba, ROUND(AVG(voltage), 0) AS voltage`).
- Where("id >= ?", habitMinId).
- Where("cow_id = ?", neckRing.CowId).
- Where("filter_high > ?", 200).
- Where("heat_date >= ?", dateTime).
- Having("nb/nba >= ?", 0.7).
- Find(&res).Error; err != nil {
- zaplog.Error("NeckRingErrorOfDataLatency", zap.Any("err", err), zap.Any("pastureId", pastureId))
- }
- if len(res) > 0 {
- return pasturePb.NeckRingNumberError_Data_Latency
- }
- return pasturePb.NeckRingNumberError_Invalid
- }
|