TaskHandle.go 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  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. 温度分布特性的测试与分析_结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
  461. if len(温度分布特性的测试与分析_开始时间) == 0 || len(温度分布特性的测试与分析_结束时间) == 0 {
  462. 温度分布特性的测试与分析_开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
  463. 温度分布特性的测试与分析_结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
  464. }
  465. if len(温度分布特性的测试与分析_开始时间) == 0 || len(温度分布特性的测试与分析_结束时间) == 0 {
  466. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "请检查 温度分布特性的测试与分析时间!"})
  467. return
  468. }
  469. fmt.Println("温湿度绑定点1 数据准备:", 温湿度绑定点1_list[0].T_id, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  470. var 温湿度绑定点1vga, 监测终端01vga, vgaca float64
  471. 温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  472. 监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  473. vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
  474. for T_deviation < math.Abs(vgaca) {
  475. // 缩放
  476. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!温湿度绑定点1 平均值:" +
  477. lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  478. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
  479. // 偏移
  480. 温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  481. 监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  482. vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
  483. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!温湿度绑定点1 平均值:" +
  484. lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  485. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((监测终端01vga-温湿度绑定点1vga)*0.8)*100)/100.0)
  486. 温湿度绑定点1vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  487. 监测终端01vga = Task.Read_TaskData_AVG(T_task_id, 监测终端01_list[0].T_sn, 监测终端01_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  488. vgaca = math.Round((监测终端01vga-温湿度绑定点1vga)*100) / 100.0
  489. }
  490. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!温湿度绑定点1 平均值:" + lib.To_string(温湿度绑定点1vga) + "℃ 监测终端01vga 平均值" + lib.To_string(监测终端01vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ !"})
  491. // -------------------- 温湿度绑定点2 --------------------
  492. 温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2")
  493. if len(温湿度绑定点2_list) != 1 {
  494. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,跳过 温湿度绑定点2"})
  495. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  496. return
  497. }
  498. 监测终端02_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "监测终端02")
  499. if len(监测终端02_list) != 1 {
  500. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "监测终端02 中找到 " + lib.To_string(len(监测终端02_list)) + "条,布点终端异常!"})
  501. return
  502. }
  503. fmt.Println("温湿度绑定点2 数据准备:", 温湿度绑定点2_list[0].T_id, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  504. var 温湿度绑定点2vga, 监测终端02vga float64
  505. 温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  506. 监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  507. vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
  508. for T_deviation < math.Abs(vgaca) {
  509. // 缩放
  510. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!温湿度绑定点2 平均值:" +
  511. lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  512. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
  513. // 偏移
  514. 温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  515. 监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  516. vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
  517. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!温湿度绑定点2 平均值:" +
  518. lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  519. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((监测终端02vga-温湿度绑定点2vga)*0.8)*100)/100.0)
  520. 温湿度绑定点2vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  521. 监测终端02vga = Task.Read_TaskData_AVG(T_task_id, 监测终端02_list[0].T_sn, 监测终端02_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  522. vgaca = math.Round((监测终端02vga-温湿度绑定点2vga)*100) / 100.0
  523. }
  524. //
  525. //lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!温湿度绑定点2 平均值:" + lib.To_string(温湿度绑定点2vga) + "℃ 监测终端02vga 平均值" + lib.To_string(监测终端02vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ !"})
  526. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  527. // Close the connection
  528. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  529. }
  530. // 绑定点与冷热点比对 (冷热点数据自检)
  531. func (c *TaskDataHandleController) SSE_Compare_binding_points_with_cold_and_hot_spots() {
  532. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  533. T_deviation, _ := c.GetFloat("T_deviation", 1.0) // 持续时间
  534. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  535. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  536. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  537. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  538. Task_r, err := Task.Read_Task(T_task_id)
  539. if err != nil {
  540. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  541. return
  542. }
  543. // ------------------
  544. 温度分布特性的测试与分析_开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)开始时间")
  545. 温度分布特性的测试与分析_结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
  546. if len(温度分布特性的测试与分析_开始时间) == 0 || len(温度分布特性的测试与分析_结束时间) == 0 {
  547. 温度分布特性的测试与分析_开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
  548. 温度分布特性的测试与分析_结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
  549. }
  550. // 均匀性布点 产品存放区域测点
  551. 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
  552. 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
  553. if len(部点终端_list) <= 2 {
  554. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
  555. return
  556. }
  557. type AVGClassList struct {
  558. T_id string
  559. T_vga float64
  560. }
  561. var AVGClassList_r []AVGClassList
  562. for _, i2 := range 部点终端_list {
  563. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  564. }
  565. // 使用 sort.Slice 对切片进行排序
  566. sort.Slice(AVGClassList_r, func(i, j int) bool {
  567. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  568. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  569. })
  570. fmt.Println("AVGClassList_r:", AVGClassList_r)
  571. // ------- 温湿度绑定点
  572. 温湿度绑定点1_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点1")
  573. if len(温湿度绑定点1_list) != 1 {
  574. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点1 中找到 " + lib.To_string(len(温湿度绑定点1_list)) + "条,布点终端异常!"})
  575. return
  576. }
  577. 温湿度绑定点2_list_is := true
  578. 温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2")
  579. if len(温湿度绑定点2_list) != 1 {
  580. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,将 温湿度绑定点1 设置低点"})
  581. 温湿度绑定点2_list = 温湿度绑定点1_list
  582. 温湿度绑定点2_list_is = false
  583. }
  584. 温湿度绑定点1vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  585. 温湿度绑定点2vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)
  586. if 温湿度绑定点1vga == 温湿度绑定点2vga {
  587. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点1 与 温湿度绑定点2 平均值相等,将 进行上下偏移处理!"})
  588. 温湿度绑定点1vga += T_deviation / 2
  589. 温湿度绑定点2vga -= T_deviation / 2
  590. T_deviation /= 2
  591. }
  592. var 温湿度绑定点vga_H, 温湿度绑定点vga_L AVGClassList
  593. if 温湿度绑定点1vga > 温湿度绑定点2vga {
  594. 温湿度绑定点vga_H.T_id = 温湿度绑定点1_list[0].T_id
  595. 温湿度绑定点vga_H.T_vga = 温湿度绑定点1vga
  596. 温湿度绑定点vga_L.T_id = 温湿度绑定点2_list[0].T_id
  597. 温湿度绑定点vga_L.T_vga = 温湿度绑定点2vga
  598. } else {
  599. 温湿度绑定点vga_L.T_id = 温湿度绑定点1_list[0].T_id
  600. 温湿度绑定点vga_L.T_vga = 温湿度绑定点1vga
  601. 温湿度绑定点vga_H.T_id = 温湿度绑定点2_list[0].T_id
  602. 温湿度绑定点vga_H.T_vga = 温湿度绑定点2vga
  603. }
  604. fmt.Println("温湿度绑定点:", 温湿度绑定点vga_H, 温湿度绑定点vga_L)
  605. // -------------------- 温湿度绑定点vga_H --------------------
  606. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 高点处理 ------"})
  607. var vgaca float64
  608. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  609. for T_deviation < math.Abs(vgaca) {
  610. // 缩放
  611. 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) +
  612. "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  613. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, 0.95)
  614. // 偏移
  615. // 均匀性布点 产品存放区域测点
  616. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  617. for _, i2 := range 部点终端_list {
  618. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  619. }
  620. // 使用 sort.Slice 对切片进行排序
  621. sort.Slice(AVGClassList_r, func(i, j int) bool {
  622. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  623. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  624. })
  625. fmt.Println("AVGClassList_r:", AVGClassList_r)
  626. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  627. 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) +
  628. "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  629. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
  630. // 均匀性布点 产品存放区域测点
  631. AVGClassList_r = AVGClassList_r[:0] // 清空切片
  632. for _, i2 := range 部点终端_list {
  633. 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, 温度分布特性的测试与分析_开始时间, 温度分布特性的测试与分析_结束时间)})
  634. }
  635. // 使用 sort.Slice 对切片进行排序
  636. sort.Slice(AVGClassList_r, func(i, j int) bool {
  637. return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序
  638. // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga
  639. })
  640. fmt.Println("AVGClassList_r:", AVGClassList_r)
  641. vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0
  642. }
  643. 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) +
  644. "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "})
  645. // -------------------- 温湿度绑定点vga_L --------------------
  646. if !温湿度绑定点2_list_is {
  647. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "低点跳过处理!"})
  648. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  649. return
  650. }
  651. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 低点处理 ------"})
  652. vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].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[len(AVGClassList_r)-1].T_id) + " 平均值:" + lib.To_string(AVGClassList_r[len(AVGClassList_r)-1].T_vga) +
  656. "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  657. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].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_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  671. 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) +
  672. "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"})
  673. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].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_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0
  686. }
  687. //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) +
  688. // "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "})
  689. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  690. // Close the connection
  691. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  692. }
  693. // 区间数据校正 (布点区域数据自检)
  694. func (c *TaskDataHandleController) SSE_Interval_data_correction() {
  695. T_task_id := c.GetString("T_task_id") // v26nplogbwt1
  696. c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
  697. c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
  698. c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
  699. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"})
  700. Task_r, err := Task.Read_Task(T_task_id)
  701. if err != nil {
  702. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"})
  703. return
  704. }
  705. // ------------------
  706. 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开")
  707. if len(结束时间) == 0 {
  708. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开")
  709. }
  710. if len(结束时间) == 0 {
  711. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)结束时间")
  712. }
  713. if len(结束时间) == 0 {
  714. 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)结束时间")
  715. }
  716. if len(结束时间) == 0 {
  717. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"})
  718. return
  719. }
  720. 温度控制范围最小值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最小值")))
  721. 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值")))
  722. if 温度控制范围最小值 == 0 || 温度控制范围最高值 == 0 {
  723. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围 标签值不正确!"})
  724. return
  725. }
  726. // 均匀性布点 产品存放区域测点
  727. 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点")
  728. 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...)
  729. if len(部点终端_list) <= 2 {
  730. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"})
  731. return
  732. }
  733. //List_data, _ := Task.Read_TaskData_ById_List(Task_r.T_task_id, 部点终端_list[0].T_sn, 部点终端_list[0].T_id, "", "", 0, 9999)
  734. //开始时间 := List_data[len(List_data) - 1].T_time
  735. 开始时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(空载)开始时间")
  736. if len(开始时间) == 0 {
  737. 开始时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度分布特性的测试与分析(满载)开始时间")
  738. }
  739. if len(开始时间) == 0 {
  740. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到开始时间 标签!"})
  741. return
  742. }
  743. type AVGClassList struct {
  744. T_id string
  745. T_max float64
  746. T_min float64
  747. }
  748. var AVGClassList_r []AVGClassList
  749. for _, i2 := range 部点终端_list {
  750. T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  751. T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  752. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_max: T_max, T_min: T_min})
  753. }
  754. fmt.Println("AVGClassList_r:", AVGClassList_r)
  755. fmt.Println("数据准备:", 开始时间, 结束时间, 温度控制范围最小值, 温度控制范围最高值)
  756. // ------- 温湿度绑定点
  757. AVGClassList_is := true
  758. // -------------------- 温湿度绑定点vga_H --------------------
  759. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 进行处理 数据!---"})
  760. for AVGClassList_is {
  761. AVGClassList_is = false
  762. // 准备数据
  763. AVGClassList_r = AVGClassList_r[:0]
  764. for _, i2 := range 部点终端_list {
  765. T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  766. T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间)
  767. AVGClassList_r = append(AVGClassList_r, AVGClassList{T_id: i2.T_id, T_max: T_max, T_min: T_min})
  768. }
  769. for _, AVGClassList_i := range AVGClassList_r {
  770. var vgaca float64
  771. if AVGClassList_i.T_max > 温度控制范围最高值 {
  772. AVGClassList_is = true
  773. vgaca = math.Round((温度控制范围最高值-AVGClassList_i.T_max)*100) / 100.0
  774. // 缩放
  775. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) +
  776. "℃ " + " 数据偏差: " + lib.To_string(vgaca) + "℃ 设置高:" + lib.To_string(温度控制范围最高值) + "℃"})
  777. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, 0.95)
  778. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, 开始时间, 结束时间, math.Round(((vgaca)*0.8)*100)/100.0)
  779. }
  780. if AVGClassList_i.T_min < 温度控制范围最小值 {
  781. AVGClassList_is = true
  782. vgaca = math.Round((温度控制范围最小值-AVGClassList_i.T_min)*100) / 100.0
  783. // 缩放
  784. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最小值:" + lib.To_string(AVGClassList_i.T_min) +
  785. "℃ " + " 数据偏差: " + lib.To_string(vgaca) + "℃ 设置小:" + lib.To_string(温度控制范围最小值) + "℃"})
  786. Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, 0.95)
  787. vgaca += float64(AVGClassList_i.T_min) - (AVGClassList_i.T_min * 0.95)
  788. Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_i.T_id, 开始时间, 结束时间, math.Round(((vgaca)*1.2)*100)/100.0)
  789. }
  790. }
  791. if AVGClassList_is {
  792. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 还有 数据需要修改 ------"})
  793. }
  794. }
  795. lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"})
  796. // Close the connection
  797. c.Ctx.ResponseWriter.WriteHeader(http.StatusOK)
  798. }
  799. // 数据等比咧缩放 温度 湿度比列
  800. //func DataGeometricScale(T_task_id,SN_List_s,StartTime,EndTime string,Temperature,Humidity float64) {
  801. //
  802. // SN_List := strings.Split(strings.Trim(SN_List_s, "|"), "|")
  803. //
  804. // for _, v := range SN_List {
  805. // sn_id := strings.Split(v, ",")
  806. // if len(sn_id) != 2 {
  807. // continue
  808. // }
  809. // sn, id := sn_id[0], sn_id[1]
  810. //
  811. //
  812. //
  813. // }
  814. //
  815. // return
  816. //}