TaskHandle.go 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  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(Task_r.T_class)
  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. var list []Task.TaskData_
  119. ct := copyTime
  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. list = append(list, Task.TaskData_{
  128. T_sn: CopySN,
  129. T_id: CopyID,
  130. T_t: T_t,
  131. T_rh: T_rh,
  132. T_time: ct.Format("2006-01-02 15:04:05"),
  133. })
  134. ct = ct.Add(time.Second * time.Duration(T_saveT))
  135. }
  136. Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
  137. for i, taskData := range list {
  138. Task.InsertTaskData(Task_r.T_task_id, taskData)
  139. if i%100 == 0 {
  140. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", i, len(list))})
  141. }
  142. }
  143. }
  144. }
  145. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  146. // Close the connection
  147. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  148. }
  149. // 自动添加缺失数据,取关联绑定终端平均复制
  150. func (c *TaskDataHandleController) SSE_Automatically_add_missing_data() {
  151. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  152. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  153. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  154. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  155. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  156. Task_r, err := Task.Read_Task(T_task_id)
  157. if err != nil {
  158. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  159. return
  160. }
  161. // 时间间隔 s
  162. T_saveT := 60
  163. // 获取 备注 下面关联设备,数量
  164. var Devicedata_list_MAX int64
  165. Devicedata_list_MAX = 0 //最大值
  166. DeviceClassList_list := Device.Read_DeviceClassList_List_id(Task_r.T_class)
  167. for _, DeviceClassListT_remark_r_list := range DeviceClassList_list {
  168. _, 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)
  169. if Devicedata_list_MAX < cnt {
  170. Devicedata_list_MAX = cnt
  171. }
  172. }
  173. logs.Println("数据标准数量:", Devicedata_list_MAX)
  174. // 选择 数据缺失的终端
  175. for _, DeviceClassList_r := range DeviceClassList_list {
  176. list, cnt := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999)
  177. if Devicedata_list_MAX != cnt {
  178. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: DeviceClassList_r.T_id + " 终端自检数据 ,自检:" + lib.To_string(Devicedata_list_MAX-cnt) + " "})
  179. for i := 0; i < len(list)-1; i++ {
  180. current := list[i].T_time
  181. next := list[i+1].T_time
  182. ct, _ := time.Parse("2006-01-02 15:04:05", current)
  183. nt, _ := time.Parse("2006-01-02 15:04:05", next)
  184. interval := nt.Unix() - ct.Unix()
  185. //logs.Debug("时间间隔:", interval, "保存时间:", saveTime)
  186. //fmt.Println("当前:", current, "下一个:", next)
  187. if int(interval) > T_saveT {
  188. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到自检点 " + current + " ~ " + next + " 开始自检"})
  189. // -------------------- 开始 平均复制到 --------------------
  190. // 获取 备注 下面关联设备,数量
  191. var DeviceClassListT_remark_r_list_MAX int64
  192. DeviceClassListT_remark_r_list_MAX = 0 //最大值
  193. DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(DeviceClassList_r.T_class, DeviceClassList_r.T_remark)
  194. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  195. _, 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)
  196. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  197. if DeviceClassListT_remark_r_list_MAX < cnt {
  198. DeviceClassListT_remark_r_list_MAX = cnt
  199. }
  200. }
  201. // 筛选 符合的数量 终端
  202. SN_List_sn := 9
  203. SN_List_s := "" // 2023282551724643,003|2023282534778895,004|
  204. SN_List_xn := 9
  205. SN_List_x := "" // 2023282551724643,003|2023282534778895,004|
  206. SN_List := "" // 2023282551724643,003|2023282534778895,004|
  207. //SN_List_num := 0 // 数量 只能两个
  208. CopyTime := current //复制的起点 2025-01-07 15:18:00
  209. StartTime := current // 2025-01-07 15:18:00
  210. EndTime := next //2025-01-07 21:17:00
  211. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  212. 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)
  213. if DeviceClassListT_remark_r_list_MAX == cnt {
  214. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  215. //SN_List += DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
  216. //CopyTime = List_data[len(List_data)-1].T_time
  217. //StartTime = List_data[len(List_data)-1].T_time
  218. EndTime = List_data[0].T_time
  219. absc := int(math.Abs(float64(lib.To_int(DeviceClassListT_remark_r_list.T_id) - lib.To_int(DeviceClassList_r.T_id))))
  220. if absc < SN_List_sn {
  221. SN_List_s = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
  222. SN_List_sn = absc
  223. continue
  224. }
  225. if absc < SN_List_xn {
  226. SN_List_x = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
  227. SN_List_xn = absc
  228. continue
  229. }
  230. }
  231. }
  232. logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
  233. if len(SN_List_x) == 0 || len(SN_List_s) == 0 {
  234. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "[" + DeviceClassList_r.T_remark + "] 中没有找到 至少2条 完整可用数据"})
  235. return
  236. }
  237. SN_List = SN_List_s + SN_List_x
  238. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: DeviceClassList_r.T_sn + "|" + DeviceClassList_r.T_id + "开始平均复制到" + SN_List})
  239. // 开始平均复制到
  240. CopySN := DeviceClassList_r.T_sn
  241. CopyID := DeviceClassList_r.T_id
  242. copyTime, _ := lib.TimeStrToTime(CopyTime)
  243. endTime, _ := lib.TimeStrToTime(EndTime)
  244. startTime, _ := lib.TimeStrToTime(StartTime)
  245. CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
  246. SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|")
  247. sn_id1 := strings.Split(SN_List_Split[0], ",")
  248. sn1, id_str1 := sn_id1[0], sn_id1[1]
  249. sn_id2 := strings.Split(SN_List_Split[1], ",")
  250. sn2, id_str2 := sn_id2[0], sn_id2[1]
  251. List1, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
  252. List2, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
  253. num := len(List1)
  254. if len(List2) < len(List1) {
  255. num = len(List2)
  256. }
  257. var list []Task.TaskData_
  258. ct := copyTime
  259. for i := 0; i < num; i++ {
  260. if List1[i].T_time != List2[i].T_time {
  261. 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)})
  262. return
  263. }
  264. T_t := (List1[i].T_t + List2[i].T_t) / 2
  265. T_rh := (List1[i].T_rh + List2[i].T_rh) / 2
  266. list = append(list, Task.TaskData_{
  267. T_sn: CopySN,
  268. T_id: CopyID,
  269. T_t: T_t,
  270. T_rh: T_rh,
  271. T_time: ct.Format("2006-01-02 15:04:05"),
  272. })
  273. ct = ct.Add(time.Second * time.Duration(T_saveT))
  274. }
  275. Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
  276. for i, taskData := range list {
  277. Task.InsertTaskData(Task_r.T_task_id, taskData)
  278. if i%100 == 0 {
  279. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", i, len(list))})
  280. }
  281. }
  282. }
  283. }
  284. }
  285. }
  286. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  287. // Close the connection
  288. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  289. }
  290. // 数据持续时间 x 分钟 没有变化
  291. func (c *TaskDataHandleController) SSE_Continuously_unchanged_data() {
  292. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  293. T_timeout, _ := c.GetInt("T_timeout", 30) // 持续时间
  294. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  295. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  296. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  297. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  298. Task_r, err := Task.Read_Task(T_task_id)
  299. if err != nil {
  300. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  301. return
  302. }
  303. // 获取 备注 下面关联设备,数量
  304. var Devicedata_list_MAX int64
  305. Devicedata_list_MAX = 0 //最大值
  306. DeviceClassList_list := Device.Read_DeviceClassList_List_id(Task_r.T_class)
  307. for _, DeviceClassListT_remark_r_list := range DeviceClassList_list {
  308. _, 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)
  309. if Devicedata_list_MAX < cnt {
  310. Devicedata_list_MAX = cnt
  311. }
  312. }
  313. logs.Println("数据标准数量:", Devicedata_list_MAX)
  314. // 选择 数据缺失的终端
  315. for _, DeviceClassList_r := range DeviceClassList_list {
  316. TaskData_list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999)
  317. var t_data float32
  318. t_data = 0
  319. t_data_num := 0
  320. current := ""
  321. next := ""
  322. for i := 0; i < len(TaskData_list)-1; i++ {
  323. if t_data == TaskData_list[i].T_t {
  324. if t_data_num == 0 {
  325. current = TaskData_list[i].T_time
  326. }
  327. t_data_num += 1
  328. continue
  329. } else {
  330. if t_data_num > T_timeout {
  331. next = TaskData_list[i].T_time
  332. 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)
  333. }
  334. // 清空标致
  335. t_data = TaskData_list[i].T_t
  336. t_data_num = 0
  337. continue
  338. }
  339. }
  340. }
  341. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  342. // Close the connection
  343. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  344. }
  345. // 平均复制到
  346. func CopyFromPositionAverage(c *context.Response, T_task_id string, T_class int, T_remark, T_sn, T_id, current, next string) {
  347. fmt.Println("平均复制到 CopyFromPositionAverage:", T_task_id, T_class, T_remark, T_sn, T_id, current, next)
  348. lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: "找到 " + T_id + " 无数据变化, 时间 " + current + " ~ " + next})
  349. // -------------------- 开始 平均复制到 --------------------
  350. // 时间间隔 s
  351. T_saveT := 60
  352. // 获取 备注 下面关联设备,数量
  353. var DeviceClassListT_remark_r_list_MAX int64
  354. DeviceClassListT_remark_r_list_MAX = 0 //最大值
  355. DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(T_class, T_remark)
  356. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  357. _, 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)
  358. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  359. if DeviceClassListT_remark_r_list_MAX < cnt {
  360. DeviceClassListT_remark_r_list_MAX = cnt
  361. }
  362. }
  363. // 筛选 符合的数量 终端
  364. SN_List := "" // 2023282551724643,003|2023282534778895,004|
  365. SN_List_num := 0 // 数量 只能两个
  366. CopyTime := current //复制的起点 2025-01-07 15:18:00
  367. StartTime := current // 2025-01-07 15:18:00
  368. EndTime := next //2025-01-07 21:17:00
  369. for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r {
  370. _, 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)
  371. if DeviceClassListT_remark_r_list_MAX == cnt {
  372. logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt)
  373. SN_List += DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|"
  374. //CopyTime = List_data[len(List_data)-1].T_time
  375. //StartTime = List_data[len(List_data)-1].T_time
  376. //EndTime = List_data[0].T_time
  377. SN_List_num++
  378. if SN_List_num >= 2 {
  379. break // 数量 只能两个
  380. }
  381. }
  382. }
  383. logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime)
  384. if SN_List_num != 2 {
  385. lib.SseWriteJSON(c, lib.JSONSSE{State: 2, Msg: "[" + T_remark + "] 中没有找到 至少2条 完整可用数据"})
  386. return
  387. }
  388. lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: T_sn + "|" + T_id + "开始平均复制到" + SN_List})
  389. // 开始平均复制到
  390. CopySN := T_sn
  391. CopyID := T_id
  392. copyTime, _ := lib.TimeStrToTime(CopyTime)
  393. endTime, _ := lib.TimeStrToTime(EndTime)
  394. startTime, _ := lib.TimeStrToTime(StartTime)
  395. CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05")
  396. SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|")
  397. sn_id1 := strings.Split(SN_List_Split[0], ",")
  398. sn1, id_str1 := sn_id1[0], sn_id1[1]
  399. sn_id2 := strings.Split(SN_List_Split[1], ",")
  400. sn2, id_str2 := sn_id2[0], sn_id2[1]
  401. List1, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999)
  402. List2, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999)
  403. num := len(List1)
  404. if len(List2) < len(List1) {
  405. num = len(List2)
  406. }
  407. fmt.Println("num:", num)
  408. var TaskData_list []Task.TaskData_
  409. ct := copyTime
  410. for TaskData_i := 0; TaskData_i < num; TaskData_i++ {
  411. if List1[TaskData_i].T_time != List2[TaskData_i].T_time {
  412. 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)})
  413. return
  414. }
  415. T_t := (List1[TaskData_i].T_t + List2[TaskData_i].T_t) / 2
  416. T_rh := (List1[TaskData_i].T_rh + List2[TaskData_i].T_rh) / 2
  417. TaskData_list = append(TaskData_list, Task.TaskData_{
  418. T_sn: CopySN,
  419. T_id: CopyID,
  420. T_t: T_t,
  421. T_rh: T_rh,
  422. T_time: ct.Format("2006-01-02 15:04:05"),
  423. })
  424. ct = ct.Add(time.Second * time.Duration(T_saveT))
  425. }
  426. fmt.Println("TaskData_list:", len(TaskData_list))
  427. Task.DeleteTaskDataByTimeRange(T_task_id, CopySN, CopyID, CopyTime, CopyEndTime)
  428. for taskData_i, taskData := range TaskData_list {
  429. Task.InsertTaskData(T_task_id, taskData)
  430. if taskData_i%100 == 0 {
  431. lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", taskData_i, len(TaskData_list))})
  432. }
  433. }
  434. }
  435. // 绑定点与终端比对 (绑定点数据自检)
  436. func (c *TaskDataHandleController) SSE_Comparison_between_binding_points_and_terminals() {
  437. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  438. T_deviation, _ := c.GetFloat("T_deviation", 1.0) // 持续时间
  439. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  440. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  441. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  442. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  443. Task_r, err := Task.Read_Task(T_task_id)
  444. if err != nil {
  445. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  446. return
  447. }
  448. // -------------------- 温湿度绑定点1 --------------------
  449. 温湿度绑定点1_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点1")
  450. if len(温湿度绑定点1_list) != 1 {
  451. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点1 中找到 " + lib.To_string(len(温湿度绑定点1_list)) + "条,只允许 一条数据!"})
  452. return
  453. }
  454. 监测终端01_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "监测终端01")
  455. if len(监测终端01_list) != 1 {
  456. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "监测终端01 中找到 " + lib.To_string(len(监测终端01_list)) + "条,只允许 一条数据!"})
  457. return
  458. }
  459. 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
  460. if len(结束时间) == 0 {
  461. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
  462. }
  463. if len(结束时间) == 0 {
  464. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
  465. }
  466. if len(结束时间) == 0 {
  467. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
  468. }
  469. if len(结束时间) == 0 {
  470. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
  471. return
  472. }
  473. 开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "运行确认及偏差处理(空载)结束时间")
  474. if len(开始时间) == 0 {
  475. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "运行确认及偏差处理(满载)结束时间")
  476. }
  477. if len(开始时间) == 0 {
  478. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)开始时间")
  479. }
  480. if len(开始时间) == 0 {
  481. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
  482. }
  483. if len(开始时间) == 0 {
  484. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到开始时间 标签!"})
  485. return
  486. }
  487. 温度分布特性的测试与分析_开始时间 := 开始时间
  488. 温度分布特性的测试与分析_结束时间 := 结束时间
  489. fmt.Println("温湿度绑定点1 数据准备:", 温湿度绑定点1_list[0].T_id, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  490. var 温湿度绑定点1vga, 监测终端01vga, vgaca float64
  491. 温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  492. 监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  493. vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
  494. for T_deviation < math.Abs(vgaca) {
  495. // 缩放
  496. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!温湿度绑定点1 平均值:" +
  497. lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  498. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
  499. // 偏移
  500. 温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  501. 监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  502. vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
  503. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!温湿度绑定点1 平均值:" +
  504. lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  505. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((监测终端01vga-温湿度绑定点1vga)*0.8)*100)/100.0)
  506. 温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  507. 监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  508. vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
  509. }
  510. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!温湿度绑定点1 平均值:" + lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ !"})
  511. // -------------------- 温湿度绑定点2 --------------------
  512. 温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2")
  513. if len(温湿度绑定点2_list) != 1 {
  514. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,跳过 温湿度绑定点2"})
  515. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  516. return
  517. }
  518. 监测终端02_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "监测终端02")
  519. if len(监测终端02_list) != 1 {
  520. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "监测终端02 中找到 " + lib.To_string(len(监测终端02_list)) + "条,布点终端异常!"})
  521. return
  522. }
  523. fmt.Println("温湿度绑定点2 数据准备:", 温湿度绑定点2_list[0].T_id, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  524. var 温湿度绑定点2vga, 监测终端02vga float64
  525. 温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  526. 监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  527. vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
  528. for T_deviation < math.Abs(vgaca) {
  529. // 缩放
  530. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!温湿度绑定点2 平均值:" +
  531. lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  532. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
  533. // 偏移
  534. 温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  535. 监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  536. vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
  537. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!温湿度绑定点2 平均值:" +
  538. lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  539. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((监测终端02vga-温湿度绑定点2vga)*0.8)*100)/100.0)
  540. 温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  541. 监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  542. vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
  543. }
  544. //
  545. //lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!温湿度绑定点2 平均值:" + lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ !"})
  546. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  547. // Close the connection
  548. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  549. }
  550. // 绑定点与冷热点比对 (冷热点数据自检)
  551. func (c *TaskDataHandleController) SSE_Compare_binding_points_with_cold_and_hot_spots() {
  552. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  553. T_deviation, _ := c.GetFloat("T_deviation", 1.0) // 持续时间
  554. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  555. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  556. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  557. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  558. Task_r, err := Task.Read_Task(T_task_id)
  559. if err != nil {
  560. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  561. return
  562. }
  563. // ------------------
  564. 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
  565. if len(结束时间) == 0 {
  566. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
  567. }
  568. if len(结束时间) == 0 {
  569. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
  570. }
  571. if len(结束时间) == 0 {
  572. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
  573. }
  574. if len(结束时间) == 0 {
  575. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
  576. return
  577. }
  578. 开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "运行确认及偏差处理(空载)结束时间")
  579. if len(开始时间) == 0 {
  580. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "运行确认及偏差处理(满载)结束时间")
  581. }
  582. if len(开始时间) == 0 {
  583. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)开始时间")
  584. }
  585. if len(开始时间) == 0 {
  586. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
  587. }
  588. if len(开始时间) == 0 {
  589. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到开始时间 标签!"})
  590. return
  591. }
  592. 温度分布特性的测试与分析_开始时间 := 开始时间
  593. 温度分布特性的测试与分析_结束时间 := 结束时间
  594. // 均匀性布点 产品存放区域测点
  595. 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
  596. 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
  597. if len(部点终端_list) <= 2 {
  598. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
  599. return
  600. }
  601. type AVGClassList struct {
  602. T_id string
  603. T_vga float64
  604. }
  605. var AVGClassList_r []AVGClassList
  606. for _, i2 := range 部点终端_list {
  607. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  608. }
  609. // 使用 sort.Slice 对切片进行排序
  610. sort.Slice(AVGClassList_r, func(i, j int) bool {
  611. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  612. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  613. })
  614. fmt.Println("AVGClassList_r:", AVGClassList_r)
  615. // ------- 温湿度绑定点
  616. 温湿度绑定点1_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点1")
  617. if len(温湿度绑定点1_list) != 1 {
  618. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点1 中找到 " + lib.To_string(len(温湿度绑定点1_list)) + "条,布点终端异常!"})
  619. return
  620. }
  621. 温湿度绑定点2_list_is := true
  622. 温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2")
  623. if len(温湿度绑定点2_list) != 1 {
  624. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,将 温湿度绑定点1 设置低点"})
  625. 温湿度绑定点2_list = 温湿度绑定点1_list
  626. 温湿度绑定点2_list_is = false
  627. }
  628. 温湿度绑定点1vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  629. 温湿度绑定点2vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  630. if 温湿度绑定点1vga == 温湿度绑定点2vga {
  631. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点1 与 温湿度绑定点2 平均值相等,将 进行上下偏移处理!"})
  632. 温湿度绑定点1vga += T_deviation / 2
  633. 温湿度绑定点2vga -= T_deviation / 2
  634. T_deviation /= 2
  635. }
  636. var 温湿度绑定点vga_H, 温湿度绑定点vga_L AVGClassList
  637. if 温湿度绑定点1vga > 温湿度绑定点2vga {
  638. 温湿度绑定点vga_H.T_id = 温湿度绑定点1_list[0].T_id
  639. 温湿度绑定点vga_H.T_vga = 温湿度绑定点1vga
  640. 温湿度绑定点vga_L.T_id = 温湿度绑定点2_list[0].T_id
  641. 温湿度绑定点vga_L.T_vga = 温湿度绑定点2vga
  642. } else {
  643. 温湿度绑定点vga_L.T_id = 温湿度绑定点1_list[0].T_id
  644. 温湿度绑定点vga_L.T_vga = 温湿度绑定点1vga
  645. 温湿度绑定点vga_H.T_id = 温湿度绑定点2_list[0].T_id
  646. 温湿度绑定点vga_H.T_vga = 温湿度绑定点2vga
  647. }
  648. fmt.Println("温湿度绑定点:", 温湿度绑定点vga_H, 温湿度绑定点vga_L)
  649. // -------------------- 温湿度绑定点vga_H --------------------
  650. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 高点处理 ------"})
  651. var vgaca float64
  652. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  653. for T_deviation < math.Abs(vgaca) {
  654. // 缩放
  655. 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) +
  656. "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  657. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
  658. // 偏移
  659. // 均匀性布点 产品存放区域测点
  660. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  661. for _, i2 := range 部点终端_list {
  662. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  663. }
  664. // 使用 sort.Slice 对切片进行排序
  665. sort.Slice(AVGClassList_r, func(i, j int) bool {
  666. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  667. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  668. })
  669. fmt.Println("AVGClassList_r:", AVGClassList_r)
  670. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  671. 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) +
  672. "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  673. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
  674. // 均匀性布点 产品存放区域测点
  675. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  676. for _, i2 := range 部点终端_list {
  677. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  678. }
  679. // 使用 sort.Slice 对切片进行排序
  680. sort.Slice(AVGClassList_r, func(i, j int) bool {
  681. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  682. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  683. })
  684. fmt.Println("AVGClassList_r:", AVGClassList_r)
  685. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  686. }
  687. 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) +
  688. "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "})
  689. // -------------------- 温湿度绑定点vga_L --------------------
  690. if !温湿度绑定点2_list_is {
  691. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "低点跳过处理!"})
  692. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  693. return
  694. }
  695. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 低点处理 ------"})
  696. vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  697. for T_deviation < math.Abs(vgaca) {
  698. // 缩放
  699. 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) +
  700. "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  701. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
  702. // 偏移
  703. // 均匀性布点 产品存放区域测点
  704. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  705. for _, i2 := range 部点终端_list {
  706. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  707. }
  708. // 使用 sort.Slice 对切片进行排序
  709. sort.Slice(AVGClassList_r, func(i, j int) bool {
  710. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  711. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  712. })
  713. fmt.Println("AVGClassList_r:", AVGClassList_r)
  714. vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  715. 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) +
  716. "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  717. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
  718. // 均匀性布点 产品存放区域测点
  719. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  720. for _, i2 := range 部点终端_list {
  721. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  722. }
  723. // 使用 sort.Slice 对切片进行排序
  724. sort.Slice(AVGClassList_r, func(i, j int) bool {
  725. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  726. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  727. })
  728. fmt.Println("AVGClassList_r:", AVGClassList_r)
  729. vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  730. }
  731. //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) +
  732. // "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "})
  733. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  734. // Close the connection
  735. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  736. }
  737. // 区间数据校正 (布点区域数据自检)
  738. func (c *TaskDataHandleController) SSE_Interval_data_correction() {
  739. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  740. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  741. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  742. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  743. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  744. Task_r, err := Task.Read_Task(T_task_id)
  745. if err != nil {
  746. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  747. return
  748. }
  749. // ------------------
  750. 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
  751. if len(结束时间) == 0 {
  752. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
  753. }
  754. if len(结束时间) == 0 {
  755. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
  756. }
  757. if len(结束时间) == 0 {
  758. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
  759. }
  760. if len(结束时间) == 0 {
  761. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
  762. return
  763. }
  764. 温度控制范围最小值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最小值")))
  765. 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值")))
  766. if 温度控制范围最小值 == 0 || 温度控制范围最高值 == 0 {
  767. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围 标签值不正确!"})
  768. return
  769. }
  770. // 均匀性布点 产品存放区域测点
  771. 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
  772. 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
  773. if len(部点终端_list) <= 2 {
  774. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
  775. return
  776. }
  777. //List_data, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, 部点终端_list[0].T_sn, 部点终端_list[0].T_id, "", "", 0, 9999)
  778. //开始时间 := List_data[len(List_data) - 1].T_time
  779. 开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "运行确认及偏差处理(空载)开始时间")
  780. if len(开始时间) == 0 {
  781. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "运行确认及偏差处理(满载)开始时间")
  782. }
  783. if len(开始时间) == 0 {
  784. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到开始时间 标签!"})
  785. return
  786. }
  787. type AVGClassList struct {
  788. T_id string
  789. T_max float64
  790. T_min float64
  791. }
  792. var AVGClassList_r []AVGClassList
  793. for _, i2 := range 部点终端_list {
  794. T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  795. T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  796. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_max: T_max, T_min: T_min})
  797. }
  798. fmt.Println("AVGClassList_r:", AVGClassList_r)
  799. fmt.Println("数据准备:", 开始时间, 结束时间, 温度控制范围最小值, 温度控制范围最高值)
  800. // ------- 温湿度绑定点
  801. AVGClassList_is := true
  802. // -------------------- 温湿度绑定点vga_H --------------------
  803. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 进行处理 数据!---"})
  804. for AVGClassList_is {
  805. AVGClassList_is = false
  806. // 准备数据
  807. AVGClassList_r = AVGClassList_r[:0]
  808. for _, i2 := range 部点终端_list {
  809. T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  810. T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  811. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_max: T_max, T_min: T_min})
  812. }
  813. for _, AVGClassList_i := range AVGClassList_r {
  814. var vgaca float64
  815. if AVGClassList_i.T_max > 温度控制范围最高值 {
  816. AVGClassList_is = true
  817. vgaca = math.Round((温度控制范围最高值-AVGClassList_i.T_max)*100) / 100.0
  818. // 缩放
  819. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) +
  820. "℃ " + " 数据偏差: " + lib.To_string(vgaca) + "℃ 设置高:" + lib.To_string(温度控制范围最高值) + "℃"})
  821. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, 0.95)
  822. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, 开始时间, 结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
  823. }
  824. if AVGClassList_i.T_min < 温度控制范围最小值 {
  825. AVGClassList_is = true
  826. vgaca = math.Round((温度控制范围最小值-AVGClassList_i.T_min)*100) / 100.0
  827. // 缩放
  828. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最小值:" + lib.To_string(AVGClassList_i.T_min) +
  829. "℃ " + " 数据偏差: " + lib.To_string(vgaca) + "℃ 设置小:" + lib.To_string(温度控制范围最小值) + "℃"})
  830. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, 0.95)
  831. vgaca += float64(AVGClassList_i.T_min) - (AVGClassList_i.T_min * 0.95)
  832. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, math.Round(((vgaca)*1.2)*100)/100.0)
  833. }
  834. }
  835. if AVGClassList_is {
  836. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 还有 数据需要修改 ------"})
  837. }
  838. }
  839. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  840. // Close the connection
  841. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  842. }
  843. // 数据等比咧缩放 温度 湿度比列
  844. //func DataGeometricScale(T_task_id,SN_List_s,StartTime,EndTime string,Temperature,Humidity float64) {
  845. //
  846. // SN_List := strings.Split(strings.Trim(SN_List_s, "|"), "|")
  847. //
  848. // for _, v := range SN_List {
  849. // sn_id := strings.Split(v, ",")
  850. // if len(sn_id) != 2 {
  851. // continue
  852. // }
  853. // sn, id := sn_id[0], sn_id[1]
  854. //
  855. //
  856. //
  857. // }
  858. //
  859. // return
  860. //}