neck_active_habit.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. package model
  2. import (
  3. "fmt"
  4. "kpt-pasture/util"
  5. "math"
  6. "strconv"
  7. "strings"
  8. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  9. )
  10. const (
  11. InitChangeFilter = -10000
  12. DefaultChangeFilter = -99
  13. DefaultRuminaFilter = -99
  14. DefaultChewFilter = -99
  15. DefaultFilterCorrect = 100
  16. DefaultWeeklyActive = 1500
  17. DefaultRecordCount = 6
  18. LowActivity = 62
  19. MiddleActivity = 80
  20. )
  21. type NeckActiveHabit struct {
  22. Id int64 `json:"id"`
  23. PastureId int64 `json:"pastureId"`
  24. NeckRingNumber string `json:"neckRingNumber"`
  25. CowId int64 `json:"cowId"`
  26. EarNumber string `json:"earNumber"`
  27. Lact int32 `json:"lact"`
  28. CalvingAge int32 `json:"calvingAge"`
  29. PenId int32 `json:"penId"`
  30. ActiveTime string `json:"activeTime"`
  31. Frameid int32 `json:"frameid"`
  32. HeatDate string `json:"heatDate"`
  33. Rumina int32 `json:"rumina"`
  34. Intake int32 `json:"intake"`
  35. Inactive int32 `json:"inactive"`
  36. Gasp int32 `json:"gasp"`
  37. Other int32 `json:"other"`
  38. High int32 `json:"high"`
  39. Active int32 `json:"active"`
  40. FilterHigh int32 `json:"filterHigh"`
  41. FilterRumina int32 `json:"filterRumina"`
  42. FilterChew int32 `json:"filterChew"`
  43. WeekHigh int32 `json:"weekHigh"`
  44. HighHabit int32 `json:"highHabit"`
  45. RuminaHabit int32 `json:"ruminaHabit"`
  46. IntakeHabit int32 `json:"intakeHabit"`
  47. ChewHabit int32 `json:"chewHabit"`
  48. InactiveHabit int32 `json:"inactiveHabit"`
  49. OtherHabit int32 `json:"otherHabit"`
  50. ChangeHigh int32 `json:"changeHigh"`
  51. ChangeRumina int32 `json:"changeRumina"`
  52. ChangeChew int32 `json:"changeChew"`
  53. ChangeAdjust int32 `json:"changeAdjust"`
  54. ChangeFilter int32 `json:"changeFilter"`
  55. RuminaFilter int32 `json:"ruminaFilter"`
  56. ChewFilter int32 `json:"chewFilter"`
  57. FilterCorrect int32 `json:"filterCorrect"`
  58. SumRumina int32 `json:"sumRumina"`
  59. SumIntake int32 `json:"sumIntake"`
  60. SumInactive int32 `json:"sumInactive"`
  61. SumActive int32 `json:"sumActive"`
  62. SumMinHigh int32 `json:"sumMinHigh"`
  63. SumMaxHigh int32 `json:"sumMaxHigh"`
  64. SumMinChew int32 `json:"SumMinChew"`
  65. BeforeThreeSumRumina int32 `json:"beforeThreeSumRumina"`
  66. BeforeThreeSumIntake int32 `json:"beforeThreeSumIntake"`
  67. Score int32 `json:"score"`
  68. IsShow pasturePb.IsShow_Kind `json:"isShow"`
  69. Cft float32 `json:"cft"`
  70. Voltage int32 `json:"voltage"`
  71. RecordCount int32 `json:"recordCount"`
  72. FirmwareVersion int32 `json:"firmwareVersion"`
  73. CreatedAt int64 `json:"createdAt"`
  74. UpdatedAt int64 `json:"updatedAt"`
  75. }
  76. func (n *NeckActiveHabit) UnShardTableName() string {
  77. return "neck_active_habit"
  78. }
  79. /*func (n *NeckActiveHabit) TableName() string {
  80. return fmt.Sprintf("%s_%06d", n.UnShardTableName(), n.PastureId)
  81. }*/
  82. func (n *NeckActiveHabit) TableName() string {
  83. return "neck_active_habit"
  84. }
  85. func (n *NeckActiveHabit) SumAvg() {
  86. n.Rumina = n.Rumina / n.RecordCount * n.RecordCount
  87. n.Inactive = n.Inactive / n.RecordCount * n.RecordCount
  88. n.Active = n.Active / n.RecordCount * n.RecordCount
  89. n.Intake = n.Intake / n.RecordCount * n.RecordCount
  90. n.Other = n.Other / n.RecordCount * n.RecordCount
  91. n.Gasp = n.Gasp / n.RecordCount * n.RecordCount
  92. n.High = n.High / n.RecordCount * n.RecordCount
  93. }
  94. func (n *NeckActiveHabit) UpdateIsShowOk() {
  95. n.IsShow = pasturePb.IsShow_Ok
  96. }
  97. func NewNeckActiveHabit(data *NeckRingOriginalMerge) *NeckActiveHabit {
  98. return &NeckActiveHabit{
  99. PastureId: data.PastureId,
  100. Frameid: data.XframeId,
  101. HeatDate: data.ActiveDate,
  102. NeckRingNumber: data.NeckRingNumber,
  103. Active: data.Active,
  104. Gasp: data.Gasp,
  105. High: data.High,
  106. Inactive: data.Inactive,
  107. Intake: data.Intake,
  108. Other: data.Other,
  109. Rumina: data.Rumina,
  110. IsShow: data.IsShow,
  111. WeekHigh: DefaultWeeklyActive,
  112. ChangeFilter: InitChangeFilter,
  113. FilterCorrect: InitChangeFilter,
  114. RuminaFilter: InitChangeFilter,
  115. ChewFilter: InitChangeFilter,
  116. ActiveTime: fmt.Sprintf("%s %02d:00:00", data.ActiveDate, data.XframeId*2+1),
  117. RecordCount: data.RecordCount,
  118. FirmwareVersion: data.FirmwareVersion,
  119. Voltage: data.Voltage,
  120. }
  121. }
  122. type NeckActiveHabitSlice []*NeckActiveHabit
  123. func (n NeckActiveHabitSlice) Len() int { return len(n) }
  124. func (n NeckActiveHabitSlice) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
  125. func (n NeckActiveHabitSlice) Less(i, j int) bool {
  126. if n[i].HeatDate != n[j].HeatDate {
  127. return n[i].HeatDate < n[j].HeatDate
  128. }
  129. return n[i].Frameid < n[j].Frameid
  130. }
  131. func (n NeckActiveHabitSlice) ToPB(curveName string) *CowBehaviorCurveData {
  132. res := &CowBehaviorCurveData{
  133. OriginalDateList: make([]int32, 0),
  134. ChangeDateList: make([]int32, 0),
  135. SumDateList: make([]int32, 0),
  136. DateTimeList: make([]string, 0),
  137. EstrusList: make(map[pasturePb.EstrusLevel_Kind][]string),
  138. EventList: make([]*pasturePb.CowEvent, 0),
  139. EventMap: make(map[pasturePb.EventType_Kind]string),
  140. RuminaChange: make([]int32, 0),
  141. IQR1: make([]int32, 0),
  142. IQR3: make([]int32, 0),
  143. }
  144. initFrameId := int32(0)
  145. dateFrameMap := make(map[string][]int32)
  146. for _, v := range n {
  147. if dateFrameMap[v.HeatDate] == nil {
  148. initFrameId = 0
  149. dateFrameMap[v.HeatDate] = make([]int32, 0)
  150. }
  151. // 补全结尾不够的数据
  152. if initFrameId == 0 && len(res.DateTimeList) > 0 {
  153. lastDateTime := res.DateTimeList[len(res.DateTimeList)-1]
  154. lastDatePare := strings.Split(lastDateTime, " ")
  155. if len(lastDatePare) == 2 {
  156. lastDay := lastDatePare[0]
  157. lastHourStr := lastDatePare[1]
  158. lastHour, _ := strconv.ParseInt(lastHourStr, 10, 64)
  159. maxHour := util.ExpectedFrameIDs[len(util.ExpectedFrameIDs)-1]
  160. xframeId := int32(lastHour-1)/2 + 1
  161. if xframeId != maxHour {
  162. for ; xframeId <= maxHour; xframeId++ {
  163. res.DateTimeList = append(res.DateTimeList, fmt.Sprintf("%s %02d", lastDay, util.ExpectedFrameIDs[xframeId]*2+1))
  164. res.OriginalDateList = append(res.OriginalDateList, 0)
  165. res.ChangeDateList = append(res.ChangeDateList, 0)
  166. res.SumDateList = append(res.SumDateList, 0)
  167. res.RuminaChange = append(res.RuminaChange, 0)
  168. res.SumChewList = append(res.SumChewList, 0)
  169. }
  170. }
  171. }
  172. }
  173. expectedFrameId := util.ExpectedFrameIDs[initFrameId]
  174. if expectedFrameId != v.Frameid {
  175. maxFrameId := int32(math.Abs(float64(expectedFrameId - v.Frameid)))
  176. for ; expectedFrameId < maxFrameId; expectedFrameId++ {
  177. res.DateTimeList = append(res.DateTimeList, fmt.Sprintf("%s %02d", v.HeatDate, util.ExpectedFrameIDs[expectedFrameId]*2+1))
  178. res.OriginalDateList = append(res.OriginalDateList, 0)
  179. res.ChangeDateList = append(res.ChangeDateList, 0)
  180. res.SumDateList = append(res.SumDateList, 0)
  181. res.RuminaChange = append(res.RuminaChange, 0)
  182. res.SumChewList = append(res.SumChewList, 0)
  183. }
  184. initFrameId = expectedFrameId
  185. }
  186. // 格式化为到小时的字符串
  187. parsedTime, _ := util.TimeParseLocal(LayoutTime, v.ActiveTime)
  188. hourStr := parsedTime.Format(LayoutHour)
  189. res.DateTimeList = append(res.DateTimeList, hourStr)
  190. switch curveName {
  191. case "active": // 活动量
  192. changeDateList := v.ChangeFilter * v.FilterCorrect / 100
  193. if changeDateList == DefaultChangeFilter {
  194. changeDateList = 0
  195. }
  196. res.OriginalDateList = append(res.OriginalDateList, v.High)
  197. res.ChangeDateList = append(res.ChangeDateList, changeDateList)
  198. res.RuminaChange = append(res.RuminaChange, v.RuminaFilter)
  199. case "rumina": // 反刍
  200. res.OriginalDateList = append(res.OriginalDateList, v.Rumina)
  201. res.ChangeDateList = append(res.ChangeDateList, v.RuminaFilter)
  202. res.SumDateList = append(res.SumDateList, v.SumRumina)
  203. res.SumChewList = append(res.SumChewList, v.SumRumina+v.SumIntake)
  204. case "intake": // 采食
  205. res.OriginalDateList = append(res.OriginalDateList, v.Intake)
  206. res.SumDateList = append(res.SumDateList, v.SumIntake)
  207. res.SumChewList = append(res.SumChewList, v.SumRumina+v.SumIntake)
  208. case "inactive": // 休息
  209. res.OriginalDateList = append(res.OriginalDateList, v.Inactive)
  210. res.SumDateList = append(res.SumDateList, v.SumInactive)
  211. case "chew": // 咀嚼
  212. res.OriginalDateList = append(res.OriginalDateList, v.Rumina+v.Intake)
  213. res.ChangeDateList = append(res.ChangeDateList, v.ChewFilter)
  214. res.SumDateList = append(res.SumDateList, v.SumRumina+v.SumIntake)
  215. case "immobility": // 静止
  216. res.OriginalDateList = append(res.OriginalDateList, 120-v.Active)
  217. res.SumDateList = append(res.SumDateList, 60*24-v.SumActive)
  218. }
  219. initFrameId++
  220. }
  221. return res
  222. }
  223. func (n NeckActiveHabitSlice) ToPB2(dataBetween []string, groupNeckActiveHabitList []*NeckActiveHabit) *pasturePb.CowBehaviorRateData {
  224. data := &pasturePb.CowBehaviorRateData{
  225. DateTime: dataBetween,
  226. RuminaRate: make([]float32, 0),
  227. IntakeRate: make([]float32, 0),
  228. InactiveRate: make([]float32, 0),
  229. GaspRate: make([]float32, 0),
  230. }
  231. neckActiveHabitMap := make(map[string]*NeckActiveHabit)
  232. for _, v := range n {
  233. if v.HeatDate == "" {
  234. continue
  235. }
  236. if _, ok := neckActiveHabitMap[v.HeatDate]; !ok {
  237. neckActiveHabitMap[v.HeatDate] = v
  238. }
  239. }
  240. groupNeckActiveHabitMap := make(map[string]*NeckActiveHabit)
  241. for _, v := range groupNeckActiveHabitList {
  242. if v.HeatDate == "" {
  243. continue
  244. }
  245. if _, ok := groupNeckActiveHabitMap[v.HeatDate]; !ok {
  246. groupNeckActiveHabitMap[v.HeatDate] = v
  247. }
  248. }
  249. for _, t := range dataBetween {
  250. ruminaRate, intakeRate, inactiveRate, gaspRate := float32(0), float32(0), float32(0), float32(0)
  251. if v, ok := neckActiveHabitMap[t]; ok {
  252. sum := v.Rumina + v.Intake + v.Inactive + v.Gasp
  253. if sum > 0 {
  254. // 保留小数点后两位
  255. ruminaRate = float32(math.Round(float64(v.Rumina)/float64(sum)*100) / 100)
  256. intakeRate = float32(math.Round(float64(v.Intake)/float64(sum)*100) / 100)
  257. inactiveRate = float32(math.Round(float64(v.Inactive)/float64(sum)*100) / 100)
  258. gaspRate = float32(math.Round(float64(v.Gasp)/float64(sum)*100) / 100)
  259. }
  260. }
  261. data.RuminaRate = append(data.RuminaRate, ruminaRate)
  262. data.IntakeRate = append(data.IntakeRate, intakeRate)
  263. data.InactiveRate = append(data.InactiveRate, inactiveRate)
  264. data.GaspRate = append(data.GaspRate, gaspRate)
  265. groupRuminaRate, groupIntakeRate, groupInactiveRate, groupGaspRate := float32(0), float32(0), float32(0), float32(0)
  266. if v, ok := groupNeckActiveHabitMap[t]; ok {
  267. groupSum := v.Rumina + v.Intake + v.Inactive + v.Gasp
  268. if groupSum > 0 {
  269. // 保留小数点后两位
  270. groupRuminaRate = float32(math.Round(float64(v.Rumina)/float64(groupSum)*100) / 100)
  271. groupIntakeRate = float32(math.Round(float64(v.Intake)/float64(groupSum)*100) / 100)
  272. groupInactiveRate = float32(math.Round(float64(v.Inactive)/float64(groupSum)*100) / 100)
  273. groupGaspRate = float32(math.Round(float64(v.Gasp)/float64(groupSum)*100) / 100)
  274. }
  275. }
  276. data.GroupRuminaRate = append(data.GroupRuminaRate, groupRuminaRate)
  277. data.GroupIntakeRate = append(data.GroupIntakeRate, groupIntakeRate)
  278. data.GroupInactiveRate = append(data.GroupInactiveRate, groupInactiveRate)
  279. data.GroupGaspRate = append(data.GroupGaspRate, groupGaspRate)
  280. }
  281. return data
  282. }
  283. func (n NeckActiveHabitSlice) ToPBApp() *pasturePb.CowNeckRingAppData {
  284. res := &pasturePb.CowNeckRingAppData{
  285. DateTime: make([]string, 0),
  286. Activity: &pasturePb.ActivityData{
  287. ChangeActivity: make([]int32, 0),
  288. ChangeRumina: make([]int32, 0),
  289. },
  290. Rumina: &pasturePb.RuminaData{
  291. ChangeRumina: make([]int32, 0),
  292. SumRumina: make([]int32, 0),
  293. },
  294. Chew: &pasturePb.ChewData{
  295. ChangeChew: make([]int32, 0),
  296. SumChew: make([]int32, 0),
  297. },
  298. Intake: &pasturePb.SumData{
  299. SumData: make([]int32, 0),
  300. },
  301. Inactive: &pasturePb.SumData{
  302. SumData: make([]int32, 0),
  303. },
  304. Immobility: &pasturePb.SumData{
  305. SumData: make([]int32, 0),
  306. },
  307. Gasp: &pasturePb.SumData{
  308. SumData: make([]int32, 0),
  309. },
  310. EstrusList: make([]string, 0),
  311. EventList: make([]*pasturePb.EventDetail, 0),
  312. }
  313. initFrameId := int32(0)
  314. dateFrameMap := make(map[string][]int32)
  315. for _, v := range n {
  316. if dateFrameMap[v.HeatDate] == nil {
  317. initFrameId = 0
  318. dateFrameMap[v.HeatDate] = make([]int32, 0)
  319. }
  320. // 补全结尾不够的数据
  321. if initFrameId == 0 && len(res.DateTime) > 0 {
  322. lastDateTime := res.DateTime[len(res.DateTime)-1]
  323. lastDatePare := strings.Split(lastDateTime, " ")
  324. if len(lastDatePare) == 2 {
  325. lastDay := lastDatePare[0]
  326. lastHourStr := lastDatePare[1]
  327. lastHour, _ := strconv.ParseInt(lastHourStr, 10, 64)
  328. maxHour := util.ExpectedFrameIDs[len(util.ExpectedFrameIDs)-1]
  329. xframeId := int32(lastHour-1)/2 + 1
  330. if xframeId != maxHour {
  331. for ; xframeId <= maxHour; xframeId++ {
  332. res.DateTime = append(res.DateTime, fmt.Sprintf("%s %02d", lastDay, util.ExpectedFrameIDs[xframeId]*2+1))
  333. res.Activity.ChangeActivity = append(res.Activity.ChangeActivity, 0)
  334. res.Activity.ChangeRumina = append(res.Activity.ChangeRumina, 0)
  335. res.Rumina.ChangeRumina = append(res.Rumina.ChangeRumina, 0)
  336. res.Rumina.SumRumina = append(res.Rumina.SumRumina, 0)
  337. res.Intake.SumData = append(res.Intake.SumData, 0)
  338. res.Inactive.SumData = append(res.Inactive.SumData, 0)
  339. res.Chew.ChangeChew = append(res.Chew.ChangeChew, 0)
  340. res.Chew.SumChew = append(res.Chew.SumChew, 0)
  341. res.Immobility.SumData = append(res.Immobility.SumData, 0)
  342. }
  343. }
  344. }
  345. }
  346. expectedFrameId := util.ExpectedFrameIDs[initFrameId]
  347. if expectedFrameId != v.Frameid {
  348. maxFrameId := int32(math.Abs(float64(expectedFrameId - v.Frameid)))
  349. for ; expectedFrameId < maxFrameId; expectedFrameId++ {
  350. res.DateTime = append(res.DateTime, fmt.Sprintf("%s %02d", v.HeatDate, util.ExpectedFrameIDs[expectedFrameId]*2+1))
  351. res.Activity.ChangeActivity = append(res.Activity.ChangeActivity, 0)
  352. res.Activity.ChangeRumina = append(res.Activity.ChangeRumina, 0)
  353. res.Rumina.ChangeRumina = append(res.Rumina.ChangeRumina, 0)
  354. res.Rumina.SumRumina = append(res.Rumina.SumRumina, 0)
  355. res.Intake.SumData = append(res.Intake.SumData, 0)
  356. res.Inactive.SumData = append(res.Inactive.SumData, 0)
  357. res.Chew.ChangeChew = append(res.Chew.ChangeChew, 0)
  358. res.Chew.SumChew = append(res.Chew.SumChew, 0)
  359. res.Immobility.SumData = append(res.Immobility.SumData, 0)
  360. }
  361. initFrameId = expectedFrameId
  362. }
  363. // 格式化为到小时的字符串
  364. parsedTime, _ := util.TimeParseLocal(LayoutTime, v.ActiveTime)
  365. hourStr := parsedTime.Format(LayoutHour)
  366. res.DateTime = append(res.DateTime, hourStr)
  367. // 活动量
  368. changeDateList := v.ChangeFilter * v.FilterCorrect / 100
  369. if changeDateList == DefaultChangeFilter {
  370. changeDateList = 0
  371. }
  372. res.Activity.ChangeActivity = append(res.Activity.ChangeActivity, changeDateList)
  373. res.Activity.ChangeRumina = append(res.Activity.ChangeRumina, v.RuminaFilter)
  374. // 反刍
  375. res.Rumina.ChangeRumina = append(res.Rumina.ChangeRumina, v.RuminaFilter)
  376. res.Rumina.SumRumina = append(res.Rumina.SumRumina, v.SumRumina)
  377. // 咀嚼
  378. res.Chew.ChangeChew = append(res.Chew.ChangeChew, v.ChewFilter)
  379. res.Chew.SumChew = append(res.Chew.SumChew, v.SumRumina+v.SumIntake)
  380. // 采食
  381. res.Intake.SumData = append(res.Intake.SumData, v.SumRumina+v.SumIntake)
  382. // 休息
  383. res.Inactive.SumData = append(res.Inactive.SumData, v.SumInactive)
  384. // 静止
  385. res.Immobility.SumData = append(res.Immobility.SumData, 60*24-v.SumActive)
  386. initFrameId++
  387. }
  388. return res
  389. }
  390. func (n NeckActiveHabitSlice) ToOriginalDataList(curveName string) (originalDataList []int32, datetimeList []string) {
  391. initFrameId := int32(0)
  392. dateFrameMap := make(map[string][]int32)
  393. for _, v := range n {
  394. if dateFrameMap[v.HeatDate] == nil {
  395. initFrameId = 0
  396. dateFrameMap[v.HeatDate] = make([]int32, 0)
  397. }
  398. // 补全结尾不够的数据
  399. if initFrameId == 0 && len(datetimeList) > 0 {
  400. lastDateTime := datetimeList[len(datetimeList)-1]
  401. lastDatePare := strings.Split(lastDateTime, " ")
  402. if len(lastDatePare) == 2 {
  403. lastDay := lastDatePare[0]
  404. lastHourStr := lastDatePare[1]
  405. lastHour, _ := strconv.ParseInt(lastHourStr, 10, 64)
  406. maxHour := util.ExpectedFrameIDs[len(util.ExpectedFrameIDs)-1]
  407. xframeId := int32(lastHour-1)/2 + 1
  408. if xframeId != maxHour {
  409. for ; xframeId <= maxHour; xframeId++ {
  410. datetimeList = append(datetimeList, fmt.Sprintf("%s %02d", lastDay, util.ExpectedFrameIDs[xframeId]*2+1))
  411. originalDataList = append(originalDataList, 0)
  412. }
  413. }
  414. }
  415. }
  416. expectedFrameId := util.ExpectedFrameIDs[initFrameId]
  417. if expectedFrameId != v.Frameid {
  418. maxFrameId := int32(math.Abs(float64(expectedFrameId - v.Frameid)))
  419. for ; expectedFrameId < maxFrameId; expectedFrameId++ {
  420. datetimeList = append(datetimeList, fmt.Sprintf("%s %02d", v.HeatDate, util.ExpectedFrameIDs[expectedFrameId]*2+1))
  421. originalDataList = append(originalDataList, 0)
  422. }
  423. initFrameId = expectedFrameId
  424. }
  425. // 格式化为到小时的字符串
  426. parsedTime, _ := util.TimeParseLocal(LayoutTime, v.ActiveTime)
  427. hourStr := parsedTime.Format(LayoutHour)
  428. datetimeList = append(datetimeList, hourStr)
  429. switch curveName {
  430. case "active": // 活动量
  431. originalDataList = append(originalDataList, v.High)
  432. case "rumina": // 反刍
  433. originalDataList = append(originalDataList, v.Rumina)
  434. case "intake": // 采食
  435. originalDataList = append(originalDataList, v.Intake)
  436. case "inactive": // 休息
  437. originalDataList = append(originalDataList, v.Inactive)
  438. case "chew": // 咀嚼
  439. originalDataList = append(originalDataList, v.Rumina+v.Intake)
  440. case "immobility": // 静止
  441. originalDataList = append(originalDataList, 120-v.Active)
  442. }
  443. initFrameId++
  444. }
  445. return
  446. }
  447. type MaxHabitIdModel struct {
  448. Id int64 `json:"id"`
  449. }
  450. type WeeklyActiveModel struct {
  451. CowId int64 `json:"cow_id"`
  452. HeatDate string `json:"heat_date"`
  453. Nb int32 `json:"nb"`
  454. High int32 `json:"high"`
  455. }
  456. type NeckRingErrorModel struct {
  457. CowId int64
  458. Nb int32
  459. Nba int32
  460. Voltage int32
  461. }