| | |
| | | using ScottPlot.Drawing.Colormaps; |
| | | using Sunny.UI; |
| | | using Sunny.UI.Win32; |
| | | using System; |
| | | using System.Collections.Concurrent; |
| | | using System.Collections.Generic; |
| | | using System.Drawing.Imaging; |
| | |
| | | |
| | | public M141Process(string productCode) : base(productCode) { } |
| | | #endregion |
| | | |
| | | TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning); |
| | | |
| | | public event Action<string, P_PRODUCT_DETAIL, string> OnSinglePostionDetectResultUpdate; |
| | | |
| | | protected M141Config M141Config => Config as M141Config; |
| | | |
| | | public static object _productListLock = new object(); |
| | | public List<ProductModel> ProductList = new List<ProductModel>(); |
| | | MachineLearningBase ML = null; |
| | | TcpListenerWrap TcpListener = null; |
| | | Spec _errorSpec = null; |
| | | |
| | | TcpListenerWrap _realTimeServer = null; |
| | | //volatile int _productIndex = 0; |
| | | |
| | | volatile int _productIndex = 0; |
| | | public M141Process_Mysql mysqlhelper = new M141Process_Mysql(); |
| | | |
| | | int _backgroundImageWidth = 2448; |
| | | public event Action RerefreshBasketcodeUI; |
| | | |
| | | M141Process_Mysql mysqlhelper = new M141Process_Mysql(); |
| | | |
| | | public void RerefreshBasketcode() |
| | | { |
| | | RerefreshBasketcodeUI?.Invoke(); |
| | | } |
| | | |
| | | |
| | | |
| | | public override void InitialProcessMethods() |
| | | { |
| | | base.InitialProcessMethods(); |
| | | |
| | | |
| | | if (ThHeartPlc == null) |
| | | { |
| | |
| | | PLCBase Plc2; |
| | | public Thread ThHeartPlc; |
| | | |
| | | public RabbitMQHelper mqtt; |
| | | |
| | | |
| | | |
| | | public override void Open() |
| | | { |
| | | base.Open(); |
| | | |
| | | devicestate = true; |
| | | ML = DeviceCollection.FirstOrDefault(u => u is MachineLearningBase) as MachineLearningBase; |
| | | if (ML == null) |
| | |
| | | _positionSpecHeads.Clear(); |
| | | |
| | | mysqlhelper.IniDBIP(M141Config.IPforall); |
| | | RerefreshBasketcode(); |
| | | |
| | | |
| | | if (M141Config.ISupMES) |
| | | { |
| | | mqtt = new RabbitMQHelper(M141Config.zIP, M141Config.zport, M141Config.zuser, M141Config.zpassword); |
| | | mqtt.Connect(M141Config.MESchannel); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | |
| | | |
| | | } |
| | | |
| | | |
| | | public void Heartplc() |
| | | { |
| | | Thread.Sleep(1000); |
| | | |
| | | //Open(); |
| | | |
| | | string _statisticFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Statistic.json"); |
| | | if (File.Exists(_statisticFilePath)) |
| | | { |
| | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | try |
| | | { |
| | | if (Plc1 != null) |
| | | { |
| | | DateTime dt = DateTime.Now; |
| | | Plc1.WriteSingleAddress(10, dt.Year, out _); |
| | | Plc1.WriteSingleAddress(11, dt.Month, out _); |
| | | Plc1.WriteSingleAddress(12, dt.Day, out _); |
| | | Plc1.WriteSingleAddress(13, dt.Hour, out _); |
| | | Plc1.WriteSingleAddress(14, dt.Minute, out _); |
| | | Plc1.WriteSingleAddress(15, dt.Second, out _); |
| | | Plc1.WriteSingleAddress(16, (int)dt.DayOfWeek, out _); |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | |
| | | Thread.Sleep(1000); |
| | | } |
| | | } |
| | |
| | | Dictionary<string, List<string>> _positionSpecHeads = new Dictionary<string, List<string>>(); |
| | | |
| | | |
| | | |
| | | |
| | | volatile int uploadId = 0; |
| | | |
| | | |
| | |
| | | throw new Exception($"产品{string.Join(",", pidList)}检测{measureBind.GetDisplayText()}未能获取图片对象"); |
| | | } |
| | | |
| | | RunCustomizedMethod(products, triggerText, triggerSource, imgSet, measureBind.CustomizedMonitorId, resultList); |
| | | RunCustomizedMethod(products, triggerText, triggerSource, imgSet, measureBind.CustomizedCombineMethodId, resultList); |
| | | |
| | | //检测顺序 ML->自定义检测 |
| | | if (!string.IsNullOrWhiteSpace(measureBind.DetectionId)) |
| | | { |
| | | string detectionName = (ML.InitialConfig as MLInitialConfigBase).DetectionConfigs.FirstOrDefault(u => u.Id == measureBind.DetectionId)?.Name; |
| | | |
| | | |
| | | //List<string> pidList2 = new List<string>();//pidList.Select(u => u.Split('_')[u.Split('_').Length - 1]).ToList(); |
| | | //Dictionary<string, string> dicpid = new Dictionary<string, string>(); |
| | | |
| | | //for (int i = 0; i < pidList.Count; i++) |
| | | //{ |
| | | // var tem = pidList[i].Split('_')[pidList[i].Split('_').Length - 1]; |
| | | // pidList2.Add(tem); |
| | | // dicpid[tem] = pidList[i]; |
| | | //} |
| | | List<DetectResult> detectResults = ML?.RunMLDetectionSync(imgSet, pidList, measureBind.DetectionId, false, null, null, "", products[0].ImagePaths); |
| | | |
| | | |
| | | List<DetectResult> detectResults = ML?.RunMLDetectionSync(imgSet, pidList, measureBind.DetectionId); |
| | | |
| | | if (measureBind.WorkPosition == "P1" && M141Config.StationCode == "S5" && detectResults.GetDefectDescList().Count == 0) |
| | | { |
| | | var defecttem = detectResults.SelectMany(u => u.AllNetResults.SelectMany(m => m.DetectDetails)).Where(u => u.ClassName == M141Config.defectname).ToList(); |
| | | |
| | | List<Netdefectdetail> Netdefectdetails = mysqlhelper.GetNetdefectdetails(products[0].SEQUENCE); |
| | | |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{products[0].SN} S3S5检测 S3数据{Netdefectdetails.Count} S5数据{defecttem.Count}"); |
| | | |
| | | Netdefectdetails.ForEach(x => |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{products[0].SN} S3S5检测 S3数据{x.name} {x.centerX},{x.centerY} "); |
| | | }); |
| | | |
| | | int num = 0; |
| | | foreach (var item1 in defecttem) |
| | | { |
| | | double x1 = item1.Rect.Point_LU.X + item1.Rect.Width / 2.0; |
| | | double y1 = item1.Rect.Point_LU.Y + item1.Rect.Height / 2.0; |
| | | num++; |
| | | |
| | | //HOperatorSet.AffineTransPoint2d(new HTuple(products[0].Centermatrix.ToArray()), x1, y1, out HTuple qx, out HTuple qy); |
| | | //HOperatorSet.ProjectiveTransPixel(new HTuple(products[0].Centermatrix.ToArray()), x1, y1, out HTuple qx, out HTuple qy); |
| | | |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{products[0].SN} S3S5检测 原坐标{num} {x1},{y1}"); |
| | | HOperatorSet.ProjectiveTransPixel(new HTuple(products[0].Centermatrix.ToArray()), x1, y1, out HTuple qx, out HTuple qy); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{products[0].SN} S3S5检测 新坐标{num} {qx},{qy}"); |
| | | |
| | | |
| | | Netdefectdetail temc = new Netdefectdetail() |
| | | { |
| | | centerX = qx, |
| | | centerY = qy, |
| | | name = M141Config.defectname, |
| | | }; |
| | | if (Netdefectdetails.Any(u => u == temc)) |
| | | { |
| | | item1.IsAbandoned = false; |
| | | item1.FinalResult = ResultState.NG; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"产品{products[0].PID}_{products[0].SEQUENCE}工位{measureBind.WorkPosition} S3S5组合检测检出缺陷:{item1.NetName}"); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | List<DetectResult> ngResults = new List<DetectResult>(); |
| | | |
| | | |
| | | //for (int i = 0; i < detectResults.Count; i++) |
| | | //{ |
| | | // detectResults[i].PID = dicpid[detectResults[i].PID]; |
| | | //} |
| | | |
| | | |
| | | detectResults.GroupBy(u => u.PID).ToList().ForEach(u => |
| | | { |
| | | if (u.ToList().Count > 0 && u.ToList().Any(m => m.ResultState != EnumHelper.ResultState.OK)) |
| | |
| | | detectResults.AddRange(ngResults); |
| | | resultList.AddRange(detectResults); |
| | | } |
| | | RunCustomizedMethod(products, triggerText, triggerSource, imgSet, measureBind.CustomizedMonitorId, resultList); |
| | | RunCustomizedMethod(products, triggerText, triggerSource, imgSet, measureBind.CustomizedCombineMethodId, resultList); |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | { |
| | | products.ForEach(p => |
| | | { |
| | | var pResults = resultList.Where(u => u.PID == p.PID).ToList(); |
| | | var pResults = resultList.ToList(); |
| | | p.AddNewDetectResults(M141Config.StationCode, measureBind.WorkPosition, pResults); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"产品{p.PID}_{p.SEQUENCE}添加工位{measureBind.WorkPosition}检测结果,数量{pResults.Count}"); |
| | | }); |
| | |
| | | if (M141Config.Isreadbasketcode) |
| | | { |
| | | p.BasketCode = M141Config.basketcode; |
| | | p.Zword = M141Config.zwoid; |
| | | } |
| | | else |
| | | { |
| | | p.BasketCode = mysqlhelper.Getbasketcode(p.SEQUENCE, out string sntem); |
| | | p.BasketCode = mysqlhelper.Getbasketcode(p.SEQUENCE, out string sntem, out string zword); |
| | | p.Zword = zword; |
| | | p.SN = sntem; |
| | | p.PID = $"{sntem}_{i}"; |
| | | if ("NoRead".Equals(p.BasketCode)) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"{p.PID}_{p.SEQUENCE}获取框具码失败 赋值Noread"); |
| | |
| | | |
| | | //初始化产品的检测次数 |
| | | var checkIndexList = M141Config.MeasureBindCollection.Where(u => u.WorkPosition == b.WorkPosition && u.ProductIndices.Contains(i)).Select(u => u.CheckIndex).OrderBy(u => u).ToList(); |
| | | p.InitialPositionCheckList(b.WorkPosition, checkIndexList); |
| | | p.InitialPositionCheckList(b.WorkPosition, checkIndexList, M141Config.StationCode); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{p.PID}_{p.SEQUENCE}已清理{b.WorkPosition}检测数据。当前已完成工位{string.Join(",", p.Details.Select(u => u.PositionName))}"); |
| | | |
| | | }); |
| | | |
| | | //初始化工位的检测次数 |
| | |
| | | |
| | | //UpdatePositionResultToDB(detail); |
| | | //var seqData = p.SEQUENCE.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries).ToList(); |
| | | ReplyPlcData(positionSet, plcresult); |
| | | |
| | | if (M141Config.StationCode == "S4" && isOK) |
| | | { |
| | | ////mysqlhelper.GetS2Result(productList[0].SEQUENCE); |
| | | //Plc1.WriteSingleAddress(1526, mysqlhelper.GetS2Result(productList[0].SEQUENCE) ? 1 : 2, out _); |
| | | |
| | | bool temS2 = mysqlhelper.GetS2Result(p.SEQUENCE); |
| | | ReplyPlcData(positionSet, new List<bool>() { temS2 }); |
| | | if (!temS2) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"{p.SN} S2工站NG抛料"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | ReplyPlcData(positionSet, plcresult); |
| | | } |
| | | |
| | | |
| | | |
| | | mysqlhelper.UpdateProduct(p); |
| | | if (positionSet.IsLastPosition) |
| | | { |
| | | UpdateProductResultAsync(p); |
| | | mysqlhelper.NewForAll(p, M141Config.StationCode); |
| | | mysqlhelper.NewForAll(p, M141Config.StationCode, M141Config.defectname); |
| | | if (M141Config.IsfinDevice) |
| | | { |
| | | SummaryAllprodata(p); |
| | | } |
| | | } |
| | | }); |
| | | //ReplyPlcData(positionSet, plcresult); |
| | | if (positionSet.IsLastPosition) |
| | | { |
| | | if (_ct != null) |
| | | { |
| | | UpdateCT(null, (float)((DateTime.Now - _ct.Value).TotalSeconds)); |
| | | } |
| | | _ct = DateTime.Now; |
| | | } |
| | | |
| | | //ReplyPlcData(positionName, config.TriggerValue); |
| | | |
| | | cameraIds.ForEach(c => |
| | | { |
| | |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"相机{camera.Name}清理缓存"); |
| | | } |
| | | }); |
| | | |
| | | //ReplyPlcData(positionSet, plcresult); |
| | | if (positionSet.IsLastPosition) |
| | | { |
| | | if (_ct != null) |
| | | { |
| | | UpdateCT(null, (float)((DateTime.Now - _ct.Value).TotalSeconds)); |
| | | } |
| | | _ct = DateTime.Now; |
| | | |
| | | if (M141Config.ISupMES && (M141Config.MESchannel == -1 || M141Config.MESchannel == 1)) |
| | | { |
| | | if (M141Config.numpro >= 50) |
| | | { |
| | | M141Config.numpro = 0; |
| | | } |
| | | |
| | | if (pList[0].Result == "OK") |
| | | { |
| | | M141Config.numpro++; |
| | | } |
| | | |
| | | //mqtt.demes(productList[0], M141Config.zwoid); |
| | | string Msgreceice = Task.Run(() => mqtt.MESForProduceAsync(pList[0], M141Config.mesnum2.ToString(),M141Config.numpro)).Result; |
| | | M141Config.mesnum2++; |
| | | if (Msgreceice == null) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"产品{pList[0].PID}数据上传MES异常 返回数据为null"); |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | var obj = JsonConvert.DeserializeObject<AutoLineMacBarcodeQueueBak>(Msgreceice); |
| | | |
| | | if (obj.zstatus == "200") |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{pList[0].PID}数据上传MES成功 {Msgreceice}"); |
| | | } |
| | | else |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"产品{pList[0].PID}数据上传MES失败 {Msgreceice}"); |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"产品{pList[0].PID}数据上传MES异常 {Msgreceice}"); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | int numplca = Convert.ToInt32(pList[0].SEQUENCE.Split('_')[0]); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"plc给出的产品序号为{numplca}"); |
| | | |
| | | lock (plcnumlock)//1-29999 |
| | | { |
| | | |
| | | if (PlcNumForAll == -1) |
| | | { |
| | | PlcNumForAll = numplca; |
| | | } |
| | | |
| | | int differ = numplca - PlcNumForAll; |
| | | |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"两个产品中间的差值differ为{differ}"); |
| | | |
| | | if (differ > 1) |
| | | { |
| | | for (int i = PlcNumForAll + 1; i < numplca; i++) |
| | | { |
| | | try |
| | | { |
| | | var plist = mysqlhelper.GetProductList(i + "_1"); |
| | | ProductModel newp = new ProductModel(); |
| | | newp.SEQUENCE = plist[0].SEQUENCE; |
| | | newp.PID = plist[0].PID; |
| | | newp.BasketCode = plist[0].BasketCode; |
| | | newp.Zword = plist[0].Zword; |
| | | newp.Result = "NG"; |
| | | newp.SN = plist[0].SN; |
| | | var tems = Task.Run(() => mqtt.MESForProduceAsync(newp, M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | M141Config.mesnum2++; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"前站NG排料产品{newp.PID}数据上传,结果为{newp.Result}"); |
| | | |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | } |
| | | } |
| | | else if (differ == -29998 && differ == 1 && differ == 0) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"生产过程中未失去产品"); |
| | | } |
| | | else if ( differ<0 && differ>-29998) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"PlcNumForAll为{PlcNumForAll},numplca为{numplca}"); |
| | | //产品从新计数时 |
| | | for (int i = PlcNumForAll + 1; i <= 29999; i++) |
| | | { |
| | | try |
| | | { |
| | | var plist = mysqlhelper.GetProductList(i + "_1"); |
| | | ProductModel newp = new ProductModel(); |
| | | newp.SEQUENCE = plist[0].SEQUENCE; |
| | | newp.PID = plist[0].PID; |
| | | newp.Zword = plist[0].Zword; |
| | | newp.BasketCode = plist[0].BasketCode; |
| | | newp.Result = "NG"; |
| | | newp.SN = plist[0].SN; |
| | | var tems = Task.Run(() => mqtt.MESForProduceAsync(newp, M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | M141Config.mesnum2++; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"PlcNumForAll,前站NG排料且plc触发清零产品{newp.PID}数据上传,结果为{newp.Result}"); |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | } |
| | | for (int i = 1; i < numplca; i++) |
| | | { |
| | | try |
| | | { |
| | | var plist = mysqlhelper.GetProductList(i + "_1"); |
| | | ProductModel newp = new ProductModel(); |
| | | newp.SEQUENCE = plist[0].SEQUENCE; |
| | | newp.PID = plist[0].PID; |
| | | newp.BasketCode = plist[0].BasketCode; |
| | | newp.Zword = plist[0].Zword; |
| | | newp.Result = "NG"; |
| | | newp.SN = plist[0].SN; |
| | | var tems = Task.Run(() => mqtt.MESForProduceAsync(newp, M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | M141Config.mesnum2++; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"numplca,前站NG排料且plc触发清零产品{newp.PID}数据上传,结果为{newp.Result}"); |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | PlcNumForAll = numplca; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | //ReplyPlcData(positionName, config.TriggerValue); |
| | | |
| | | |
| | | |
| | | return pList; |
| | | |
| | |
| | | newp.SEQUENCE = p.SEQUENCE; |
| | | newp.PID = p.PID; |
| | | newp.BasketCode = p.BasketCode; |
| | | newp.Zword = p.Zword; |
| | | newp.Result = p.Result; |
| | | newp.SN = p.SN; |
| | | |
| | | Thread.Sleep(500); |
| | | var plist = mysqlhelper.GetProductList(p.SEQUENCE); |
| | | |
| | | |
| | |
| | | newp.Details.AddRange(item.Details); |
| | | } |
| | | } |
| | | //LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"AllDeviceProductRecord从数据库获取到数据{p.SEQUENCE} plist数量{plist.Count} Details数量{newp.Details.Count}"); |
| | | |
| | | //newp.Details.AddRange(p.Details); |
| | | |