using JinYuan.Helper; using JinYuan.MES.Enums; using JinYuan.Models; using JinYuan.VirtualDataLibrary; using Language; using PLC; using PLCCommunication; using PLCCommunication.Common; using PLCCommunication.Common.DataConvert; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace JinYuan.ControlCenters { public partial class ControlCenter { public object FileLock = new object();//文件锁 #region 上料工位(数据处理) /// /// 上料工位A /// //上料解析 private async Task FeedingStationA(JYResult bArrays, object plcModel) { PlcGroup pf = plcModel as PlcGroup; var sw = new Stopwatch(); var sw1 = new Stopwatch(); if (bArrays.IsSuccess && bArrays.Content != null) { try { sw.Start(); #region 数据初始化 //解析数据 List list = new List();//实体 List listRes = GetList(8, 2);//默认为1,良品 List listMark = GetList(8, false);//有料标志 List listCode = GetList(8, "");//电芯码 List listRemark = GetList(8, "");//备注 List listFlag = GetList(8, "0");//是否上传标志 List listResult = GetList(8, "NG");//结果 List listMesage = GetList(8, "");//mesMesage List listRfid = GetList(8, "");//RFID List listMesResType = GetList(8, MesResType.B);//mesType #endregion #region 数据解析 byte[] bytes = bArrays.Content.ByteReverse();//高低位转换 sw1.Restart(); //有料标志 for (int i = 0; i < listMark.Count; i++) { listMark[i] = ShortLib.GetShortFromByteArray(bArrays.Content, (i * 2)) == 1 ? true : false;// 从D2021开始 if (listMark[i]) { LogHelper.Instance.WriteLog($"进站A有料标志为1".Translated() + "通道号".Translated() + $":{i}", "loca进站"); #region 数据读取 //条码长度 int codeLength = ShortLib.GetShortFromByteArray(bArrays.Content, (i * 2) + (20 * 2));// 从D2041开始 if (codeLength > 0) { //RFID码 listRfid[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, (i * 50) + (79 * 2), codeLength, System.Text.Encoding.ASCII).// 从D2100开始 Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); string currentRfid = listRfid[i]; DataTable dt = null; // 1. 首先尝试从 dbServer2 查询 LogHelper.Instance.WriteLog($"通道[{i}], RFID={currentRfid}", "loca进站"); dt = CommonMethods.dbServer2.QueryDataTable(CommonMethods.dBSQL.GetRFIDList(currentRfid)); // 2. 如果 dbServer2 没有结果,回退到 dbServer 查询 if (dt == null || dt.Rows.Count == 0) { LogHelper.Instance.WriteLog($"dbServer2未查到RFID={currentRfid}对应的条码".Translated(), "loca进站"); dt = CommonMethods.dbServer.QueryDataTable(CommonMethods.dBSQL.GetRFIDList(currentRfid)); } // 直接处理当前通道 if (dt != null && dt.Rows.Count > 0) { // 取第一条匹配记录 listCode[i] = dt.Rows[0]["BarCode"].ToString(); LogHelper.Instance.WriteLog($"查到RFID={currentRfid}对应的条码:{listCode[i]}".Translated(), "loca进站"); } else { listCode[i] = "ERROR"; LogHelper.Instance.WriteLog($"dbServer未查到RFID={currentRfid}对应的条码".Translated(), "loca进站"); } } #endregion #region 数据保存 AGearEntity m = new AGearEntity(); m.BarCode = listCode[i]; m.RFID = listRfid[i]; m.ChannelNo = (i + 1).ToString(); m.TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); list.Add(m); #endregion } else { #region 数据保存 AGearEntity m = new AGearEntity(); m.BarCode = ""; m.RFID = ""; m.Remark = $"本通道{i}无料"; m.ChannelNo = (i + 1).ToString(); m.TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); list.Add(m); #endregion CommonMethods.AddDataMonitorLog(0, "进站上料工位A有料标志为0".Translated() + "通道号".Translated() + $":{i}"); } } sw1.Stop(); LogHelper.Instance.WriteLog($"数据解析 耗时:{sw1.Elapsed.TotalMilliseconds}ms", "A进站性能"); string strAllBar = ""; var index = 0; /* int startBarCodePlcAddr = 2350; //int.TryParse(pf.VarList[1].VarAddress.Trim('D'), out startPlcAddr); //写入·结果反馈 for (int i = 0; i < listMark.Count; i++) { int plcAddr = startBarCodePlcAddr + i * 50; if (listCode[i] != "") { strAllBar = list[i].BarCode + GetString_0(50 - list[i].BarCode.Length); } else strAllBar = GetString_0(50); byte[] Codebytes = Encoding.Default.GetBytes(strAllBar).ByteReverse(); var JResult = CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D"+ plcAddr.ToString(), Codebytes, PLC.DataType.ArrByte); if (JResult != null) { LogHelper.Instance.WriteLog($"电芯进站A, 通道号: {i}, 往{"D" + plcAddr.ToString()} 写条码:{strAllBar},写入是否成功:{JResult.IsSuccess}, Message= {JResult.Message}", "loca进站"); } else { LogHelper.Instance.WriteLog($"电芯进站A, 通道号: {i}, 往{"D" + plcAddr.ToString()} 写条码:{strAllBar},JResult=null", "loca进站"); } } LogHelper.Instance.WriteLog($"电芯进站A, 往D2350 写条码:{strAllBar}", "loca进站");*/ sw1.Restart(); for (int k = 0; k < listRfid.Count; k++) { if (listCode[k] != "") { strAllBar += list[k].BarCode + GetString_0(50 - list[k].BarCode.Length); } else strAllBar += GetString_0(50); } byte[] Codebytes = Encoding.Default.GetBytes(strAllBar).ByteReverse(); CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D2350", Codebytes, PLC.DataType.ArrByte); sw1.Stop(); LogHelper.Instance.WriteLog($"电芯进站A, 往D2350 写条码:{strAllBar},总耗时:{sw1.Elapsed.TotalMilliseconds}ms", "A进站性能"); sw1.Restart(); JYResult resByte = CommonMethods.plcDevices[pf.PlcNum - 1].ReadValue>("D2350", PLC.DataType.ArrByte, 400); sw1.Stop(); LogHelper.Instance.WriteLog($"电芯进站A, 读 D2350 条码总耗时:{sw1.Elapsed.TotalMilliseconds}ms", "A进站性能"); sw1.Restart(); List listCodeTmp = GetList(8, "");//电芯码 byte[] bytes2 = resByte.Content.ByteReverse(); for (int i = 0; i < listRfid.Count; i++) { //条码 listCodeTmp[i] = StringLib.GetStringFromByteArrayByEncoding(bytes2, i * 50, 50, System.Text.Encoding.ASCII).// 从D2350开始 Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); } sw1.Stop(); LogHelper.Instance.WriteLog($"电芯进站A, 解析读取 D2350 条码:{string.Join(",", listCodeTmp)},总耗时:{sw1.Elapsed.TotalMilliseconds}ms", "A进站性能"); for (int k = 0; k < listRfid.Count; k++) { if (listCode[k] != listCodeTmp[k]) { LogHelper.Instance.WriteError($"进站A工位,通道:{k},条码写入与读取不一致:{listCode[k]}=>{listCodeTmp[k]}", "loca进站"); } } #endregion #region 上传MES if (list.Count > 0) { if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected) { var allMesMessages = new List(); var allMesResTypes = new List(); var allFlags = new List(); foreach (var item in list) { if (String.IsNullOrEmpty(item.RFID) || item.RFID.Trim() == "ERROR") { // 收集失败结果 allMesMessages.Add($"本通道{item.ChannelNo}无料"); allMesResTypes.Add(MesResType.B); allFlags.Add("2"); continue; } else if (String.IsNullOrEmpty(item.BarCode) || item.BarCode.Trim() == "ERROR" || !IsAlphaNumeric(item.BarCode)) { // 收集失败结果 allMesMessages.Add("扫码不良"); allMesResTypes.Add(MesResType.B); allFlags.Add("2"); continue; } // 每次只上传一个条码 var singleCodeList = new List { item.BarCode }; var (success1, mesage1, mesResType1) = await CommonMethods.hbgMes.ManyCellInStationAsync( CommonMethods.mesConfig.ProductInStation, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.mesUserName, singleCodeList); // 单条码列表 allMesMessages.Add(mesage1[0]); allMesResTypes.Add(mesResType1[0]); if (success1) { allFlags.Add("1"); } else { allFlags.Add("2"); // 记录失败状态 listRes = GetList(8, 3); listRemark = GetList(8, ""); if (mesage1.Count > 0 && mesage1[0].Contains("一个或多个错误")) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short); // 反馈PLC结果 } } } // 将收集的结果赋给主列表 listMesage = allMesMessages; listMesResType = allMesResTypes; listFlag = allFlags; } else { listRes = GetList(8, 3); listRemark = GetList(8, "MES断连".Translated()); listFlag = GetList(8, "2"); CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short);//反馈MES结果 } } #endregion #region 数据组合 for (int i = 0; i < list.Count; i++) { if (!listMark[i]) { listRes[i] = 0; listResult[i] = "OK"; listRemark[i] = "无料"; } else if (String.IsNullOrEmpty(list[i].BarCode) || list[i].BarCode.Trim() == "ERROR" || !IsAlphaNumeric(list[i].BarCode)) { listRes[i] = 2; listResult[i] = "NG"; listRemark[i] = "电芯码不良".Translated(); } else { int codeIndex = i;//listCode.Count - i - 1; listResult[i] = "OK,"; switch (listMesResType[codeIndex]) { case MesResType.A:// 停线,设备报警停机 listResult[i] += "MES NG"; listRemark[i] += listMesage[codeIndex]; listRes[i] = 3;//10 break; case MesResType.B:// 排出 listResult[i] += "MES NG"; listRemark[i] += listMesage[codeIndex]; listRes[i] = 3;//2 break; case MesResType.C:// 警示 case MesResType.D:// 条码上传OK listResult[i] += "MES OK";//MES认为是可以当成良品流下去的 listRemark[i] += listMesage[codeIndex]; listRes[i] = 1; break; default: listResult[i] += "MES NG"; listRemark[i] += listMesage[codeIndex]; listRes[i] = 3;//2 break; } } list[i].Result = listResult[i].TrimStart(',').TrimEnd(','); list[i].Remark = listRemark[i].TrimStart(',').TrimEnd(','); list[i].Flag = listFlag[i]; } #endregion LogHelper.Instance.WriteError($"进站A工位发送反馈{listRes}给PLC", "loca进站"); #region 数据反馈&保存 sw1.Start(); _ = Task.Run(async () => { try { await SaveFeedingDataAsync(list); } catch (Exception ex) { LogHelper.Instance.WriteError($"SaveFeedingDataAsync 异常{ex.Message}", "SysErrorLog"); } }); sw1.Stop(); LogHelper.Instance.WriteLog($"SaveFeedingDataAsync 耗时:{sw1.Elapsed.TotalMilliseconds}ms", "A进站性能"); sw1.Restart(); //写入·结果反馈 JYResult result = CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue(pf.VarList[1].VarAddress, listRes.ToArray(), PLC.DataType.ArrShort);//判断结果写入PLC if (result != null) { string strres = "进站A工位发送给PLC".Translated() + $",[{pf.VarList[1].VarAddress}]:{string.Join(",", listRes)}"; CommonMethods.AddDataMonitorLog(0, strres); LogHelper.Instance.WriteLog($"【进站A】 反馈条码给PLC,result != null, ret={result.IsSuccess}, message={result.Message}", "loca进站"); } sw1.Stop(); LogHelper.Instance.WriteLog($"【进站A】 反馈结果给PLC,耗时{sw1.ElapsedMilliseconds}ms, 结果:{string.Join(",", listRes)}", "A进站性能"); sw1.Restart(); //读取结果显示 //数据存储 -异步处理 LogHelper.Instance.WriteLog("电芯进站A 开始置0", "loca进站"); bool bRet = CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0);//置位0 sw1.Stop(); LogHelper.Instance.WriteLog($"电芯进站A 置0完成{bRet},耗时{sw1.ElapsedMilliseconds}ms", "A进站性能"); #endregion } catch (Exception ex) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteError($"电芯进站A线程数据处理:{ex}", "SysErrorLog"); } sw.Stop(); ////输出上料数据处理耗时: CommonMethods.AddDataMonitorLog(0, "卷芯进站共耗时".Translated() + $":{sw.Elapsed.TotalMilliseconds}ms"); } else { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteLog($"电芯进站A线程数据处理bArrays.IsSuccess:{bArrays.IsSuccess}", "loca进站"); } } #region 保存上料数据 /// /// 保存上料数据到数据 /// /// private async Task SaveFeedingDataAsync(List list) { LogHelper.Instance.WriteLog($"SaveFeedingDataAsync 开始", "loca进站"); //数据的保存 try { if (list != null && list.Count > 0) { // 异步执行所有删除操作 var deleteTasks = new List(); var sw1 = new Stopwatch(); sw1.Start(); foreach (AGearEntity m in list) { if (m.RFID != null) { // 为每个RFID启动删除任务 deleteTasks.Add(TryDeleteRfidAsync(m.RFID)); } } LogHelper.Instance.WriteLog("SaveFeedingData prepare deleteTasks", "loca进站"); // 等待所有删除操作完成 await Task.WhenAll(deleteTasks).ConfigureAwait(false); sw1.Stop(); LogHelper.Instance.WriteLog($"deleteTasks false wait 耗时:{sw1.Elapsed.TotalMilliseconds}ms", "loca进站"); sw1.Restart(); bool b = await CommonMethods.db.AddReturnBoolAsync(list).ConfigureAwait(false); sw1.Stop(); LogHelper.Instance.WriteLog($"AddReturnBoolAsync false wait 耗时:{sw1.Elapsed.TotalMilliseconds}ms", "loca进站"); //数据显示 CommonMethods.ShowFeedingDelegate.Invoke(list); LogHelper.Instance.WriteLog("SaveFeedingData ShowFeedingDelegate", "loca进站"); } } catch (Exception ex) { LogHelper.Instance.WriteError($"卷芯上料保存处理异常:{ex}", "SysErrorLog"); } } #endregion #endregion #region 下料工位(数据处理) /// /// 电芯出站A /// /// /// private async Task BlankingStationA(JYResult bArrays, object plcModel) { PlcGroup pf = plcModel as PlcGroup; var sw = new Stopwatch(); var swTotal = new Stopwatch(); if (bArrays.IsSuccess && bArrays.Content != null) { try { swTotal.Start(); #region 初始化数据 List list = new List(); List listRes = GetList(8, 2);//默认为1,良品 List listMark = GetList(8, false);//有料标志 List listCode = GetList(8, "");//电芯码 List listRemark = GetList(8, "");//备注 List listFlag = GetList(8, "0");//是否上传标志 List listResult = GetList(8, "OK");//结果 List listMesMesage = GetList(8, "");//mesMesage //List listRfid = GetList(8, "");//RFID List listcavityLeakageRateSetValue = GetList(8, ""); List listproductLeakageRateSetValue = GetList(8, ""); List listcavityLeakageRateActualValue = GetList(8, ""); List listproductLeakageRateActualValue = GetList(8, ""); List listpalletNumber = GetList(8, "");//托盘号 List listMesResType = GetList(8, MesResType.B);//mesType //ushort listRes = 1; // 默认为1,良品 string lst_RFIDCodes = ""; // 托杯码 string lst_BarCodes = ""; // 条码 //string cavityLeakageRateSetValue;// 清腔漏率设定值 //string productLeakageRateSetValue;// 产品漏率设定值 string leakPressureSetValue;// 检漏口压力设定值 //string cavityLeakageRateActualValue;// 清腔漏率实际值 //string productLeakageRateActualValue;// 产品漏率实际值 string leakPressureActualValue;// 检漏口压力实际值 string palletNumber;// 托盘号 int result = 0;//总结果 int info = 0;//NG详情 #endregion #region 数据解析 sw.Start(); byte[] bytes = bArrays.Content.ByteReverse(); //有料标志 for (int i = 0; i < listMark.Count; i++) { listMark[i] = ShortLib.GetShortFromByteArray(bArrays.Content, i * 2) == 1 ? true : false;// 从D4021开始 获取标志位为true的电芯位 if (listMark[i]) { #region 数据读取 //条码长度 int codeLength = ShortLib.GetShortFromByteArray(bArrays.Content, (i * 2) + (20 * 2));// 从D4041开始 if (codeLength > 0) { //条码 listCode[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, i * 50 + (79 * 2), codeLength, System.Text.Encoding.ASCII).// 从D4100开始 Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); listCode[i] = Regex.Replace(listCode[i], @"[^a-zA-Z0-9]", ""); } else { listCode[i] = "ERROR"; } int palletcodeLength = (int)FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (675 * 2)); if (palletcodeLength > 0) { listpalletNumber[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, i * 50 + (707 * 2), palletcodeLength, System.Text.Encoding.ASCII). Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); } else { listpalletNumber[i] = "ERROR"; } listcavityLeakageRateSetValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (579 * 2), DataFormat.CDAB).ToString(); // 清腔漏率设定值 D4600 579 科学计数法 listproductLeakageRateSetValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (595 * 2), DataFormat.CDAB).ToString(); // 产品漏率设定值 D4616 595 科学计数法 leakPressureSetValue = GetValueFromByteArray(bArrays.Content, "leakPressureSetValue", i * 4);// 腔体真空设定值 D4632 611 listcavityLeakageRateActualValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (627 * 2), DataFormat.CDAB).ToString(); // 清腔漏率实际值 D4648 627 listproductLeakageRateActualValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (643 * 2), DataFormat.CDAB).ToString(); // 产品漏率实际值 D4664 643 leakPressureActualValue = GetValueFromByteArray(bArrays.Content, "leakPressureActualValue", i * 4);// 腔体真空实际值 D4680 659 //palletNumber = GetValueFromByteArray(bArrays.Content, "palletNumber", i * 4);// 托盘号 D4696 675 palletNumber = listpalletNumber[i];// 托盘号 result = int.Parse(GetValueFromByteArray(bArrays.Content, "result", i * 2)); // 总结果 D4712 691 info = int.Parse(GetValueFromByteArray(bArrays.Content, "info", i * 2));// NG详情 D4720 699 //lst_RFIDCodes = listRfid[i];//StringLib.GetStringFromByteArrayByEncoding(bytes, 0, 39, Encoding.ASCII).Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); // RFID D3200-3219 lst_BarCodes = listCode[i];//条码 LogHelper.Instance.WriteLog($"BlankingStationA 正常下料, {listCode[i]}, 总结果: {result}, NG详情:{info}。清腔漏率设定值:{listcavityLeakageRateSetValue[i]},清腔漏率实际值:{listcavityLeakageRateActualValue[i]};产品漏率设定值:{listproductLeakageRateSetValue[i]},产品漏率实际值:{listproductLeakageRateActualValue[i]};腔体真空设定值:{leakPressureSetValue},腔体真空实际值:{leakPressureActualValue}", "loca出站A"); #endregion #region 数据判断 BGearEntity m = new BGearEntity { ChannelNo = (i + 1).ToString(), TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), //RFID = lst_RFIDCodes, BarCode = lst_BarCodes, CavityLeakageRateSetValue = listcavityLeakageRateSetValue[i], ProductLeakageRateSetValue = listproductLeakageRateSetValue[i], LeakPressureSetValue = leakPressureSetValue, CavityLeakageRateActualValue = listcavityLeakageRateActualValue[i], ProductLeakageRateActualValue = listproductLeakageRateActualValue[i], LeakPressureActualValue = leakPressureActualValue, PalletNumber = palletNumber, Flag = "0", Flag1 = "2", Result = result == 1 ? "OK" : "NG", Info = info.ToString("f3"), MaterialCode = CommonMethods.mesConfig.MaterialCode, }; list.Add(m); #endregion } else { #region 数据判断 BGearEntity m = new BGearEntity { ChannelNo = (i + 1).ToString(), TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), BarCode = "", RFID = "", Flag = "0", Flag1 = "2", Result = "NG", MaterialCode = CommonMethods.mesConfig.MaterialCode, }; list.Add(m); #endregion CommonMethods.AddDataMonitorLog(0, "出站下料工位A有料标志为0".Translated() + "通道号".Translated() + $":{i}"); } } sw.Stop(); LogHelper.Instance.WriteLog($"A出站数据解析耗时: {sw.ElapsedMilliseconds}ms", "loca出站A"); #endregion #region 数据上传 sw.Restart(); if (list.Count > 0) { if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected)//点击切换mes状态或者是否连接 { // 初始化结果收集列表 var tempMesMessages = new List(); var tempMesResTypes = new List(); var tempFlags = new List(); foreach (var item in list) { if (String.IsNullOrEmpty(item.BarCode) || item.BarCode.Trim() == "ERROR" || !IsAlphaNumeric(item.BarCode)) { // 收集失败结果 tempMesMessages.Add("扫码不良"); tempMesResTypes.Add(MesResType.C); tempFlags.Add("2"); continue; } // 创建单个电池的列表 var singleBatteryList = new List { item }; // 调用MES接口(每次只传一个电池) var (success, mesage, mesResType) = await CommonMethods.hbgMes.ManyCellOutStationAsync( CommonMethods.mesConfig.ProductOutStation, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.ModelName, CommonMethods.mesConfig.mesUserName, singleBatteryList, 1, CommonMethods.mesConfig.materialLotCodeLocator); tempMesMessages.Add(mesage[0]); tempMesResTypes.Add(mesResType[0]); if (success) { tempFlags.Add("1"); } else { tempFlags.Add("2"); // 记录失败状态 listRes = GetList(8, 3); listRemark = GetList(8, ""); if (mesage.Count > 0 && mesage[0].Contains("一个或多个错误")) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short); // 反馈PLC结果 } } } // 将收集的结果赋给主列表 listMesMesage = tempMesMessages; listMesResType = tempMesResTypes; listFlag = tempFlags; } else { listRes = GetList(8, 3); listRemark = GetList(8, "MES断连".Translated() + ","); listFlag = GetList(8, "2"); CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short);//反馈MES结果 } } sw.Stop(); LogHelper.Instance.WriteLog($"A出站mes 上传耗时: {sw.ElapsedMilliseconds}ms", "loca出站A"); #endregion #region 上传产品结果参数 if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected) { sw.Restart(); _ = Task.Run(async () => { try { await UpProducResultParamAsync(list); } catch (Exception ex) { LogHelper.Instance.WriteError($"UpProducResultParamAsync 异常{ex.Message}", "SysErrorLog"); } }); sw.Stop(); LogHelper.Instance.WriteLog($"A出站上传结果参数 UpProducResultParamAsync 耗时: {sw.ElapsedMilliseconds}ms", "loca出站A"); } #endregion #region 数据组合 sw.Restart(); for (int i = 0; i < list.Count; i++) { if (!listMark[i]) { listRes[i] = 0; listResult[i] = "OK"; listRemark[i] = "无料"; } else if (String.IsNullOrEmpty(list[i].BarCode) || list[i].BarCode.Trim() == "ERROR" || !IsAlphaNumeric(list[i].BarCode)) { listRes[i] = 2; listResult[i] = "NG"; list[i].Info = "电芯码不良".Translated(); listFlag[i] = "2"; } else { string strErr = ""; listResult[i] = list[i].Result; list[i].Info = list[i].Result == "OK" ? "" : list[i].Info; if (!CheckValue(list[i])) { listResult[i] += ",数据异常"; listRemark[i] += $"数据异常"; listRes[i] = 2; listFlag[i] = "2"; } // 本地判断OK,MES判断OK else if (listResult[i] == "OK" && listMesResType[i] == MesResType.D) { listResult[i] += ",MES OK"; list[i].Info = "良品".Translated(); listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; } // 本地判断OK,MES判断NG else if (listResult[i] == "OK" && listMesResType[i] != MesResType.D) { switch (listMesResType[i]) { case MesResType.A: // 停线,设备报警停机 listResult[i] += ",MES NG"; listRemark[i] += $"A,{listMesMesage[i]}"; listRes[i] = 3;//10 listFlag[i] = "2"; break; case MesResType.B: // MES不良 listResult[i] += ",MES NG"; listRemark[i] += $"B,{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; break; case MesResType.C: // 警示 listResult[i] += ",MES OK"; // MES认为是可以当成良品流下去的 listRemark[i] += $"Alarm:{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; break; case MesResType.D: // 条码上传OK listResult[i] += ",MES OK"; listRemark[i] += $"D,{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; break; default: listResult[i] += ",MES NG"; listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; break; } } // 本地判断NG,MES判断OK else if (listResult[i] == "NG" && listMesResType[i] == MesResType.D) { listResult[i] += ",NG料,MES OK"; listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 2; listFlag[i] = "2"; } // 本地判断NG,MES判断NG else if (listResult[i] == "NG" && listMesResType[i] != MesResType.D) { listResult[i] += ",NG料,MES NG"; listRemark[i] += $"{listMesResType[i].ToString()},{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; } // 其他情况 else { listResult[i] += ",MES NG"; listRemark[i] += listMesMesage[i]; listRes[i] = 3;//9 listFlag[i] = "2"; } } list[i].Result = listResult[i].TrimStart(',').TrimEnd(','); list[i].Remark = listRemark[i].TrimStart(',').TrimEnd(','); list[i].Flag = listFlag[i]; } sw.Stop(); LogHelper.Instance.WriteLog($"A出站 数据组合 上传耗时: {sw.ElapsedMilliseconds}ms", "loca出站A"); #endregion #region 数据保存&上传 sw.Restart(); // 数据存储 - 异步处理 _ = Task.Run(async () => { try { await SaveBlankingDataAsync(list); } catch (Exception ex) { LogHelper.Instance.WriteError($"SaveBlankingDataAsync 异常{ex.Message}", "SysErrorLog"); } }); sw.Stop(); LogHelper.Instance.WriteLog($"A出站存储数据耗时: SaveBlankingDataAsync: {sw.ElapsedMilliseconds}ms", "loca出站A"); sw.Restart(); if (pf.IsFeedbackPlc) { //写入·结果反馈 JYResult result1 = CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue(pf.VarList[1].VarAddress, listRes.ToArray(), PLC.DataType.ArrShort);//判断结果写入PLC if (result1 != null) { string strres = "出站A工位发送给PLC".Translated() + $",[{pf.VarList[1].VarAddress}]:{string.Join(",", listRes)}"; CommonMethods.AddDataMonitorLog(0, strres); LogHelper.Instance.WriteLog($"A出站发送信息给PLC:{string.Join(",", listRes)}", "loca出站A"); } } sw.Stop(); LogHelper.Instance.WriteLog($"A出站 PLC 反馈结果 耗时: {sw.ElapsedMilliseconds}ms", "loca出站A"); sw.Restart(); if (CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0))//置位0 { LogHelper.Instance.WriteLog($"A出站给PLC清0成功", "loca出站A"); } else { int count = 0; bool success = false; do { success = CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); count++; LogHelper.Instance.WriteLog($"A出站给PLC清0失败第{count + 1}次复清结果: {success},", "loca出站A"); } while (count < 3 && success == false); } sw.Stop(); LogHelper.Instance.WriteLog($"A出站 PLC 置0 耗时: {sw.ElapsedMilliseconds}ms", "loca出站A"); #endregion } catch (Exception ex) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteLog($"电芯出站A线程数据处理:{ex}", "SysErrorLog"); } swTotal.Stop(); // 输出上料数据处理耗时: CommonMethods.AddDataMonitorLog(0, "电芯出站A共耗时".Translated() + $":{swTotal.Elapsed.TotalMilliseconds}ms"); LogHelper.Instance.WriteLog($"A出站 总耗时: {swTotal.ElapsedMilliseconds}ms", "loca出站A"); } else { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteLog($"电芯进站A 线程数据处理bArrays.IsSuccess:{bArrays.IsSuccess}", "loca出站A"); } } private bool CheckValue(BGearEntity m) { if (m.LeakPressureSetValue == "0" || m.LeakPressureActualValue == "0" || m.ProductLeakageRateActualValue == "0" || m.ProductLeakageRateSetValue == "0") return false; return true; } /// /// 电芯出站B /// /// /// private async Task BlankingStationB(JYResult bArrays, object plcModel) { PlcGroup pf = plcModel as PlcGroup; var sw = new Stopwatch(); var swTotal = new Stopwatch(); if (bArrays.IsSuccess && bArrays.Content != null) { try { swTotal.Start(); #region 初始化数据 List list = new List(); List listRes = GetList(8, 2);//默认为1,良品 List listMark = GetList(8, false);//有料标志 List listCode = GetList(8, "");//电芯码 List listRemark = GetList(8, "");//备注 List listFlag = GetList(8, "0");//是否上传标志 List listResult = GetList(8, "OK");//结果 List listMesMesage = GetList(8, "");//mesMesage List listRfid = GetList(8, "");//RFID List listBar = GetList(8, "");//钢壳码 List listcavityLeakageRateSetValue = GetList(8, ""); List listproductLeakageRateSetValue = GetList(8, ""); List listcavityLeakageRateActualValue = GetList(8, ""); List listproductLeakageRateActualValue = GetList(8, ""); List listpalletNumber = GetList(8, ""); List listMesResType = GetList(8, MesResType.B);//mesType //ushort listRes = 1; // 默认为1,良品 string lst_RFIDCodes = ""; // 托杯码 string lst_BarCodes = ""; // 条码 string cavityLeakageRateSetValue;// 清腔漏率设定值 string productLeakageRateSetValue;// 产品漏率设定值 string leakPressureSetValue;// 检漏口压力设定值 string cavityLeakageRateActualValue;// 清腔漏率实际值 string productLeakageRateActualValue;// 产品漏率实际值 string leakPressureActualValue;// 检漏口压力实际值 string palletNumber;// 托盘号 int result = 0;//总结果 int info = 0;//NG详情 #endregion #region 数据解析 sw.Start(); byte[] bytes = bArrays.Content.ByteReverse(); //有料标志 for (int i = 0; i < listMark.Count; i++) { listMark[i] = ShortLib.GetShortFromByteArray(bArrays.Content, i * 2) == 1 ? true : false;// 从D6021开始 if (listMark[i]) { #region 数据读取 //条码长度 int codeLength = ShortLib.GetShortFromByteArray(bArrays.Content, (i * 2) + (20 * 2));// 从D4041开始 if (codeLength > 0) { //条码 listBar[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, i * 50 + (79 * 2), codeLength, System.Text.Encoding.ASCII).// 从D4100开始 Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); listBar[i] = Regex.Replace(listBar[i], @"[^a-zA-Z0-9]", ""); } else { listBar[i] = "ERROR"; } int palletcodeLength = (int)FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (675 * 2)); if (palletcodeLength > 0) { listpalletNumber[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, i * 50 + (707 * 2), palletcodeLength, System.Text.Encoding.ASCII). Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); } else { listpalletNumber[i] = "ERROR"; } listCode[i] = listBar[i]; listcavityLeakageRateSetValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (579 * 2), DataFormat.CDAB).ToString(); // 清腔漏率设定值 D6600 579 listproductLeakageRateSetValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (595 * 2), DataFormat.CDAB).ToString(); // 产品漏率设定值 D6616 595 leakPressureSetValue = GetValueFromByteArray(bArrays.Content, "leakPressureSetValue", i * 4);// 检漏口压力设定值 D6632 611 listcavityLeakageRateActualValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (627 * 2), DataFormat.CDAB).ToString(); // 清腔漏率实际值 D6648 627 listproductLeakageRateActualValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (643 * 2), DataFormat.CDAB).ToString(); // 产品漏率实际值 D6664 643 leakPressureActualValue = GetValueFromByteArray(bArrays.Content, "leakPressureActualValue", i * 4);// 检漏口压力实际值 D6680 659 palletNumber = listpalletNumber[i];// 托盘号 result = int.Parse(GetValueFromByteArray(bArrays.Content, "result", i * 2)); // 总结果 D6712 691 info = int.Parse(GetValueFromByteArray(bArrays.Content, "info", i * 2));// NG详情 D6720 699 lst_RFIDCodes = listRfid[i];//StringLib.GetStringFromByteArrayByEncoding(bytes, 0, 39, Encoding.ASCII).Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); // RFID D3200-3219 lst_BarCodes = listCode[i]; LogHelper.Instance.WriteLog($"BlankingStationB 正常下料, {listCode[i]}, 总结果: {result}, NG详情:{info}。清腔漏率设定值:{listcavityLeakageRateSetValue[i]},清腔漏率实际值:{listcavityLeakageRateActualValue[i]};产品漏率设定值:{listproductLeakageRateSetValue[i]},产品漏率实际值:{listproductLeakageRateActualValue[i]};腔体真空设定值:{leakPressureSetValue},腔体真空实际值:{leakPressureActualValue}", "loca出站B"); #endregion #region 数据判断 BGearEntity m = new BGearEntity { ChannelNo = (i + 1).ToString(), TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), RFID = lst_RFIDCodes, BarCode = lst_BarCodes, CavityLeakageRateSetValue = listcavityLeakageRateSetValue[i], ProductLeakageRateSetValue = listproductLeakageRateSetValue[i], LeakPressureSetValue = leakPressureSetValue, CavityLeakageRateActualValue = listcavityLeakageRateActualValue[i], ProductLeakageRateActualValue = listproductLeakageRateActualValue[i], LeakPressureActualValue = leakPressureActualValue, PalletNumber = palletNumber, Flag = "0", Flag1 = "2", Result = result == 1 ? "OK" : "NG", Info = info.ToString("f3"), MaterialCode = CommonMethods.mesConfig.MaterialCode, }; list.Add(m); #endregion } else { #region 数据判断 BGearEntity m = new BGearEntity { ChannelNo = (i + 1).ToString(), TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), BarCode = "", RFID = "", Flag = "0", Flag1 = "2", Result = "NG", MaterialCode = CommonMethods.mesConfig.MaterialCode, }; list.Add(m); #endregion CommonMethods.AddDataMonitorLog(0, "出站下料工位B有料标志为0".Translated() + "通道号".Translated() + $":{i}"); } } sw.Stop(); LogHelper.Instance.WriteLog($"B出站数据解析耗时: {sw.ElapsedMilliseconds}ms", "loca出站B"); #endregion #region 数据上传 sw.Restart(); if (list.Count > 0) { if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected)//点击切换mes状态或者是否连接 { // 初始化结果收集列表 var tempMesMessages = new List(); var tempMesResTypes = new List(); var tempFlags = new List(); foreach (var item in list) { if (String.IsNullOrEmpty(item.BarCode) || item.BarCode.Trim() == "ERROR" || !IsAlphaNumeric(item.BarCode)) { // 收集失败结果 tempMesMessages.Add("扫码不良"); tempMesResTypes.Add(MesResType.C); tempFlags.Add("2"); continue; } // 创建单个电池的列表 var singleBatteryList = new List { item }; // 调用MES接口(每次只传一个电池) var (success, mesage, mesResType) = await CommonMethods.hbgMes.ManyCellOutStationAsync( CommonMethods.mesConfig.ProductOutStation, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.ModelName, CommonMethods.mesConfig.mesUserName, singleBatteryList, 1, CommonMethods.mesConfig.materialLotCodeLocator); tempMesMessages.Add(mesage[0]); tempMesResTypes.Add(mesResType[0]); if (success) { tempFlags.Add("1"); } else { tempFlags.Add("2"); // 记录失败状态 listRes = GetList(8, 3); listRemark = GetList(8, ""); if (mesage.Count > 0 && mesage[0].Contains("一个或多个错误")) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short); // 反馈PLC结果 } } } // 将收集的结果赋给主列表 listMesMesage = tempMesMessages; listMesResType = tempMesResTypes; listFlag = tempFlags; } else { listRes = GetList(8, 3); listRemark = GetList(8, "MES断连".Translated() + ","); listFlag = GetList(8, "2"); CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short);//反馈MES结果 } } sw.Stop(); LogHelper.Instance.WriteLog($"B出站mes 上传耗时: {sw.ElapsedMilliseconds}ms", "loca出站B"); #endregion #region 上传产品结果参数 sw.Restart(); //Thread.Sleep(150); if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected) { //UpProducResultParam(list); _ = Task.Run(async () => { try { await UpProducResultParamAsync(list); } catch (Exception ex) { LogHelper.Instance.WriteError($"UpProducResultParamAsync 异常{ex.Message}", "SysErrorLog"); } }); } sw.Stop(); LogHelper.Instance.WriteLog($"B出站 上传产品结果参数UpProducResultParamAsync 耗时: {sw.ElapsedMilliseconds}ms", "loca出站B"); #endregion #region 数据组合 sw.Restart(); for (int i = 0; i < list.Count; i++) { if (!listMark[i]) { listRes[i] = 0; listResult[i] = "OK"; listRemark[i] = "无料"; } else if (String.IsNullOrEmpty(list[i].BarCode) || list[i].BarCode.Trim() == "ERROR" || !IsAlphaNumeric(list[i].BarCode)) { listRes[i] = 2; listResult[i] = "NG"; list[i].Info = "电芯码不良".Translated(); listFlag[i] = "2"; //LogHelper.Instance.WriteError($"B listCode i={i}:" + listCode[i] + " ;Info=" + list[i].Info, "loca出站"); } else { string strErr = ""; listResult[i] = list[i].Result; list[i].Info = list[i].Result == "OK" ? "" : list[i].Info; if (!CheckValue(list[i])) { listResult[i] += ",数据异常"; listRemark[i] += $"数据异常"; //list[i].Info = "数据异常"; listRes[i] = 2; listFlag[i] = "2"; } // 本地判断OK,MES判断OK else if (listResult[i] == "OK" && listMesResType[i] == MesResType.D) { listResult[i] += ",MES OK"; list[i].Info = "良品".Translated(); listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; } // 本地判断OK,MES判断NG else if (listResult[i] == "OK" && listMesResType[i] != MesResType.D) { switch (listMesResType[i]) { case MesResType.A: // 停线,设备报警停机 listResult[i] += ",MES NG"; listRemark[i] += $"A,{listMesMesage[i]}"; listRes[i] = 3;//10 listFlag[i] = "2"; break; case MesResType.B: // MES不良 listResult[i] += ",MES NG"; listRemark[i] += $"B,{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; break; case MesResType.C: // 警示 listResult[i] += ",MES OK"; // MES认为是可以当成良品流下去的 listRemark[i] += $"Alarm:{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; break; case MesResType.D: // 条码上传OK listResult[i] += ",MES OK"; listRemark[i] += $"D,{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; break; default: listResult[i] += ",MES NG"; listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; break; } } // 本地判断NG,MES判断OK else if (listResult[i] == "NG" && listMesResType[i] == MesResType.D) { listResult[i] += ",NG料,MES OK"; listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 2; listFlag[i] = "2"; } // 本地判断NG,MES判断NG else if (listResult[i] == "NG" && listMesResType[i] != MesResType.D) { listResult[i] += ",NG料,MES NG"; listRemark[i] += $"{listMesResType[i].ToString()},{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; } // 其他情况 else { listResult[i] += ",MES NG"; listRemark[i] += listMesMesage[i]; listRes[i] = 3;//9 listFlag[i] = "2"; } } list[i].Result = listResult[i].TrimStart(',').TrimEnd(','); list[i].Remark = listRemark[i].TrimStart(',').TrimEnd(','); list[i].Flag = listFlag[i]; //LogHelper.Instance.WriteError($"B2 listCode i={i}:" + listCode[i] + " ;Info=" + list[i].Info, "loca出站"); } sw.Stop(); LogHelper.Instance.WriteLog($"B出站 数据组合 上传耗时: {sw.ElapsedMilliseconds}ms", "loca出站B"); #endregion #region 数据保存&上传 sw.Restart(); //SaveBlankingData(list); _ = Task.Run(async () => { try { await SaveBlankingDataAsync(list); } catch (Exception ex) { LogHelper.Instance.WriteError($"SaveBlankingDataAsync 异常{ex.Message}", "SysErrorLog"); } }); sw.Stop(); LogHelper.Instance.WriteLog($"B出站 存库SaveBlankingDataAsync 耗时: {sw.ElapsedMilliseconds}ms", "loca出站B"); sw.Restart(); if (pf.IsFeedbackPlc) { //写入·结果反馈 JYResult result1 = CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue(pf.VarList[1].VarAddress, listRes.ToArray(), PLC.DataType.ArrShort);//判断结果写入PLC if (result1 != null) { string strres = "出站B工位发送给PLC".Translated() + $",[{pf.VarList[1].VarAddress}]:{string.Join(",", listRes)}"; CommonMethods.AddDataMonitorLog(0, strres); LogHelper.Instance.WriteLog($"B出站发送信息给PLC:{string.Join(",", listRes)}", "loca出站B"); } } sw.Stop(); LogHelper.Instance.WriteLog($"B出站 PLC 反馈结果 耗时: {sw.ElapsedMilliseconds}ms", "loca出站B"); sw.Restart(); if (CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0))//置位0 { LogHelper.Instance.WriteLog($"B出站给PLC清0成功", "loca出站B"); } else { int count = 0; bool success = false; do { success = CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); count++; LogHelper.Instance.WriteLog($"B出站给PLC清0失败第{count + 1}次复清结果: {success},", "loca出站B"); } while (count < 3 && success == false); } sw.Stop(); LogHelper.Instance.WriteLog($"B出站 PLC 置0 耗时: {sw.ElapsedMilliseconds}ms", "loca出站B"); #endregion } catch (Exception ex) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteLog($"电芯出站B线程数据处理:{ex}", "loca出站B"); } swTotal.Stop(); // 输出上料数据处理耗时: CommonMethods.AddDataMonitorLog(0, "电芯出站B共耗时".Translated() + $":{swTotal.Elapsed.TotalMilliseconds}ms"); LogHelper.Instance.WriteLog($"电芯进站B耗时:{swTotal.Elapsed.TotalMilliseconds}ms", "loca出站B"); } else { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteLog($"电芯进站B线程数据处理bArrays.IsSuccess:{bArrays.IsSuccess}", "loca出站B"); } } /// /// 电芯出站C /// /// /// private async Task BlankingStationC(JYResult bArrays, object plcModel) { PlcGroup pf = plcModel as PlcGroup; var sw = new Stopwatch(); var sw1 = new Stopwatch(); //CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 2); if (bArrays.IsSuccess && bArrays.Content != null) { sw.Restart(); try { #region 初始化数据 List list = new List(); List listRes = GetList(8, 2);//默认为1,良品 List listMark = GetList(8, false);//有料标志 List listCode = GetList(8, "");//电芯码 List listRemark = GetList(8, "");//备注 List listFlag = GetList(8, "0");//是否上传标志 List listResult = GetList(8, "OK");//结果 List listMesMesage = GetList(8, "");//mesMesage List listRfid = GetList(8, ""); List listcavityLeakageRateSetValue = GetList(8, ""); List listproductLeakageRateSetValue = GetList(8, ""); List listcavityLeakageRateActualValue = GetList(8, ""); List listproductLeakageRateActualValue = GetList(8, ""); List listpalletNumber = GetList(8, ""); List listMesResType = GetList(8, MesResType.B);//mesType //ushort listRes = 1; // 默认为1,良品 string lst_RFIDCodes = ""; // 托杯码 string lst_BarCodes = ""; // 条码 string cavityLeakageRateSetValue;// 清腔漏率设定值 string productLeakageRateSetValue;// 产品漏率设定值 string leakPressureSetValue;// 检漏口压力设定值 string cavityLeakageRateActualValue;// 清腔漏率实际值 string productLeakageRateActualValue;// 产品漏率实际值 string leakPressureActualValue;// 检漏口压力实际值 string palletNumber;// 托盘号 int result = 0;//总结果 int info = 0;//NG详情 #endregion #region 数据解析 byte[] bytes = bArrays.Content.ByteReverse(); //有料标志 for (int i = 0; i < listMark.Count; i++) { listMark[i] = ShortLib.GetShortFromByteArray(bArrays.Content, i * 2) == 1 ? true : false;// 从D8021开始 if (listMark[i]) { #region 数据读取 //条码长度 int codeLength = ShortLib.GetShortFromByteArray(bArrays.Content, (i * 2) + (20 * 2));// 从D4041开始 if (codeLength > 0) { //条码 listCode[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, i * 50 + (79 * 2), codeLength, System.Text.Encoding.ASCII).// 从D4100开始 Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); listCode[i] = Regex.Replace(listCode[i], @"[^a-zA-Z0-9]", ""); LogHelper.Instance.WriteLog($"NG 下料 通道={i}:" + listCode[i], "loca出站C"); } else { listCode[i] = "ERROR"; } int palletcodeLength = (int)FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (675 * 2)); if (palletcodeLength > 0) { listpalletNumber[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, i * 50 + (707 * 2), palletcodeLength, System.Text.Encoding.ASCII). Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); } else { listpalletNumber[i] = "ERROR"; } listcavityLeakageRateSetValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (579 * 2), DataFormat.CDAB).ToString(); // 清腔漏率设定值 D8600 579 listproductLeakageRateSetValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (595 * 2), DataFormat.CDAB).ToString(); // 产品漏率设定值 D8616 595 leakPressureSetValue = GetValueFromByteArray(bArrays.Content, "leakPressureSetValue", i * 4);// 腔体真空设定值 D8632 611 listcavityLeakageRateActualValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (627 * 2), DataFormat.CDAB).ToString(); // 清腔漏率实际值 D8648 627 listproductLeakageRateActualValue[i] = FloatLib.GetFloatFromByteArray(bArrays.Content, (i * 4) + (643 * 2), DataFormat.CDAB).ToString(); // 产品漏率实际值 D8664 643 leakPressureActualValue = GetValueFromByteArray(bArrays.Content, "leakPressureActualValue", i * 4);// 腔体真空实际值 D8680 659 palletNumber = listpalletNumber[i];// 托盘号 result = int.Parse(GetValueFromByteArray(bArrays.Content, "result", i * 2)); // 总结果 D8712 691 info = int.Parse(GetValueFromByteArray(bArrays.Content, "info", i * 2));// NG详情 D8720 699 LogHelper.Instance.WriteLog($"BlankingStationC NG 下料, {listCode[i]}, 总结果: {result}, NG详情: {info}", "loca出站C"); lst_RFIDCodes = listRfid[i];//StringLib.GetStringFromByteArrayByEncoding(bytes, 0, 39, Encoding.ASCII).Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); // RFID D3200-3219 lst_BarCodes = listCode[i]; #endregion #region 数据判断 BGearEntity m = new BGearEntity { ChannelNo = (i + 1).ToString(), TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), RFID = lst_RFIDCodes, BarCode = lst_BarCodes, CavityLeakageRateSetValue = listcavityLeakageRateSetValue[i], ProductLeakageRateSetValue = listproductLeakageRateSetValue[i], LeakPressureSetValue = leakPressureSetValue, CavityLeakageRateActualValue = listcavityLeakageRateActualValue[i], ProductLeakageRateActualValue = listproductLeakageRateActualValue[i], LeakPressureActualValue = leakPressureActualValue, PalletNumber = palletNumber, Flag = "0", Flag1 = "2", Result = result == 1 ? "OK" : "NG", Info = GetResult(info),//info.ToString("f3"), MaterialCode = CommonMethods.mesConfig.MaterialCode, }; list.Add(m); #endregion } else { #region 数据判断 BGearEntity m = new BGearEntity { ChannelNo = (i + 1).ToString(), TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), BarCode = "", RFID = "", Flag = "0", Flag1 = "2", Result = "NG", MaterialCode = CommonMethods.mesConfig.MaterialCode, }; list.Add(m); #endregion CommonMethods.AddDataMonitorLog(0, "出站下料工位C有料标志为0".Translated() + "通道号".Translated() + $":{i}"); } } #endregion #region 数据上传 if (list.Count > 0) { if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected) { // 初始化结果收集列表 var tempMesMessages = new List(); var tempMesResTypes = new List(); var tempFlags = new List(); foreach (var item in list) { if (String.IsNullOrEmpty(item.BarCode) || item.BarCode.Trim() == "ERROR" || !IsAlphaNumeric(item.BarCode)) { // 收集失败结果 tempMesMessages.Add("扫码不良"); tempMesResTypes.Add(MesResType.C); tempFlags.Add("2"); continue; } // 创建单个电池的列表 var singleBatteryList = new List { item }; // 调用MES接口(每次只传一个电池) var (success, mesage, mesResType) = await CommonMethods.hbgMes.ManyCellOutStationAsync( CommonMethods.mesConfig.ProductOutStation, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.ModelName, CommonMethods.mesConfig.mesUserName, singleBatteryList, 1, CommonMethods.mesConfig.materialLotCodeLocator); tempMesMessages.Add(mesage[0]); tempMesResTypes.Add(mesResType[0]); if (success) { tempFlags.Add("1"); } else { tempFlags.Add("2"); // 记录失败状态 listRes = GetList(8, 3); listRemark = GetList(8, ""); if (mesage.Count > 0 && mesage[0].Contains("一个或多个错误")) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short); // 反馈PLC结果 } } } // 将收集的结果赋给主列表 listMesMesage = tempMesMessages; listMesResType = tempMesResTypes; listFlag = tempFlags; } else { listRes = GetList(8, 3); listRemark = GetList(8, "MES断连".Translated() + ","); listFlag = GetList(8, "2"); CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue("D80", 1, PLC.DataType.Short);//反馈MES结果 } } #endregion //Thread.Sleep(150); if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected) { sw1.Restart(); //UpProducResultParam(list); _ = Task.Run(async () => { try { await UpProducResultParamAsync(list); } catch (Exception ex) { LogHelper.Instance.WriteError($"UpProducResultParamAsync 异常{ex.Message}", "SysErrorLog"); } }); sw1.Stop(); LogHelper.Instance.WriteLog($"C出站上传结果参数耗时: {sw1.ElapsedMilliseconds}ms", "loca出站C"); } #region 数据组合 for (int i = 0; i < list.Count; i++) { if (!listMark[i]) { listRes[i] = 0; listResult[i] = "OK"; listRemark[i] = "无料"; } else if (String.IsNullOrEmpty(list[i].BarCode) || list[i].BarCode.Trim() == "ERROR" || !IsAlphaNumeric(list[i].BarCode)) { listRes[i] = 2; listResult[i] = "NG"; list[i].Info = "电芯码不良".Translated(); listFlag[i] = "2"; LogHelper.Instance.WriteLog($"C listCode i={i}:" + listCode[i] + " ;Info=" + list[i].Info, "loca出站C"); } else { string strErr = ""; listResult[i] = list[i].Result; list[i].Info = list[i].Result == "OK" ? "" : list[i].Info; // 本地判断OK,MES判断OK if (listResult[i] == "OK" && listMesResType[i] == MesResType.D) { listResult[i] += ",MES OK"; list[i].Info = "良品".Translated(); listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; } // 本地判断OK,MES判断NG else if (listResult[i] == "OK" && listMesResType[i] != MesResType.D) { switch (listMesResType[i]) { case MesResType.A: // 停线,设备报警停机 listResult[i] += ",MES NG"; listRemark[i] += $"A,{listMesMesage[i]}"; listRes[i] = 3;//10 listFlag[i] = "2"; break; case MesResType.B: // MES不良 listResult[i] += ",MES NG"; listRemark[i] += $"B,{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; break; case MesResType.C: // 警示 listResult[i] += ",MES OK"; // MES认为是可以当成良品流下去的 listRemark[i] += $"Alarm:{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; break; case MesResType.D: // 条码上传OK listResult[i] += ",MES OK"; listRemark[i] += $"D,{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; break; default: listResult[i] += ",MES NG"; listRemark[i] += $"{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; break; } } // 本地判断NG,MES判断OK else if (listResult[i] == "NG" && listMesResType[i] == MesResType.D) { listResult[i] += ",MES OK"; listRemark[i] += $"D,{listMesMesage[i]}"; listRes[i] = 1; listFlag[i] = "1"; } // 本地判断NG,MES判断NG else if (listResult[i] == "NG" && listMesResType[i] != MesResType.D) { listResult[i] += ",MES NG"; listRemark[i] += $"{listMesResType[i].ToString()},{listMesMesage[i]}"; listRes[i] = 3;//9 listFlag[i] = "2"; } // 其他情况 else { listResult[i] += ",MES NG"; listRemark[i] += listMesMesage[i]; listRes[i] = 3;//9 listFlag[i] = "2"; } } list[i].Result = listResult[i].TrimStart(',').TrimEnd(','); list[i].Remark = listRemark[i].TrimStart(',').TrimEnd(','); list[i].Flag = listFlag[i]; LogHelper.Instance.WriteLog($"C2 listCode i={i}:" + listCode[i] + " ;Info=" + list[i].Info, "loca出站C"); } #endregion #region 数据保存&上传 sw1.Restart(); // 数据存储 - 异步处理 //SaveBlankingData(list); //Thread.Sleep(150); _ = Task.Run(async () => { try { await SaveBlankingDataAsync(list); } catch (Exception ex) { LogHelper.Instance.WriteError($"SaveBlankingDataAsync 异常{ex.Message}", "SysErrorLog"); } }); sw1.Stop(); LogHelper.Instance.WriteLog($"C出站存储数据耗时: {sw1.ElapsedMilliseconds}ms", "loca出站C"); if (pf.IsFeedbackPlc) { //CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[1].VarAddress, (short)listRes); // 反馈PLC结果 //写入·结果反馈 JYResult result1 = CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue(pf.VarList[1].VarAddress, listRes.ToArray(), PLC.DataType.ArrShort);//判断结果写入PLC if (result1 != null) { string strres = "出站C工位发送给PLC".Translated() + $",[{pf.VarList[1].VarAddress}]:{string.Join(",", listRes)}"; CommonMethods.AddDataMonitorLog(0, strres); LogHelper.Instance.WriteLog($"C出站发送信息给PLC:{string.Join(",", listRes)}", "loca出站C"); } } if (CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0))//置位0 { LogHelper.Instance.WriteLog($"C出站给PLC清0成功", "loca出站C"); } else { int count = 0; bool success = false; do { success = CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); count++; LogHelper.Instance.WriteLog($"C出站给PLC清0失败第{count + 1}次复清结果: {success}", "loca出站C"); } while (count < 3 && success == false); } #endregion } catch (Exception ex) { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteLog($"电芯出站C线程数据处理:{ex}", "loca出站C"); } sw.Stop(); // 输出上料数据处理耗时: CommonMethods.AddDataMonitorLog(0, "电芯出站C共耗时".Translated() + $":{sw.Elapsed.TotalMilliseconds}ms"); } else { CommonMethods.plcDevices[pf.PlcNum - 1].WriteInt16(pf.VarList[0].VarAddress, 0); LogHelper.Instance.WriteLog($"电芯进站C线程数据处理bArrays.IsSuccess:{bArrays.IsSuccess}", "loca出站C"); } } #region 保存下料数据 /// /// 保存下料数据到数据 /// /// private async Task SaveBlankingDataAsync(List list) { //数据的保存 try { if (list != null && list.Count > 0) { //数据显示 bool b = await CommonMethods.db.AddReturnBoolAsync(list); //数据显示 CommonMethods.ShowBlankingDelegate.Invoke(list); //数据保存本地 string strData = string.Empty;//数据字符串,本地保存 foreach (BGearEntity m in list) { foreach (var item in m.GetType().GetProperties()) { strData += item.GetValue(m) + ","; } strData = strData.TrimEnd(','); BlankingDataSaveLocal(strData); } } else { LogHelper.Instance.WriteError($"电芯出站数据List为空", "SysErrorLog"); } } catch (Exception ex) { LogHelper.Instance.WriteError($"电芯出站数据保存异常:{ex}", "SysErrorLog"); } } #endregion /// /// 电池结果判断 /// /// private string GetResult(int ngType) { string strErr = ""; switch (ngType) { case 1: strErr += "OK"; break; case 2: strErr += "扫码NG"; break; case 3: strErr += "真空NG"; break; case 4: strErr += "保压NG"; break; case 5: strErr += "检测NG"; break; default: strErr += "未知NG类型"; break; } return strErr; } #region 结果数据上传 /// /// 结果数据上传 /// /// private async Task UpProducResultParamAsync(List listBger) { try { if (listBger != null && listBger.Count > 0) { foreach (BGearEntity m in listBger) { if (m.BarCode != "NG" && m.BarCode != "ERROR" && m.BarCode != "") { //var AGearList = CommonMethods.db.QueryList(CommonMethods.dBSQL.GetInStationTop1Sql(m.BarCode)); string Mesage = ""; var (success, message) = await CommonMethods.hbgMes.ProducResultParamAsync(CommonMethods.mesConfig.ProductResultParams, CommonMethods.mesConfig.siteCode, CommonMethods.mesConfig.lineCode, CommonMethods.mesConfig.equipNum, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.mesUserName, m, MesUploadType.DD); if (!success) { CommonMethods.AddDataMonitorLog(1, $"Code: {m.BarCode}, " + "结果数据上传失败".Translated()); LogHelper.Instance.WriteError($"条码: {m.BarCode}, 结果数据上传失败, {message}", "系统报错"); } else { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); m.Flag1 = "1"; await CommonMethods.db.UpdateSingleAsync(m, it => new BGearEntity() { Flag1 = m.Flag1 }, it => it.BarCode == m.BarCode); stopWatch.Stop(); LogHelper.Instance.WriteLog($"上传结果参数 UpdateSingleAsync 耗时: {stopWatch.ElapsedMilliseconds}ms", "loca出站A"); } } } } } catch (Exception ex) { LogHelper.Instance.WriteError(ex.Message.ToString(), "系统报错"); } } #endregion #region 定时补传 /// /// 定时补传 /// public void ReUpProducResultParam() { try { List list = CommonMethods.db.QuerySqlList(CommonMethods.dBSQL.GetOutFlag1Sql("2")); if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected) { //UpProducResultParam(list); } } catch (Exception ex) { LogHelper.Instance.WriteError($"结果数据补传失败, 原因: {ex}", "系统报错"); //throw new Exception(ex.ToString()); } } #endregion #endregion #region 结构件料盘工位(数据处理) /// /// 结构件料盘工位 /// /// /// /// private async Task MaterialStation(JYResult bArrays, object plcModel) { PlcGroup pf = plcModel as PlcGroup; var sw = new Stopwatch(); if (bArrays.IsSuccess && bArrays.Content != null) { sw.Restart(); #region 初始化数据 List list = new List();//实体 List listMaterialCode = GetList(1, "");//料盘码 List listRes = GetList(1, 1);//默认为1,良品 #endregion #region 数据解析 byte[] bytes = bArrays.Content.ByteReverse(); for (int i = 0; i < listMaterialCode.Count; i++) { listMaterialCode[i] = StringLib.GetStringFromByteArrayByEncoding(bytes, i * 40, 39, System.Text.Encoding.ASCII). Replace('\0', ' ').Replace('\r', ' ').Replace(" ", "").Trim(); } #endregion for (int i = 0; i < listMaterialCode.Count; i++) { DGearEntity m = new DGearEntity(); try { switch (pf.GroupName) { case "结构件料盘B": m.ChannelNo = 1; break; case "结构件料盘D": m.ChannelNo = 2; break; } m.TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); m.MaterialCode = listMaterialCode[i]; m.MaterialCodes = CommonMethods.mesConfig.MaterialCode; m.EquipNum = CommonMethods.mesConfig.equipNum; m.Flag = 0; if (String.IsNullOrEmpty(m.MaterialCode) || m.MaterialCode.Trim() == "ERROR" || m.MaterialCode.Trim() == "NG") { m.MaterialCode = "NG"; m.Result = "NG"; m.Remark = "料盘码不良"; listRes[i] = 2; } else { m.Result = "OK"; m.Remark = "良品"; #region MES对接 if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.isConnected) { var (mesRes, Mesage, mesResType) = await CommonMethods.hbgMes.RawMaterialStationAsync(CommonMethods.mesConfig.MaterialInputInfo, CommonMethods.mesConfig.MaterialCode, CommonMethods.mesConfig.equipNum, m.MaterialCode); if (mesRes) //调用接口成功 { m.Flag = 1; //本地判断OK,MES判断OK if (m.Result == "OK" && mesResType == MesResType.D) { m.Result = "OK"; m.Remark = m.Remark + Mesage; listRes[i] = 1; } //本地判断OK,MES判断NG else if (m.Result == "OK" && mesResType != MesResType.D) { switch (mesResType) { case MesResType.B: m.Result = "MES NG"; m.Remark = $"{Mesage}"; listRes[i] = 9; break; default: m.Result = "MES NG"; m.Remark = $"{Mesage}"; listRes[i] = 9; break; } } //其他情况 else { m.Result = " MES NG"; m.Remark = Mesage; listRes[i] = 9; } } else { m.Result = " MES NG"; m.Remark = Mesage; listRes[i] = 9; if (Mesage.Contains("接口调用失败")) { listRes[i] = 10; CommonMethods.AddLog(false, $"原材料上传失败,请联系IT人员检查MES网络或服务器"); LogHelper.Instance.WriteLog($"原材料上传失败,请联系IT人员检查MES网络或服务器", "SysErrorLog"); } } } #endregion } list.Add(m); } catch (Exception ex) { LogHelper.Instance.WriteError($"结构件料盘线程数据解析:{ex}", "系统报错"); } } JYResult result1 = CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue(pf.VarList[2].VarAddress, listRes.ToArray(), PLC.DataType.ArrShort);//判断结果写入PLC JYResult result3 = CommonMethods.plcDevices[pf.PlcNum - 1].WriteValue(pf.VarList[0].VarAddress, 0);//置位 //数据存储 -异步处理 await SaveMaterialData(list); sw.Stop(); ////输出上料数据处理耗时: CommonMethods.AddDataMonitorLog(0, $"结构件料盘线程共耗时:{sw.Elapsed.TotalMilliseconds}ms"); } } /// /// 结构件料盘保存 /// /// private async Task SaveMaterialData(List list) { //数据的保存 try { if (list != null && list.Count > 0) { string strRes = ""; foreach (DGearEntity m in list) { if (m.MaterialCode != "NG") { bool b1 = await CommonMethods.db.AddReturnBoolAsync(m); strRes = b1 ? ",本存Yes" : ",本存No"; } else { strRes = ",不存储"; } m.Remark = m.Remark + strRes; } //数据显示 CommonMethods.ShowMaterialDelegate.Invoke(list); } else { LogHelper.Instance.WriteError($"结构件料盘数据List为空", "SysErrorLog"); } } catch (Exception ex) { LogHelper.Instance.WriteError($"结构件料盘保存处理异常:{ex}", "SysErrorLog"); } } #endregion #region 创建空的数组List public List GetList(int num, T data) { List list = new List(); for (int i = 0; i < num; i++) { list.Add(data); } return list; } public List GetMesType(int Num) { List mesResTypes = new List(); for (int i = 0; i < Num; i++) { mesResTypes.Add(MesResType.UnKnow); } return mesResTypes; } /// /// PLC内批量写\0 /// /// /// public string GetString_0(int Num) { string ff = ""; for (int i = 0; i < Num; i++) { ff = ff.Insert(ff.Length, "\0"); } return ff; } public string GetBarCodeNum(int Num) { string CodeNo = ""; int CodeLenth = Num.ToString().Length; switch (CodeLenth) { case 1: return CodeNo = $"00000{Num}"; case 2: return CodeNo = $"0000{Num}"; case 3: return CodeNo = $"000{Num}"; case 4: return CodeNo = $"00{Num}"; case 5: return CodeNo = $"0{Num}"; default: return CodeNo = $"{Num}"; } } #endregion /// /// 检测数据是否只包含字母加数字 /// /// /// public bool IsAlphaNumeric(string input) { // 使用正则表达式检查是否只包含字母和数字 return Regex.IsMatch(input, "^[a-zA-Z0-9]+$"); } #region 方法 /// /// 下料数据保存本地 /// /// private void BlankingDataSaveLocal(string strData) { #region string savePath = string.Format(@"{0}\{1}\{2}\{3}\", @"D:\LocalData", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); bool acquiredLock = false; Monitor.TryEnter(FileLock, ref acquiredLock); if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); } try { if (acquiredLock) { string strFileName = System.DateTime.Now.ToString("yyyyMMdd") + ".csv";//yyyyMMdd.csv if (!File.Exists(savePath + strFileName)) //如果文件不存在,创建文件,并保存到本地 { string strProlnfoFileHead = string.Empty; foreach (var item in CommonMethods.m_DBCtrl.HeaderTextOut) { strProlnfoFileHead += item + ","; } strProlnfoFileHead = strProlnfoFileHead.TrimEnd(','); strProlnfoFileHead = strProlnfoFileHead.Substring(strProlnfoFileHead.IndexOf(',') + 1); StreamWriter sw = new StreamWriter(savePath + strFileName, true, Encoding.GetEncoding("GB2312")); sw.WriteLine(strProlnfoFileHead); sw.WriteLine(strData); sw.Flush(); sw.Close(); sw.Dispose(); } else { StreamWriter sw = new StreamWriter(savePath + strFileName, true, Encoding.GetEncoding("GB2312")); sw.WriteLine(strData); sw.Flush(); sw.Close(); sw.Dispose(); } Monitor.Exit(FileLock); } } catch (Exception ex) { LogHelper.Instance.WriteError($"下料数据保存异常:{ex}", "SysErrorLog"); if (acquiredLock) { Monitor.Exit(FileLock); } } #endregion } #endregion } }