using iTextSharp.text.pdf; using iTextSharp.text; using iWare_SCADA_BusinessLogical.BLL; using iWare_SCADA_BusinessLogical.Utils; using iWare_SCADA_Model; using iWare_SCADA_Model.MiddleModel; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web.UI.WebControls; using iTextSharp.text.pdf.parser.clipper; using iTextSharp.text.pdf.parser; using iWare_SCADA_Model.TableModelSC; using static System.Net.WebRequestMethods; using File = System.IO.File; using Spire.Additions.Xps.Schema; using log4net; namespace iWare_SCADA_BusinessLogical { /// /// 测量完成标记 /// public class DataCaptureHandler_02 : DataCaptureHandler { public static readonly DataCaptureHandler_02 Instance = new DataCaptureHandler_02(); public DataCaptureHandler_02() { } public override string WorkingProcedure { get { return _dataCaptureConfig.WorkingProcedure; } } public override string DataCapturePointCode { get { return _dataCaptureConfig.DataCapturePointCode; } } public override string DataCapturePointCname { get { return _dataCaptureConfig.DataCapturePointCname; } } public override void RefreshDataList(List dataCaptureConfig) { } public override void DataCaptureStart() { if (SystemValue.isStartedModel) { var plcService = PLCManger.GetSinglePLCService(_dataCaptureConfig); WorkPieceLogMiddle wplog = new WorkPieceLogMiddle(); wplog.Id = Yitter.IdGenerator.YitIdHelper.NextId(); wplog.WorkingProcedure = WorkingProcedure; wplog.EquipmentID = WorkingProcedure; wplog.Remarks = WorkingProcedure; wplog.MonitoringPoint = DataCapturePointCode; wplog.WorkPieceID = "123456"; wplog.CreatedTime = DateTimeHelper.GetDateTime(); wplog.CreatedUserName = DataCapturePointCode; wplog.IsDeleted = false; wplog.QualityType = QualityType.Online.ToString(); wplog.WorkPieceID = WorkPieceID; wplog.EquipmentID = _dataCaptureConfig.EquipmentID; wplog.UpdatedTime = DateTimeHelper.GetDateTime(); wplog.UpdatedUserName = DataCapturePointCode; wplog.QualityState = (int)QualityState.NG; wplog.QualityStateUpdateUser = WorkingProcedure; wplog.QualityStateUpdateMode = QualityStateUpdateMode.Auto.ToString(); //wplog.QualityTo1 = "QualityTo1"; //wplog.QualityTo2 = "QualityTo2"; //wplog.QualityTo3 = "QualityTo3"; //wplog.QualityTo4 = "QualityTo4"; //wplog.QualityTo5 = "QualityTo5"; //wplog.QualityTo6 = "QualityTo6"; //wplog.QualityTo7 = "QualityTo7"; //更新WorkPieceInfo表以及插入WorkPieceLog表和WorkPieceInfoLog表 WorkPieceInfoManager.QualityInfoComplete(wplog, PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure)); return; } ThreadStatusMonitorMiddle threadStatusMonitor = new ThreadStatusMonitorMiddle(); if (IsCaptureflag) { //_dataCaptureConfig.DataCapturePLCType = 5; //var plcService = PLCManger.GetSinglePLCService(_dataCaptureConfig); var plcService = SystemValue.GetPLCService(_dataCaptureConfig); if (plcService == null) { threadStatusMonitor.ErrorMsg = $"{RandomHelper.GenerateRandomCode(4)} 没有找到{_dataCaptureConfig.WorkingProcedure}的PLC设备"; return; } if (plcService != null && !plcService.IsConnected) { SystemValue.PLCServiceReconnect(plcService); //plcService.Close(); //plcService.OpenService(); } string value_02 = ""; string path36 = ConfigHelper.GetConfigString("OP30QualityDataFor36Station");//op30 3工位,6工位地址 string path45 = ConfigHelper.GetConfigString("OP30QualityDataFor45Station");//op30 4工位,5工位地址 string pathOP20 = ConfigHelper.GetConfigString("OP20QualityData"); //string pathOP60 = ConfigHelper.GetConfigString("OP60QualityData"); string pathOP60 = @"Q:\Measuring_Data_dfq\";//写死地址 【Editby shaocx,2024-06-25】 if (string.IsNullOrEmpty(path36)) { path36 = @"Z:\"; } if (string.IsNullOrEmpty(path45)) { path45 = @"U:\"; } if (string.IsNullOrEmpty(pathOP20)) { pathOP20 = @"W:\"; } if (string.IsNullOrEmpty(pathOP60)) { pathOP60 = @"Q:\Measuring_Data_dfq\"; } if (DataCapturePointCode.Contains("CH3")) {//工位3 涨断力矩 path36 = path36 + "kistler_crack"; } else if (DataCapturePointCode.Contains("CH4")) {//工位4 预拧紧力矩 SEQ_04 path45 = path45 + "NutrunnerData\\FO\\SEQ_04"; } else if (DataCapturePointCode.Contains("CH5")) {//工位5 拧紧力矩 SEQ_24 path45 = path45 + "NutrunnerData\\FO\\SEQ_24"; } else if (DataCapturePointCode.Contains("CH6")) {//工位6 衬套压装力矩 path36 = path36 + "kistler_bush"; } DateTime? fileFindTime = null; DateTime? op60QualityTime = null; // 质量信息:涨断力矩... 预拧紧力矩 预拧紧角度 终拧紧力矩 终拧紧角度 //kistler_crack 涨断力矩 工位3 涨断力矩(Y - Maximum) 质量结果(Result) //kistler_bush 压装力矩 工位6 衬套压装力矩(Y - Maximum) 衬套压装位移(Block X) 质量结果(Result) //Bosch_Rexroth /(Ch_0_1.csv / Ch_0_2.csv 两通道 同时取最新的(或者id对应?)) 预拧紧力矩工位4 预拧紧角度 预拧紧力矩(T + Nm) 质量结果(结果) 目前文件不能自动生成 博世 力士乐拧紧系统 //Bosch_Rexroth /(Ch_0_3.csv / Ch_0_4.csv 两通道 同时取最新的(或者id对应?)) 终拧紧工位5 终拧紧角度 拧紧力矩(T + Nm) 终拧紧角度 while (true) { threadStatusMonitor.ErrorMsg = ""; threadStatusMonitor.Threadcode = DataCapturePointCode; threadStatusMonitor.Threadcname = DataCapturePointCname; threadStatusMonitor.Threadendtime = DateTime.Now; //threadStatusMonitor.Threadlastmodifytime = DateTime.Now; threadStatusMonitor.Threadstatue = 0; threadStatusMonitor.ThreadId = Thread.CurrentThread.ManagedThreadId.ToString(); try { //_dataCaptureConfig if (plcService == null || !plcService.IsConnected) { threadStatusMonitor.ErrorMsg = $" {RandomHelper.GenerateRandomCode(4)} {_dataCaptureConfig.WorkingProcedure} PLC连接已断开,正在尝试打开!"; WorkPieceInfoManager.ThreadMonitor(threadStatusMonitor); SystemValue.PLCServiceReconnect(plcService); //plcService.Close(); //plcService.OpenService(); Thread.Sleep(100); continue; } else { object value; //判断DBNumber不同 【Editby shaocx,2024-06-07】 if (_dataCaptureConfig.DbNumber.ToUpper() == "M") { value = plcService.ReadValuePointV2(_dataCaptureConfig.DbNumber + _dataCaptureConfig.Offset, PLCManger.GetTypeForString(_dataCaptureConfig.DataCaptureColumnType)); } else { value = plcService.ReadValuePoint(_dataCaptureConfig.DbNumber, _dataCaptureConfig.Offset, PLCManger.GetTypeForString(_dataCaptureConfig.DataCaptureColumnType)); } Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}测量完成【{value_02}】【{value.ToString()}】【{_dataCaptureConfig.PLCIP}】【{_dataCaptureConfig.DbNumber}】【{_dataCaptureConfig.Offset}】[{_dataCaptureConfig.DataCapturePLCType}][{plcService.IsConnected.ToString()}]"); if (value_02.ToUpper().Equals("FALSE") && value.ToString().ToUpper().Equals("TRUE")) {//当上一标记位0,当前获取标记为1时, //触发操作, 并给静态变量赋值为1 //业务代码 Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}进入测量完成【{value_02}】【{value.ToString()}】"); threadStatusMonitor.Threadlastmodifytime = DateTime.Now; WorkPieceLogMiddle logMiddle = new WorkPieceLogMiddle(); logMiddle.Id = Yitter.IdGenerator.YitIdHelper.NextId(); logMiddle.WorkingProcedure = WorkingProcedure; logMiddle.EquipmentID = _dataCaptureConfig.EquipmentID; ; logMiddle.Remarks = WorkingProcedure; logMiddle.MonitoringPoint = DataCapturePointCode; logMiddle.CreatedTime = DateTimeHelper.GetDateTime(); logMiddle.CreatedUserName = DataCapturePointCode; logMiddle.UpdatedUserName = Environment.MachineName + "自动" + Thread.CurrentThread.ManagedThreadId.ToString(); logMiddle.UpdatedTime = DateTimeHelper.GetDateTime(); logMiddle.IsDeleted = false; logMiddle.QualityType = QualityType.Online.ToString(); foreach (var col in colConfig.Where(o => o.DataCapturePointCode == DataCapturePointCode)) { try { var valuecol = plcService.ReadValuePoint(col.DbNumber, col.Offset, col.DataCaptureColumnLength.Value, PLCManger.GetTypeForString(col.DataCaptureColumnType)); //wplog.GetType().GetProperty(col.DataCaptureColumnTabelName).SetValue(wplog, valuecol);//给动态字段赋值 var set = logMiddle.GetType().GetProperty(col.DataCaptureColumnTabelName); if (set == null) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $" {DataCapturePointCode}工序监控测量完成标记 读取工件码动态由于字段名没找到,赋值【{WorkingProcedure ?? "空字符串"}】失败{logMiddle.Id}"); } if (set.PropertyType.FullName.Equals("System.String")) { set.SetValue(logMiddle, valuecol.ToString());//给动态字段赋值 } else { set.SetValue(logMiddle, valuecol);//给动态字段赋值 } } catch (Exception setex) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $" {DataCapturePointCode}工序监控测量完成标记 读取工件码动态赋值【{WorkingProcedure ?? "空字符串"}】异常{logMiddle.Id}", setex); } } try { if (WorkingProcedure.Equals("OP30")) { var time = DateTimeHelper.GetDateTime(); if (fileFindTime == null) { fileFindTime = time.AddMinutes(-10); } //获取文件夹名称 List directorylist = new List(); string directory = time.ToString("yyyy-MM-dd_HH"); string directoryOther = time.AddSeconds(-30).ToString("yyyy-MM-dd_HH"); directorylist.Add(directory); if (!directory.Equals(directoryOther)) {//如果30秒前是另一个文件夹 directorylist.Add(directoryOther); } List files = new List(); foreach (var dir in directorylist) { try { if (DataCapturePointCode.Contains("CH3") || DataCapturePointCode.Contains("CH6")) {//工位3 涨断力矩 //扫描当前时间与30秒前出现的文件,一般节拍在15秒左右(两个服务器时间不一样会导致取不到文件) var newFiles = FileHelper.DetectNewFiles(path36 + @"\" + dir, "*.pdf", 10, fileFindTime.Value, time.AddMinutes(120)); foreach (var file in newFiles) { files.Add((FileInfo)file); } } else if (DataCapturePointCode.Contains("CH4") || DataCapturePointCode.Contains("CH5")) {//工位4 预拧紧力矩 SEQ_04 //扫描当前时间与30秒前出现的文件,一般节拍在15秒左右(两个服务器时间不一样会导致取不到文件) var newFiles = FileHelper.DetectNewFiles(path45, "*.txt", 10, fileFindTime.Value, time.AddMinutes(120)); foreach (var file in newFiles) { files.Add((FileInfo)file); } } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}测量完成读取文件{dir}数据时异常,采集时间{fileFindTime.Value},避免工序完成异常1:", ex); } } files = files.OrderByDescending(o => o.LastWriteTime).ToList(); if (files.Count > 0) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"工位【{DataCapturePointCode}】工件【{logMiddle.WorkPieceID ?? "空字符"}】文件{files[0].FullName}测量完成读取文件数据开始"); switch (DataCapturePointCode) { case "OP3002CH3": logMiddle.OP30QualityFilePathCH3 = files[0].FullName; logMiddle.QualityStateStr = FileHelper.ReadPdfFileForSpire(files[0].FullName, "Result"); logMiddle.QualityOP30To1 = FileHelper.ReadPdfFileForSpire(files[0].FullName, "Y-Maximum");//涨断力矩 break; case "OP3002CH4": logMiddle = GetCH4Info(files[0].FullName, logMiddle); logMiddle.OP30QualityFilePathCH4 = files[0].FullName; break; case "OP3002CH5": logMiddle = GetCH5Info(files[0].FullName, logMiddle); logMiddle.OP30QualityFilePathCH5 = files[0].FullName; break; case "OP3002CH6": logMiddle.OP30QualityFilePathCH6 = files[0].FullName; logMiddle.QualityStateStr = FileHelper.ReadPdfFileForSpire(files[0].FullName, "Result"); logMiddle.QualityOP30To6 = FileHelper.ReadPdfFileForSpire(files[0].FullName, "Y-Maximum");//衬套压装力矩 logMiddle.QualityOP30To7 = FileHelper.ReadPdfFileForSpire(files[0].FullName, "Block X");//衬套压装位移 break; default: break; } fileFindTime = files[0].LastWriteTime; } } else if (WorkingProcedure.Equals("OP35")) { if (logMiddle.OP35OK) { logMiddle.QualityStateStr = "OK"; } else { logMiddle.QualityStateStr = "NG"; } } else if (WorkingProcedure.Equals("OP60")) { //增加OP60 质量信息读取校验 【Editby shaocx,2024-06-07】 var gongweiStr = DataCapturePointCode.Substring(DataCapturePointCode.Length - 1, 1); if (logMiddle.Op60_Place_Flag == false) { Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成,是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr},不通过,读取Op60_Place_Flag:false"); continue; }; Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成,是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr},校验通过,读取Op60_Place_Flag:true"); var time = DateTimeHelper.GetDateTime(); if (fileFindTime == null) { fileFindTime = time.AddMinutes(-10); } //OP60 需要扫描文件读取质量信息 //扫描修改时间在上次扫描时间之前30秒到当前时间的之间的文件 List files = new List(); var newFiles = FileHelper.DetectNewFiles(pathOP60, "*.dfq", 300, fileFindTime.Value, time.AddHours(2)); foreach (var file in newFiles) { files.Add((FileInfo)file); } //注意:一定要筛选制定的文件数据 files = files.Where(x => x.Name.Contains("SP-" + gongweiStr)).OrderByDescending(o => o.LastWriteTime).ToList();//筛选取最新的文件 【Editby shaocx,2024-06-19】 if (files.Count() > 0) { Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{files.Count()}个,是指定的工件{logMiddle.WorkPieceID},,工位{gongweiStr}上次获取尼伯丁文件里的时间值:{(op60QualityTime == null ? "" : op60QualityTime.ToString())}"); List op60Infos = new List(); bool isFindFile = false; //注意:只取第一个文件就可以啦!!!!!! 【Editby shaocx,2024-06-19】 var source_doFile = files.First();//原始读的文件 //拷贝文件 //目标文件的完整目录 string destFileName = source_doFile.FullName.Replace("Measuring_Data_dfq", "Measuring_Data_df_Copy"); string source_file_name = source_doFile.Name.Replace(".dfq", "");//不带扩展名的文件名字 destFileName = destFileName.Replace(source_file_name, source_file_name + "_" + logMiddle.WorkPieceID + "_" + DateTime.Now.ToString("yyyyMMddHHmmss")); File.Copy(source_doFile.FullName, destFileName, true); FileInfo destFile = new FileInfo(destFileName); var doFiles = new List() { destFile }; foreach (var file in doFiles) {//取倒序匹配的文件名为工件号的文件 if (file.Name.Contains("SP-" + gongweiStr)) { Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},,工位{gongweiStr}上次获取尼伯丁文件里的时间值:{(op60QualityTime == null ? "" : op60QualityTime.ToString())}"); isFindFile = true; var datatable = CSVHelper.ReadCSVList(file.FullName); Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取文件{file.Name},指定工件号{logMiddle.WorkPieceID},,工位{gongweiStr}发现文件行数{datatable.Count}"); if (datatable.Count < 106) {//质量数据从106行开始 Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取文件{file.Name},指定工件号{logMiddle.WorkPieceID},,工位{gongweiStr}发现文件行数{datatable.Count}小于106"); continue; } datatable.Reverse(); System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding(); byte[] byteArray = new byte[] { (byte)15 }; string strCharacter = asciiEncoding.GetString(byteArray); var list = datatable[0].Split(new String[] { strCharacter }, StringSplitOptions.None); byte[] byteArray2 = new byte[] { (byte)20 }; string strCharacter2 = asciiEncoding.GetString(byteArray2); foreach (var item in list) { var listitem = item.Split(new String[] { strCharacter2 }, StringSplitOptions.None); if (listitem.Count() == 3) { OP60Info info = new OP60Info(); info.datetime = listitem[2]; info.col2 = listitem[1]; info.value = listitem[0]; info.datetimeHandle = CommonManager.GetOP60Time(info.datetime); op60Infos.Add(info); } } if (op60Infos.Count() >= 2) { if (op60QualityTime.HasValue) { //if (op60Infos[0].datetimeHandle > op60QualityTime.Value) //{//这个时间判断要不要拿掉?? 【Editby shaocx,2024-06-19】 // wplog.QualityOP60To1 = op60Infos[0].value; // wplog.QualityOP60To2 = op60Infos[1].value; // wplog.OP60QualityFilePath = file.FullName; // Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{wplog.WorkPieceID},工位{gongweiStr}成功赋值了OP60QualityFilePath等字段"); //} //else //{ // var msg = $",因为判断时间不符合,op60Infos[0].datetimeHandle:{(op60Infos[0].datetimeHandle == null ? "" : op60Infos[0].datetimeHandle.ToString())}小于等于op60QualityTime:{(op60QualityTime.Value == null ? "" : op60QualityTime.Value.ToString())}"; // Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{wplog.WorkPieceID},工位{gongweiStr}没能赋值OP60QualityFilePath等字段,{msg}"); // break; //} logMiddle.QualityOP60To1 = op60Infos[0].value; logMiddle.QualityOP60To2 = op60Infos[1].value; logMiddle.OP60QualityFilePath = file.FullName; Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr}成功赋值了OP60QualityFilePath等字段,读取时间:{op60Infos[0].datetimeHandle.ToString()}"); if (op60Infos[0].datetimeHandle > op60QualityTime.Value) {//这个时间判断要不要拿掉?? 【Editby shaocx,2024-06-19】 } else { var msg = $",只是警告!因为判断时间不符合,op60Infos[0].datetimeHandle:{(op60Infos[0].datetimeHandle == null ? "" : op60Infos[0].datetimeHandle.ToString())}小于等于op60QualityTime:{(op60QualityTime.Value == null ? "" : op60QualityTime.Value.ToString())}"; Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr}没能赋值OP60QualityFilePath等字段,{msg}"); } } else { logMiddle.QualityOP60To1 = op60Infos[0].value; logMiddle.QualityOP60To2 = op60Infos[1].value; logMiddle.OP60QualityFilePath = file.FullName; Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr}成功赋值了OP60QualityFilePath等字段,读取时间:{op60Infos[0].datetimeHandle.ToString()}"); } op60QualityTime = op60Infos[0].datetimeHandle; break; } } else { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取文件{file.Name}不是指定工件{logMiddle.WorkPieceID},工位{gongweiStr}"); } } if (isFindFile == false) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成没有找到文件,指定工件{logMiddle.WorkPieceID},工位{gongweiStr}"); } } else { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成,通过筛选过滤,没有找到文件,指定工件{logMiddle.WorkPieceID},工位{gongweiStr}"); } } else if (WorkingProcedure.Equals("OP20")) { var gongweiStr = DataCapturePointCode.Substring(DataCapturePointCode.Length - 1, 1); //记录公用变量,保存点位M88的信息 【Editby shaocx,2024-06-07】 if (DataCapturePointCode.Contains("OP2002C")) {//从OP2002C读取,因为顺序是 CBA,而不是ABC string sideValue = GetSideForOP20(plcService, logMiddle); SystemValue.OP20_Side_Value = sideValue; } logMiddle.MonitoringPoint += SystemValue.OP20_Side_Value; logMiddle.CreatedUserName = logMiddle.MonitoringPoint; Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成,是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr},校验通过,读取Op60_Place_Flag:true"); var time = DateTimeHelper.GetDateTime(); if (fileFindTime == null) { fileFindTime = time.AddMinutes(-60); } //OP20 需要扫描文件读取质量信息 //扫描修改时间在上次扫描时间之前30秒到当前时间的之间的文件 List files = new List(); var newFiles = FileHelper.DetectNewFiles(pathOP20, "*.dfq", 300, fileFindTime.Value, time.AddHours(2)); foreach (var file in newFiles) { files.Add((FileInfo)file); } //注意:一定要筛选制定的文件数据 files = files.Where(x => x.Name.Contains("SP-" + gongweiStr)).OrderByDescending(o => o.LastWriteTime).ToList();//筛选取最新的文件 【Editby shaocx,2024-06-19】 Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"工位【{DataCapturePointCode}】工件【{logMiddle.WorkPieceID ?? "空字符"}】获取到【{files.Count()}】个文件,【{fileFindTime.Value}】【{time.AddHours(2)}】"); if (files.Count() > 0) { bool isFindFile = false; Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{files.Count()}个,是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr},上次获取尼伯丁文件里的时间值:{(op60QualityTime == null ? "" : op60QualityTime.ToString())}"); files = files.OrderByDescending(o => o.LastWriteTime).ToList(); List op60Infos = new List(); //注意:只取第一个文件就可以啦!!!!!! 【Editby shaocx,2024-06-19】 var doFiles = new List() { files.First() }; foreach (var file in doFiles) {//取倒序匹配的文件名为工件号的文件 if (file.Name.Contains("SP-" + gongweiStr)) { isFindFile = true; Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr},上次获取尼伯丁文件里的时间值:{(op60QualityTime == null ? "" : op60QualityTime.ToString())}"); var datatable = CSVHelper.ReadCSVList(file.FullName); Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取文件{file.Name},指定工件号{logMiddle.WorkPieceID},,工位{gongweiStr}发现文件行数{datatable.Count}"); if (datatable.Count < 57) {//质量数据从106行开始 Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取文件{file.Name},指定工件号{logMiddle.WorkPieceID},,工位{gongweiStr}发现文件行数{datatable.Count}小于106"); continue; } datatable.Reverse(); System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding(); byte[] byteArray = new byte[] { (byte)15 }; string strCharacter = asciiEncoding.GetString(byteArray); var list = datatable[0].Split(new String[] { strCharacter }, StringSplitOptions.None); byte[] byteArray2 = new byte[] { (byte)20 }; string strCharacter2 = asciiEncoding.GetString(byteArray2); foreach (var item in list) { var listitem = item.Split(new String[] { strCharacter2 }, StringSplitOptions.None); if (listitem.Count() == 3) { OP60Info info = new OP60Info(); info.datetime = listitem[2]; info.col2 = listitem[1]; info.value = listitem[0]; info.datetimeHandle = CommonManager.GetOP60Time(info.datetime); op60Infos.Add(info); } } if (op60Infos.Count() >= 1) { if (op60QualityTime.HasValue) { //if (op60Infos[0].datetimeHandle > op60QualityTime.Value) //{ // wplog.QualityOP20To1 = op60Infos[0].value; // wplog.OP20QualityFilePath = file.FullName; //} //else //{ // break; //} logMiddle.QualityOP20To1 = op60Infos[0].value; logMiddle.OP20QualityFilePath = file.FullName; Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr}成功赋值了OP20QualityFilePath等字段,读取时间:{op60Infos[0].datetimeHandle.ToString()}"); if (op60Infos[0].datetimeHandle > op60QualityTime.Value) {//这个时间判断要不要拿掉?? 【Editby shaocx,2024-06-19】 } else { var msg = $",只是警告!因为判断时间不符合,op60Infos[0].datetimeHandle:{(op60Infos[0].datetimeHandle == null ? "" : op60Infos[0].datetimeHandle.ToString())}小于等于op60QualityTime:{(op60QualityTime.Value == null ? "" : op60QualityTime.Value.ToString())}"; Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr}没能赋值OP60QualityFilePath等字段,{msg}"); } } else { logMiddle.QualityOP20To1 = op60Infos[0].value; logMiddle.OP20QualityFilePath = file.FullName; Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取到文件{file.Name},是指定的工件{logMiddle.WorkPieceID},工位{gongweiStr}成功赋值了OP20QualityFilePath等字段,读取时间:{op60Infos[0].datetimeHandle.ToString()}"); } op60QualityTime = op60Infos[0].datetimeHandle; break; } } else { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成读取文件{file.FullName}不是指定工件{logMiddle.WorkPieceID}"); } } if (isFindFile == false) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成没有找到文件,指定工件{logMiddle.WorkPieceID},工位{gongweiStr}"); } } else { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}下线完成,通过筛选过滤,没有找到文件,指定工件{logMiddle.WorkPieceID},工位{gongweiStr}"); } } } catch (Exception ex) { threadStatusMonitor.ErrorMsg = $" {RandomHelper.GenerateRandomCode(4)} 读取{DataCapturePointCode}测量完成出现异常,请查看日志!"; Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"{DataCapturePointCode}测量完成读取文件数据时异常,避免工序完成异常:", ex); } //根据质量数据判断是否合格/不合格 【Editby shaocx,2024-06-25】 QualityNoOkEnum? qualityNoOkEnum = null; QualityState qualityState = CalcQualityStateForOP(logMiddle, ref qualityNoOkEnum); logMiddle.QualityState = (int)qualityState; if (qualityNoOkEnum != null) { logMiddle.QualityNoOk = (int)qualityNoOkEnum; logMiddle.QualityNoOkReason = qualityNoOkEnum.ToString(); } //更新WorkPieceInfo表以及插入WorkPieceLog表和WorkPieceInfoLog表 WorkPieceInfoManager.QualityInfoComplete(logMiddle, PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure)); threadStatusMonitor.Threadstatue = 1; } value_02 = value.ToString(); } threadStatusMonitor.Remarks = $"abcdefg:{RandomHelper.GenerateRandomCode(4)}"; if (!_dataCaptureConfig.DataCaptureFrequency.HasValue || _dataCaptureConfig.DataCaptureFrequency < 10) { threadStatusMonitor.ThreadFrequency = 5000; Thread.Sleep(5000); } else { threadStatusMonitor.ThreadFrequency = _dataCaptureConfig.DataCaptureFrequency.Value; Thread.Sleep(_dataCaptureConfig.DataCaptureFrequency.Value); } } catch (Exception ex) { threadStatusMonitor.ErrorMsg = $" {RandomHelper.GenerateRandomCode(4)} 读取{DataCapturePointCode}工序监控测量标记 出现异常,请查看日志!"; Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"读取 {DataCapturePointCode}工序监控测量标记数据时异常:", ex); } finally { WorkPieceInfoManager.ThreadMonitor(threadStatusMonitor); } } } else { threadStatusMonitor.ErrorMsg = ""; threadStatusMonitor.Threadcode = DataCapturePointCode; threadStatusMonitor.Threadcname = DataCapturePointCname; threadStatusMonitor.Threadendtime = DateTime.Now; //threadStatusMonitor.Threadlastmodifytime = DateTime.Now; threadStatusMonitor.Threadstatue = 0; threadStatusMonitor.ThreadId = Thread.CurrentThread.ManagedThreadId.ToString(); threadStatusMonitor.Remarks = $" {RandomHelper.GenerateRandomCode(4)} {DataCapturePointCode}工序监控测量标记 不做校验,请确认配置信息!"; WorkPieceInfoManager.ThreadMonitor(threadStatusMonitor); Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"读{DataCapturePointCode}工序监控测量标记 不做校验,请确认是否配置异常"); } } /// /// 获取OP20的哪个面 /// /// /// private string GetSideForOP20(PLCService plcService, WorkPieceLogMiddle wplog) { try { object value_M88 = plcService.ReadValuePointV2("M88", PLCManger.GetTypeForString("int")); int i_value_M88 = 0; var isRight = int.TryParse(value_M88.ToString(), out i_value_M88); Log4NetHelper.WriteInfoLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"读取 {DataCapturePointCode}工序监控测量标记数据,获取OP20的哪个面,i_value_M88:{i_value_M88},工件号:{wplog.WorkPieceID}"); if (isRight) { if (i_value_M88 == 64) { return "1"; } else if (i_value_M88 == 16384) {//原定为16384为正在旋转,监控下来,发现 16384应该是工位1的问题 【Editby shaocx,2024-06-12】 return "1"; } else if (i_value_M88 == 256) { return "2"; } else if (i_value_M88 == 1024) { return "3"; } else if (i_value_M88 == 4096) { return "4"; } } Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"读取 {DataCapturePointCode}工序监控测量标记数据时,无效数值,获取OP20的哪个面,,i_value_M88:{i_value_M88},工件号:{wplog.WorkPieceID}", null); return ""; } catch (Exception ex) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"读取 {DataCapturePointCode}工序监控测量标记数据时异常,获取OP20的哪个面,工件号:{wplog.WorkPieceID}", ex); return ""; } } public WorkPieceLogMiddle GetCH4Info(string FullName, WorkPieceLogMiddle wplog) { try { string fileContent = File.ReadAllText(FullName); string[] lines2 = fileContent.Split('\n'); bool IDCodeIndex = false; int Mcount = 0; int i = 0; int count = 0; foreach (string line in lines2) { count++; if (count == 4) {//获取质量结果 var list = line.Split(' '); if (list.Count() > 0) { var str = list[list.Count() - 1].ToString().Trim(); wplog.QualityStateStr = str.Equals("OK") ? "OK" : "NG"; } } // 处理每一行的逻辑 if (line.Contains("ID-Code"))//两个拧紧,每个前面都有ID-Code { i++; IDCodeIndex = true; Mcount = 0; } if (IDCodeIndex) { if (line.Contains(" M "))//第三个M行是拧紧数据 {//预拧紧力矩 Mcount++; if (Mcount == 3) { i++; var str = line.Replace("+", "").Replace("-", ""); var list = str.Split('M'); if (list.Count() == 4) { if (i <= 2) {//CH1 wplog.QualityOP30To2 = list[2].ToString().Trim(); } else {//CH2 wplog.QualityOP30To8 = list[2].ToString().Trim(); } } IDCodeIndex = false; } } } } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"读取 {DataCapturePointCode}CH4工位质量数据异常工件号:{(wplog.WorkPieceID == null ? "" : wplog.WorkPieceID)} 文件名:{FullName}:", ex); } return wplog; } public WorkPieceLogMiddle GetCH5Info(string FullName, WorkPieceLogMiddle wplog) { try { string fileContent = File.ReadAllText(FullName); string[] lines2 = fileContent.Split('\n'); bool IDCodeIndex = false; int Mcount = 0; int i = 0; int count = 0; foreach (string line in lines2) { count++; if (count == 4) {//获取质量结果 var list = line.Split(' '); if (list.Count() > 0) { var str = list[list.Count() - 1].ToString().Trim(); wplog.QualityStateStr = str.Equals("OK") ? "OK" : "NG"; } } // 处理每一行的逻辑 if (line.Contains("ID-Code"))//两个拧紧,每个前面都有ID-Code { i++; IDCodeIndex = true; Mcount = 0; } if (IDCodeIndex) { if (line.Contains(" M "))//第三个M行是拧紧数据 {//最终力矩 Mcount++; if (Mcount == 3) { var str = line.Replace("+", "").Replace("-", ""); var list = str.Split('M'); if (list.Count() == 4) { if (i == 1) {//CH3 wplog.QualityOP30To3 = list[2].ToString().Trim(); } else {//CH4 wplog.QualityOP30To9 = list[2].ToString().Trim(); } } IDCodeIndex = false; } } } if (line.Contains(" MWSP ")) {//终拧紧力矩 终拧紧角度 var list = line.Split(new String[] { " MWS " }, StringSplitOptions.None); if (list.Count() == 2) { if (i == 1) {//CH3 wplog.QualityOP30To4 = list[1].ToString().Trim(); } else {//CH4 wplog.QualityOP30To10 = list[1].ToString().Trim(); } var list2 = list[0].Split(new String[] { " W " }, StringSplitOptions.None); if (list2.Count() == 2) { var str = list2[1].ToString(); if (i == 1) {//CH3 wplog.QualityOP30To5 = str.Substring(0, str.IndexOf("MWSP")).Trim(); } else {//CH4 wplog.QualityOP30To11 = str.Substring(0, str.IndexOf("MWSP")).Trim(); } } } } } } catch (Exception ex) { //Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"读取 {DataCapturePointCode}CH5工位质量数据异常工件号:{(wplog.WorkPieceID == null ? "" : wplog.WorkPieceID)} 文件名:{FullName}:", ex); } return wplog; } /// /// 计算OP 质量数据是否合格 /// public QualityState CalcQualityStateForOP(WorkPieceLogMiddle logMiddle, ref QualityNoOkEnum? qualityNoOkEnum) { QualityState qualityState = QualityState.Suspected; if (logMiddle.WorkingProcedure == "OP60") { decimal _QualityOP60To1 = SystemHelper.GetDecimal(logMiddle.QualityOP60To1); decimal _QualityOP60To2 = SystemHelper.GetDecimal(logMiddle.QualityOP60To2); var isPass_QualityOP60To1 = false; var isPass_QualityOP60To2 = false; if (_QualityOP60To1 >= (decimal)53.018 && _QualityOP60To1 <= (decimal)53.030) { isPass_QualityOP60To1 = true; } else { qualityNoOkEnum = QualityNoOkEnum.OP60大头孔直径超差; } if (_QualityOP60To2 >= (decimal)22.005 && _QualityOP60To2 <= (decimal)22.011) { isPass_QualityOP60To2 = true; } else { qualityNoOkEnum = QualityNoOkEnum.OP60小头孔直径超差; } if (isPass_QualityOP60To1 && isPass_QualityOP60To2) { qualityState = QualityState.OK; } else { qualityState = QualityState.NG; } if (_QualityOP60To1 == 0 || _QualityOP60To2 == 0) { qualityState = QualityState.Suspected; return qualityState; } return qualityState; } else if (logMiddle.WorkingProcedure == "OP10") { if (logMiddle.QualityState != (int)QualityState.OK) { qualityNoOkEnum = QualityNoOkEnum.OP10厚度超差; } return qualityState; } else if (logMiddle.WorkingProcedure == "OP20") { if (logMiddle.QualityState != (int)QualityState.OK) { qualityNoOkEnum = QualityNoOkEnum.OP20小头孔直径超差; } return qualityState; } else if (logMiddle.WorkingProcedure == "OP35") { if (logMiddle.QualityState != (int)QualityState.OK) { qualityNoOkEnum = QualityNoOkEnum.OP35滚压力不合格; } return qualityState; } else if (logMiddle.WorkingProcedure == "OP40") { if (logMiddle.QualityState != (int)QualityState.OK) { qualityNoOkEnum = QualityNoOkEnum.OP40厚度超差; } return qualityState; } return qualityState; } } }