package controllers import ( "ColdVerify_local/lib" "ColdVerify_local/logs" "ColdVerify_local/models/Device" "ColdVerify_local/models/Task" "ColdVerify_local/models/VerifyTemplate" "fmt" beego "github.com/beego/beego/v2/server/web" "github.com/beego/beego/v2/server/web/context" "math" "net/http" "sort" "strings" "time" ) type TaskDataHandleController struct { beego.Controller } /* 同区域数据缺失 */ // 测点自检 自动添加缺失终端,取关联绑定终端平均复制 func (c *TaskDataHandleController) SSE_Automatically_add_missing_terminal() { T_task_id := c.GetString("T_task_id") // v26nplogbwt1 println("T_task_id:", T_task_id) c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream") c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache") c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive") lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"}) Task_r, err := Task.Read_Task(T_task_id) if err != nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"}) return } DeviceClassList_r := Device.Read_DeviceClassList_List_id_By_Terminal(Task_r.T_class, false) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "终端总共:" + lib.To_string(len(DeviceClassList_r)) + " 正在检查自检探头..."}) for _, class_ := range DeviceClassList_r { _, cnt := Task.Read_TaskData_ById_List(Task_r.T_task_id, class_.T_sn, class_.T_id, "", "", 0, 1) if cnt == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到" + class_.T_id + class_.T_remark + " 自检探头"}) // 获取 备注 下面关联设备,数量 var DeviceClassListT_remark_r_list_MAX int64 DeviceClassListT_remark_r_list_MAX = 0 //最大值 DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(class_.T_class, class_.T_remark) for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r { _, 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) logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt) if DeviceClassListT_remark_r_list_MAX < cnt { DeviceClassListT_remark_r_list_MAX = cnt } } // 筛选 符合的数量 终端 SN_List_sn := 9 SN_List_s := "" // 2023282551724643,003|2023282534778895,004| SN_List_xn := 9 SN_List_x := "" // 2023282551724643,003|2023282534778895,004| SN_List := "" //SN_List_num := 0 // 数量 只能两个 CopyTime := "" //复制的起点 2025-01-07 15:18:00 StartTime := "" // 2025-01-07 15:18:00 EndTime := "" //2025-01-07 21:17:00 for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r { 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) if len(List_data) == 0 { //lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: DeviceClassListT_remark_r_list.T_id+"没有找到对应数据!"}) continue } if DeviceClassListT_remark_r_list_MAX == cnt { logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt) CopyTime = List_data[len(List_data)-1].T_time StartTime = List_data[len(List_data)-1].T_time EndTime = List_data[0].T_time absc := int(math.Abs(float64(lib.To_int(DeviceClassListT_remark_r_list.T_id) - lib.To_int(class_.T_id)))) if absc < SN_List_sn { SN_List_s = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|" SN_List_sn = absc continue } if absc < SN_List_xn { SN_List_x = DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|" SN_List_xn = absc continue } //SN_List_num++ //if SN_List_num >= 2 { // break // 数量 只能两个 //} } } logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime) if len(SN_List_x) == 0 || len(SN_List_s) == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "[" + class_.T_remark + "]中没有找到 至少2条 完整可用数据"}) return } SN_List = SN_List_s + SN_List_x lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: class_.T_sn + "|" + class_.T_id + "开始平均复制到" + SN_List}) // 开始平均复制到 CopySN := class_.T_sn CopyID := class_.T_id copyTime, _ := lib.TimeStrToTime(CopyTime) endTime, _ := lib.TimeStrToTime(EndTime) startTime, _ := lib.TimeStrToTime(StartTime) // 时间间隔 s T_saveT := 60 CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05") SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|") sn_id1 := strings.Split(SN_List_Split[0], ",") sn1, id_str1 := sn_id1[0], sn_id1[1] sn_id2 := strings.Split(SN_List_Split[1], ",") sn2, id_str2 := sn_id2[0], sn_id2[1] List1, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999) List2, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999) num := len(List1) if len(List2) < len(List1) { num = len(List2) } ct := copyTime var valueStrings []string for i := 0; i < num; i++ { if List1[i].T_time != List2[i].T_time { 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)}) return } T_t := (List1[i].T_t + List2[i].T_t) / 2 T_rh := (List1[i].T_rh + List2[i].T_rh) / 2 valueStrings = append(valueStrings, fmt.Sprintf("('%s','%s',%v,%v,'%s')", CopySN, CopyID, T_t, T_rh, ct.Format("2006-01-02 15:04:05"))) ct = ct.Add(time.Second * time.Duration(T_saveT)) } Task.DeleteTaskDataByTimeRange(Task_r.T_task_id, CopySN, CopyID, CopyTime, CopyEndTime) err = Task.Batch_Adds_TaskData(T_task_id, valueStrings) if err == nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", len(valueStrings), len(valueStrings))}) } } } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"}) // Close the connection c.Ctx.ResponseWriter.WriteHeader(http.StatusOK) } // 测点数据自检 自动添加缺失数据,取关联绑定终端平均复制 func (c *TaskDataHandleController) SSE_Automatically_add_missing_data() { T_task_id := c.GetString("T_task_id") // v26nplogbwt1 c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream") c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache") c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive") lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"}) Task_r, err := Task.Read_Task(T_task_id) if err != nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"}) return } // 时间间隔 s T_saveT := 60 // 获取 备注 下面关联设备,数量 var Devicedata_list_MAX int64 Devicedata_list_MAX = 0 //最大值 DeviceClassList_list := Device.Read_DeviceClassList_List_id_By_Terminal(Task_r.T_class, false) for _, DeviceClassListT_remark_r_list := range DeviceClassList_list { _, 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) if Devicedata_list_MAX < cnt { Devicedata_list_MAX = cnt } } logs.Println("数据标准数量:", Devicedata_list_MAX) // 选择 数据缺失的终端 for _, DeviceClassList_r := range DeviceClassList_list { list, cnt := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999) if Devicedata_list_MAX != cnt { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: DeviceClassList_r.T_id + " 终端自检数据 ,自检:" + lib.To_string(Devicedata_list_MAX-cnt) + " "}) for i := 0; i < len(list)-1; i++ { current := list[i].T_time next := list[i+1].T_time ct, _ := time.Parse("2006-01-02 15:04:05", current) nt, _ := time.Parse("2006-01-02 15:04:05", next) interval := nt.Unix() - ct.Unix() //logs.Debug("时间间隔:", interval, "保存时间:", saveTime) //fmt.Println("当前:", current, "下一个:", next) // 缺一个时间点 补漏 if int(interval) == 2*T_saveT { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到自检点 " + current + " ~ " + next + " 开始自检"}) t := ct.Add(time.Second * time.Duration(T_saveT)).Format("2006-01-02 15:04:05") //时间临时变量 ttt := (list[i].T_t + list[i+1].T_t) / 2 trht := (list[i].T_rh + list[i+1].T_rh) / 2 Task.InsertTaskData(Task_r.T_task_id, Task.TaskData_{ T_sn: list[i].T_sn, T_id: list[i].T_id, T_t: ttt, T_rh: trht, T_time: t, }) continue } // 缺的数据大于一个时间点,执行平均复制到 if int(interval) > T_saveT { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "找到自检点 " + current + " ~ " + next + " 开始自检"}) // -------------------- 开始 平均复制到 -------------------- // 获取 备注 下面关联设备,数量 var DeviceClassListT_remark_r_list_MAX int64 DeviceClassListT_remark_r_list_MAX = 0 //最大值 DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(DeviceClassList_r.T_class, DeviceClassList_r.T_remark) for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r { _, 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) logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt) if DeviceClassListT_remark_r_list_MAX < cnt { DeviceClassListT_remark_r_list_MAX = cnt } } // 筛选 符合的数量 终端 //SN_List_sn := 9 //SN_List_s := "" // 2023282551724643,003|2023282534778895,004| //SN_List_xn := 9 //SN_List_x := "" // 2023282551724643,003|2023282534778895,004| SN_List := "" // 2023282551724643,003|2023282534778895,004| //SN_List_num := 0 // 数量 只能两个 CopyTime := current //复制的起点 2025-01-07 15:18:00 StartTime := current // 2025-01-07 15:18:00 EndTime := next //2025-01-07 21:17:00 var completeDataDeviceClassList []Device.DeviceClassList for _, DeviceClassList := range DeviceClassListT_remark_r { List_data, count := Task.Read_TaskData_ById_List(Task_r.T_task_id, DeviceClassList.T_sn, DeviceClassList.T_id, "", "", 0, 9999) if DeviceClassListT_remark_r_list_MAX == count { logs.Println(DeviceClassList.T_sn, DeviceClassList.T_id, "数量:", cnt) EndTime = List_data[0].T_time completeDataDeviceClassList = append(completeDataDeviceClassList, DeviceClassList) } } logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime) if len(completeDataDeviceClassList) < 2 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "[" + DeviceClassList_r.T_remark + "] 中没有找到 至少2条 完整可用数据,【请手动处理!】"}) return } // -----------开始平均复制到 device := Device.DeviceClassList{ T_id: DeviceClassList_r.T_id, T_sn: DeviceClassList_r.T_sn, } c.SetAdjacentDeviceAVGTaskData(T_task_id, device, completeDataDeviceClassList, StartTime, EndTime) // -----------开始平均复制到结束 } } } } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"}) // Close the connection c.Ctx.ResponseWriter.WriteHeader(http.StatusOK) } // 数据持续时间 x 分钟 没有变化 func (c *TaskDataHandleController) SSE_Continuously_unchanged_data() { T_task_id := c.GetString("T_task_id") // v26nplogbwt1 T_timeout, _ := c.GetInt("T_timeout", 30) // 持续时间 c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream") c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache") c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive") lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"}) Task_r, err := Task.Read_Task(T_task_id) if err != nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"}) return } // 获取 备注 下面关联设备,数量 var Devicedata_list_MAX int64 Devicedata_list_MAX = 0 //最大值 DeviceClassList_list := Device.Read_DeviceClassList_List_id(Task_r.T_class) for _, DeviceClassListT_remark_r_list := range DeviceClassList_list { _, 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) if Devicedata_list_MAX < cnt { Devicedata_list_MAX = cnt } } logs.Println("数据标准数量:", Devicedata_list_MAX) // 选择 数据缺失的终端 for _, DeviceClassList_r := range DeviceClassList_list { TaskData_list, _ := Task.Read_TaskData_ById_List_AES(Task_r.T_task_id, DeviceClassList_r.T_sn, DeviceClassList_r.T_id, "", "", 0, 9999) var t_data float32 t_data = 0 t_data_num := 0 current := "" next := "" for i := 0; i < len(TaskData_list)-1; i++ { if t_data == TaskData_list[i].T_t { if t_data_num == 0 { current = TaskData_list[i].T_time } t_data_num += 1 continue } else { if t_data_num > T_timeout { next = TaskData_list[i].T_time 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) } // 清空标致 t_data = TaskData_list[i].T_t t_data_num = 0 continue } } } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"}) // Close the connection c.Ctx.ResponseWriter.WriteHeader(http.StatusOK) } // 平均复制到 func CopyFromPositionAverage(c *context.Response, T_task_id string, T_class int, T_remark, T_sn, T_id, current, next string) { fmt.Println("平均复制到 CopyFromPositionAverage:", T_task_id, T_class, T_remark, T_sn, T_id, current, next) lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: "找到 " + T_id + " 无数据变化, 时间 " + current + " ~ " + next}) // -------------------- 开始 平均复制到 -------------------- // 时间间隔 s T_saveT := 60 // 获取 备注 下面关联设备,数量 var DeviceClassListT_remark_r_list_MAX int64 DeviceClassListT_remark_r_list_MAX = 0 //最大值 DeviceClassListT_remark_r := Device.Read_DeviceClassList_List_id_T_remark(T_class, T_remark) for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r { _, 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) logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt) if DeviceClassListT_remark_r_list_MAX < cnt { DeviceClassListT_remark_r_list_MAX = cnt } } // 筛选 符合的数量 终端 SN_List := "" // 2023282551724643,003|2023282534778895,004| SN_List_num := 0 // 数量 只能两个 CopyTime := current //复制的起点 2025-01-07 15:18:00 StartTime := current // 2025-01-07 15:18:00 EndTime := next //2025-01-07 21:17:00 for _, DeviceClassListT_remark_r_list := range DeviceClassListT_remark_r { _, 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) if DeviceClassListT_remark_r_list_MAX == cnt { logs.Println(DeviceClassListT_remark_r_list.T_sn, DeviceClassListT_remark_r_list.T_id, "数量:", cnt) SN_List += DeviceClassListT_remark_r_list.T_sn + "," + DeviceClassListT_remark_r_list.T_id + "|" //CopyTime = List_data[len(List_data)-1].T_time //StartTime = List_data[len(List_data)-1].T_time //EndTime = List_data[0].T_time SN_List_num++ if SN_List_num >= 2 { break // 数量 只能两个 } } } logs.Println("复制参数:", SN_List, CopyTime, StartTime, EndTime) if SN_List_num != 2 { lib.SseWriteJSON(c, lib.JSONSSE{State: 2, Msg: "[" + T_remark + "] 中没有找到 至少2条 完整可用数据"}) return } lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: T_sn + "|" + T_id + "开始平均复制到" + SN_List}) // 开始平均复制到 CopySN := T_sn CopyID := T_id copyTime, _ := lib.TimeStrToTime(CopyTime) endTime, _ := lib.TimeStrToTime(EndTime) startTime, _ := lib.TimeStrToTime(StartTime) CopyEndTime := copyTime.Add(endTime.Sub(startTime)).Format("2006-01-02 15:04:05") SN_List_Split := strings.Split(strings.Trim(SN_List, "|"), "|") sn_id1 := strings.Split(SN_List_Split[0], ",") sn1, id_str1 := sn_id1[0], sn_id1[1] sn_id2 := strings.Split(SN_List_Split[1], ",") sn2, id_str2 := sn_id2[0], sn_id2[1] List1, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999) List2, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999) num := len(List1) if len(List2) < len(List1) { num = len(List2) } fmt.Println("num:", num) ct := copyTime var valueStrings []string for TaskData_i := 0; TaskData_i < num; TaskData_i++ { if List1[TaskData_i].T_time != List2[TaskData_i].T_time { 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)}) return } T_t := (List1[TaskData_i].T_t + List2[TaskData_i].T_t) / 2 T_rh := (List1[TaskData_i].T_rh + List2[TaskData_i].T_rh) / 2 valueStrings = append(valueStrings, fmt.Sprintf("('%s','%s',%v,%v,'%s')", CopySN, CopyID, T_t, T_rh, ct.Format("2006-01-02 15:04:05"))) ct = ct.Add(time.Second * time.Duration(T_saveT)) } Task.DeleteTaskDataByTimeRange(T_task_id, CopySN, CopyID, CopyTime, CopyEndTime) err := Task.Batch_Adds_TaskData(T_task_id, valueStrings) if err == nil { lib.SseWriteJSON(c, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", len(valueStrings), len(valueStrings))}) } } // 绑定点与终端比对 (绑定点数据自检) 终端数据为参照物,绑定点数据在终端偏差±1℃,保温箱为±0.5℃ func (c *TaskDataHandleController) SSE_Comparison_between_binding_points_and_terminals() { T_task_id := c.GetString("T_task_id") // v26nplogbwt1 T_deviation, _ := c.GetFloat("T_deviation", 1.0) // 误差绑定点数据与终端对比偏差 c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream") c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache") c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive") lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"}) Task_r, err := Task.Read_Task(T_task_id) if err != nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"}) return } // 保温箱偏差为0.5 if Task_r.T_device_type == "X" { T_deviation = 0.5 } // -------------------- 获取开始时间-------------------- 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值"))) if 温度控制范围最高值 == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围最高值 标签值不正确!"}) return } // 均匀性布点 产品存放区域测点 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点") 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...) 部点终端_list = Device.DeduplicateById(部点终端_list) if len(部点终端_list) <= 2 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"}) return } 开始时间 := "" // 开始时间 获取温度下降到第二个低点时间 // 1. 获取温度平均值 部点终端_sn_list := []string{} for _, v := range 部点终端_list { 部点终端_sn_list = append(部点终端_sn_list, v.T_sn) } list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, strings.Join(部点终端_sn_list, "|"), "", "") if len(list) < 2 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点+产品存放区域测点 数据平均值 少于2条!"}) return } // 找平均值低于温度控制范围最高值的第二个最低点 lowPoint := 0 for i := 1; i <= len(list)-2; i++ { if list[i].T_t < list[i-1].T_t && list[i].T_t < list[i+1].T_t && list[i].T_t < float32(温度控制范围最高值) { lowPoint += 1 } if lowPoint == 2 { 开始时间 = list[i].T_time break } } if len(开始时间) == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 开始时间 数据!"}) return } // -------------------- 获取开始时间结束 -------------------- 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开") if len(结束时间) == 0 { 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开") } if len(结束时间) == 0 { 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "现场测试结束时间") } if len(结束时间) == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"}) return } 监测终端_list := Device.Read_DeviceClassList_List_id_By_Terminal(Task_r.T_class, true) if len(监测终端_list) < 1 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 监测终端!"}) } // 查询监测终端开始时间 for i, 监测终端 := range 监测终端_list { // -------------------- 温湿度绑定点 -------------------- 温湿度绑定点_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点"+lib.To_string(i+1)) if len(温湿度绑定点_list) != 1 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点" + lib.To_string(i+1) + " 中找到 " + lib.To_string(len(温湿度绑定点_list)) + "条,只允许 一条数据!"}) } fmt.Println("温湿度绑定点"+lib.To_string(i+1)+"数据准备:", 温湿度绑定点_list[0].T_id, 监测终端.T_id, 开始时间, 结束时间) var 温湿度绑定点vga, 监测终端vga, vgaca float64 温湿度绑定点vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点_list[0].T_sn, 温湿度绑定点_list[0].T_id, 开始时间, 结束时间) 监测终端vga = Task.Read_TaskData_AVG(T_task_id, 监测终端.T_sn, 监测终端.T_id, 开始时间, 结束时间) vgaca = RoundToDecimal(监测终端vga-温湿度绑定点vga, 1) for T_deviation < math.Abs(vgaca) { // 缩放 lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行缩放 数据!" + "温湿度绑定点" + lib.To_string(i+1) + " 平均值:" + lib.To_string(温湿度绑定点vga) + "℃ " + "监测终端0" + lib.To_string(i+1) + " 平均值" + lib.To_string(监测终端vga) + "℃ " + "数据偏差: " + lib.To_string(vgaca) + "℃ " + "设置:" + lib.To_string(T_deviation) + "℃"}) // 获取缩放度 compress := RoundToDecimal((监测终端vga-T_deviation-0.1)/温湿度绑定点vga, 2) // 缩放 Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, 温湿度绑定点_list[0].T_id, "", "", compress) // 偏移 温湿度绑定点vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点_list[0].T_sn, 温湿度绑定点_list[0].T_id, 开始时间, 结束时间) 监测终端vga = Task.Read_TaskData_AVG(T_task_id, 监测终端.T_sn, 监测终端.T_id, 开始时间, 结束时间) vgaca = math.Round((监测终端vga-温湿度绑定点vga)*100) / 100.0 lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行偏移 数据!" + "温湿度绑定点1 平均值:" + lib.To_string(温湿度绑定点vga) + "℃ " + "监测终端0" + lib.To_string(i+1) + " 平均值" + lib.To_string(监测终端vga) + "℃ " + "数据偏差: " + lib.To_string(vgaca) + "℃ " + "设置:" + lib.To_string(T_deviation) + "℃"}) Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, 温湿度绑定点_list[0].T_id, "", "", math.Round(((监测终端vga-温湿度绑定点vga)*0.8)*100)/100.0) 温湿度绑定点vga = Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点_list[0].T_sn, 温湿度绑定点_list[0].T_id, 开始时间, 结束时间) 监测终端vga = Task.Read_TaskData_AVG(T_task_id, 监测终端.T_sn, 监测终端.T_id, 开始时间, 结束时间) vgaca = RoundToDecimal(监测终端vga-温湿度绑定点vga, 1) } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "数据满足要求!" + "温湿度绑定点" + lib.To_string(i+1) + " 平均值:" + lib.To_string(温湿度绑定点vga) + "℃ " + "监测终端0" + lib.To_string(i+1) + " 平均值" + lib.To_string(监测终端vga) + "℃ " + "数据偏差: " + lib.To_string(vgaca) + "℃ !"}) } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"}) // Close the connection c.Ctx.ResponseWriter.WriteHeader(http.StatusOK) } // 绑定点与冷热点比对 (冷热点数据自检)绑定点数据为参照物,绑定点数据在终端偏差±1℃,保温箱为±0.5℃ func (c *TaskDataHandleController) SSE_Compare_binding_points_with_cold_and_hot_spots() { T_task_id := c.GetString("T_task_id") // v26nplogbwt1 T_deviation, _ := c.GetFloat("T_deviation", 1.0) // 偏差时间 c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream") c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache") c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive") lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"}) Task_r, err := Task.Read_Task(T_task_id) if err != nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"}) return } // 保温箱偏差为0.5 if Task_r.T_device_type == "X" { T_deviation = 0.5 } 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值"))) if 温度控制范围最高值 == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围最高值 标签值不正确!"}) return } // 均匀性布点 产品存放区域测点 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点") 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...) 部点终端_list = Device.DeduplicateById(部点终端_list) 开始时间 := "" // 开始时间 获取温度下降到第二个低点时间 // 1. 获取温度平均值 部点终端_sn_list := []string{} for _, v := range 部点终端_list { 部点终端_sn_list = append(部点终端_sn_list, v.T_sn) } list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, strings.Join(部点终端_sn_list, "|"), "", "") if len(list) < 2 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点+产品存放区域测点 数据平均值 少于2条!"}) return } // 找平均值低于温度控制范围最高值的第二个最低点 lowPoint := 0 for i := 1; i <= len(list)-2; i++ { if list[i].T_t < list[i-1].T_t && list[i].T_t < list[i+1].T_t && list[i].T_t < float32(温度控制范围最高值) { lowPoint += 1 } if lowPoint == 2 { 开始时间 = list[i].T_time break } } if len(开始时间) == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 开始时间 数据!"}) return } // ------------------ 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开") if len(结束时间) == 0 { 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开") } if len(结束时间) == 0 { 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "现场测试结束时间") } if len(结束时间) == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"}) return } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 开始时间--- " + 开始时间}) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 结束时间--- " + 结束时间}) if len(部点终端_list) <= 2 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"}) return } type AVGClassList struct { T_id string T_vga float64 } var AVGClassList_r []AVGClassList for _, i2 := range 部点终端_list { 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, 开始时间, 结束时间)}) } // 使用 sort.Slice 对切片进行排序 sort.Slice(AVGClassList_r, func(i, j int) bool { return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序 // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga }) fmt.Println("AVGClassList_r:", AVGClassList_r) // ------- 温湿度绑定点 温湿度绑定点1_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点1") if len(温湿度绑定点1_list) != 1 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温湿度绑定点1 中找到 " + lib.To_string(len(温湿度绑定点1_list)) + "条,布点终端异常!"}) return } 温湿度绑定点2_list_is := true 温湿度绑定点2_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "温湿度绑定点2") if len(温湿度绑定点2_list) != 1 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点2 没找到,将 温湿度绑定点1 设置低点"}) 温湿度绑定点2_list = 温湿度绑定点1_list 温湿度绑定点2_list_is = false } 温湿度绑定点1vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点1_list[0].T_sn, 温湿度绑定点1_list[0].T_id, 开始时间, 结束时间) 温湿度绑定点2vga := Task.Read_TaskData_AVG(T_task_id, 温湿度绑定点2_list[0].T_sn, 温湿度绑定点2_list[0].T_id, 开始时间, 结束时间) if 温湿度绑定点1vga == 温湿度绑定点2vga { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "温湿度绑定点1 与 温湿度绑定点2 平均值相等,将 进行上下偏移处理!"}) 温湿度绑定点1vga += T_deviation / 2 温湿度绑定点2vga -= T_deviation / 2 T_deviation /= 2 } var 温湿度绑定点vga_H, 温湿度绑定点vga_L AVGClassList if 温湿度绑定点1vga > 温湿度绑定点2vga { 温湿度绑定点vga_H.T_id = 温湿度绑定点1_list[0].T_id 温湿度绑定点vga_H.T_vga = 温湿度绑定点1vga 温湿度绑定点vga_L.T_id = 温湿度绑定点2_list[0].T_id 温湿度绑定点vga_L.T_vga = 温湿度绑定点2vga } else { 温湿度绑定点vga_L.T_id = 温湿度绑定点1_list[0].T_id 温湿度绑定点vga_L.T_vga = 温湿度绑定点1vga 温湿度绑定点vga_H.T_id = 温湿度绑定点2_list[0].T_id 温湿度绑定点vga_H.T_vga = 温湿度绑定点2vga } fmt.Println("温湿度绑定点:", 温湿度绑定点vga_H, 温湿度绑定点vga_L) // -------------------- 温湿度绑定点vga_H -------------------- lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 高点处理 ------"}) var vgaca float64 vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0 for T_deviation < math.Abs(vgaca) { // 缩放 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) + "℃ " + "高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(fmt.Sprintf("%.2f", 温湿度绑定点vga_H.T_vga)) + "℃ " + "数据偏差: " + lib.To_string(vgaca) + "℃ " + "设置:" + lib.To_string(T_deviation) + "℃"}) Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[0].T_id, "", "", 0.95) // 偏移 // 均匀性布点 产品存放区域测点 AVGClassList_r = AVGClassList_r[:0] // 清空切片 for _, i2 := range 部点终端_list { 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, 开始时间, 结束时间)}) } // 使用 sort.Slice 对切片进行排序 sort.Slice(AVGClassList_r, func(i, j int) bool { return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序 // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga }) fmt.Println("AVGClassList_r:", AVGClassList_r) vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0 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) + "℃ 高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_H.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"}) Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[0].T_id, "", "", math.Round(((vgaca)*0.8)*100)/100.0) // 均匀性布点 产品存放区域测点 AVGClassList_r = AVGClassList_r[:0] // 清空切片 for _, i2 := range 部点终端_list { 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, 开始时间, 结束时间)}) } // 使用 sort.Slice 对切片进行排序 sort.Slice(AVGClassList_r, func(i, j int) bool { return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序 // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga }) fmt.Println("AVGClassList_r:", AVGClassList_r) vgaca = math.Round((温湿度绑定点vga_H.T_vga-AVGClassList_r[0].T_vga)*100) / 100.0 } 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) + "℃ " + "高点 " + lib.To_string(温湿度绑定点vga_H.T_id) + " 平均值" + lib.To_string(fmt.Sprintf("%.2f", 温湿度绑定点vga_H.T_vga)) + "℃ " + "数据偏差: " + lib.To_string(vgaca) + "℃ "}) // -------------------- 温湿度绑定点vga_L -------------------- if !温湿度绑定点2_list_is { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "低点跳过处理!"}) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"}) return } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "------ 进行 低点处理 ------"}) vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0 for T_deviation < math.Abs(vgaca) { // 缩放 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) + "℃ " + "低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ " + "数据偏差: " + lib.To_string(vgaca) + "℃ " + "设置:" + lib.To_string(T_deviation) + "℃"}) Task.UpdateTaskDataTemperatureAndHumidityByGeometric_id(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, "", "", 0.95) // 偏移 // 均匀性布点 产品存放区域测点 AVGClassList_r = AVGClassList_r[:0] // 清空切片 for _, i2 := range 部点终端_list { 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, 开始时间, 结束时间)}) } // 使用 sort.Slice 对切片进行排序 sort.Slice(AVGClassList_r, func(i, j int) bool { return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序 // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga }) fmt.Println("AVGClassList_r:", AVGClassList_r) vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0 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) + "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ 设置:" + lib.To_string(T_deviation) + "℃"}) Task.UpdateTaskDataTemperatureAndHumidityByGeometricAVG(T_task_id, AVGClassList_r[len(AVGClassList_r)-1].T_id, "", "", math.Round(((vgaca)*0.8)*100)/100.0) // 均匀性布点 产品存放区域测点 AVGClassList_r = AVGClassList_r[:0] // 清空切片 for _, i2 := range 部点终端_list { 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, 开始时间, 结束时间)}) } // 使用 sort.Slice 对切片进行排序 sort.Slice(AVGClassList_r, func(i, j int) bool { return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga // 降序排序 // 如果需要降序排序,可以使用:return AVGClassList_r[i].T_vga > AVGClassList_r[j].T_vga }) fmt.Println("AVGClassList_r:", AVGClassList_r) vgaca = math.Round((温湿度绑定点vga_L.T_vga-AVGClassList_r[len(AVGClassList_r)-1].T_vga)*100) / 100.0 } //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) + // "℃ 低点 " + lib.To_string(温湿度绑定点vga_L.T_id) + " 平均值" + lib.To_string(温湿度绑定点vga_L.T_vga) + "℃ 数据偏差: " + lib.To_string(vgaca) + "℃ "}) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"}) // Close the connection c.Ctx.ResponseWriter.WriteHeader(http.StatusOK) } // 区间数据校正 (布点区域数据自检) 均匀性布点,产品存放区域测点 区间数据超标校正 超标数据偏移到区间内 func (c *TaskDataHandleController) SSE_Interval_data_correction() { T_task_id := c.GetString("T_task_id") // v26nplogbwt1 c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream") c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache") c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive") lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "任务开始......"}) Task_r, err := Task.Read_Task(T_task_id) if err != nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "获取任务信息失败!"}) return } 结束时间 := VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开空开") if len(结束时间) == 0 { 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "开满开") } if len(结束时间) == 0 { 结束时间 = VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "现场测试结束时间") } if len(结束时间) == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到结束时间 标签!"}) return } 温度控制范围最小值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最小值"))) 温度控制范围最高值 := float64(lib.To_float32(VerifyTemplate.Read_VerifyTemplateMapData_T_name(Task_r.T_task_id, Task_r.T_VerifyTemplate_id, "温度控制范围最高值"))) if 温度控制范围最小值 == 0 || 温度控制范围最高值 == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "温度控制范围 标签值不正确!"}) return } // 均匀性布点 产品存放区域测点 部点终端_list := Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "均匀性布点") 部点终端_list = append(部点终端_list, Device.Read_DeviceClassList_List_id_T_remark(Task_r.T_class, "产品存放区域测点")...) 部点终端_list = Device.DeduplicateById(部点终端_list) if len(部点终端_list) <= 2 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点,产品存放区域测点 太少了,至少两条以上!"}) return } 开始时间 := "" // 开始时间 获取温度下降到第二个低点时间 // 1. 获取温度平均值 部点终端_sn_list := []string{} for _, v := range 部点终端_list { 部点终端_sn_list = append(部点终端_sn_list, v.T_sn) } list := Task.Read_TaskData_ById_AVG(Task_r.T_task_id, strings.Join(部点终端_sn_list, "|"), "", "") if len(list) < 2 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "均匀性布点+产品存放区域测点 数据平均值 少于2条!"}) return } // 找平均值低于温度控制范围最高值的第二个最低点 lowPoint := 0 for i := 1; i <= len(list)-2; i++ { if list[i].T_t < list[i-1].T_t && list[i].T_t < list[i+1].T_t && list[i].T_t < float32(温度控制范围最高值) { lowPoint += 1 } if lowPoint == 2 { 开始时间 = list[i].T_time break } } if len(开始时间) == 0 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 2, Msg: "未找到 开始时间 数据!"}) return } type AVGClassList struct { T_sn string T_id string T_max float64 T_min float64 T_diff float64 // 最大最小值差异 } var AVGClassList_r []AVGClassList for _, i2 := range 部点终端_list { T_max := Task.Read_TaskData_max(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间) T_min := Task.Read_TaskData_min(T_task_id, i2.T_sn, i2.T_id, 开始时间, 结束时间) AVGClassList_r = append(AVGClassList_r, AVGClassList{T_sn: i2.T_sn, T_id: i2.T_id, T_max: T_max, T_min: T_min, T_diff: T_max - T_min}) } fmt.Println("AVGClassList_r:", AVGClassList_r) fmt.Println("数据准备:", 开始时间, 结束时间, 温度控制范围最小值, 温度控制范围最高值) // -------------------- 温湿度绑定点vga_H -------------------- lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "--- 进行处理 数据!---"}) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("开始时间:%s 结束时间:%s", 开始时间, 结束时间)}) for _, AVGClassList_i := range AVGClassList_r { var vgaca float64 if AVGClassList_i.T_max > 温度控制范围最高值 && AVGClassList_i.T_min < 温度控制范围最小值 { // 压缩 diff := RoundToDecimal(AVGClassList_i.T_max-AVGClassList_i.T_min, 1) // 获取压缩度 compress := RoundToDecimal((温度控制范围最高值-温度控制范围最小值-0.4)/diff, 2) // 压缩 Task.UpdateTaskDataTemperatureAndHumidityByGeometric(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", compress, 1) // 向上偏移 vgaca = RoundToDecimal(温度控制范围最小值-AVGClassList_i.T_min*compress, 1) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " + " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " + " 数据偏差:" + lib.To_string(vgaca) + "℃ " + " 压缩:" + lib.To_string(compress) + " 向上偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "}) Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", RoundToDecimal(vgaca+0.1, 1), 0) } if (AVGClassList_i.T_max - AVGClassList_i.T_min) > (温度控制范围最高值 - 温度控制范围最小值 - 0.2) { // 压缩 diff := RoundToDecimal(AVGClassList_i.T_max-AVGClassList_i.T_min, 1) // 获取压缩度 compress := RoundToDecimal((温度控制范围最高值-温度控制范围最小值-0.4)/diff, 2) // 压缩 Task.UpdateTaskDataTemperatureAndHumidityByGeometric(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", compress, 1) // 判断压缩后是否在 温度控制范围最小值-温度控制范围最高值范围内 不做处理 if AVGClassList_i.T_max*compress > 温度控制范围最高值 && AVGClassList_i.T_min*compress < 温度控制范围最小值 { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " + " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " + " 压缩:" + lib.To_string(fmt.Sprintf("%.2f", compress)) + " 压缩后最大值:" + lib.To_string(fmt.Sprintf("%.2f", AVGClassList_i.T_max*compress)) + "℃ " + " 压缩后最小值:" + lib.To_string(fmt.Sprintf("%.2f", AVGClassList_i.T_min*compress)) + "℃ "}) continue } // 压缩后仍高于 温度控制范围最高值,向下偏移 if AVGClassList_i.T_max*compress > 温度控制范围最高值 { vgaca = RoundToDecimal(AVGClassList_i.T_max*compress-温度控制范围最高值, 1) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " + " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " + " 压缩:" + lib.To_string(compress) + " 压缩后最大值:" + lib.To_string(AVGClassList_i.T_max*compress) + "℃ " + " 压缩后最小值:" + lib.To_string(AVGClassList_i.T_min*compress) + "℃ " + " 数据偏差:" + lib.To_string(vgaca) + "℃ " + " 向下偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "}) Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", -RoundToDecimal(vgaca+0.1, 1), 0) continue } // 压缩后仍低于 温度控制范围最小值,向上偏移 if AVGClassList_i.T_min*compress < 温度控制范围最小值 { // 向上偏移 vgaca = RoundToDecimal(温度控制范围最小值-AVGClassList_i.T_min*compress, 1) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " + " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " + " 压缩:" + lib.To_string(compress) + " 压缩后最大值:" + lib.To_string(AVGClassList_i.T_max*compress) + "℃ " + " 压缩后最小值:" + lib.To_string(AVGClassList_i.T_min*compress) + "℃ " + " 数据偏差:" + lib.To_string(vgaca) + "℃ " + " 向上偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "}) Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", RoundToDecimal(vgaca+0.1, 1), 0) } continue } // 向下偏移 if AVGClassList_i.T_max > 温度控制范围最高值 { vgaca = RoundToDecimal(AVGClassList_i.T_max-温度控制范围最高值, 1) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " + " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " + " 数据偏差:" + lib.To_string(vgaca) + "℃ " + " 向下偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "}) // 偏移 Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", -RoundToDecimal(vgaca+0.1, 1), 0) continue } if AVGClassList_i.T_min < 温度控制范围最小值 { vgaca = RoundToDecimal(温度控制范围最小值-AVGClassList_i.T_min, 1) lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: "进行处理 数据!" + lib.To_string(AVGClassList_i.T_id) + " 最大值:" + lib.To_string(AVGClassList_i.T_max) + "℃ " + " 最小值:" + lib.To_string(AVGClassList_i.T_min) + "℃ " + " 数据偏差: " + lib.To_string(vgaca) + "℃ " + " 向上偏移:" + lib.To_string(RoundToDecimal(vgaca+0.1, 1)) + "℃ "}) Task.UpdateTaskDataTemperatureAndHumidity(Task_r.T_task_id, AVGClassList_i.T_sn, AVGClassList_i.T_id, "", "", RoundToDecimal(vgaca+0.1, 1), 0) } } lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 1, Msg: "完成!"}) // Close the connection c.Ctx.ResponseWriter.WriteHeader(http.StatusOK) } // 获取相邻2个终端值平均复制到 func (c *TaskDataHandleController) SetAdjacentDeviceAVGTaskData(T_task_id string, device Device.DeviceClassList, data []Device.DeviceClassList, StartTime, EndTime string) { twoDevice := getBeforeAndAfter(device.T_id, data) sn1, id_str1 := twoDevice[0].T_sn, twoDevice[0].T_id sn2, id_str2 := twoDevice[1].T_sn, twoDevice[1].T_id lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: device.T_sn + "|" + device.T_id + "开始平均复制到" + fmt.Sprintf("%s,%s|%s,%s", sn1, id_str1, sn2, id_str2)}) List1, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn1, id_str1, StartTime, EndTime, 0, 9999) List2, _ := Task.Read_TaskData_ById_List_AES(T_task_id, sn2, id_str2, StartTime, EndTime, 0, 9999) num := len(List1) if len(List2) < len(List1) { num = len(List2) } if num == 0 { return } T_saveT := 60 //var list []Task.TaskData_ ct, _ := lib.TimeStrToTime(List1[0].T_time) var valueStrings []string for i := 0; i < num; i++ { if List1[i].T_time != List2[i].T_time { c.Data["json"] = lib.JSONS{202, fmt.Sprintf("%s【%s】、%s【%s】时间不一致", List1[i].T_id, List1[i].T_time, List2[i].T_id, List2[i].T_time), nil} c.ServeJSON() return //ct = ct.Add(time.Second * time.Duration(T_saveT)) //continue } T_t := (List1[i].T_t + List2[i].T_t) / 2 T_rh := (List1[i].T_rh + List2[i].T_rh) / 2 valueStrings = append(valueStrings, fmt.Sprintf("('%s','%s',%v,%v,'%s')", device.T_sn, device.T_id, T_t, T_rh, ct.Format("2006-01-02 15:04:05"))) ct = ct.Add(time.Second * time.Duration(T_saveT)) } Task.DeleteTaskDataByTimeRange(T_task_id, device.T_sn, device.T_id, StartTime, EndTime) err := Task.Batch_Adds_TaskData(T_task_id, valueStrings) if err == nil { lib.SseWriteJSON(c.Ctx.ResponseWriter, lib.JSONSSE{State: 0, Msg: fmt.Sprintf("%d/%d", len(valueStrings), len(valueStrings))}) } } func getBeforeAndAfter(T_id string, data []Device.DeviceClassList) []Device.DeviceClassList { var result []Device.DeviceClassList var index int for i, d := range data { if d.T_id == T_id { index = i break } } if index == 0 { result = append(result, data[len(data)-1], data[1]) } else if index == len(data)-1 { result = append(result, data[len(data)-2], data[0]) } else { result = append(result, data[index-1], data[index+1]) } return result } func RoundToDecimal(num float64, decimal int) float64 { shift := math.Pow(10, float64(decimal)) return math.Round(num*shift) / shift }