| | |
| | | using Bro.Device.InsCamera; |
| | | using Bro.M135.Common; |
| | | using Bro.M135.DBManager; |
| | | using Bro.M141.Process.UI; |
| | | using Bro.Process; |
| | | using Bro.Process.DataBase.Models; |
| | | using Bro.UI.Model.Winform; |
| | | using HalconDotNet; |
| | | using MySql.Data.MySqlClient; |
| | | using Newtonsoft.Json; |
| | | using Newtonsoft.Json.Linq; |
| | | using NPOI.SS.Formula.Functions; |
| | |
| | | |
| | | public event Action RerefreshBasketcodeUI; |
| | | |
| | | public Action<bool, string> OnContinuousNGAlarmRaised; |
| | | |
| | | public void RerefreshBasketcode() |
| | | { |
| | | RerefreshBasketcodeUI?.Invoke(); |
| | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | public override void Open() |
| | | { |
| | | base.Open(); |
| | |
| | | mqtt.Connect(M141Config.MESchannel); |
| | | } |
| | | |
| | | |
| | | InitialContinuousNGAlarm(); |
| | | } |
| | | |
| | | |
| | | |
| | | public override void Close() |
| | | { |
| | | devicestate = false; |
| | |
| | | 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); |
| | | HOperatorSet.ProjectiveTransPixel(new HTuple(products[0].Centermatrix.ToArray()), y1, x1, out HTuple qx, out HTuple qy); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Detail, $"{products[0].SN} S3S5检测 新坐标{num} {qx},{qy}"); |
| | | |
| | | |
| | |
| | | { |
| | | item1.IsAbandoned = false; |
| | | item1.FinalResult = ResultState.NG; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"产品{products[0].PID}_{products[0].SEQUENCE}工位{measureBind.WorkPosition} S3S5组合检测检出缺陷:{item1.NetName}"); |
| | | |
| | | //products[0].Result = M141Config.defectname; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"产品{products[0].PID}_{products[0].SEQUENCE}工位{measureBind.WorkPosition} S3S5组合检测检出缺陷:{item1.NetName},产品结果为{products[0].Result}"); |
| | | break; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | string ngImageFile = Path.Combine(folder, $"{id}.{post}"); |
| | | var bitmap = imgSet.HImage.ConvertHImageToBitmap(); |
| | | bitmap.Save(ngImageFile, M141Config.ImageFormatNG); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{id}NG图片已保存"); |
| | | bitmap.Dispose(); |
| | | //var bitmap = imgSet.HImage.ConvertHImageToBitmap(); |
| | | //bitmap.Save(ngImageFile, M141Config.ImageFormatNG); |
| | | //LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{id}NG图片已保存"); |
| | | //bitmap.Dispose(); |
| | | try |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{id}NG图片测试转存{ngImageFile}"); |
| | | imgSet.HImage.WriteImage(M141Config.ImageFormatOK.ToString().ToLower(), 0, ngImageFile); |
| | | } |
| | | catch (Exception) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"{id}NG图片保存失败"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | string ngImageFile = Path.Combine(folder, $"{id}.{post}"); |
| | | var bitmap = imgSet.HImage.ConvertHImageToBitmap(); |
| | | bitmap.Save(ngImageFile, M141Config.ImageFormatOK); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{id}OK图片已保存"); |
| | | bitmap.Dispose(); |
| | | //var bitmap = imgSet.HImage.ConvertHImageToBitmap(); |
| | | //bitmap.Save(ngImageFile, M141Config.ImageFormatOK); |
| | | //LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{id}OK图片已保存"); |
| | | //bitmap.Dispose(); |
| | | try |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{id}OK图片测试转存{ngImageFile}"); |
| | | imgSet.HImage.WriteImage(M141Config.ImageFormatOK.ToString().ToLower(), 0, ngImageFile); |
| | | } |
| | | catch (Exception) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Error, $"{id}OK图片保存失败"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | 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)) |
| | |
| | | |
| | | |
| | | mysqlhelper.UpdateProduct(p); |
| | | |
| | | |
| | | |
| | | if (positionSet.IsLastPosition) |
| | | { |
| | | UpdateProductResultAsync(p); |
| | | |
| | | |
| | | //班次统计时间划分 |
| | | if (M141Config.WorkShiftList.Count == 0) |
| | | { |
| | | //生成一个报表 |
| | | string name = $"ProductRecord_{DateTime.Now.ToString("yyyyMMdd")}.csv"; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"创建{name}数据报表"); |
| | | UpdateProductResultAsync(p, name); |
| | | } |
| | | else |
| | | { |
| | | foreach (var item in M141Config.WorkShiftList) |
| | | { |
| | | DateTime now = DateTime.Now; |
| | | |
| | | if (item.ShiftTime_Start < item.ShiftTime_End) |
| | | { |
| | | if (now.TimeOfDay >= item.ShiftTime_Start.TimeOfDay && now.TimeOfDay < item.ShiftTime_End.TimeOfDay) |
| | | { |
| | | //生成一个报表 |
| | | string name = $"ProductRecord_{DateTime.Now.ToString("yyyyMMdd")}_{item.ShiftName}.csv"; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"创建{name}数据报表"); |
| | | UpdateProductResultAsync(p, name); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (now.TimeOfDay >= item.ShiftTime_Start.TimeOfDay ) |
| | | { |
| | | //生成一个报表 |
| | | string name = $"ProductRecord_{DateTime.Now.ToString("yyyyMMdd")}_{item.ShiftName}.csv"; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"创建{name}数据报表"); |
| | | UpdateProductResultAsync(p, name); |
| | | } |
| | | if (now.TimeOfDay < item.ShiftTime_End.TimeOfDay) |
| | | { |
| | | // 生成一个报表 |
| | | string name = $"ProductRecord_{DateTime.Now.AddDays(-1).ToString("yyyyMMdd")}_{item.ShiftName}.csv"; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"创建{name}数据报表"); |
| | | UpdateProductResultAsync(p, name); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | //UpdateProductResultAsync(p); |
| | | |
| | | 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; |
| | | } |
| | | |
| | | string Msgreceice = null; |
| | | |
| | | if (pList[0].Result == "OK") |
| | | { |
| | | M141Config.numpro++; |
| | | Msgreceice = Task.Run(() => mqtt.MESForProduceAsync(pList[0], M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | } |
| | | else |
| | | { |
| | | if (M141Config.ISupNG) |
| | | { |
| | | Msgreceice = Task.Run(() => mqtt.MESForProduceAsync(pList[0], M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{pList[0].PID}启动NG上传"); |
| | | |
| | | } |
| | | else |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{pList[0].PID}关闭NG上传"); |
| | | } |
| | | } |
| | | M141Config.mesnum2++; |
| | | if (Msgreceice == null && !M141Config.ISupNG) |
| | | { |
| | | if (!M141Config.ISupNG) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{pList[0].PID}数据NG,开启关闭NG上传MES"); |
| | | } |
| | | else |
| | | { |
| | | 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; |
| | | if (M141Config.ISupNG) |
| | | { |
| | | var tems = Task.Run(() => mqtt.MESForProduceAsync(newp, M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | M141Config.mesnum2++; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{newp.PID}启动NG上传"); |
| | | } |
| | | else |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{newp.PID}关闭NG上传"); |
| | | } |
| | | |
| | | } |
| | | catch |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{i + "_1"}上传失败"); |
| | | } |
| | | } |
| | | } |
| | | 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; |
| | | if (M141Config.ISupNG) |
| | | { |
| | | var tems = Task.Run(() => mqtt.MESForProduceAsync(newp, M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | M141Config.mesnum2++; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{newp.PID}启动NG上传"); |
| | | } |
| | | else |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{newp.PID}关闭NG上传"); |
| | | } |
| | | //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; |
| | | if (M141Config.ISupNG) |
| | | { |
| | | var tems = Task.Run(() => mqtt.MESForProduceAsync(newp, M141Config.mesnum2.ToString(), M141Config.numpro)).Result; |
| | | M141Config.mesnum2++; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{newp.PID}启动NG上传"); |
| | | } |
| | | else |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"产品{newp.PID}关闭NG上传"); |
| | | } |
| | | |
| | | //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; |
| | | |
| | |
| | | |
| | | public void SummaryAllprodata(ProductModel p) |
| | | { |
| | | |
| | | _taskFactory.StartNew(() => |
| | | { |
| | | try |
| | |
| | | newp.SEQUENCE = p.SEQUENCE; |
| | | newp.PID = p.PID; |
| | | newp.BasketCode = p.BasketCode; |
| | | newp.Zword = p.Zword; |
| | | newp.Result = p.Result; |
| | | newp.SN = p.SN; |
| | | |
| | |
| | | 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); |
| | |
| | | |
| | | |
| | | #endregion |
| | | |
| | | List<DefectNGRecord> DefectNGRecordList = new List<DefectNGRecord>(); |
| | | |
| | | public void InitialContinuousNGAlarm() |
| | | { |
| | | DefectNGRecordList = M141Config.ContinuousNGAlarmColletion.Where(u => u.IsEnabled).Select(u => |
| | | { |
| | | DefectNGRecord record = new DefectNGRecord(); |
| | | record.DefectName = u.DefectType; |
| | | record.AlarmSetting = u; |
| | | return record; |
| | | }).ToList(); |
| | | OnContinuousNGAlarmRaised = NGAlarmRaised; |
| | | if (M141Config.ContinuousNGAlarmAddress > 0 && Plc1 != null) |
| | | { |
| | | if (!Plc1.WriteSingleAddress(M141Config.ContinuousNGAlarmAddress, 0, out string error)) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"连续NG监控通知PLC重置报警失败,{error}"); |
| | | } |
| | | } |
| | | } |
| | | public async void CheckContinuousNGAlarmAsync(ProductModel product) |
| | | { |
| | | await Task.Run(() => |
| | | { |
| | | if (!M141Config.IsEnableContinuousNGAlarm) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"连续NG报警总开关已关闭"); |
| | | return; |
| | | } |
| | | |
| | | if (DefectNGRecordList.Count == 0) |
| | | return; |
| | | |
| | | string allMsg = ""; |
| | | bool isAlarmRaised = false; |
| | | int alarmType = 0; |
| | | string ngItem = ""; |
| | | try |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"连续NG数据记录"); |
| | | DefectNGRecordList.ForEach(d => |
| | | { |
| | | string alarmMsg = ""; |
| | | int alarmTypeTemp = 0; |
| | | |
| | | if (product.Result == "OK") |
| | | { |
| | | if (d.CheckIsAlarmRaised(product.Result == "OK", out alarmMsg, out alarmTypeTemp)) |
| | | { |
| | | allMsg += $"{alarmMsg}\r\n"; |
| | | |
| | | isAlarmRaised = true; |
| | | ngItem = "产品结果"; |
| | | alarmType = alarmTypeTemp; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{product.PID}数据结果为{product.Result}参与连续NG统计"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (product.Result.Contains(d.DefectName)) |
| | | { |
| | | if (d.CheckIsAlarmRaised(!product.Result.Contains(d.DefectName), out alarmMsg, out alarmTypeTemp)) |
| | | { |
| | | allMsg += $"{alarmMsg}\r\n"; |
| | | isAlarmRaised = true; |
| | | ngItem = "产品结果"; |
| | | alarmType = alarmTypeTemp; |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{product.PID}数据结果为{product.Result}参与连续NG统计"); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Warning, $"连续NG数据记录失败"); |
| | | } |
| | | if (isAlarmRaised) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Warning, $"连续NG监控报警,{allMsg}"); |
| | | if (M141Config.IsOperatorReset) |
| | | { |
| | | if (M141Config.ContinuousNGAlarmAddress > 0 && Plc1 != null) |
| | | { |
| | | if (!Plc1.WriteSingleAddress(M141Config.ContinuousNGAlarmAddress, 1, out string error)) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"连续NG监控通知PLC重置报警失败,{error}"); |
| | | } |
| | | } |
| | | OnContinuousNGAlarmRaised?.Invoke(true, allMsg); |
| | | } |
| | | else |
| | | { |
| | | Task.Delay(50).Wait(); |
| | | ResetContinuousNGAlarm(); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | object _continuousNGAlarmLock = new object(); |
| | | |
| | | FrmContinuousNGAlarm _continuousNGAlarmFrm = null; |
| | | private async void NGAlarmRaised(bool isRaiseAlarm, string alarmMsg) |
| | | { |
| | | await Task.Run(() => |
| | | { |
| | | if (isRaiseAlarm) |
| | | { |
| | | if (_continuousNGAlarmFrm == null) |
| | | { |
| | | lock (_continuousNGAlarmLock) |
| | | { |
| | | if (_continuousNGAlarmFrm == null) |
| | | { |
| | | _continuousNGAlarmFrm = new FrmContinuousNGAlarm(); |
| | | |
| | | _continuousNGAlarmFrm.TopMost = true; |
| | | |
| | | _continuousNGAlarmFrm.FormClosed += _continuousNGAlarmFrm_FormClosed; |
| | | |
| | | Task.Run(() => |
| | | { |
| | | _continuousNGAlarmFrm.ShowDialog(); |
| | | |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | Task.Delay(100).Wait(); |
| | | _continuousNGAlarmFrm.ShowAlarmMsg(alarmMsg); |
| | | } |
| | | else |
| | | { |
| | | if (_continuousNGAlarmFrm != null) |
| | | { |
| | | _continuousNGAlarmFrm.Close(); |
| | | } |
| | | |
| | | } |
| | | }); |
| | | |
| | | } |
| | | |
| | | private void _continuousNGAlarmFrm_FormClosed(object? sender, FormClosedEventArgs e) |
| | | { |
| | | ResetContinuousNGAlarm(); |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Action, $"连续NG报警已复位"); |
| | | _continuousNGAlarmFrm = null; |
| | | } |
| | | |
| | | public void ResetContinuousNGAlarm() |
| | | { |
| | | //连续NG复位 |
| | | DefectNGRecordList.Where(u => u.IsAlarmRaised).ToList().ForEach(u => u.ResetAlarm()); |
| | | if (M141Config.ContinuousNGAlarmAddress > 0 && Plc1 != null) |
| | | { |
| | | if (!Plc1.WriteSingleAddress(M141Config.ContinuousNGAlarmAddress, 0, out string error)) |
| | | { |
| | | LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"连续NG监控通知PLC重置报警失败,{error}"); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | [ProcessMethod("", "ContinuousNGAlarmTest", "连续NG报警测试", InvokeType.TestInvoke)] |
| | | public ResponseMessage ContinuousNGAlarmTest(IOperationConfig config, IDevice invokeDevice, IDevice sourceDevice) |
| | | { |
| | | ProductModel p = new ProductModel(); |
| | | |
| | | p.Result = config.TriggerStr; |
| | | |
| | | CheckContinuousNGAlarmAsync(p); |
| | | |
| | | return new ResponseMessage(); |
| | | } |
| | | } |
| | | |
| | | public class DefectNGRecord |
| | | { |
| | | public string DefectName { get; set; } |
| | | public List<DateTime> NGRecords { get; set; } = new List<DateTime>(); |
| | | public int ContinuousNGNum { get; set; } = 0; |
| | | public ContinuousNGAlarm AlarmSetting { get; set; } |
| | | |
| | | private object _lockObj = new object(); |
| | | |
| | | public bool IsAlarmRaised = false; |
| | | |
| | | bool _isContinuousAlarm = false; |
| | | |
| | | } |
| | | bool _timeAlarm = false; |
| | | |
| | | public bool CheckIsAlarmRaised(bool isOK, out string alarmMsg, out int alarmType) |
| | | { |
| | | alarmType = 0; |
| | | alarmMsg = ""; |
| | | bool isAlarmRasied = false; |
| | | |
| | | if (IsAlarmRaised) |
| | | return false; |
| | | |
| | | lock (_lockObj) |
| | | { |
| | | if (IsAlarmRaised) |
| | | return false; |
| | | |
| | | if (isOK) |
| | | { |
| | | ContinuousNGNum = 0; |
| | | } |
| | | else |
| | | { |
| | | //连续NG数量阈值 |
| | | if (AlarmSetting.ContinuousNumThreshold > 0) |
| | | { |
| | | ContinuousNGNum++; |
| | | CommonLogger.LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{DefectName}连续NG数量为:{ContinuousNGNum}个"); |
| | | } |
| | | //时间内NG数量阈值 |
| | | if (AlarmSetting.TimePeriodNumThresold > 0) |
| | | { |
| | | NGRecords.Add(DateTime.Now); |
| | | } |
| | | } |
| | | |
| | | if (NGRecords.Count >= AlarmSetting.TimePeriodNumThresold && NGRecords.Count > 0) |
| | | { |
| | | |
| | | NGRecords = NGRecords.Skip(NGRecords.Count - AlarmSetting.TimePeriodNumThresold).OrderBy(u => u).ToList(); |
| | | |
| | | int timeInMinute = (int)Math.Ceiling((NGRecords[NGRecords.Count - 1] - NGRecords[0]).TotalMinutes); |
| | | //监控时间段 |
| | | if (timeInMinute <= AlarmSetting.TimePeriod) |
| | | { |
| | | isAlarmRasied = true; |
| | | alarmMsg += $"{DefectName}{timeInMinute}分钟内NG{NGRecords.Count}个 "; |
| | | alarmType = AlarmSetting.TimePeriodAlarmType; |
| | | _timeAlarm = true; |
| | | } |
| | | } |
| | | |
| | | if (ContinuousNGNum >= AlarmSetting.ContinuousNumThreshold) |
| | | { |
| | | isAlarmRasied = true; |
| | | alarmMsg += $"{DefectName}连续NG{ContinuousNGNum}个 "; |
| | | alarmType = AlarmSetting.ContinuousAlarmType; |
| | | _isContinuousAlarm = true; |
| | | } |
| | | IsAlarmRaised = isAlarmRasied; |
| | | return isAlarmRasied; |
| | | } |
| | | } |
| | | |
| | | public void ResetAlarm() |
| | | { |
| | | string msg = ""; |
| | | lock (_lockObj) |
| | | { |
| | | IsAlarmRaised = false; |
| | | if (_isContinuousAlarm) |
| | | { |
| | | _isContinuousAlarm = false; |
| | | ContinuousNGNum = 0; |
| | | msg += "连续NG报警 "; |
| | | } |
| | | |
| | | if (_timeAlarm) |
| | | { |
| | | |
| | | _timeAlarm = false; |
| | | NGRecords.Clear(); |
| | | msg += "时段内NG报警 "; |
| | | } |
| | | } |
| | | CommonLogger.LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{DefectName}{msg}已重置"); |
| | | } |
| | | |
| | | } |
| | | } |