using Bro.Common.Helper; using Bro.M135.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Bro.M141.Process { public partial class M141Process { List DefectNGRecordList = new List(); 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(); } 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; //var allDefects = product.DETAILS.SelectMany(u => u.DetectResults).ToList().GetDefectDescList(); List allDefects = new List(); foreach (var v in product.Details) { allDefects.AddRange(v.ResultList.GetDefectDescList()); allDefects.AddRange(v.DefectList); } allDefects = allDefects.Distinct().ToList(); string allMsg = ""; bool isAlarmRaised = false; int alarmType = 0; string ngItem = ""; DefectNGRecordList.ForEach(d => { string alarmMsg = ""; if (d.CheckIsAlarmRaised(!allDefects.Contains(d.DefectName), out alarmMsg, out int alarmTypeTemp)) { allMsg += $"{alarmMsg}\r\n"; isAlarmRaised = true; ngItem = d.DefectName; alarmType = alarmTypeTemp; } }); if (isAlarmRaised) { var state = Plc1.Read(3027, 1, out _)[0]; if (state == 0) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"连续NG监控报警,{allMsg}"); if (!Plc1.WriteSingleAddress(3006, 1, out _)) { LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, $"连续NG监控通知PLC报警失败"); } else { DefectNGRecordList.ForEach(d => { d.ResetAlarm(); }); } } else { DefectNGRecordList.ForEach(d => { d.ResetAlarm(); }); } } }); } } public class DefectNGRecord { public string DefectName { get; set; } public List NGRecords { get; set; } = new List(); 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 { if (AlarmSetting.ContinuousNumThreshold > 0) { ContinuousNGNum++; } 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) { ContinuousNGNum = 0; _isContinuousAlarm = false; msg += "连续NG报警 "; } if (_timeAlarm) { NGRecords.Clear(); _timeAlarm = false; msg += "时段内NG报警 "; } } CommonLogger.LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{DefectName}{msg}已重置"); } } }