Browse Source

crontab: cowNeckRingError update

Yi 3 weeks ago
parent
commit
0077b7611c

+ 7 - 6
config/app.develop.yaml

@@ -46,15 +46,16 @@ cron:
   system_basic_crontab: "0 35 1 * * ?"
   update_disease_to_calendar: "0 50 1 * * ?"
   cow_pregnant: "0 01 15 * * ?"
-  neck_ring_estrus: "0 45 * * * *"     # 每小时的45分钟执行一次
-  neck_ring_merge: "*/60 * * * * ?"      # 合并脖环原始2小时数据(5分钟)
-  neck_ring_calculate: "*/300 * * * * ?"  # 计算脖环数据
+  neck_ring_estrus: "0 45 * * * *"             # 每小时的45分钟执行一次
+  neck_ring_merge: "*/60 * * * * ?"            # 合并脖环原始2小时数据(5分钟)
+  neck_ring_calculate: "*/300 * * * * ?"       # 计算脖环数据
   neck_ring_estrus_warning: "* */30 * * * ?"   # 脖环发情预警(每50分钟执行一次
   neck_ring_health_warning: "* */30 * * * ?"   # 脖环健康预警
   update_pen_behavior: "0 */20 * * * ?"        # 更新栏舍行为数据(20分钟执行一次)
-  update_pen_behavior_daily: "0 50 15 * * ?"  # 更新栏舍饲养监测数据
-  update_milk_original: "0 */30 * * * ?"     # 更新奶厅原始数据(每30分钟执行一次)
-  insert_milk_daily: "0 05 02 * * ?"          # 更新每日奶量和活动量数据
+  update_pen_behavior_daily: "0 50 15 * * ?"   # 更新栏舍饲养监测数据
+  update_milk_original: "0 */30 * * * ?"       # 更新奶厅原始数据(每30分钟执行一次)
+  insert_milk_daily: "0 05 02 * * ?"           # 更新每日奶量和活动量数据
+  cow_neck_ring_error: "0 0 */2 * * ?"         # 异常脖环数据上报
 
 mqtt:
   broker: "kptyun.com:1983"

+ 1 - 0
config/app.go

