using Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; using Bro.M135.Common; using Newtonsoft.Json; using NPOI.SS.Formula.Functions; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using System.Drawing.Printing; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Bro.M141.Process { public partial class M141Process { public event Action UploadProductForStatistic; public List GetSpecHeads() { return Config.GetSpecList().Where(u => u.IsEnabled).OrderBy(u => u.Code).ToList(); } object _pListForStatisticLock = new object(); public List ProductListForStatistic { get; set; } = new List(); private async void HandleProductStatistc(ProductModel product) { await Task.Run(() => { if (product == null) return; lock (_pListForStatisticLock) { //foreach (var item in product.ProductResultCollection) //{ // item.Value.PID = product.PID; // item.Value.ProductSeq = item.Key; // item.Value.EndTime = DateTime.Now; SummaryOKRate(product); ProductListForStatistic.Insert(0, product); UploadProductForStatistic?.Invoke(product); //} while (ProductListForStatistic.Count > M141Config.MaxProductNumForStatistic) { ProductListForStatistic.RemoveAt(ProductListForStatistic.Count - 1); } } //UploadProductForStatistic?.Invoke(product); }); } #region 良率统计 public SummaryData SummaryData { get; set; } = new SummaryData(); object _okRateLock = new object(); public OKRateModel OKRateModel => SummaryData.OKRateModel; public List ShiftSummaryDatas => SummaryData.ShiftSummaryDatas; private void SummaryOKRate(ProductModel singleResult) { var results = singleResult.Result; if (results == "NG") { List ngitem = new List(); foreach (var v in singleResult.Details) { ngitem.AddRange(v.ResultList.GetDefectDescList()); ngitem.AddRange(v.DefectList); } ngitem = ngitem.Distinct().ToList(); List ngitemD = ngitem.Where(u => u.ToUpper().Contains("FAI")).ToList(); //List ngitemC = ngitem.Where(u => !u.ToUpper().Contains("FAI")).ToList(); if (ngitemD != null && ngitemD.Count > 0) { results = "CNG"; } else { results = "WNG"; } } lock (_okRateLock) { OKRateModel.TotalNum++; bool isSpecOK = true; bool isDefectOK = true; if (results.ToUpper().Equals("CNG")) { OKRateModel.Spec_NG++; isSpecOK = false; } if (results.ToUpper().Equals("WNG")) { OKRateModel.Defect_NG++; isDefectOK = false; } if (isSpecOK && isDefectOK) { OKRateModel.OKNum++; } ShiftSummary? shift = InitialCurrentShift(singleResult.EndTime??DateTime.Now); var hourData = shift.HourDatas.FirstOrDefault(u => u.HourTime <= singleResult.EndTime && u.HourTime.AddHours(1) > singleResult.EndTime); if (hourData == null) { LogAsync(DateTime.Now, Common.Helper.EnumHelper.LogLevel.Error, $"产品{singleResult.PID},结束时间{(singleResult.EndTime??DateTime.Now).ToString("MM/dd HH:mm")}未能统计到合适的时段"); } else { hourData.OKRateModel.TotalNum++; if (!isSpecOK) { hourData.OKRateModel.Spec_NG++; } if (!isDefectOK) { hourData.OKRateModel.Defect_NG++; } if (isSpecOK && isDefectOK) { hourData.OKRateModel.OKNum++; } } _saveSummaryDataTimer.Change(15 * 1000, -1); } } private ShiftSummary InitialCurrentShift(DateTime dtNow) { var shift = ShiftSummaryDatas.FirstOrDefault(u => u.StartTime <= dtNow && u.EndTime > dtNow); if (shift == null) { DateTime shiftStartTime = DateTime.Now; if (dtNow.Hour >= 8 && dtNow.Hour < 20) { shiftStartTime = dtNow.Date.AddHours(8); } else if (dtNow.Hour >= 20 && dtNow.Hour < 0) { shiftStartTime = dtNow.Date.AddHours(20); } else { shiftStartTime = dtNow.AddDays(-1).AddHours(20); } shift = new ShiftSummary() { StartTime = shiftStartTime, EndTime = shiftStartTime.AddHours(12), }; shift.Initial(); ShiftSummaryDatas.Add(shift); while (ShiftSummaryDatas.Count > 2) { ShiftSummaryDatas.RemoveAt(0); } while (ShiftSummaryDatas.Count < 2) { ShiftSummary tempShift = new ShiftSummary() { StartTime = ShiftSummaryDatas[ShiftSummaryDatas.Count - 1].EndTime, EndTime = ShiftSummaryDatas[ShiftSummaryDatas.Count - 1].EndTime.AddHours(12), }; tempShift.Initial(); ShiftSummaryDatas.Add(tempShift); } } return shift; } public void ResetOKRate() { lock (_okRateLock) { OKRateModel.TotalNum = OKRateModel.OKNum = OKRateModel.Spec_NG = OKRateModel.Defect_NG = 0; } } System.Threading.Timer _saveSummaryDataTimer = null; public void InitialSummaryData() { if (_saveSummaryDataTimer == null) { _saveSummaryDataTimer = new System.Threading.Timer(SaveSummaryData, null, -1, -1); } string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SummaryData.json"); if (File.Exists(filePath)) { try { using (StreamReader reader = new StreamReader(filePath, System.Text.Encoding.UTF8)) { var dataStr = reader.ReadToEnd(); SummaryData = JsonConvert.DeserializeObject(dataStr); if (SummaryData == null) { SummaryData = new SummaryData(); } } } catch (Exception ex) { SummaryData = new SummaryData(); LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"统计汇总信息读取失败,初始化统计汇总"); } } InitialCurrentShift(DateTime.Now); } private void SaveSummaryData(object? state) { if (!SaveSummaryData(out string error)) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"统计汇总信息保存失败,{error}"); } } public bool SaveSummaryData(out string error) { error = ""; try { using (StreamWriter sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SummaryData.json"), false, System.Text.Encoding.UTF8)) { sw.Write(JsonConvert.SerializeObject(SummaryData)); } } catch (Exception ex) { error = ex.GetExceptionMessage(); return false; } return true; } #endregion //[ProcessMethod("TestHandleProductStatistic", "TestHandleProductStatistic", "处理产品统计测试方法", InvokeType.TestInvoke)] //public ResponseMessage TestHandleProductStatistic(IOperationConfig config, IDevice executeDevice, IDevice sourceDevice) //{ // ProductModel productModel = new ProductModel(); // SingleProductResultCollection resultCollection = new SingleProductResultCollection(); // productModel.ProductResultCollection.Add(0, resultCollection); // DetectResult result = new DetectResult(); // result.ResultState = EnumHelper.ResultState.OK; // resultCollection.AddPositionSnapshotResult(1, new List() { result }); // if (config is M141Process.HandleProductStatisticTestOpConfig opConfig) // { // if (opConfig.Defects.Count > 0) // { // opConfig.Defects.ForEach(d => // { // result.AddNetResult(new NetResult() // { // DetectDetails = new List() // { // new DefectDetail() // { // ClassName=d, // FinalResult=EnumHelper.ResultState.NG, // } // } // }); // }); // } // if (opConfig.FAINGs.Count > 0) // { // opConfig.FAINGs.ForEach(f => // { // result.Specs.Add(new Spec() // { // Code = f, // ActualValue = 999, // MeasureResult = false, // }); // }); // } // result.SetResult(); // } // HandleProductStatistc(productModel); // return new ResponseMessage(); //} //[Device("TestHandleProductStatistic", "处理产品统计测试方法配置", EnumHelper.DeviceAttributeType.OperationConfig)] //public class HandleProductStatisticTestOpConfig : OperationConfigBase //{ // [Category("缺陷信息")] // [Description("缺陷NG信息")] // [DisplayName("缺陷NG信息")] // [TypeConverter(typeof(SimpleCollectionConvert))] // [Editor(typeof(SimpleCollectionEditor), typeof(UITypeEditor))] // public List Defects { get; set; } = new List(); // [Category("缺陷信息")] // [Description("尺寸NG信息")] // [DisplayName("尺寸NG信息")] // [TypeConverter(typeof(SimpleCollectionConvert))] // [Editor(typeof(SimpleCollectionEditor), typeof(UITypeEditor))] // public List FAINGs { get; set; } = new List(); //} } } public class SummaryData { public OKRateModel OKRateModel { get; set; } = new OKRateModel(); public List ShiftSummaryDatas { get; set; } = new List(); } public class OKRateModel { public int TotalNum { get; set; } = 0; public int OKNum { get; set; } = 0; public int Spec_NG { get; set; } = 0; public int Defect_NG { get; set; } = 0; } public class ShiftSummary { public DateTime StartTime { get; set; } public DateTime EndTime { get; set; } public List HourDatas { get; set; } = new List(); public class HourData { public DateTime HourTime { get; set; } public OKRateModel OKRateModel { get; set; } = new OKRateModel(); } public void Initial() { HourDatas.Clear(); for (int i = 0; i < 12; i++) { HourDatas.Add(new HourData() { HourTime = StartTime.AddHours(i), }); } } } //public class SingleProductResultCollection //{ // public string PID { get; set; } = ""; // public int ProductSeq { get; set; } = 0; // public DateTime EndTime { get; set; } // //public List> DetectResults { get; set; } = new List>(); // public Dictionary>> DetectResults { get; set; } = new Dictionary>>(); // object _resultLock = new object(); // public void AddPositionSnapshotResult(int positionNum, List results) // { // lock (_resultLock) // { // if (!DetectResults.ContainsKey(positionNum)) // { // DetectResults[positionNum] = new List>(); // } // DetectResults[positionNum].Add(results); // } // } //}