using iWare_SCADA_BusinessLogical.BLL; using iWare_SCADA_BusinessLogical.Utils; using iWare_SCADA_Model; using iWare_SCADA_Model.MiddleModel; using log4net; using System; using System.Collections.Generic; using System.Data.Entity.Core.Common.CommandTrees; using System.Data.Entity.Validation; using System.Data.SqlTypes; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web.UI.WebControls; using System.Windows.Forms; namespace iWare_SCADA_BusinessLogical { /// /// OP80质量数据采集 /// public class OP80QualityDataHandler : DataCaptureHandler { public static readonly OP80QualityDataHandler Instance = new OP80QualityDataHandler(); public static readonly string path = ConfigHelper.GetConfigString("OP80QualityData");//OP80的地址 public static readonly string query_WorkingProcedureCurrent = "OP80"; public static readonly string _DataCapturePointCode = "OP8002"; public static readonly LogType logType = LogType.PLCOP80_QC; public OP80QualityDataHandler() { } 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() { while (true) { try { Do(); Thread.Sleep(1000 * 10); } catch (Exception ex) { Log4NetHelper.WriteErrorLog(logType, $"OP80质量数据采集异常:", ex); } finally { } } } private void Do() { using (DbModel db = new DbModel()) { try { ThreadStatusMonitorMiddle threadStatusMonitor = new ThreadStatusMonitorMiddle(); threadStatusMonitor.ErrorMsg = ""; threadStatusMonitor.Threadcode = logType.ToString(); threadStatusMonitor.Threadcname = "OP80质量数据采集"; threadStatusMonitor.Threadendtime = DateTime.Now; threadStatusMonitor.Threadstatue = 0; threadStatusMonitor.ThreadId = Thread.CurrentThread.ManagedThreadId.ToString(); threadStatusMonitor.Threadlastmodifytime = DateTime.Now; var processList = db.WorkPieceProcess.Where(o => o.WorkingProcedureCurrent == query_WorkingProcedureCurrent && o.GetQcDataFlag == 0 ).OrderBy(x => x.CreatedTime).ToList(); foreach (var item in processList) { var qualityData = db.QualityDataInfo.Where(o => o.WorkPieceID == item.WorkPieceID).FirstOrDefault(); if (qualityData == null) { Log4NetHelper.WriteErrorLog(logType, $"OP80质量数据采集异常,根据工件号{item.WorkPieceID}没有找到质量数据"); continue; } WorkPieceInfo info = db.WorkPieceInfo.Where(o => o.WorkPieceID == item.WorkPieceID).FirstOrDefault(); if (info == null) { Log4NetHelper.WriteErrorLog(logType, $"OP80质量数据采集异常,根据工件号{item.WorkPieceID}没有找到工件数据"); continue; } Do_One(db, info, item, qualityData, query_WorkingProcedureCurrent); Thread.Sleep(1000); } WorkPieceInfoManager.ThreadMonitor(threadStatusMonitor); } catch (Exception e) { Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:{e.Message} {e.StackTrace}"); } } } private void Do_One(DbModel db, WorkPieceInfo info, WorkPieceProcess pieceProcess, QualityDataInfo qualityData, string WorkingProcedure) { try { if (WorkingProcedure.Equals("OP80")) { var time = DateTimeHelper.GetDateTime(); //OP80 需要扫描文件读取质量信息 //扫描修改时间在上次扫描时间之前30秒到当前时间的之间的文件 List files = new List(); var newFiles = FileHelper.DetectNewFilesCSV(path, 300, time.AddDays(-7), time.AddDays(1)); foreach (var file in newFiles) { files.Add((FileInfo)file); } //files = files.OrderByDescending(o => o.LastWriteTime).ToList(); files = files.OrderBy(o => o.LastWriteTime).ToList();//时间升序 Log4NetHelper.WriteErrorLog(logType, $"OP80下线完成读取到文件{files.Count()}个工件{pieceProcess.WorkPieceID} "); bool isGetQcSuccess = false; var findFiles = files.Where(x => x.Name.Contains(pieceProcess.WorkPieceID)).OrderByDescending(x => x.LastWriteTime).ToList(); if (findFiles != null && findFiles.Count > 0) { var file = findFiles.First(); Log4NetHelper.WriteErrorLog(logType, $"OP80下线完成读取到文件{file.Name},是指定的工件{pieceProcess.WorkPieceID}"); WorkPieceLogMiddle wplog = new WorkPieceLogMiddle(); wplog.WorkPieceID = pieceProcess.WorkPieceID; wplog.WorkingProcedure = query_WorkingProcedureCurrent; wplog.Id = Yitter.IdGenerator.YitIdHelper.NextId(); wplog.EquipmentID = _dataCaptureConfig.EquipmentID; ; wplog.Remarks = wplog.WorkingProcedure; wplog.MonitoringPoint = _DataCapturePointCode; wplog.CreatedTime = DateTimeHelper.GetDateTime(); wplog.CreatedUserName = _DataCapturePointCode; wplog.UpdatedTime = DateTimeHelper.GetDateTime(); wplog.UpdatedUserName = Environment.MachineName + "自动" + Thread.CurrentThread.ManagedThreadId.ToString(); wplog.IsDeleted = false; WorkPieceLog loginfo2 = new WorkPieceLog(); loginfo2 = EntityPropHelper.Mapper(wplog); var datatable = CSVHelper.ReadCSVList(file.FullName); List rowFirst = new List(); List rowSecond = new List(); if (datatable.Count == 2) { rowFirst = datatable[0].Split(',').ToList(); rowSecond = datatable[1].Split(',').ToList(); if (rowSecond.Count < 11) { return; } //日期和时间 批号/标识号 嵌套号/主轴号 操作符 文本 测量机 过程参数 测量系统 过程参数值 序列号 零件识别号 1 OP80Info oP80Info = new OP80Info(); oP80Info.日期和时间 = rowSecond[0]; oP80Info.批号 = rowSecond[1]; oP80Info.嵌套号 = rowSecond[2]; oP80Info.操作符 = rowSecond[3]; oP80Info.文本 = rowSecond[4]; oP80Info.测量机 = rowSecond[5]; oP80Info.过程参数 = rowSecond[6]; oP80Info.测量系统 = rowSecond[7]; oP80Info.过程参数值 = rowSecond[8]; oP80Info.序列号 = rowSecond[9]; oP80Info.零件识别号 = rowSecond[10]; for (int i = 1; i <= (rowSecond.Count - 11) / 10; i++) { if (rowSecond.Count < (11 + i * 10)) { break; } //名称 相对值 相对值单位 绝对值 绝对值单位 名义值 上限 下限 状态/等级 分隔符 OP80ItemInfo item = new OP80ItemInfo(); item.分隔符 = rowSecond[1 + i * 10];//例如:* 表头:状态 item.名称 = rowSecond[2 + i * 10];//例如:Weight Big End 表头:* item.相对值 = rowSecond[3 + i * 10];//例如:-2.8 表头:简述 item.相对值单位 = rowSecond[4 + i * 10];//例如:gr 表头:Weight Big End item.绝对值 = rowSecond[5 + i * 10];//例如:371.66 表头:测量单位 item.绝对值单位 = rowSecond[6 + i * 10];//例如:gr 表头:绝对值 item.名义值 = rowSecond[7 + i * 10];//例如:374.5 表头:绝对值测量单位(UoM) item.上限 = rowSecond[8 + i * 10];//例如:10.5 表头:名义值 item.下限 = rowSecond[9 + i * 10];//例如:-10.5 表头:USL值 item.状态 = rowSecond[10 + i * 10];//例如:3 表头:LSL值 oP80Info.OP80ItemInfolist.Add(item); if (item.名称.Equals("Weight Class") || item.名称.Equals("Weight Small End") || item.名称.Equals("Weight Big End") || item.名称.Equals("Dime Small_End Class") || item.名称.Equals("Dime Big_End Class")) { } else { if (!string.IsNullOrEmpty(item.状态)) { oP80Info.OP80ItemStatusInfolist.Add(item); } } } if (oP80Info.OP80ItemStatusInfolist.Count > 0) { if (oP80Info.OP80ItemStatusInfolist.Any(o => !o.状态.Equals("OK"))) { wplog.QualityStateStr = "NG"; } else { wplog.QualityStateStr = "OK"; } } else { wplog.QualityStateStr = "OK"; } wplog.OP80QualityFilePath = file.FullName; wplog.OP80NewCode = oP80Info.批号?.Replace("#", ""); //大头重量 wplog.QualityOP80To1 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Big End")).FirstOrDefault()?.绝对值; //小头重量 wplog.QualityOP80To2 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Small End")).FirstOrDefault()?.绝对值; //总重 wplog.QualityOP80To3 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Total Weight")).FirstOrDefault()?.绝对值; //弯曲 wplog.QualityOP80To4 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Bend to A")).FirstOrDefault()?.绝对值; //扭度 wplog.QualityOP80To5 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Twist to A")).FirstOrDefault()?.绝对值; //大头垂直度 wplog.QualityOP80To6 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_C_Squareness")).FirstOrDefault()?.绝对值; //小头垂直度 wplog.QualityOP80To10 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Sma_End_C_Squareness")).FirstOrDefault()?.绝对值; //大头孔分组级别 wplog.QualityOP80To7 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Dime Big_End Class")).FirstOrDefault()?.状态; //小头孔分组级别 wplog.QualityOP80To8 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Dime Small_End Class")).FirstOrDefault()?.状态; //重量组别 wplog.QualityOP80To9 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Class")).FirstOrDefault()?.状态; //wplog.Remarks = (wplog.Remarks ?? "") + $"OP80下线完成读取文件{file.FullName},数据【{wplog.OP80NewCode??"空"}】【{wplog.QualityOP80To1 ?? "空"}】【{wplog.QualityOP80To2 ?? "空"}】【{wplog.QualityOP80To3 ?? "空"}】【{wplog.QualityOP80To4 ?? "空"}】【{wplog.QualityOP80To5 ?? "空"}】"; //新增OP80的一些质量数据 【Editby shaocx,2024-06-13】 wplog.QualityOP80_Houdu = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Thickness")).FirstOrDefault()?.绝对值; wplog.QualityOP80_ZXJ = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Distance of Two Head")).FirstOrDefault()?.绝对值; wplog.QualityOP80_DTKYZD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Cylindricity")).FirstOrDefault()?.绝对值; wplog.QualityOP80_XTSMYD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_Roundn")).FirstOrDefault()?.绝对值; wplog.QualityOP80_XTXMYD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_Roundn")).FirstOrDefault()?.绝对值; wplog.QualityOP80_D_S_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Top_X_Dia.")).FirstOrDefault()?.绝对值; wplog.QualityOP80_D_S_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Top_Y_Dia.")).FirstOrDefault()?.绝对值; wplog.QualityOP80_D_X_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Bot_X_Dia.")).FirstOrDefault()?.绝对值; wplog.QualityOP80_D_X_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Bot_Y_Dia.")).FirstOrDefault()?.绝对值; //计算大头孔直径,大头孔直径=(大头上面X方向直径+大头上面Y方向直径+大头下面X方向直径+大头下面Y方向直径)/4 List valueList = new List() { SystemHelper.GetDecimal(wplog.QualityOP80_D_S_X), SystemHelper.GetDecimal(wplog.QualityOP80_D_S_Y), SystemHelper.GetDecimal(wplog.QualityOP80_D_X_X), SystemHelper.GetDecimal(wplog.QualityOP80_D_X_Y), }; wplog.QualityOP80_D_TKZJ = SystemHelper.CalcDecimalAvg(valueList, 3); wplog.QualityOP80_X_S_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_X_Dia.")).FirstOrDefault()?.绝对值; wplog.QualityOP80_X_S_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_Y_Dia.")).FirstOrDefault()?.绝对值; wplog.QualityOP80_X_X_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_X_Dia.")).FirstOrDefault()?.绝对值; wplog.QualityOP80_X_X_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_Y_Dia.")).FirstOrDefault()?.绝对值; //计算小头孔直径,小头孔直径=(小头上面X方向直径+小头上面Y方向直径+小头下面X方向直径+小头下面Y方向直径)/4 valueList = new List(); valueList = new List() { SystemHelper.GetDecimal(wplog.QualityOP80_X_S_X), SystemHelper.GetDecimal(wplog.QualityOP80_X_S_Y), SystemHelper.GetDecimal(wplog.QualityOP80_X_X_X), SystemHelper.GetDecimal(wplog.QualityOP80_X_X_Y), }; wplog.QualityOP80_X_TKZJ = SystemHelper.CalcDecimalAvg(valueList, 3); } else { wplog.Remarks = (wplog.Remarks ?? "") + $"OP80下线完成读取文件{file.FullName}异常,行数不是2行"; } //更新WorkPieceInfo表以及插入WorkPieceLog表和WorkPieceInfoLog表 info.OP80NewCode = wplog.OP80NewCode;//更新成品吗 info.QualityState = (int)((wplog.QualityStateStr.Equals("OK") || wplog.QualityStateStr.Equals("0K")) ? QualityState.OK : QualityState.NG); wplog.QualityState = info.QualityState; info.QualityStateUpdateUser = wplog.UpdatedUserName; info.QualityStateUpdateTime = wplog.UpdatedTime.Value.LocalDateTime; info.QualityStateUpdateMode = QualityStateUpdateMode.Auto.ToString(); //var qualityData = db.QualityDataInfo.Where(o => o.WorkPieceID == wplog.WorkPieceID).FirstOrDefault(); //if (qualityData == null || qualityData.WorkPieceID.Length < 1 || qualityData.WorkingProcedure.Length < 1) //{//插入QualityDataInfo表 // qualityData = EntityPropHelper.Mapper(wplog); // db.QualityDataInfo.Add(GetAddQualityDataInfo(qualityData)); //} //修改QualityDataInfo表 //重复收到质量信息,会覆盖之前的 EntityPropHelper.CopyProp(wplog, qualityData, WorkPieceInfoManager.GetQualityDataInfoUpdate(wplog.WorkingProcedure, wplog.MonitoringPoint));//指定修改字段 qualityData.EquipmentID = "EOP80"; qualityData.QualityStateUpdateUser = info.UpdatedUserName; qualityData.QualityReceiveTime = info.UpdatedTime.Value.LocalDateTime; qualityData.QualityStateUpdateMode = info.QualityStateUpdateMode; qualityData.OP80QualityState = wplog.QualityState.HasValue ? wplog.QualityState.Value.ToString() : "3"; qualityData.OP80QualityReceiveTime = DateTimeHelper.GetDateTime(); qualityData.OP80QualityFilePath = wplog.OP80QualityFilePath; long op80id = qualityData.Id; if (op80id > 0) { pieceProcess.QualityDataInfoID = op80id; } loginfo2.Remarks = (loginfo2.Remarks ?? "") + $"质量:{wplog.QualityStateStr ?? "空"}"; if (!info.QualityState.Equals(((int)QualityState.OK).ToString())) { info.QualityErrorInfo = $"{wplog.WorkingProcedure}工序质量采集数据不合格"; } else { info.QualityErrorInfo = ""; } pieceProcess.GetQcDataCount = (pieceProcess.GetQcDataCount ?? 0) + 1; pieceProcess.GetQcDataFlag_Remark = "找到文件"; pieceProcess.GetQcDataFlag = 1; pieceProcess.QualityState = info.QualityState.HasValue ? info.QualityState.Value : (int)QualityState.OK; db.WorkPieceLog.Add(WorkPieceInfoManager.GetAddWorkPieceLog(loginfo2));//插入工件采集日志表 db.QualityDataInfoLog.Add(WorkPieceInfoManager.GetAddQualityDataInfoLog(qualityData));//插入质量日志 //转移文件 foreach (var item in findFiles) { var toPath = item.FullName.Replace("CA4GC20TD", "CA4GC20TD_COPY"); File.Move(item.FullName, toPath);//移动 } db.SaveChanges(); isGetQcSuccess = true; Log4NetHelper.WriteInfoLog(logType, $"OP80下线完成读取文件,成功处理了指定工件{info.WorkPieceID}的文件"); } if (isGetQcSuccess == false) { pieceProcess.GetQcDataCount = (pieceProcess.GetQcDataCount ?? 0) + 1; pieceProcess.GetQcDataFlag_Remark = "没有找到文件"; if (pieceProcess.GetQcDataCount >= 10) { pieceProcess.GetQcDataFlag = 2; } db.SaveChanges(); Log4NetHelper.WriteErrorLog(logType, $"OP80下线完成读取文件没有找到指定工件{info.WorkPieceID}的文件"); } } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(logType, $"指定工件{info.WorkPieceID},OP80下线完成读取文件数据时异常,避免工序完成异常:", ex); } } } }