@@ -74,6 +74,7 @@ type CronSetting struct {
 	UpdateMilkOriginal      string `yaml:"update_milk_original"`       //  奶厅原始数据更新
 	InsertMilkDaily         string `yaml:"insert_milk_daily"`          //  牛只每日奶量数据
 	TwentyOnePregnantRate   string `yaml:"twenty_one_pregnant_rate"`   //  21怀孕率
+	CowNeckRingError        string `yaml:"cow_neck_ring_error"`        //  异常脖环数据
 }
 
 type JwtTokenKeyConfig struct {

+ 5 - 0
dep/di_crontab.go

@@ -82,6 +82,11 @@ func EntryCrontab(dependency CrontabDependency) *cron.Crontab {
 		panic(err)
 	}
 
+	if err := newCrontab.Bind("CowNeckRingErrorEnter", cs.CowNeckRingError, dependency.CrontabHub.CowNeckRingErrorEnter); err != nil {
+		zaplog.Error("EntryCrontab", zap.Any("CowNeckRingErrorEnter", err))
+		panic(err)
+	}
+
 	if err := newCrontab.Bind("UpdateCowEstrus", cs.NeckRingEstrus, dependency.CrontabHub.UpdateCowEstrus); err != nil {
 		zaplog.Error("EntryCrontab", zap.Any("UpdateCowEstrus", err))
 		panic(err)

+ 49 - 0
model/cow_neck_ring_error.go

@@ -0,0 +1,49 @@
+package model
+
+import pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+
+type CowNeckRingError struct {
+	Id              int64                              `json:"id"`
+	PastureId       int64                              `json:"pastureId"`
+	NeckRingNumber  string                             `json:"neckRingNumber"`
+	DateTime        string                             `json:"dateTime"`
+	ErrorKind       pasturePb.NeckRingNumberError_Kind `json:"errorKind"`
+	ErrorName       string                             `json:"errorName"`
+	AcceptedNumber  int64                              `json:"acceptedNumber"`
+	HighNumber      int64                              `json:"highNumber"`
+	CowId           int64                              `json:"cowId"`
+	EarNumber       string                             `json:"earNumber"`
+	PenName         string                             `json:"penName"`
+	Voltage         int32                              `json:"voltage"`
+	FirmwareVersion int32                              `json:"firmwareVersion"`
+	ReceiveNumber   string                             `json:"receiveNumber"`
+	CreatedAt       int64                              `json:"createdAt"`
+	UpdatedAt       int64                              `json:"updatedAt"`
+}
+
+func (c *CowNeckRingError) TableName() string {
+	return "cow_neck_ring_error"
+}
+
+func NewCowNeckRingError(
+	pastureId int64,
+	cowInfo *Cow,
+	errorKind pasturePb.NeckRingNumberError_Kind,
+	errorMap map[pasturePb.NeckRingNumberError_Kind]string,
+) *CowNeckRingError {
+	return &CowNeckRingError{
+		PastureId:       pastureId,
+		NeckRingNumber:  cowInfo.NeckRingNumber,
+		DateTime:        "",
+		ErrorKind:       errorKind,
+		ErrorName:       errorMap[errorKind],
+		AcceptedNumber:  0,
+		HighNumber:      0,
+		CowId:           cowInfo.Id,
+		EarNumber:       cowInfo.EarNumber,
+		PenName:         cowInfo.PenName,
+		Voltage:         0,
+		FirmwareVersion: 0,
+		ReceiveNumber:   "",
+	}
+}

+ 2 - 0
model/neck_active_habit.go

@@ -68,6 +68,7 @@ type NeckActiveHabit struct {
 	Score                int32                 `json:"score"`
 	IsShow               pasturePb.IsShow_Kind `json:"isShow"`
 	Cft                  float32               `json:"cft"`
+	Voltage              int32                 `json:"voltage"`
 	RecordCount          int32                 `json:"recordCount"`
 	FirmwareVersion      int32                 `json:"firmwareVersion"`
 	CreatedAt            int64                 `json:"createdAt"`
@@ -122,6 +123,7 @@ func NewNeckActiveHabit(data *NeckRingOriginalMerge) *NeckActiveHabit {
 		ActiveTime:      fmt.Sprintf("%s %02d:00:00", data.ActiveDate, data.XframeId*2+1),
 		RecordCount:     data.RecordCount,
 		FirmwareVersion: data.FirmwareVersion,
+		Voltage:         data.Voltage,
 	}
 }
 

+ 21 - 13
model/neck_ring.go

@@ -7,19 +7,21 @@ import (
 )
 
 type NeckRing struct {
-	Id             int64                         `json:"id"`
-	PastureId      int64                         `json:"pastureId"`
-	NeckRingNumber string                        `json:"neckRingNumber"`
-	CowId          int64                         `json:"cowId"`
-	EarNumber      string                        `json:"earNumber"`
-	WearAt         int64                         `json:"wearAt"`
-	IsBind         pasturePb.NeckRingIsBind_Kind `json:"isBind"`
-	Status         pasturePb.NeckRingStatus_Kind `json:"status"`
-	ErrorReason    string                        `json:"errorReason"`
-	OperationId    int32                         `json:"operationId"`
-	OperationName  string                        `json:"operationName"`
-	CreatedAt      int64                         `json:"createdAt"`
-	UpdatedAt      int64                         `json:"updatedAt"`
+	Id             int64                              `json:"id"`
+	PastureId      int64                              `json:"pastureId"`
+	NeckRingNumber string                             `json:"neckRingNumber"`
+	CowId          int64                              `json:"cowId"`
+	EarNumber      string                             `json:"earNumber"`
+	WearAt         int64                              `json:"wearAt"`
+	IsBind         pasturePb.NeckRingIsBind_Kind      `json:"isBind"`
+	Status         pasturePb.NeckRingStatus_Kind      `json:"status"`
+	ErrorKind      pasturePb.NeckRingNumberError_Kind `json:"errorKind"`
+	ErrorReason    string                             `json:"errorReason"`
+	Describe       string                             `json:"describe"`
+	OperationId    int32                              `json:"operationId"`
+	OperationName  string                             `json:"operationName"`
+	CreatedAt      int64                              `json:"createdAt"`
+	UpdatedAt      int64                              `json:"updatedAt"`
 }
 
 func (n *NeckRing) TableName() string {
@@ -100,3 +102,9 @@ type NeckRingModel struct {
 	CreatedAt      int64                         `json:"createdAt"`
 	UpdatedAt      int64                         `json:"updatedAt"`
 }
+
+type NeckRingStats struct {
+	ErrorKind   pasturePb.NeckRingNumberError_Kind
+	ErrorReason string `json:"error_reason"`
+	Describe    string `json:"describe"`
+}

+ 3 - 0
model/neck_ring_original.go

@@ -90,6 +90,7 @@ type NeckRingOriginalMerge struct {
 	RecordCount     int32
 	PastureId       int64
 	FirmwareVersion int32
+	Voltage         int32
 	IsShow          pasturePb.IsShow_Kind
 }
 
@@ -115,6 +116,7 @@ func (n *NeckRingOriginalMerge) IsMageData(data *NeckRingOriginal, xframeId int3
 	n.Other += data.Other * avgParam
 	n.Gasp += data.Gasp * avgParam
 	n.High += high
+	n.Voltage += data.Voltage
 	n.ActiveDate = data.ActiveDate
 	n.NeckRingNumber = data.NeckRingNumber
 	n.XframeId = xframeId
@@ -131,6 +133,7 @@ func (n *NeckRingOriginalMerge) SumAvg() {
 	n.Other = int32(float32(n.Other) / float32(n.RecordCount) * float32(n.RecordCount))
 	n.Gasp = int32(float32(n.Gasp) / float32(n.RecordCount) * float32(n.RecordCount))
 	n.High = int32(float32(n.High) / float32(n.RecordCount) * float32(n.RecordCount))
+	n.Voltage = int32(float32(n.Voltage) / float32(n.RecordCount))
 }
 
 type NeckRingOriginalMap map[string]*NeckRingOriginalMerge

+ 261 - 0
module/crontab/cow_neck_ring_error.go

@@ -0,0 +1,261 @@
+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"
+)
+
+func (e *Entry) CowNeckRingErrorEnter() (err error) {
+	pastureList := e.FindPastureList()
+	if pastureList == nil || len(pastureList) == 0 {
+		return nil
+	}
+	for _, pasture := range pastureList {
+		e.DB.Model(new(model.NeckRingError)).Delete(new(model.NeckRingError)).Where("pasture_id = ?", pasture.Id)
+		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("MIN(id) 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("MIN(id) as id").
+		Where("pasture_id = ?", pastureId).
+		Where("heat_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.NeckRingError)).
+		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 {
+		c1 := e.NeckRingErrorOfNoSignal(pastureId, neckRing, int64(habitMinId), yesterday)
+		if c1 > 0 {
+			updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
+				ErrorKind:   c1,
+				ErrorReason: errorMap[c1],
+				Describe:    "",
+			}
+		}
+
+		c2 := e.NeckRingErrorOfSuspectedFallOffAndLowBattery(pastureId, neckRing, int64(habitMinId), yesterday)
+		if c2 > 0 {
+			updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
+				ErrorKind:   c2,
+				ErrorReason: errorMap[c2],
+				Describe:    "",
+			}
+		}
+
+		c3 := e.NeckRingErrorOfReceivingLess(pastureId, neckRing, int64(habitMinId), int64(originalMinId), yesterday)
+		if c3 > 0 {
+			updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
+				ErrorKind:   c3,
+				ErrorReason: errorMap[c3],
+				Describe:    "",
+			}
+		}
+		c4 := e.NeckRingErrorOfDataLatency(pastureId, neckRing, int64(habitMinId), yesterday)
+		if c4 > 0 {
+			updateNeckRingMap[neckRing.Id] = &model.NeckRingStats{
+				ErrorKind:   c4,
+				ErrorReason: errorMap[c4],
+				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":       pasturePb.IsShow_No,
+					"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)).
+		Select(``).
+		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 {
+	var count int64
+	if err := e.DB.Model(new(model.NeckActiveHabit)).
+		Select(`h.cow_id, h.ear_number, SUM(IF(TIMESTAMPDIFF(HOUR, UNIX_TIMESTAMP(h.active_time), h.created_at)>9, 1, 0)) AS nb, COUNT(1) AS nba, ROUND(AVG(h.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).
+		Count(&count).Error; err != nil {
+		zaplog.Error("NeckRingErrorOfDataLatency", zap.Any("err", err), zap.Any("pastureId", pastureId))
+	}
+	if count > 0 {
+		return pasturePb.NeckRingNumberError_Data_Latency
+	}
+	return pasturePb.NeckRingNumberError_Invalid
+}

+ 1 - 2
module/crontab/interface.go

@@ -2,7 +2,6 @@ package crontab
 
 import (
 	"kpt-pasture/config"
-	"kpt-pasture/service/alert"
 	"kpt-pasture/service/asynqsvc"
 	"kpt-pasture/service/redis"
 	"kpt-pasture/store/kptstore"
@@ -19,7 +18,6 @@ type Entry struct {
 	DB          *kptstore.DB
 	AsynqClient asynqsvc.Client
 	Redis       *redis.CacheStoreRedisEntry
-	Alert       *alert.Alert
 }
 
 func NewCrontab(entry Entry) Crontab {
@@ -44,6 +42,7 @@ type Crontab interface {
 	UpdateCowEstrus() error       // 获取牛只疑似发情数据
 	NeckRingEstrusWarning() error // 发情预警
 	NeckRingHealthWarning() error // 健康预警
+	CowNeckRingErrorEnter() error // 异常脖环数据
 
 	UpdatePenBehavior() error      // 栏舍行为数据
 	UpdatePenBehaviorDaily() error // 栏舍饲养监测

+ 50 - 0
module/crontab/other.go

@@ -77,3 +77,53 @@ func (e *Entry) IsExistSameTimeCow(cow *model.Cow, sameTime *model.SameTime) boo
 	}
 	return false
 }
+
+func (e *Entry) NeckRingErrorMap() map[pasturePb.NeckRingNumberError_Kind]string {
+	res := make(map[pasturePb.NeckRingNumberError_Kind]string)
+	for _, v := range e.NeckRingErrorEnumList("") {
+		res[pasturePb.NeckRingNumberError_Kind(v.Value)] = v.Label
+	}
+	return res
+}
+
+func (e *Entry) NeckRingErrorEnumList(isAll string) []*pasturePb.ConfigOptionsList {
+	configOptions := make([]*pasturePb.ConfigOptionsList, 0)
+	if isAll == model.IsAllYes {
+		configOptions = append(configOptions,
+			&pasturePb.ConfigOptionsList{
+				Value:    int32(0),
+				Label:    "全部",
+				Disabled: true,
+			})
+	}
+	configOptions = append(configOptions, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.NeckRingNumberError_Suspected_Fall_Off),
+		Label:    "疑似脱落",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.NeckRingNumberError_No_Signal),
+		Label:    "无信号",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.NeckRingNumberError_Receiving_Less),
+		Label:    "接受率低",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.NeckRingNumberError_Data_Latency),
+		Label:    "数据延迟",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.NeckRingNumberError_Low_Activity_Level),
+		Label:    "活动量低",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.NeckRingNumberError_Abnormal_Wearing),
+		Label:    "佩戴异常",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.NeckRingNumberError_Should_Associated),
+		Label:    "应关联",
+		Disabled: true,
+	})
+	return configOptions
+}