using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using NPOI.Util; using Newtonsoft.Json; using System.Threading.Tasks; using MainForm.ClassFile.XiaomiAPI; using MainForm.ClassFile.XiaomiAPI_MES; using static MainForm.ClassFile.XiaomiAPI.XiaomiMqttClient_Extend; using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationInbound; using static MainForm.ClassFile.XiaomiAPI_MES.XiaomiMESHttp_StationOutbound; namespace MainForm { /// /// Form_Home类 - 保存数据 /// 简单拆分Form_Home类 /// public partial class Form_Home { #region 保存数据 #region 进站数据 /// /// 调用进站接口并保存进站数据 /// /// 工站信息 /// 工单号 /// 型号(物料号) /// 产品SN /// 进站数据 /// 1成功;5MES报警;6上位机报警 public int SaveStationInData(string stationNameStr, string workorder_code, string mtltmrk, string sn, List items,out string msg) { int result = 0; msg = ""; XmMES_StationInRequest_Body inRequest_Body = new XmMES_StationInRequest_Body(); switch (stationNameStr) { case "[S1]Tray盘上料装备": inRequest_Body.machineId = GlobalContext.S1_MachineId; // 装备ID(可配置) inRequest_Body.stationId = GlobalContext.S1_StationId; // ⼯位ID(可配置) break; case "[S2]FCT": inRequest_Body.machineId = GlobalContext.S2_MachineId; // 装备ID(可配置) inRequest_Body.stationId = GlobalContext.S2_StationId; // ⼯位ID(可配置) break; case "[S3]值板机": inRequest_Body.machineId = GlobalContext.S3_MachineId; // 装备ID(可配置) inRequest_Body.stationId = GlobalContext.S3_StationId; // ⼯位ID(可配置) break; case "[S4_1]载具下线装备": inRequest_Body.machineId = GlobalContext.S4_MachineId; // 装备ID(可配置) inRequest_Body.stationId = GlobalContext.S4_StationId; // ⼯位ID(可配置) break; case "[S4_3]提升机1": //inRequest_Body.machineId = GlobalContext.S5_1_MachineId; // 装备ID(可配置) //inRequest_Body.stationId = GlobalContext.S5_1_StationId; // ⼯位ID(可配置) break; case "[S4_4]提升机2": //inRequest_Body.machineId = GlobalContext.S5_2_MachineId; // 装备ID(可配置) //inRequest_Body.stationId = GlobalContext.S5_2_StationId; // ⼯位ID(可配置) break; case "[S4_5]载具上线装备": inRequest_Body.machineId = GlobalContext.S6_MachineId; // 装备ID(可配置) inRequest_Body.stationId = GlobalContext.S6_StationId; // ⼯位ID(可配置) break; case "[S5]Tray盘下料装备": inRequest_Body.machineId = GlobalContext.S7_MachineId; // 装备ID(可配置) inRequest_Body.stationId = GlobalContext.S7_StationId; // ⼯位ID(可配置) break; default: break; } inRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX inRequest_Body.clientTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff inRequest_Body.unitSn = sn; // 产品SN inRequest_Body.userId = GlobalContext.MESUserId; // 用户ID;非必填 inRequest_Body.factoryId = GlobalContext.Factory_Code; // 工厂ID;非必填 string json_Body = JsonConvert.SerializeObject(inRequest_Body); StationIn stationIn = new StationIn() { Workorder_code = workorder_code, // 车间订单号 Mtltmrk = mtltmrk, // 产品型号(物料号) Sn = sn, // SN StationIn_body = json_Body, // 进站接口Json数据 - Body Parameter_values = items, // 进站数据 Write_user = inRequest_Body.userId, // 员工Id Test_time = inRequest_Body.clientTime // 进站时间 }; // 本地数据 string sql = stationIn.ToStringInsert(0); string ret = SQLHelper_New.ExecuteNonQuery(sql, null); result = ret == "成功" ? 1 : 6; msg = ret; AddMessage_Station(stationNameStr, LogType.Info, string.Concat(stationNameStr, "_保存本地进站数据---" + ret)); //await Task.Delay(200); // 上传MES if (result == 1 && GlobalContext.IsSendStationIn) { try { XmMES_StationInResponse response = new XmMES_StationInResponse(); string mesRet = string.Empty; int i = 0; while (i < 2) // 1009会多次尝试上传 { response = XiaomiMESHttp_StationInbound.StationIn(inRequest_Body); if (response != null && response.header.code == "200") break; else if (response != null && response.header.code != "503") // 503是服务器报错 i++; i++; mesRet = $"[{response?.header?.code}]{response?.header?.desc}"; // 记录失败原因 OnMessage(LogType.Error, "上传出站数据到MES服务器---失败!正在重新上传!接口报错信息:" + mesRet + "参数:" + json_Body); } AddMessage_Station(stationNameStr, LogType.Info, stationNameStr + "_上传进站数据到MES服务器---" + mesRet); if (response?.header?.code == "200") { string sql_Upd = stationIn.ToStringUpdateStatusByID(1); string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null); result = ret_Upd == "成功" ? result : 6; msg = ret_Upd == "成功" ? msg : "更新【进站数据 id {stationIn.GUID}】上传状态---失败"; AddMessage_Station(stationNameStr, LogType.Info, $"更新【进站数据 id {stationIn.GUID}】上传状态---" + ret_Upd); } else { result = 5; msg = "上传进站数据到MES服务器---失败!接口报错信息:" + mesRet + "参数:" + json_Body; OnMessage(LogType.Error, "上传进站数据到MES服务器---失败!接口报错信息:" + mesRet + "参数:" + json_Body); } } catch (Exception ex) { result = 6; string str = ex.StackTrace; msg = $"PLC上传进站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1); AddMessage_Station(stationNameStr, LogType.Error, $"PLC上传进站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1)); } } return result; } #endregion 进站数据 #region 出站数据 /// /// 选择如何记录出站数据 /// /// 工站信息 /// 出站数据 /// 设备编号 /// 测试项目 /// 车间订单号 /// 型号 /// 产品序列号的 /// 产品结果 /// 载具SN /// 载具穴号 /// 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警; private int SwitctProcessData(string stationNameStr, List items, string equipmentCode, string processItem, string workorder_code, string mtltmrk, string sn, bool pass, string vehicleSn, string vehicleSlot) { //if (DataSwitch == 1) //{ return SaveProcessDataByDB(stationNameStr, items, equipmentCode, processItem, workorder_code, mtltmrk, sn, pass, vehicleSn, vehicleSlot); //} //else // 旧代码,废弃 //{ // return SaveProcessData(items, equipmentCode, processItem, sn_Number); //} } /// /// 添加出站数据(提交到MES+本地保存到数据库) /// /// 工站信息 /// 出站数据 /// 设备编号 /// 测试项目 /// 车间订单号 /// 型号 /// 产品序列号 /// 产品结果 /// 载具SN /// 载具穴号 /// 上位机发送1代表OK;2代表上传客户MES失败;3代表上位机保存数据失败;4代表上位机报警; public int SaveProcessDataByDB(string stationNameStr, List items, string equipmentCode, string processItem, string workorder_code, string mtltmrk, string sn, bool pass, string vehicleSn, string vehicleSlot) { int mesUpload = 0; // 0未上传或上传失败;1上传成功;2忽略 int iotUpload = 0; // 0未上传或上传失败;1上传成功;2忽略 ProcessData processData = new ProcessData() { Equipment_code = equipmentCode, Testitem = processItem, Workorder_code = workorder_code, //Batch_number = batch_num, Sn = sn, // SN Parameter_values = items, Write_user = GlobalContext.CurrentUser, Test_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") }; // 本地数据 string sql = processData.ToStringInsert(mesUpload, iotUpload); string ret = SQLHelper_New.ExecuteNonQuery(sql, null); AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]保存本地出站数据---" + ret)); if (ret != "成功") return 3; // 3代表上位机保存数据失败 //await Task.Delay(200); // 上传MES string mesJson = string.Empty; if (GlobalContext.IsSendProcessData) { try { string id = processData.ID; XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body(); switch (stationNameStr) { case "[S1]Tray盘上料装备": outRequest_Body.machineId = GlobalContext.S1_MachineId; // 装备ID(可配置) outRequest_Body.stationId = GlobalContext.S1_StationId; // ⼯位ID(可配置) break; case "[S2]FCT": outRequest_Body.machineId = GlobalContext.S2_MachineId; // 装备ID(可配置) outRequest_Body.stationId = GlobalContext.S2_StationId; // ⼯位ID(可配置) break; case "[S3]值板机": outRequest_Body.machineId = GlobalContext.S3_MachineId; // 装备ID(可配置) outRequest_Body.stationId = GlobalContext.S3_StationId; // ⼯位ID(可配置) break; case "[S4_1]载具下线装备": outRequest_Body.machineId = GlobalContext.S4_MachineId; // 装备ID(可配置) outRequest_Body.stationId = GlobalContext.S4_StationId; // ⼯位ID(可配置) break; case "[S4_3]提升机1": //outRequest_Body.machineId = GlobalContext.S5_1_MachineId; // 装备ID(可配置) //outRequest_Body.stationId = GlobalContext.S5_1_StationId; // ⼯位ID(可配置) break; case "[S4_4]提升机2": //outRequest_Body.machineId = GlobalContext.S5_2_MachineId; // 装备ID(可配置) //outRequest_Body.stationId = GlobalContext.S5_2_StationId; // ⼯位ID(可配置) break; case "[S4_5]载具上线装备": outRequest_Body.machineId = GlobalContext.S6_MachineId; // 装备ID(可配置) outRequest_Body.stationId = GlobalContext.S6_StationId; // ⼯位ID(可配置) break; case "[S5]Tray盘下料装备": outRequest_Body.machineId = GlobalContext.S7_MachineId; // 装备ID(可配置) outRequest_Body.stationId = GlobalContext.S7_StationId; // ⼯位ID(可配置) break; default: break; } outRequest_Body.clientMac = GlobalContext.MacStr; // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX outRequest_Body.clientTime = processData.Test_time; // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff outRequest_Body.unitSn = sn; // 产品SN outRequest_Body.state = pass ? "PASS" : "FAIL"; // 出站条件 PASS或FAIL outRequest_Body.userId = GlobalContext.MESUserId; // ⽤⼾ID;非必填 outRequest_Body.factoryId = GlobalContext.Factory_Code; // ⼯⼚id;非必填 //outRequest_Body.unitData.vehicleData.Add( // new XmMES_StationOutRequest_Body.XmStationOut_VehicleData() // { // vehicleSn = vehicleSn, // vehicleType = string.Empty, // slot = vehicleSlot // }); // 设备数据 - 载具信息 mesJson = JsonConvert.SerializeObject(outRequest_Body); XmMES_StationOutResponse response = new XmMES_StationOutResponse(); string mesRet = string.Empty; int i = 0; while (i < 2) // 404等会多次尝试上传 { response = XiaomiMESHttp_StationOutbound.StationOut(outRequest_Body); if (response != null && response.header.code == "200") break; else if (response != null && response.header.code != "503") // 503是服务器报错 i++; i++; mesRet = $"[{response?.header?.code}]{response?.header?.desc}"; // 记录失败原因 OnMessage(LogType.Error, "上传出站数据到MES服务器---失败!正在重新上传!接口报错信息:" + mesRet + "参数:" + mesJson); } AddMessage_Station(stationNameStr, LogType.Info, "[" + processItem + "]上传出站数据到MES服务器---" + mesRet); if (response != null && response.header.code == "200") mesUpload = 1; else mesUpload = 0; } catch (Exception ex) { mesUpload = 0; string str = ex.StackTrace; AddMessage_Station(stationNameStr, LogType.Error, $"PLC上传出站数据MES报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1)); } } else mesUpload = 2; // 上传IOT string iotJson = string.Empty; if (GlobalContext.IsMqttSendProcessData) { try { string id = processData.ID; string guid = Guid.NewGuid().ToString(); // 过站结果 0 PassStationResultRequest passStaResultRequ = new PassStationResultRequest(); passStaResultRequ.pass_station_id = guid; // 过站唯⼀标识(36位) passStaResultRequ.project_code = GlobalContext.Project_Code; // 项⽬编码 passStaResultRequ.factory_code = GlobalContext.Factory_Code; // ⼯⼚Id passStaResultRequ.process_section_code = GlobalContext.Process_Section_Code; // ⼯段编码 passStaResultRequ.line_code = GlobalContext.LineCode; // 线体编码 switch (stationNameStr) { // [S1] Tray盘上料装备 // [S2] FCT // [S3] 值板机 // [S4_1] 载具下线装备 [S4_5] 载具上线装备 // [S5] Tray盘下料装备 case "[S1]Tray盘上料装备": passStaResultRequ.work_station = GlobalContext.S1_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S1_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S1_station; // ⼯位Id break; case "[S2]FCT": passStaResultRequ.work_station = GlobalContext.S2_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S2_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S2_station; // ⼯位Id break; case "[S3]值板机": passStaResultRequ.work_station = GlobalContext.S3_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S3_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S3_station; // ⼯位Id break; case "[S4_1]载具下线装备": passStaResultRequ.work_station = GlobalContext.S4_1_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S4_1_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S4_1_station; // ⼯位Id break; case "[S4_3]提升机1": passStaResultRequ.work_station = GlobalContext.S4_3_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S4_3_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S4_3_station; // ⼯位Id break; case "[S4_4]提升机2": passStaResultRequ.work_station = GlobalContext.S4_4_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S4_4_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S4_4_station; // ⼯位Id break; case "[S4_5]载具上线装备": passStaResultRequ.work_station = GlobalContext.S4_5_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S4_5_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S4_5_station; // ⼯位Id break; case "[S5]Tray盘下料装备": passStaResultRequ.work_station = GlobalContext.S5_work_station; // ⼯站 passStaResultRequ.device_code = GlobalContext.S5_device_code; // 装备编码 passStaResultRequ.station = GlobalContext.S5_station; // ⼯位Id break; default: break; } passStaResultRequ.process_time = processData.Test_time; // 过站时间 passStaResultRequ.slot = "1"; // 槽位编码 passStaResultRequ.sn = processData.Sn; // 产品SN passStaResultRequ.result = pass ? "PASS" : "FAIL"; // 过站结果 passStaResultRequ.work_type = "OUT_STATION"; // 作业类型 iotJson = JsonConvert.SerializeObject(passStaResultRequ); int result_Result = XiaomiMqttClient_Extend.Write_PassStationResult(passStaResultRequ); string result_ResultStr = string.Empty; var try1 = Enum.TryParse(result_Result.ToString(), out XiaomiMqttResponse_ErrCode errCode); if (try1) result_ResultStr = errCode.ToString(); AddMessage_Station(stationNameStr, LogType.Info, "[" + processItem + $"]上传【过站结果 id {id}】到IOT服务器---[" + result_Result + "]" + result_ResultStr); iotUpload = result_Result == 0 ? 1 : 0; //// 过站数据 0 int result_Log = 0; { //List passStaLogRequs = new List(); //PassStationLogRequest passStaLogRequ = new PassStationLogRequest(); //passStaLogRequ.pass_station_id = guid; //passStaLogRequ.sn = processData.Sn; // 产品SN //passStaLogRequ.slot ="1"; // 槽位 //passStaLogRequ.test_item_num ="1"; // 测试项序号 1,2,递增 //passStaLogRequ.function_name = "Machine_"+stationNameStr; // 功能名称 //passStaLogRequ.test_item =""; // 测试项 //passStaLogRequ.result_val =""; // 测试值/输出值 //passStaLogRequ.hi_limit =""; // 上限值 //passStaLogRequ.low_limit =""; // 下限值 //passStaLogRequ.status =""; // 测试状态 //passStaLogRequ.test_time =""; // 单项测试时间 //passStaLogRequ.error_code =""; // 错误码 //passStaLogRequ.project_code =""; // 描述 //passStaLogRequs.Add(passStaLogRequ); //int result_Log = XiaomiMqttClient_Extend.Write_PassStationLog(passStaLogRequs); //if (result_Log == 0) //{ // string sql_Upd = ProcessData.ToStringUpdateStatusByID(1, processData.ID); // string ret_Upd = string.Empty; // //ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null); // AddMessage_Station(stationNameStr, LogType.Info, $"更新【过站明细 id {processData.ID}】上传状态---" + ret_Upd); //} //else //{ // OnMessage(LogType.Error, $"上传过站明细到MES服务器---失败!id {processData.ID}"); //} } AddMessage_Station(stationNameStr, LogType.Info, "[" + processItem + $"]上传[{processData.Sn}]过站数据到IOT服务器---" + result_Result + "," + result_Log); } catch (Exception ex) { iotUpload = 0; string str = ex.StackTrace; AddMessage_Station(stationNameStr, LogType.Error, $"PLC上传过站数据IOT报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1)); } } else iotUpload = 2; // 更新上传状态 int mesUpload1 = mesUpload; if (mesUpload1 == 2) mesUpload1 = 0; int iotUpload1 = iotUpload; if (iotUpload1 == 2) iotUpload1 = 0; string sql_Upd = ProcessData.ToStringUpdateStatusByID(mesJson, mesUpload1, iotJson, iotUpload1, processData.ID); string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null); AddMessage_Station(stationNameStr, LogType.Info, $"更新【出站数据 id {processData.ID}】上传状态---" + ret_Upd); if (mesUpload == 2) mesUpload = 1; if (iotUpload == 2) iotUpload = 1; int result = (mesUpload == 1 && iotUpload == 1) ? 1 : 2; return result; } #endregion 出站数据 #region 点检数据 /// /// 选择如何记录点检数据 /// /// /// /// /// /// private int SwitctOneCheckData(OneCheckData oneCheckData, string equipmentCode, string stationNameStr) { //if (DataSwitch == 1) //{ return SaveOneCheckDataByDB(oneCheckData, equipmentCode, stationNameStr); //} //else // 废弃 //{ // SaveOneCheckData(names, contents, results, equipmentCode, stationNameStr); //} } /// /// 添加点检数据ByDB(本地保存;不提交到MES) /// /// 点检数据 /// 设备编号 /// 工站名称 public int SaveOneCheckDataByDB(OneCheckData oneCheckData, string equipmentCode, string stationNameStr) { int upload = 0; //本地数据保存 string sql = oneCheckData.ToStringInsert(upload); string ret = SQLHelper_New.ExecuteNonQuery(sql, null); AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]保存本地点检数据---", ret)); //Task.Run(() => // 上传mes-异步 //{ // //上传mes // string jsonstr = JsonConvert.SerializeObject(oneCheckData); // if (GlobalContext.IsSendCheckOneData) // { // string url = @"HTTP://" + GlobalContext.ServerHost + ":" + GlobalContext.ServerPort + @"/api/ProductionLine/OneCheckData"; // string mesRet = HttpUitls.SubmitDataToMES(url, jsonstr); // AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]上传点检数据到MES---", mesRet)); // if (mesRet == "成功") // { // // 更新上传状态 // string sql_Upd = OneCheckData.ToStringUpdateStatusByID(1, oneCheckData.ID); // string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null); // AddMessage_Station(stationNameStr, LogType.Info, $"更新【点检数据 id {oneCheckData.ID}】上传状态---" + ret_Upd); // } // } //}); return ret == "成功" ? 1 : 0; } /// /// 提交点检数据到MES /// /// 工序编号 = 设备编号 /// 车间订单号 /// public int SubmitToMESByDB(string procedure_code, string stationNameStr, string plcOrder) { // 获取今天的点检数据 string querySQL_Today = new OneCheckData().ToQuerySQL_Today(procedure_code, plcOrder); DataSet ds = SQLHelper_New.Query(querySQL_Today, null); if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { // 拼接所有点检数据 OneCheckData oneCheckDatas_MES = new OneCheckData() { ID = ds.Tables[0].Rows[0][0].ToString(), Line_code = ds.Tables[0].Rows[0][1].ToString(), Line_name = ds.Tables[0].Rows[0][2].ToString(), Equipment_code = ds.Tables[0].Rows[0][3].ToString(), Equipment_name = ds.Tables[0].Rows[0][4].ToString(), Workorder_code = ds.Tables[0].Rows[0][5].ToString(), Procedure_code = ds.Tables[0].Rows[0][6].ToString(), Procedure_name = ds.Tables[0].Rows[0][7].ToString(), Onecheck_empcode = ds.Tables[0].Rows[0][8].ToString(), Onecheck_empname = ds.Tables[0].Rows[0][9].ToString(), Onecheck_time = ds.Tables[0].Rows[0][10].ToString() }; List upd_Ids = new List(); foreach (DataRow row in ds.Tables[0].Rows) { var obj1 = row["Oneckeck_values"]; if (obj1 != null) { upd_Ids.Add(row["ID"].ToString()); List item = JsonConvert.DeserializeObject>(obj1.ToString()); oneCheckDatas_MES.Oneckeck_values.AddRange(item); } } //上传mes string jsonstr = JsonConvert.SerializeObject(oneCheckDatas_MES); if (GlobalContext.IsSendCheckOneData) { string url = @"HTTP://" + GlobalContext.ServerHost + ":" + @"/api/ProductionLine/OneCheckData"; string mesRet = HttpUitls.SubmitDataToMES(url, jsonstr); AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[", stationNameStr, "]PLC通知上传点检数据到MES到---", mesRet)); if (mesRet == "成功") { // 更新上传状态 string sql_Upd = OneCheckData.ToStringUpdateStatusByIDs(1, upd_Ids); string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null); AddMessage_Station(stationNameStr, LogType.Info, $"更新【点检数据 id [{string.Join("','", upd_Ids)}]】上传状态---" + ret_Upd); // 保存最新一条点检数据 到文件中 StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, "S" + procedure_code, "WorkOrderCode", GlobalContext.WorkOrderCode); StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, "S" + procedure_code, "Oneckeck_values", JsonConvert.SerializeObject(oneCheckDatas_MES.Oneckeck_values)); return ret_Upd == "成功" ? 1 : 0; } } } //else //{ // AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[", stationNameStr, "]PLC通知上传点检数据到MES---失败!今天还未点检。")); //} return 0; } /// /// 添加点检数据ByDB(本地保存 + 提交到MES) /// /// 点检数据 /// 设备编号 /// 工站名称 /// public int SaveOneCheckDataByDBAndSubmit(OneCheckData oneCheckData, string equipmentCode, string stationNameStr) { int upload = 0; //本地数据保存 string sql = oneCheckData.ToStringInsert(upload); string ret = SQLHelper_New.ExecuteNonQuery(sql, null); AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]保存本地点检数据---", ret)); Task.Run(() => // 上传mes-异步 { //上传mes string jsonstr = JsonConvert.SerializeObject(oneCheckData); string jsonItems = JsonConvert.SerializeObject(oneCheckData.Oneckeck_values); if (GlobalContext.IsSendCheckOneData) { string url = @"HTTP://" + GlobalContext.ServerHost + ":" + @"/api/ProductionLine/OneCheckData"; string mesRet = HttpUitls.SubmitDataToMES(url, jsonstr); AddMessage_Station(stationNameStr, LogType.Info, string.Concat("[[", equipmentCode, "]", stationNameStr, "]上传点检数据到MES---", mesRet)); if (mesRet == "成功") { // 更新上传状态 string sql_Upd = OneCheckData.ToStringUpdateStatusByID(1, oneCheckData.ID); string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Upd, null); AddMessage_Station(stationNameStr, LogType.Info, $"更新【点检数据 id {oneCheckData.ID}】上传状态---" + ret_Upd); // 保存最新一条点检数据 到文件中 StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, equipmentCode, "WorkOrderCode", GlobalContext.WorkOrderCode); StandardLibrary.IniFile.INIWriteValue(GlobalContext.CheckOneDataPath, equipmentCode, "Oneckeck_values", jsonItems); } } }); return ret == "成功" ? 1 : 0; } /// /// 清空 点检数据 By 工序号、订单号 /// /// 工序号 /// 工站号 /// 订单号 /// /// private int ClearOneCheckDataByDB(string procedure_code, string stationNameStr, string plcOrder) { // 清空 string sql_Det = OneCheckData.ToDeteleByProcedurecodeAndPlcOrder(procedure_code, plcOrder); string ret_Upd = SQLHelper_New.ExecuteNonQuery(sql_Det, null); AddMessage_Station(stationNameStr, LogType.Info, $"清空【工位编号{procedure_code}】【车间订单{plcOrder}】的点检项缓存 ---" + ret_Upd); return ret_Upd == "成功" ? 1 : 2; } /// /// 生产过程中,自动判断 是否 使用上次的点检数据 /// 在工单加工第一个产品时触发该方法 /// 如果工单是上次的点检工单则直接返回成功,工单不是上次的点检工单则使用上个工单的点检数据,上传点检信息 /// /// /// 设备编号 /// 工序编号 /// 点检数据 /// private int SwitctOneCheckData_First(string stationNameStr, string equipmentCode, string accno, string processItem) { string WorkOrderCode = StandardLibrary.IniFile.INIGetStringValue(GlobalContext.CheckOneDataPath, equipmentCode, "WorkOrderCode", string.Empty); //如果当前工单和记录中的工单是一致,表示这个工单是需要点检的,跳过 //如果当前工单和记录中的工单是不一致,表示这个工单和上个工单是同型号的,可以使用上个工单的点检数据 if (GlobalContext.WorkOrderCode == WorkOrderCode) { return 1; } //点检数据 string Oneckeck_values = StandardLibrary.IniFile.INIGetStringValue(GlobalContext.CheckOneDataPath, equipmentCode, "Oneckeck_values", string.Empty); List items = new List(); try { items = JsonConvert.DeserializeObject>(Oneckeck_values); } catch (Exception ex) { return 0; } // 拼接所有点检数据 OneCheckData oneCheckDatas_MES = new OneCheckData() { ID = Guid.NewGuid().ToString(), Line_code = GlobalContext.LineCode, Line_name = GlobalContext.LineName, Equipment_code = equipmentCode, Equipment_name = equipmentCode, Workorder_code = GlobalContext.WorkOrderCode, Procedure_code = accno, Procedure_name = processItem, Onecheck_empcode = "", Onecheck_empname = "", Onecheck_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), Oneckeck_values = items }; // 本地保存 + 提交到MES return SaveOneCheckDataByDBAndSubmit(oneCheckDatas_MES, equipmentCode, stationNameStr); } #endregion 点检数据 #region 报警数据 /// /// 添加报警数据ByDB(提交到MES+本地保存) /// /// 数据 /// 更新而不是新增 public void SaveAlarmDataByDB(string stationNameStr, AlarmData alarmData, bool isUpd) { if (isUpd) { string sql = alarmData.ToStringUpdate(); SQLHelper_New.ExecuteSQL(sql, null); AddMessage_Station(stationNameStr, LogType.Info, "消除报警[" + alarmData.LineName + "-" + alarmData.AlarmDesc + "]完毕!"); } else { string sql = alarmData.ToStringInsert(); SQLHelper_New.ExecuteSQL(sql, null); AddMessage_Station(stationNameStr, LogType.Info, "发生了报警[" + alarmData.LineName + "-" + alarmData.AlarmDesc + "]!"); } } #endregion 报警数据 #region 节拍数据 /// /// 上传节拍数据 /// /// public (short, string) SaveOEEData(int plcNo, string stationNameStr, XiaomiDeviceOEE deviceOEE, string oEEPartNo, string oEEProductSN) { // 上传OEE if (GlobalContext.IsMqttStationInputBegin) { Task.Run(() => { try { StationInputBeginRequest oee = new StationInputBeginRequest(); oee.action = deviceOEE.ToString(); // 节拍动作(XiaomiDeviceOEE) oee.beat_tm = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); // 节拍发⽣时间 oee.action_subject = oEEPartNo; // 该动作操作的⽬标对象(SN) oee.action_subject_parent = oEEProductSN; // ⼤板SN/载具SN oee.action_location = GlobalContext.S1_station; // 该动作的位置信息(⼯位、槽位),如:F06-GSTPLA11_01-SLOT-01 switch (stationNameStr) { case "[S1]Tray盘上料装备": oee.action_location = GlobalContext.S1_station; break; case "[S2]FCT": oee.action_location = GlobalContext.S2_station; break; case "[S3]值板机": oee.action_location = GlobalContext.S3_station; break; case "[S4_1]载具下线装备": oee.action_location = GlobalContext.S4_1_station; break; case "[S4_3]提升机1": oee.action_location = GlobalContext.S4_3_station; break; case "[S4_4]提升机2": oee.action_location = GlobalContext.S4_4_station; break; case "[S4_5]载具上线装备": oee.action_location = GlobalContext.S4_5_station; break; case "[S5]Tray盘下料装备": oee.action_location = GlobalContext.S5_station; break; } oee.action_material = string.Empty; // 该动作的物料信息 oee.extra = string.Empty; // 额外信息 oee.class_level_1 = string.Empty; // 分类层级1 oee.class_level_2 = string.Empty; // 分类层级2 oee.class_level_3 = string.Empty; // 分类层级3 int result = XiaomiMqttClient_Extend.Write_StationInputBegin(oee); string msg = $"[{result}]"; bool errCodeParse = Enum.TryParse(result.ToString(), out XiaomiMqttResponse_ErrCode errCode); msg += errCodeParse ? errCode.ToString() : "ERR_UNKOWN"; AddMessage(LogType.Info, stationNameStr + $"_异步上传节拍接口;接口结果:-- {msg}"); } catch (Exception ex) { string str = ex.StackTrace; AddMessage(LogType.Error, $"PLC{plcNo}_{stationNameStr} 异步上传节拍接口出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1)); } }); return ((short)1, "异步上传中!"); } else return ((short)1, "未启用上传!"); } #endregion 节拍数据 #endregion 保存数据 } }