TaskHandle.go 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  1. package controllers
  2. import (
  3. "ColdVerify_local/lib"
  4. "ColdVerify_local/logs"
  5. "ColdVerify_local/models/Device"
  6. "ColdVerify_local/models/Task"
  7. "ColdVerify_local/models/VerifyTemplate"
  8. "fmt"
  9. beego "github.com/beego/beego/v2/server/web"
  10. "github.com/beego/beego/v2/server/web/context"
  11. "math"
  12. "net/http"
  13. "sort"
  14. "strings"
  15. "time"
  16. )
  17. type TaskDataHandleController struct {
  18. beego.Controller
  19. }
  20. /*
  21. 同区域数据缺失
  22. */
  23. // 测点自检 自动添加缺失终端,取关联绑定终端平均复制
  24. func (c *TaskDataHandleController) SSE_Automatically_add_missing_terminal() {
  25. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  26. println("T_task_id:", T_task_id)
  27. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  28. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  29. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  30. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  31. Task_r, err := Task.Read_Task(T_task_id)
  32. if err != nil {
  33. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  34. return
  35. }
  36. DeviceClassList_r := Device.Read_DeviceClassList_List_id_By_Terminal(Task_r.T_class, false)
  37. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "终端总共:" + lib.To_string(len(DeviceClassList_r)) + " 正在检查自检探头..."})
  38. for _, class_ := range DeviceClassList_r {
  39. _, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, class_.T_sn, class_.T_id, "", "", 0, 1)
  40. if cnt == 0 {
  41. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到" + class_.T_id + class_.T_remark + " 自检探头"})
  42. // 获取 备注 下面关联设备,数量
  43. var DeviceClassListT_remark_r_list_MAX int64
  44. DeviceClassListT_remark_r_list_MAX = 0 //最大值
  45. DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(class_.T_class, class_.T_remark)
  46. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  47. _, cnt = Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
  48. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  49. if DeviceClassListT_remark_r_list_MAX < cnt {
  50. DeviceClassListT_remark_r_list_MAX = cnt
  51. }
  52. }
  53. // 筛选 符合的数量 终端
  54. SN_List_sn := 9
  55. SN_List_s := "" // 2023282551724643,003|2023282534778895,004|
  56. SN_List_xn := 9
  57. SN_List_x := "" // 2023282551724643,003|2023282534778895,004|
  58. SN_List := ""
  59. //SN_List_num := 0 // 数量 只能两个
  60. CopyTime := "" //复制的起点 2025-01-07 15:18:00
  61. StartTime := "" // 2025-01-07 15:18:00
  62. EndTime := "" //2025-01-07 21:17:00
  63. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  64. List_data, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
  65. if len(List_data) == 0 {
  66. //lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: DeviceClassListT_remark_r_list.T_id+"没有找到对应数据!"})
  67. continue
  68. }
  69. if DeviceClassListT_remark_r_list_MAX == cnt {
  70. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  71. CopyTime = List_data[len(List_data)-1].T_time
  72. StartTime = List_data[len(List_data)-1].T_time
  73. EndTime = List_data[0].T_time
  74. absc := int(math.Abs(float64(lib.To_int(DeviceClassListT_remark_r_list.T_id) - lib.To_int(class_.T_id))))
  75. if absc < SN_List_sn {
  76. SN_List_s = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
  77. SN_List_sn = absc
  78. continue
  79. }
  80. if absc < SN_List_xn {
  81. SN_List_x = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
  82. SN_List_xn = absc
  83. continue
  84. }
  85. //SN_List_num++
  86. //if SN_List_num >= 2 {
  87. // break // 数量 只能两个
  88. //}
  89. }
  90. }
  91. logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
  92. if len(SN_List_x) == 0 || len(SN_List_s) == 0 {
  93. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "[" + class_.T_remark + "]中没有找到 至少2条 完整可用数据"})
  94. return
  95. }
  96. SN_List = SN_List_s + SN_List_x
  97. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: class_.T_sn + "|" + class_.T_id + "开始平均复制到" + SN_List})
  98. // 开始平均复制到
  99. CopySN := class_.T_sn
  100. CopyID := class_.T_id
  101. copyTime, _ := lib.TimeStrToTime(CopyTime)
  102. endTime, _ := lib.TimeStrToTime(EndTime)
  103. startTime, _ := lib.TimeStrToTime(StartTime)
  104. // 时间间隔 s
  105. T_saveT := 60
  106. CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
  107. SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|")
  108. sn_id1 := strings.Split(SN_List_Split[0], ",")
  109. sn1, id_str1 := sn_id1[0], sn_id1[1]
  110. sn_id2 := strings.Split(SN_List_Split[1], ",")
  111. sn2, id_str2 := sn_id2[0], sn_id2[1]
  112. List1, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
  113. List2, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
  114. num := len(List1)
  115. if len(List2) < len(List1) {
  116. num = len(List2)
  117. }
  118. ct := copyTime
  119. var valueStrings []string
  120. for i := 0; i < num; i++ {
  121. if List1[i].T_time != List2[i].T_time {
  122. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: fmt.Sprintf("%s【%s】、%s【%s】时间不一致", List1[i].T_id, List1[i].T_time, List2[i].T_id, List2[i].T_time)})
  123. return
  124. }
  125. T_t := (List1[i].T_t + List2[i].T_t) / 2
  126. T_rh := (List1[i].T_rh + List2[i].T_rh) / 2
  127. valueStrings = append(valueStrings, fmt.Sprintf("('%s','%s',%v,%v,'%s')", CopySN, CopyID, T_t, T_rh, ct.Format("2006-01-02 15:04:05")))
  128. ct = ct.Add(time.Second * time.Duration(T_saveT))
  129. }
  130. Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
  131. err = Task.Batch_Adds_TaskData(T_task_id, valueStrings)
  132. if err == nil {
  133. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", len(valueStrings), len(valueStrings))})
  134. }
  135. }
  136. }
  137. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  138. // Close the connection
  139. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  140. }
  141. // 测点数据自检 自动添加缺失数据,取关联绑定终端平均复制
  142. func (c *TaskDataHandleController) SSE_Automatically_add_missing_data() {
  143. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  144. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  145. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  146. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  147. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  148. Task_r, err := Task.Read_Task(T_task_id)
  149. if err != nil {
  150. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  151. return
  152. }
  153. // 时间间隔 s
  154. T_saveT := 60
  155. // 获取 备注 下面关联设备,数量
  156. var Devicedata_list_MAX int64
  157. Devicedata_list_MAX = 0 //最大值
  158. DeviceClassList_list := Device.Read_DeviceClassList_List_id_By_Terminal(Task_r.T_class, false)
  159. for _, DeviceClassListT_remark_r_list := range DeviceClassList_list {
  160. _, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
  161. if Devicedata_list_MAX < cnt {
  162. Devicedata_list_MAX = cnt
  163. }
  164. }
  165. logs.Println("数据标准数量:", Devicedata_list_MAX)
  166. // 选择 数据缺失的终端
  167. for _, DeviceClassList_r := range DeviceClassList_list {
  168. list, cnt := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999)
  169. if Devicedata_list_MAX != cnt {
  170. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: DeviceClassList_r.T_id + " 终端自检数据 ,自检:" + lib.To_string(Devicedata_list_MAX-cnt) + " "})
  171. for i := 0; i < len(list)-1; i++ {
  172. current := list[i].T_time
  173. next := list[i+1].T_time
  174. ct, _ := time.Parse("2006-01-02 15:04:05", current)
  175. nt, _ := time.Parse("2006-01-02 15:04:05", next)
  176. interval := nt.Unix() - ct.Unix()
  177. //logs.Debug("时间间隔:", interval, "保存时间:", saveTime)
  178. //fmt.Println("当前:", current, "下一个:", next)
  179. // 缺一个时间点 补漏
  180. if int(interval) == 2*T_saveT {
  181. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到自检点 " + current + " ~ " + next + " 开始自检"})
  182. t := ct.Add(time.Second * time.Duration(T_saveT)).Format("2006-01-02 15:04:05") //时间临时变量
  183. ttt := (list[i].T_t + list[i+1].T_t) / 2
  184. trht := (list[i].T_rh + list[i+1].T_rh) / 2
  185. Task.InsertTaskData(Task_r.T_task_id, Task.TaskData_{
  186. T_sn: list[i].T_sn,
  187. T_id: list[i].T_id,
  188. T_t: ttt,
  189. T_rh: trht,
  190. T_time: t,
  191. })
  192. continue
  193. }
  194. // 缺的数据大于一个时间点,执行平均复制到
  195. if int(interval) > T_saveT {
  196. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到自检点 " + current + " ~ " + next + " 开始自检"})
  197. // -------------------- 开始 平均复制到 --------------------
  198. // 获取 备注 下面关联设备,数量
  199. var DeviceClassListT_remark_r_list_MAX int64
  200. DeviceClassListT_remark_r_list_MAX = 0 //最大值
  201. DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(DeviceClassList_r.T_class, DeviceClassList_r.T_remark)
  202. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  203. _, cnt = Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
  204. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  205. if DeviceClassListT_remark_r_list_MAX < cnt {
  206. DeviceClassListT_remark_r_list_MAX = cnt
  207. }
  208. }
  209. // 筛选 符合的数量 终端
  210. //SN_List_sn := 9
  211. //SN_List_s := "" // 2023282551724643,003|2023282534778895,004|
  212. //SN_List_xn := 9
  213. //SN_List_x := "" // 2023282551724643,003|2023282534778895,004|
  214. SN_List := "" // 2023282551724643,003|2023282534778895,004|
  215. //SN_List_num := 0 // 数量 只能两个
  216. CopyTime := current //复制的起点 2025-01-07 15:18:00
  217. StartTime := current // 2025-01-07 15:18:00
  218. EndTime := next //2025-01-07 21:17:00
  219. var completeDataDeviceClassList []Device.DeviceClassList
  220. for _, DeviceClassList := range DeviceClassListT_remark_r {
  221. List_data, count := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassList.T_sn, DeviceClassList.T_id, "", "", 0, 9999)
  222. if DeviceClassListT_remark_r_list_MAX == count {
  223. logs.Println(DeviceClassList.T_sn, DeviceClassList.T_id, "数量:", cnt)
  224. EndTime = List_data[0].T_time
  225. completeDataDeviceClassList = append(completeDataDeviceClassList, DeviceClassList)
  226. }
  227. }
  228. logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
  229. if len(completeDataDeviceClassList) < 2 {
  230. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "[" + DeviceClassList_r.T_remark + "] 中没有找到 至少2条 完整可用数据,【请手动处理!】"})
  231. return
  232. }
  233. // -----------开始平均复制到
  234. device := Device.DeviceClassList{
  235. T_id: DeviceClassList_r.T_id,
  236. T_sn: DeviceClassList_r.T_sn,
  237. }
  238. c.SetAdjacentDeviceAVGTaskData(T_task_id, device, completeDataDeviceClassList, StartTime, EndTime)
  239. // -----------开始平均复制到结束
  240. }
  241. }
  242. }
  243. }
  244. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  245. // Close the connection
  246. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  247. }
  248. // 数据持续时间 x 分钟 没有变化
  249. func (c *TaskDataHandleController) SSE_Continuously_unchanged_data() {
  250. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  251. T_timeout, _ := c.GetInt("T_timeout", 30) // 持续时间
  252. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  253. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  254. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  255. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  256. Task_r, err := Task.Read_Task(T_task_id)
  257. if err != nil {
  258. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  259. return
  260. }
  261. // 获取 备注 下面关联设备,数量
  262. var Devicedata_list_MAX int64
  263. Devicedata_list_MAX = 0 //最大值
  264. DeviceClassList_list := Device.Read_DeviceClassList_List_id(Task_r.T_class)
  265. for _, DeviceClassListT_remark_r_list := range DeviceClassList_list {
  266. _, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "", "", 0, 9999)
  267. if Devicedata_list_MAX < cnt {
  268. Devicedata_list_MAX = cnt
  269. }
  270. }
  271. logs.Println("数据标准数量:", Devicedata_list_MAX)
  272. // 选择 数据缺失的终端
  273. for _, DeviceClassList_r := range DeviceClassList_list {
  274. TaskData_list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999)
  275. var t_data float32
  276. t_data = 0
  277. t_data_num := 0
  278. current := ""
  279. next := ""
  280. for i := 0; i < len(TaskData_list)-1; i++ {
  281. if t_data == TaskData_list[i].T_t {
  282. if t_data_num == 0 {
  283. current = TaskData_list[i].T_time
  284. }
  285. t_data_num += 1
  286. continue
  287. } else {
  288. if t_data_num > T_timeout {
  289. next = TaskData_list[i].T_time
  290. CopyFromPositionAverage(c.Ctx.ResponseWriter, Task_r.T_task_id, DeviceClassList_r.T_class, DeviceClassList_r.T_remark, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, current, next)
  291. }
  292. // 清空标致
  293. t_data = TaskData_list[i].T_t
  294. t_data_num = 0
  295. continue
  296. }
  297. }
  298. }
  299. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  300. // Close the connection
  301. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  302. }
  303. // 平均复制到
  304. func CopyFromPositionAverage(c *context.Response, T_task_id string, T_class int, T_remark, T_sn, T_id, current, next string) {
  305. fmt.Println("平均复制到 CopyFromPositionAverage:", T_task_id, T_class, T_remark, T_sn, T_id, current, next)
  306. lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: "找到 " + T_id + " 无数据变化, 时间 " + current + " ~ " + next})
  307. // -------------------- 开始 平均复制到 --------------------
  308. // 时间间隔 s
  309. T_saveT := 60
  310. // 获取 备注 下面关联设备,数量
  311. var DeviceClassListT_remark_r_list_MAX int64
  312. DeviceClassListT_remark_r_list_MAX = 0 //最大值
  313. DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(T_class, T_remark)
  314. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  315. _, cnt := Task.Read_TaskData_ById_List(T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, current, next, 0, 9999)
  316. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  317. if DeviceClassListT_remark_r_list_MAX < cnt {
  318. DeviceClassListT_remark_r_list_MAX = cnt
  319. }
  320. }
  321. // 筛选 符合的数量 终端
  322. SN_List := "" // 2023282551724643,003|2023282534778895,004|
  323. SN_List_num := 0 // 数量 只能两个
  324. CopyTime := current //复制的起点 2025-01-07 15:18:00
  325. StartTime := current // 2025-01-07 15:18:00
  326. EndTime := next //2025-01-07 21:17:00
  327. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  328. _, cnt := Task.Read_TaskData_ById_List(T_task_id, DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, current, next, 0, 9999)
  329. if DeviceClassListT_remark_r_list_MAX == cnt {
  330. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  331. SN_List += DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
  332. //CopyTime = List_data[len(List_data)-1].T_time
  333. //StartTime = List_data[len(List_data)-1].T_time
  334. //EndTime = List_data[0].T_time
  335. SN_List_num++
  336. if SN_List_num >= 2 {
  337. break // 数量 只能两个
  338. }
  339. }
  340. }
  341. logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
  342. if SN_List_num != 2 {
  343. lib.SseWriteJSON(c, lib.JSONSSE{State: 2, Msg: "[" + T_remark + "] 中没有找到 至少2条 完整可用数据"})
  344. return
  345. }
  346. lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: T_sn + "|" + T_id + "开始平均复制到" + SN_List})
  347. // 开始平均复制到
  348. CopySN := T_sn
  349. CopyID := T_id
  350. copyTime, _ := lib.TimeStrToTime(CopyTime)
  351. endTime, _ := lib.TimeStrToTime(EndTime)
  352. startTime, _ := lib.TimeStrToTime(StartTime)
  353. CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
  354. SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|")
  355. sn_id1 := strings.Split(SN_List_Split[0], ",")
  356. sn1, id_str1 := sn_id1[0], sn_id1[1]
  357. sn_id2 := strings.Split(SN_List_Split[1], ",")
  358. sn2, id_str2 := sn_id2[0], sn_id2[1]
  359. List1, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
  360. List2, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
  361. num := len(List1)
  362. if len(List2) < len(List1) {
  363. num = len(List2)
  364. }
  365. fmt.Println("num:", num)
  366. ct := copyTime
  367. var valueStrings []string
  368. for TaskData_i := 0; TaskData_i < num; TaskData_i++ {
  369. if List1[TaskData_i].T_time != List2[TaskData_i].T_time {
  370. lib.SseWriteJSON(c, lib.JSONSSE{State: 2, Msg: fmt.Sprintf("%s【%s】、%s【%s】时间不一致", List1[TaskData_i].T_id, List1[TaskData_i].T_time, List2[TaskData_i].T_id, List2[TaskData_i].T_time)})
  371. return
  372. }
  373. T_t := (List1[TaskData_i].T_t + List2[TaskData_i].T_t) / 2
  374. T_rh := (List1[TaskData_i].T_rh + List2[TaskData_i].T_rh) / 2
  375. valueStrings = append(valueStrings, fmt.Sprintf("('%s','%s',%v,%v,'%s')", CopySN, CopyID, T_t, T_rh, ct.Format("2006-01-02 15:04:05")))
  376. ct = ct.Add(time.Second * time.Duration(T_saveT))
  377. }
  378. Task.DeleteTaskDataByTimeRange(T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
  379. err := Task.Batch_Adds_TaskData(T_task_id, valueStrings)
  380. if err == nil {
  381. lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", len(valueStrings), len(valueStrings))})
  382. }
  383. }
  384. // 绑定点与终端比对 (绑定点数据自检) 终端数据为参照物,绑定点数据在终端偏差±1℃,保温箱为±0.5℃
  385. func (c *TaskDataHandleController) SSE_Comparison_between_binding_points_and_terminals() {
  386. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  387. T_deviation, _ := c.GetFloat("T_deviation", 1.0) // 误差绑定点数据与终端对比偏差
  388. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  389. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  390. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  391. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  392. Task_r, err := Task.Read_Task(T_task_id)
  393. if err != nil {
  394. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  395. return
  396. }
  397. // 保温箱偏差为0.5
  398. if Task_r.T_device_type == "X" {
  399. T_deviation = 0.5
  400. }
  401. // -------------------- 获取开始时间--------------------
  402. 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值")))
  403. if 温度控制范围最高值 == 0 {
  404. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围最高值 标签值不正确!"})
  405. return
  406. }
  407. // 均匀性布点 产品存放区域测点
  408. 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
  409. 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
  410. 部点终端_list = Device.DeduplicateById(部点终端_list)
  411. if len(部点终端_list) <= 2 {
  412. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
  413. return
  414. }
  415. 开始时间 := ""
  416. // 开始时间 获取温度下降到第二个低点时间
  417. // 1. 获取温度平均值
  418. 部点终端_sn_list := []string{}
  419. for _, v := range 部点终端_list {
  420. 部点终端_sn_list = append(部点终端_sn_list, v.T_sn)
  421. }
  422. list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, strings.Join(部点终端_sn_list, "|"), "", "")
  423. if len(list) < 2 {
  424. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点+产品存放区域测点 数据平均值 少于2条!"})
  425. return
  426. }
  427. // 找平均值低于温度控制范围最高值的第二个最低点
  428. lowPoint := 0
  429. for i := 1; i <= len(list)-2; i++ {
  430. if list[i].T_t < list[i-1].T_t && list[i].T_t < list[i+1].T_t && list[i].T_t < float32(温度控制范围最高值) {
  431. lowPoint += 1
  432. }
  433. if lowPoint == 2 {
  434. 开始时间 = list[i].T_time
  435. break
  436. }
  437. }
  438. if len(开始时间) == 0 {
  439. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 开始时间 数据!"})
  440. return
  441. }
  442. // -------------------- 获取开始时间结束 --------------------
  443. 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
  444. if len(结束时间) == 0 {
  445. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
  446. }
  447. if len(结束时间) == 0 {
  448. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "现场测试结束时间")
  449. }
  450. if len(结束时间) == 0 {
  451. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
  452. return
  453. }
  454. 监测终端_list := Device.Read_DeviceClassList_List_id_By_Terminal(Task_r.T_class, true)
  455. if len(监测终端_list) < 1 {
  456. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 监测终端!"})
  457. }
  458. // 查询监测终端开始时间
  459. for i, 监测终端 := range 监测终端_list {
  460. // -------------------- 温湿度绑定点 --------------------
  461. 温湿度绑定点_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点"+lib.To_string(i+1))
  462. if len(温湿度绑定点_list) != 1 {
  463. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点" + lib.To_string(i+1) + " 中找到 " + lib.To_string(len(温湿度绑定点_list)) + "条,只允许 一条数据!"})
  464. }
  465. fmt.Println("温湿度绑定点"+lib.To_string(i+1)+"数据准备:", 温湿度绑定点_list[0].T_id, 监测终端.T_id, 开始时间, 结束时间)
  466. var 温湿度绑定点vga, 监测终端vga, vgaca float64
  467. 温湿度绑定点vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点_list[0].T_sn, 温湿度绑定点_list[0].T_id, 开始时间, 结束时间)
  468. 监测终端vga = Task.Read_TaskData_AVG(T_task_id, 监测终端.T_sn, 监测终端.T_id, 开始时间, 结束时间)
  469. vgaca = RoundToDecimal(监测终端vga-温湿度绑定点vga, 1)
  470. for T_deviation < math.Abs(vgaca) {
  471. // 缩放
  472. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!" +
  473. "温湿度绑定点" + lib.To_string(i+1) + " 平均值:" + lib.To_string(温湿度绑定点vga) + "℃ " +
  474. "监测终端0" + lib.To_string(i+1) + " 平均值" + lib.To_string(监测终端vga) + "℃ " +
  475. "数据偏差: " + lib.To_string(vgaca) + "℃ " +
  476. "设置:" + lib.To_string(T_deviation) + "℃"})
  477. // 获取缩放度
  478. compress := RoundToDecimal((监测终端vga-T_deviation-0.1)/温湿度绑定点vga, 2)
  479. // 缩放
  480. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点_list[0].T_id, "", "", compress)
  481. // 偏移
  482. 温湿度绑定点vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点_list[0].T_sn, 温湿度绑定点_list[0].T_id, 开始时间, 结束时间)
  483. 监测终端vga = Task.Read_TaskData_AVG(T_task_id, 监测终端.T_sn, 监测终端.T_id, 开始时间, 结束时间)
  484. vgaca = math.Round((监测终端vga-温湿度绑定点vga)*100) / 100.0
  485. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!" +
  486. "温湿度绑定点1 平均值:" + lib.To_string(温湿度绑定点vga) + "℃ " +
  487. "监测终端0" + lib.To_string(i+1) + " 平均值" + lib.To_string(监测终端vga) + "℃ " +
  488. "数据偏差: " + lib.To_string(vgaca) + "℃ " +
  489. "设置:" + lib.To_string(T_deviation) + "℃"})
  490. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点_list[0].T_id, "", "", math.Round(((监测终端vga-温湿度绑定点vga)*0.8)*100)/100.0)
  491. 温湿度绑定点vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点_list[0].T_sn, 温湿度绑定点_list[0].T_id, 开始时间, 结束时间)
  492. 监测终端vga = Task.Read_TaskData_AVG(T_task_id, 监测终端.T_sn, 监测终端.T_id, 开始时间, 结束时间)
  493. vgaca = RoundToDecimal(监测终端vga-温湿度绑定点vga, 1)
  494. }
  495. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!" +
  496. "温湿度绑定点" + lib.To_string(i+1) + " 平均值:" + lib.To_string(温湿度绑定点vga) + "℃ " +
  497. "监测终端0" + lib.To_string(i+1) + " 平均值" + lib.To_string(监测终端vga) + "℃ " +
  498. "数据偏差: " + lib.To_string(vgaca) + "℃ !"})
  499. }
  500. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  501. // Close the connection
  502. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  503. }
  504. // 绑定点与冷热点比对 (冷热点数据自检)绑定点数据为参照物,绑定点数据在终端偏差±1℃,保温箱为±0.5℃
  505. func (c *TaskDataHandleController) SSE_Compare_binding_points_with_cold_and_hot_spots() {
  506. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  507. T_deviation, _ := c.GetFloat("T_deviation", 1.0) // 偏差时间
  508. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  509. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  510. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  511. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  512. Task_r, err := Task.Read_Task(T_task_id)
  513. if err != nil {
  514. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  515. return
  516. }
  517. // 保温箱偏差为0.5
  518. if Task_r.T_device_type == "X" {
  519. T_deviation = 0.5
  520. }
  521. 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值")))
  522. if 温度控制范围最高值 == 0 {
  523. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围最高值 标签值不正确!"})
  524. return
  525. }
  526. // 均匀性布点 产品存放区域测点
  527. 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
  528. 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
  529. 部点终端_list = Device.DeduplicateById(部点终端_list)
  530. 开始时间 := ""
  531. // 开始时间 获取温度下降到第二个低点时间
  532. // 1. 获取温度平均值
  533. 部点终端_sn_list := []string{}
  534. for _, v := range 部点终端_list {
  535. 部点终端_sn_list = append(部点终端_sn_list, v.T_sn)
  536. }
  537. list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, strings.Join(部点终端_sn_list, "|"), "", "")
  538. if len(list) < 2 {
  539. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点+产品存放区域测点 数据平均值 少于2条!"})
  540. return
  541. }
  542. // 找平均值低于温度控制范围最高值的第二个最低点
  543. lowPoint := 0
  544. for i := 1; i <= len(list)-2; i++ {
  545. if list[i].T_t < list[i-1].T_t && list[i].T_t < list[i+1].T_t && list[i].T_t < float32(温度控制范围最高值) {
  546. lowPoint += 1
  547. }
  548. if lowPoint == 2 {
  549. 开始时间 = list[i].T_time
  550. break
  551. }
  552. }
  553. if len(开始时间) == 0 {
  554. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 开始时间 数据!"})
  555. return
  556. }
  557. // ------------------
  558. 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
  559. if len(结束时间) == 0 {
  560. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
  561. }
  562. if len(结束时间) == 0 {
  563. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "现场测试结束时间")
  564. }
  565. if len(结束时间) == 0 {
  566. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
  567. return
  568. }
  569. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 开始时间--- " + 开始时间})
  570. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 结束时间--- " + 结束时间})
  571. if len(部点终端_list) <= 2 {
  572. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
  573. return
  574. }
  575. type AVGClassList struct {
  576. T_id string
  577. T_vga float64
  578. }
  579. var AVGClassList_r []AVGClassList
  580. for _, i2 := range 部点终端_list {
  581. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)})
  582. }
  583. // 使用 sort.Slice 对切片进行排序
  584. sort.Slice(AVGClassList_r, func(i, j int) bool {
  585. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  586. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  587. })
  588. fmt.Println("AVGClassList_r:", AVGClassList_r)
  589. // ------- 温湿度绑定点
  590. 温湿度绑定点1_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点1")
  591. if len(温湿度绑定点1_list) != 1 {
  592. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点1 中找到 " + lib.To_string(len(温湿度绑定点1_list)) + "条,布点终端异常!"})
  593. return
  594. }
  595. 温湿度绑定点2_list_is := true
  596. 温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2")
  597. if len(温湿度绑定点2_list) != 1 {
  598. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,将 温湿度绑定点1 设置低点"})
  599. 温湿度绑定点2_list = 温湿度绑定点1_list
  600. 温湿度绑定点2_list_is = false
  601. }
  602. 温湿度绑定点1vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 开始时间, 结束时间)
  603. 温湿度绑定点2vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 开始时间, 结束时间)
  604. if 温湿度绑定点1vga == 温湿度绑定点2vga {
  605. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点1 与 温湿度绑定点2 平均值相等,将 进行上下偏移处理!"})
  606. 温湿度绑定点1vga += T_deviation / 2
  607. 温湿度绑定点2vga -= T_deviation / 2
  608. T_deviation /= 2
  609. }
  610. var 温湿度绑定点vga_H, 温湿度绑定点vga_L AVGClassList
  611. if 温湿度绑定点1vga > 温湿度绑定点2vga {
  612. 温湿度绑定点vga_H.T_id = 温湿度绑定点1_list[0].T_id
  613. 温湿度绑定点vga_H.T_vga = 温湿度绑定点1vga
  614. 温湿度绑定点vga_L.T_id = 温湿度绑定点2_list[0].T_id
  615. 温湿度绑定点vga_L.T_vga = 温湿度绑定点2vga
  616. } else {
  617. 温湿度绑定点vga_L.T_id = 温湿度绑定点1_list[0].T_id
  618. 温湿度绑定点vga_L.T_vga = 温湿度绑定点1vga
  619. 温湿度绑定点vga_H.T_id = 温湿度绑定点2_list[0].T_id
  620. 温湿度绑定点vga_H.T_vga = 温湿度绑定点2vga
  621. }
  622. fmt.Println("温湿度绑定点:", 温湿度绑定点vga_H, 温湿度绑定点vga_L)
  623. // -------------------- 温湿度绑定点vga_H --------------------
  624. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 高点处理 ------"})
  625. var vgaca float64
  626. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  627. for T_deviation < math.Abs(vgaca) {
  628. // 缩放
  629. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!热点" + lib.To_string(AVGClassList_r[0].T_id) +
  630. " 平均值:" + lib.To_string(AVGClassList_r[0].T_vga) + "℃ " +
  631. "高点 " + lib.To_string(温湿度绑定点vga_H.T_id) +
  632. " 平均值" + lib.To_string(fmt.Sprintf("%.2f", 温湿度绑定点vga_H.T_vga)) + "℃ " +
  633. "数据偏差: " + lib.To_string(vgaca) + "℃ " +
  634. "设置:" + lib.To_string(T_deviation) + "℃"})
  635. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[0].T_id, "", "", 0.95)
  636. // 偏移
  637. // 均匀性布点 产品存放区域测点
  638. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  639. for _, i2 := range 部点终端_list {
  640. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)})
  641. }
  642. // 使用 sort.Slice 对切片进行排序
  643. sort.Slice(AVGClassList_r, func(i, j int) bool {
  644. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  645. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  646. })
  647. fmt.Println("AVGClassList_r:", AVGClassList_r)
  648. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  649. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!热点" + lib.To_string(AVGClassList_r[0].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[0].T_vga) +
  650. "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  651. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, "", "", math.Round(((vgaca)*0.8)*100)/100.0)
  652. // 均匀性布点 产品存放区域测点
  653. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  654. for _, i2 := range 部点终端_list {
  655. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)})
  656. }
  657. // 使用 sort.Slice 对切片进行排序
  658. sort.Slice(AVGClassList_r, func(i, j int) bool {
  659. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  660. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  661. })
  662. fmt.Println("AVGClassList_r:", AVGClassList_r)
  663. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  664. }
  665. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "热点 数据满足要求!" +
  666. "热点" + lib.To_string(AVGClassList_r[0].T_id) +
  667. " 平均值:" + lib.To_string(AVGClassList_r[0].T_vga) + "℃ " +
  668. "高点 " + lib.To_string(温湿度绑定点vga_H.T_id) +
  669. " 平均值" + lib.To_string(fmt.Sprintf("%.2f", 温湿度绑定点vga_H.T_vga)) + "℃ " +
  670. "数据偏差: " + lib.To_string(vgaca) + "℃ "})
  671. // -------------------- 温湿度绑定点vga_L --------------------
  672. if !温湿度绑定点2_list_is {
  673. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "低点跳过处理!"})
  674. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  675. return
  676. }
  677. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 低点处理 ------"})
  678. vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  679. for T_deviation < math.Abs(vgaca) {
  680. // 缩放
  681. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!" +
  682. "冷点" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_id) +
  683. " 平均值:" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_vga) + "℃ " +
  684. "低点 " + lib.To_string(温湿度绑定点vga_L.T_id) +
  685. " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ " +
  686. "数据偏差: " + lib.To_string(vgaca) + "℃ " +
  687. "设置:" + lib.To_string(T_deviation) + "℃"})
  688. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, "", "", 0.95)
  689. // 偏移
  690. // 均匀性布点 产品存放区域测点
  691. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  692. for _, i2 := range 部点终端_list {
  693. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)})
  694. }
  695. // 使用 sort.Slice 对切片进行排序
  696. sort.Slice(AVGClassList_r, func(i, j int) bool {
  697. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  698. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  699. })
  700. fmt.Println("AVGClassList_r:", AVGClassList_r)
  701. vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  702. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!冷点" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_vga) +
  703. "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  704. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, "", "", math.Round(((vgaca)*0.8)*100)/100.0)
  705. // 均匀性布点 产品存放区域测点
  706. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  707. for _, i2 := range 部点终端_list {
  708. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_vga: Task.Read_TaskData_AVG(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)})
  709. }
  710. // 使用 sort.Slice 对切片进行排序
  711. sort.Slice(AVGClassList_r, func(i, j int) bool {
  712. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  713. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  714. })
  715. fmt.Println("AVGClassList_r:", AVGClassList_r)
  716. vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  717. }
  718. //lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "冷点 数据满足要求!冷点" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_vga) +
  719. // "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "})
  720. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  721. // Close the connection
  722. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  723. }
  724. // 区间数据校正 (布点区域数据自检) 均匀性布点,产品存放区域测点 区间数据超标校正 超标数据偏移到区间内
  725. func (c *TaskDataHandleController) SSE_Interval_data_correction() {
  726. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  727. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  728. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  729. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  730. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  731. Task_r, err := Task.Read_Task(T_task_id)
  732. if err != nil {
  733. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  734. return
  735. }
  736. 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
  737. if len(结束时间) == 0 {
  738. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
  739. }
  740. if len(结束时间) == 0 {
  741. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "现场测试结束时间")
  742. }
  743. if len(结束时间) == 0 {
  744. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
  745. return
  746. }
  747. 温度控制范围最小值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最小值")))
  748. 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值")))
  749. if 温度控制范围最小值 == 0 || 温度控制范围最高值 == 0 {
  750. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围 标签值不正确!"})
  751. return
  752. }
  753. // 均匀性布点 产品存放区域测点
  754. 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
  755. 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
  756. 部点终端_list = Device.DeduplicateById(部点终端_list)
  757. if len(部点终端_list) <= 2 {
  758. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
  759. return
  760. }
  761. 开始时间 := ""
  762. // 开始时间 获取温度下降到第二个低点时间
  763. // 1. 获取温度平均值
  764. 部点终端_sn_list := []string{}
  765. for _, v := range 部点终端_list {
  766. 部点终端_sn_list = append(部点终端_sn_list, v.T_sn)
  767. }
  768. list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, strings.Join(部点终端_sn_list, "|"), "", "")
  769. if len(list) < 2 {
  770. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点+产品存放区域测点 数据平均值 少于2条!"})
  771. return
  772. }
  773. // 找平均值低于温度控制范围最高值的第二个最低点
  774. lowPoint := 0
  775. for i := 1; i <= len(list)-2; i++ {
  776. if list[i].T_t < list[i-1].T_t && list[i].T_t < list[i+1].T_t && list[i].T_t < float32(温度控制范围最高值) {
  777. lowPoint += 1
  778. }
  779. if lowPoint == 2 {
  780. 开始时间 = list[i].T_time
  781. break
  782. }
  783. }
  784. if len(开始时间) == 0 {
  785. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 开始时间 数据!"})
  786. return
  787. }
  788. type AVGClassList struct {
  789. T_sn string
  790. T_id string
  791. T_max float64
  792. T_min float64
  793. T_diff float64 // 最大最小值差异
  794. }
  795. var AVGClassList_r []AVGClassList
  796. for _, i2 := range 部点终端_list {
  797. T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  798. T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  799. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_sn: i2.T_sn, T_id: i2.T_id, T_max: T_max, T_min: T_min, T_diff: T_max - T_min})
  800. }
  801. fmt.Println("AVGClassList_r:", AVGClassList_r)
  802. fmt.Println("数据准备:", 开始时间, 结束时间, 温度控制范围最小值, 温度控制范围最高值)
  803. // -------------------- 温湿度绑定点vga_H --------------------
  804. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 进行处理 数据!---"})
  805. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("开始时间:%s 结束时间:%s", 开始时间, 结束时间)})
  806. for _, AVGClassList_i := range AVGClassList_r {
  807. var vgaca float64
  808. if AVGClassList_i.T_max > 温度控制范围最高值 && AVGClassList_i.T_min < 温度控制范围最小值 {
  809. // 压缩
  810. diff := RoundToDecimal(AVGClassList_i.T_max-AVGClassList_i.T_min, 1)
  811. // 获取压缩度
  812. compress := RoundToDecimal((温度控制范围最高值-温度控制范围最小值-0.4)/diff, 2)
  813. // 压缩
  814. Task.UpdateTaskDataTemperatureAndHumidityByGeometric(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", compress, 1)
  815. // 向上偏移
  816. vgaca = RoundToDecimal(温度控制范围最小值-AVGClassList_i.T_min*compress, 1)
  817. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) +
  818. " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " +
  819. " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " +
  820. " 数据偏差:" + lib.To_string(vgaca) + "℃ " +
  821. " 压缩:" + lib.To_string(compress) +
  822. " 向上偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "})
  823. Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", RoundToDecimal(vgaca+0.1, 1), 0)
  824. }
  825. if (AVGClassList_i.T_max - AVGClassList_i.T_min) > (温度控制范围最高值 - 温度控制范围最小值 - 0.2) {
  826. // 压缩
  827. diff := RoundToDecimal(AVGClassList_i.T_max-AVGClassList_i.T_min, 1)
  828. // 获取压缩度
  829. compress := RoundToDecimal((温度控制范围最高值-温度控制范围最小值-0.4)/diff, 2)
  830. // 压缩
  831. Task.UpdateTaskDataTemperatureAndHumidityByGeometric(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", compress, 1)
  832. // 判断压缩后是否在 温度控制范围最小值-温度控制范围最高值范围内 不做处理
  833. if AVGClassList_i.T_max*compress > 温度控制范围最高值 && AVGClassList_i.T_min*compress < 温度控制范围最小值 {
  834. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) +
  835. " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " +
  836. " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " +
  837. " 压缩:" + lib.To_string(fmt.Sprintf("%.2f", compress)) +
  838. " 压缩后最大值:" + lib.To_string(fmt.Sprintf("%.2f", AVGClassList_i.T_max*compress)) + "℃ " +
  839. " 压缩后最小值:" + lib.To_string(fmt.Sprintf("%.2f", AVGClassList_i.T_min*compress)) + "℃ "})
  840. continue
  841. }
  842. // 压缩后仍高于 温度控制范围最高值,向下偏移
  843. if AVGClassList_i.T_max*compress > 温度控制范围最高值 {
  844. vgaca = RoundToDecimal(AVGClassList_i.T_max*compress-温度控制范围最高值, 1)
  845. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) +
  846. " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " +
  847. " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " +
  848. " 压缩:" + lib.To_string(compress) +
  849. " 压缩后最大值:" + lib.To_string(AVGClassList_i.T_max*compress) + "℃ " +
  850. " 压缩后最小值:" + lib.To_string(AVGClassList_i.T_min*compress) + "℃ " +
  851. " 数据偏差:" + lib.To_string(vgaca) + "℃ " +
  852. " 向下偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "})
  853. Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", -RoundToDecimal(vgaca+0.1, 1), 0)
  854. continue
  855. }
  856. // 压缩后仍低于 温度控制范围最小值,向上偏移
  857. if AVGClassList_i.T_min*compress < 温度控制范围最小值 {
  858. // 向上偏移
  859. vgaca = RoundToDecimal(温度控制范围最小值-AVGClassList_i.T_min*compress, 1)
  860. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) +
  861. " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " +
  862. " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " +
  863. " 压缩:" + lib.To_string(compress) +
  864. " 压缩后最大值:" + lib.To_string(AVGClassList_i.T_max*compress) + "℃ " +
  865. " 压缩后最小值:" + lib.To_string(AVGClassList_i.T_min*compress) + "℃ " +
  866. " 数据偏差:" + lib.To_string(vgaca) + "℃ " +
  867. " 向上偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "})
  868. Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", RoundToDecimal(vgaca+0.1, 1), 0)
  869. }
  870. continue
  871. }
  872. // 向下偏移
  873. if AVGClassList_i.T_max > 温度控制范围最高值 {
  874. vgaca = RoundToDecimal(AVGClassList_i.T_max-温度控制范围最高值, 1)
  875. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) +
  876. " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " +
  877. " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " +
  878. " 数据偏差:" + lib.To_string(vgaca) + "℃ " +
  879. " 向下偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "})
  880. // 偏移
  881. Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", -RoundToDecimal(vgaca+0.1, 1), 0)
  882. continue
  883. }
  884. if AVGClassList_i.T_min < 温度控制范围最小值 {
  885. vgaca = RoundToDecimal(温度控制范围最小值-AVGClassList_i.T_min, 1)
  886. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) +
  887. " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " +
  888. " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " +
  889. " 数据偏差: " + lib.To_string(vgaca) + "℃ " +
  890. " 向上偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "})
  891. Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", RoundToDecimal(vgaca+0.1, 1), 0)
  892. }
  893. }
  894. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  895. // Close the connection
  896. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  897. }
  898. // 获取相邻2个终端值平均复制到
  899. func (c *TaskDataHandleController) SetAdjacentDeviceAVGTaskData(T_task_id string, device Device.DeviceClassList, data []Device.DeviceClassList, StartTime, EndTime string) {
  900. twoDevice := getBeforeAndAfter(device.T_id, data)
  901. sn1, id_str1 := twoDevice[0].T_sn, twoDevice[0].T_id
  902. sn2, id_str2 := twoDevice[1].T_sn, twoDevice[1].T_id
  903. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: device.T_sn + "|" + device.T_id + "开始平均复制到" +
  904. fmt.Sprintf("%s,%s|%s,%s", sn1, id_str1, sn2, id_str2)})
  905. List1, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
  906. List2, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
  907. num := len(List1)
  908. if len(List2) < len(List1) {
  909. num = len(List2)
  910. }
  911. if num == 0 {
  912. return
  913. }
  914. T_saveT := 60
  915. //var list []Task.TaskData_
  916. ct, _ := lib.TimeStrToTime(List1[0].T_time)
  917. var valueStrings []string
  918. for i := 0; i < num; i++ {
  919. if List1[i].T_time != List2[i].T_time {
  920. c.Data["json"] = lib.JSONS{202, fmt.Sprintf("%s【%s】、%s【%s】时间不一致", List1[i].T_id, List1[i].T_time, List2[i].T_id, List2[i].T_time), nil}
  921. c.ServeJSON()
  922. return
  923. //ct = ct.Add(time.Second * time.Duration(T_saveT))
  924. //continue
  925. }
  926. T_t := (List1[i].T_t + List2[i].T_t) / 2
  927. T_rh := (List1[i].T_rh + List2[i].T_rh) / 2
  928. valueStrings = append(valueStrings, fmt.Sprintf("('%s','%s',%v,%v,'%s')", device.T_sn, device.T_id, T_t, T_rh, ct.Format("2006-01-02 15:04:05")))
  929. ct = ct.Add(time.Second * time.Duration(T_saveT))
  930. }
  931. Task.DeleteTaskDataByTimeRange(T_task_id, device.T_sn, device.T_id, StartTime, EndTime)
  932. err := Task.Batch_Adds_TaskData(T_task_id, valueStrings)
  933. if err == nil {
  934. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", len(valueStrings), len(valueStrings))})
  935. }
  936. }
  937. func getBeforeAndAfter(T_id string, data []Device.DeviceClassList) []Device.DeviceClassList {
  938. var result []Device.DeviceClassList
  939. var index int
  940. for i, d := range data {
  941. if d.T_id == T_id {
  942. index = i
  943. break
  944. }
  945. }
  946. if index == 0 {
  947. result = append(result, data[len(data)-1], data[1])
  948. } else if index == len(data)-1 {
  949. result = append(result, data[len(data)-2], data[0])
  950. } else {
  951. result = append(result, data[index-1], data[index+1])
  952. }
  953. return result
  954. }
  955. func RoundToDecimal(num float64, decimal int) float64 {
  956. shift := math.Pow(10, float64(decimal))
  957. return math.Round(num*shift) / shift
  958. }