using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.ParameterCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Tolerance; using Aitex.Core.Util; using FurnaceRT.Equipments.PMs.RecipeExecutions; using FurnaceRT.Equipments.Systems; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Event; using MECF.Framework.Common.OperationCenter; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Xml; namespace FurnaceRT.Equipments.PMs { public partial class PMModule { private string _currentAlarmConditionFileName; private int _currentAlarmConditionIndex; private Dictionary _alarmConditionDic; private List _heaterChecker; private List _mfcChecker; private List _apcChecker; private List _auxChecker; private object _alarmConditionLocker = new object(); private bool _isAlarmConditionHasRecipeCommand;//End,Reset,Hold,JumpStep,CallAlarmRecipe,CallAbortRecipe private Dictionary _hardwareInterlockAlarmConditionDic; private Dictionary _clnAlarmConditionDic; private AlarmEventItem _lastAlarmInAlarmCondition; private void SetAlarmConditionTableIndex(int index) { if (_alarmConditionDic == null) return; var ret = _alarmConditionDic.TryGetValue(index, out var currentParameter); if (!ret) return; _currentAlarmConditionIndex = index; SC.SetItemValueFromString("PM1.AlarmConditionIndex", index.ToString()); //ResetAlarmCondition(); for (int i=0;i< _heaterChecker.Count;i++) { var checker = _heaterChecker[i]; //checker.Parameter = checker.Parameter.Clone(currentParameter.HeaterParameterLst.Find(x => x.Name == checker.Heater.Display)); checker.Parameter = currentParameter.HeaterParameterLst[i]; //checker.ToleranceCheckerWarning.Reset(checker.Parameter.WarningTime); //checker.ToleranceCheckerAlarm.Reset(checker.Parameter.AlarmTime); } for (int i = 0; i < _mfcChecker.Count && i < currentParameter.MFCParameterLst.Count; i++) { var checker = _mfcChecker[i]; checker.Parameter = currentParameter.MFCParameterLst[i]; } for (int i = 0; i < _apcChecker.Count && i < currentParameter.APCParameterLst.Count; i++) { var checker = _apcChecker[i]; checker.Parameter = currentParameter.APCParameterLst[i]; } for (int i = 0; i < _auxChecker.Count && i < currentParameter.AUXParameterLst.Count; i++) { var checker = _auxChecker[i]; checker.Parameter = currentParameter.AUXParameterLst[i]; } } public void ResetAlarmCondition() { for (int i = 0; i < _heaterChecker.Count; i++) { var checker = _heaterChecker[i]; checker.ToleranceCheckerWarning.RST = true; checker.ToleranceCheckerAlarm.RST = true; checker?.DelayTimer.Restart(); } for (int i = 0; i < _mfcChecker.Count; i++) { var checker = _mfcChecker[i]; checker.ToleranceCheckerWarning.RST = true; checker.ToleranceCheckerAlarm.RST = true; checker?.DelayTimer.Restart(); } for (int i = 0; i < _apcChecker.Count; i++) { var checker = _apcChecker[i]; checker.ToleranceCheckerWarning.RST = true; checker.ToleranceCheckerAlarm.RST = true; checker?.DelayTimer.Restart(); } for (int i = 0; i < _auxChecker.Count; i++) { var checker = _auxChecker[i]; checker.ToleranceCheckerWarning.RST = true; checker.ToleranceCheckerAlarm.RST = true; checker?.DelayTimer.Restart(); } } private void InitAlarmConditionChecker() { InitHeaterChecker(); InitMFCChecker(); InitAPCChecker(); InitAUXChecker(); _hardwareInterlockAlarmConditionDic = new Dictionary() { {"AlarmSignalOPBoxPS11Out1", "Air/N2-7 Pressure Too Low"},//deviceModel的名称和AlarmCondition ParameterFormat.xml的名称 {"AlarmSignalGLBoxPG1CNT1Alarm", "N2-1 Pressure Too Low"}, {"AlarmSignalGLBoxPG1CNT2Alarm", "N2-1 Pressure Too High"}, {"AlarmSignalGLBoxPG2CNT1Alarm", "SiH2Cl2 Pressure Too Low"}, {"AlarmSignalGLBoxPG2CNT2Alarm", "SiH2Cl2 Pressure Too High"}, {"AlarmSignalGLBoxPG3CNT1Alarm", "NH3-1 Pressure To Low"}, {"AlarmSignalGLBoxPG3CNT2Alarm", "NH3-1 Pressure Too High"}, {"AlarmSignalGLBoxPG4CNT1Alarm", "NH3-2 Pressure Too Low"}, {"AlarmSignalGLBoxPG4CNT2Alarm", "NH3-2 Pressure Too High"}, {"AlarmSignalGLBoxPG5CNT1Alarm", "N2-2 Pressure Too Low"}, {"AlarmSignalGLBoxPG5CNT2Alarm", "N2-2 Pressure Too High"}, {"AlarmSignalGLBoxPG6CNT1Alarm", "20% F2/N2 Pressure Too Low"}, {"AlarmSignalGLBoxPG6CNT2Alarm", "20% F2/N2 Pressure Too High"}, {"AlarmSignalPG12OUT1", "N2-8-1 Pressure Too Low"}, {"AlarmSignalPG12OUT2", "N2-8-1 Pressure Too High"}, {"AlarmSignalPG13OUT1", "N2-8-2 Pressure Too Low"}, {"AlarmSignalPS14OUT1", "O.PRS-PS14 Pressure Too High"}, {"AlarmSignalPS14OUT2", "O.PRS-PS14 Pressure Too High"}, {"AlarmSignalN2PurgeBOXPG16CNT1", "N2-6 Pressure Too Low"}, {"AlarmSignalN2PurgeBOXPG70CNT2", "N2-70 Pressure Too Low"}, {"AlarmSignalPS17ValueLowLimitAlarm", "Air/N2-1 Pressure Too Low"}, {"AlarmSignalHeatingExhaust1stAlarmMS1", "Heater Exhaust Pressure Too Low"}, {"AlarmSignalScavengeExhaust1stAlarmMS3", "Scavenge Exhaust Pressure Too Low"}, {"AlarmSignalValveBoxExhaust1stAlarmMS4", "ValveBox Exhaust Pressure Too Low"}, {"AlarmSignalGasBoxExhaust1stAlarmMS2", "GasBox Exhaust Pressure Too Low"}, {"AlarmSignalLAExhaust1stAlarmMS7", "LA Exhaust Pressure Too Low"}, {"AlarmSignalRHC1stAlarmMS8", "RHC Exhaust Pressure Too Low"}, {"AlarmSignalLoadingAreaExhaust1stAlarmMS5", "Loading Area Exhaust Abnormal"}, {"AlarmSignalFrontBodyExhaust1stAlarmMS6", "FrontBody Exhaust Pressure Too Low"}, {"AlarmSignalMainFurnaceCellingTS306", "TEMP1 HTR Abnormal"}, {"AlarmSignalT101TempStatus", "TEMP3 TR1 Abnormal"}, {"AlarmSignalT102TempStatus", "TEMP4 TR2 Abnormal"}, {"AlarmSignalT103TempStatus", "TEMP5 TR3 Abnormal"}, {"AlarmSignalMagneticFluidLeak", "Magnetic Water Leak"}, {"AlarmSignalCoolingWaterLeak", "Cooling Water Leak"}, {"AlarmSignalFBFrontDoorSwitch", "Front Panel Abnormal"}, {"AlarmSignalFilterBox1DoorSwitch", "Filter Box Cover Abnormal"}, {"AlarmSignalLABacksideDoorSwitch", "Transfer Room Panel Abnormal"}, {"AlarmSignalHeaterRoomSWS11S12", "Heater Room Panel Abnormal"}, {"AlarmSignalGasBoxLowerDoorSW", "GasBox Lower Door Abnormal"}, {"AlarmSignalGasBoxUpperDoorSW", "GasBox Upper Door Abnormal"}, {"AlarmSignalRHCTS305", "RHC Abnormal Radiator"}, {"AlarmSignalRHCFlowAlarmFL901", "RHC Flow Abnormal"}, {"AlarmSignalCoolingWaterFlowAlarmOfFurnaceFL902", "Cooling Water Flow Of Furnace Abnormal"}, {"AlarmSignalCoolingWaterFlowAlarmOfShuttleFL903", "Cooling Water Flow Of Shuttle Abnormal"}, {"AlarmSignalCoolingWaterFlowAlarmOfBoatRotationFL904", "Cooling Water Flow Of BoatRotation Abnormal"}, {"AlarmSignalCoolingWaterFlowAlarmOfFlangeFL905", "Cooling Water Flow Of Flange Abnormal"}, {"AlarmSignalCoolingWaterFlowAlarmOfLoadingAreaFL906", "Cooling Water Flow Of Loading Area Abnormal"}, {"AlarmSignalRFAlarm", "RF Alarm"}, {"AlarmSignalAirFlowFL70", "RF N2 Flow Abnormal"}, {"AlarmSignalAirFlowFL71", "RF N2 Flow Abnormal"}, {"AlarmSignalFilterBox1Fan1Alarm", "Filter Box Fan Abnormal"}, {"AlarmSignalFilterBox1Fan2Alarm", "Filter Box Fan Abnormal"}, {"AlarmSignalHCLGasLeak1stAlarm", "SiH2CL2 Gas Leak"}, {"AlarmSignalHCLGasLeak2ndAlarm", "SiH2CL2 Gas Leak"}, {"AlarmSignalNH3GasLeak1stAlarm", "NH3 Gas Leak"}, {"AlarmSignalNH3GasLeak2ndAlarm", "NH3 Gas Leak"}, {"AlarmSignalF2GasLeak1stAlarm", "F2 Gas Leak"}, {"AlarmSignalF2GasLeak2ndAlarm", "F2 Gas Leak"}, {"AlarmSignalGasLeakFault", "Gas Leak Fault"}, //{"AlarmSignalFurnaceMainCircuitBreakerStatusMonitor", "Heater Power Down"}, {"AlarmSignalVaccumPumpWarning", "Vacuum Pump Warning"}, {"AlarmSignalVaccumPumpAlarm", "Vacuum Pump Alarm"}, {"AlarmSignalPS13HStatus", "O.PRS Too High"}, {"AlarmSignalPS13LStatus", "CK.PRS Too Low"}, {"AlarmSignalFFU1DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU2DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU3DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU4DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU5DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU6DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU7DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU8DataWriteError", "FFU Data Write Error"}, {"AlarmSignalFFU9DataWriteError", "FFU Data Write Error"}, {"AlarmSignalDG1Output1", "P.CNT Pressure NG"}, {"AlarmSignalDG1Output2", "P.CNT Pressure NG"}, {"AlarmSignalAV91_1RHCAirInOpened", "RHC.DMR Abnormal"}, {"AlarmSignalAV91_2RHCAirInOpened", "RHC.DMR Abnormal"}, {"AlarmSignalAV91_3RHCAirInOpened", "RHC.DMR Abnormal"}, {"AlarmSignalAV91_4RHCAirInOpened", "RHC.DMR Abnormal"}, {"AlarmSignalBlowerPower", "BlowerPower Overload"}, {"AlarmSignalRFSetPowerReached", "RF Output Abnormal"}, {"AlarmSignalN2FlowInFOUPAbnormal", "N2 Flow in FOUP Abnormal"}, {"AlarmSignalCapHeaterAbnormal", "Cap Heater Abnormal"}, {"AlarmSignalHeaterUOverTemp", "Tube Heater OverTemp"}, {"AlarmSignalHeaterCUOverTemp", "Tube Heater OverTemp"}, {"AlarmSignalHeaterCOverTemp", "Tube Heater OverTemp"}, {"AlarmSignalHeaterCLOverTemp", "Tube Heater OverTemp"}, {"AlarmSignalHeaterLOverTemp", "Tube Heater OverTemp"}, {"InterlockAlarm", "Valve Interlock"}, {"GasLine1AlarmSignalTempOutRange", "temp range alarm"}, {"GasLine2AlarmSignalTempOutRange", "temp range alarm"}, {"GasLine3AlarmSignalTempOutRange", "temp range alarm"}, {"GasLine4AlarmSignalTempOutRange", "temp range alarm"}, {"GasLine5AlarmSignalTempOutRange", "temp range alarm"}, {"GasLine6AlarmSignalTempOutRange", "temp range alarm"}, {"GasLine7AlarmSignalTempOutRange", "temp range alarm"}, {"GasLine1AlarmSignalCLN", "CLN alarm"}, {"GasLine2AlarmSignalCLN", "CLN alarm"}, {"GasLine3AlarmSignalCLN", "CLN alarm"}, {"GasLine4AlarmSignalCLN", "CLN alarm"}, {"GasLine5AlarmSignalCLN", "CLN alarm"}, {"GasLine6AlarmSignalCLN", "CLN alarm"}, {"GasLine7AlarmSignalCLN", "CLN alarm"}, }; _clnAlarmConditionDic = new Dictionary() { {"AlarmSignalOPBoxPS11Out1", "temp range warning"},//deviceModel的名称和AlarmCondition ParameterFormat.xml的名称 {"AlarmSignalTempOutRange", "temp range alarm"}, {"AlarmSignalGLBoxPG1CNT2Alarm", "CLN warning"}, {"AlarmSignalCLN", "CLN alarm"}, }; if (!string.IsNullOrEmpty(SC.GetStringValue("PM1.AlarmCondition"))) { InitAlarmCondition(SC.GetStringValue("PM1.AlarmCondition")); int.TryParse(SC.GetStringValue("PM1.AlarmConditionIndex"), out int index); SetAlarmConditionTableIndex(index); } } private void InitAUXChecker() { _auxChecker = new List(); for (int index = 0; index < 512; index++) { if (!SC.ContainsItem($"PM1.RecipeEditParameter.AUX.{index}.AI")) continue; var checker = new AlarmConditionChecker() { AUXIOName = SC.GetStringValue($"PM1.RecipeEditParameter.AUX.{index}.AI"), AUXIndex = index, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }; _auxChecker.Add(checker); } } private void InitAPCChecker() { _apcChecker = new List() { new AlarmConditionChecker() { APC = APC, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { APC = APC, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { APC = APC, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, }; } private void InitMFCChecker() { _mfcChecker = new List() { new AlarmConditionChecker() { MFC = MFC1, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC2, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC3, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC4, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC5, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC6, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC7, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC8, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC9, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC10, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC11, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { MFC = MFC12, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, }; if(MFC13 != null) { _mfcChecker.Add(new AlarmConditionChecker() { MFC = MFC13, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }); } if (MFC14 != null) { _mfcChecker.Add(new AlarmConditionChecker() { MFC = MFC14, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }); } if (MFC15 != null) { _mfcChecker.Add(new AlarmConditionChecker() { MFC = MFC15, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }); } if (MFC16 != null) { _mfcChecker.Add(new AlarmConditionChecker() { MFC = MFC16, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }); } } private void InitHeaterChecker() { _heaterChecker = new List() { new AlarmConditionChecker() { Heater = HeaterU, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { Heater = HeaterCU, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { Heater = HeaterC, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { Heater = HeaterCL, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, new AlarmConditionChecker() { Heater = HeaterL, ToleranceCheckerWarning = new ToleranceChecker(), ToleranceCheckerAlarm = new ToleranceChecker(), Parameter = new AlarmConditionAIParameter(), DelayTimer = new Stopwatch(), }, }; } public void InitAlarmCondition(string fileName) { if (string.IsNullOrEmpty(fileName)) { //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature correct file is empty"); return; } _currentAlarmConditionFileName = fileName; //_currentAlarmConditionIndex = index; var content = ParameterFileManager.Instance.LoadParameter("Parameter\\AlarmCondition", fileName, false); if (string.IsNullOrEmpty(content)) { //EV.PostWarningLog(ModuleName.PM1.ToString(), $"{fileNameAndPath} heater temperature correct file is empty"); return; } var doc = new XmlDocument(); doc.LoadXml(content); XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step"); if (nodeSteps == null) nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step"); if (nodeSteps == null) { EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid alarm condition file {fileName}"); return; } SC.SetItemValueFromString("PM1.AlarmCondition", fileName); _alarmConditionDic = new Dictionary(); for (int i = 0; i < nodeSteps.Count; i++) { var step = nodeSteps[i]; XmlElement stepNode = step as XmlElement; int tableIndex = i + 1; AlarmConditionTableParameter table = new AlarmConditionTableParameter(); List valveInterlockParameterLst = null; List clnParameterLst = null; foreach (XmlAttribute att in stepNode.Attributes) { switch (att.Name) { case "StepNo": int.TryParse(att.Value, out int no); table.No = no; break; case "Name": table.Name = att.Value; break; case "TempHeater": table.HeaterParameterLst = InitAlarmConditionItem(att.Value); break; case "TempBoat": break; case "FlowDeviation": table.MFCParameterLst = InitAlarmConditionItem(att.Value); break; case "Press": table.APCParameterLst = InitAlarmConditionItem(att.Value); break; case "AUX": table.AUXParameterLst = InitAlarmConditionItem(att.Value); break; case "HWILK": table.InterlockParameterLst = InitAlarmConditionDIItem(att.Value); break; case "ValveILK": valveInterlockParameterLst = InitAlarmConditionDIItem(att.Value); break; case "TempController": break; case "APCController": break; case "TransferError": break; case "SerialLineDown": break; case "LanLineDown": break; case "DeviceNetLineDown": break; case "Sensor": break; case "CLNAlarmList": clnParameterLst = InitAlarmConditionDIItem(att.Value); break; } } if (table.InterlockParameterLst != null && valveInterlockParameterLst != null) table.InterlockParameterLst.AddRange(valveInterlockParameterLst); if (table.InterlockParameterLst != null && clnParameterLst != null) table.InterlockParameterLst.AddRange(clnParameterLst); if (!_alarmConditionDic.ContainsKey(table.No)) _alarmConditionDic.Add(table.No, table); _alarmConditionDic[table.No] = table; } } public void MonitorAlarmCondition() { if (_alarmConditionDic == null) return; _isAlarmConditionHasRecipeCommand = false; MonitorHeaterAlarmCondition(); MonitorMFCAlarmCondition(); MonitorAUXAlarmCondition(); MonitorAPCAlarmCondition(); MonitorInterlockAlarmCondition(); } private void MonitorInterlockAlarmCondition() { if (_triggeredAlarmList == null || _triggeredAlarmList.Count == 0) return; if (_hardwareInterlockAlarmConditionDic == null) return; if (_alarmConditionDic == null || !_alarmConditionDic.ContainsKey(_currentAlarmConditionIndex) || _alarmConditionDic[_currentAlarmConditionIndex].InterlockParameterLst == null) return; var newAlarm = _triggeredAlarmList[_triggeredAlarmList.Count - 1]; var alarmConditionItemName = ""; for (int i= _triggeredAlarmList.Count - 1; i>=0;i--) { var alarm = _triggeredAlarmList[i]; var interval = DateTime.Now - newAlarm.OccuringTime; if (interval.TotalMilliseconds > 1000)//老的alarm continue; var paras = newAlarm.EventEnum.Split('.'); if (paras.Length < 2) continue; var ret = _hardwareInterlockAlarmConditionDic.TryGetValue(paras[1], out string name); if (ret) { newAlarm = alarm; alarmConditionItemName = name; var alarmConditionItem = _alarmConditionDic[_currentAlarmConditionIndex].InterlockParameterLst.FirstOrDefault(x => x.Name == alarmConditionItemName); if (alarmConditionItem == null) continue; if (alarmConditionItem.IsEnable) ProcessAlarmConditionErrorCommand(alarmConditionItem.Command); break; } } } private void MonitorAPCAlarmCondition() { for (int i = 0; i < _apcChecker.Count; i++) { var checker = _apcChecker[i]; if (checker.Parameter.Unit == null) continue; var warningLow = checker.Parameter.WarningLow; var warningHigh = checker.Parameter.WarningHigh; var alarmLow = checker.Parameter.AlarmLow; var alarmHigh = checker.Parameter.AlarmHigh; var unit = checker.Parameter.Unit; if (checker.Parameter.Unit.ToLower().Contains("%")) { unit = "%"; //angle if (checker.Parameter.Unit.ToLower() == "%d") { //do nothing } else { warningLow = (float)checker.APC.DeviceData.PositionSetPoint * warningLow; warningHigh = (float)checker.APC.DeviceData.PositionSetPoint * warningHigh; alarmLow = (float)checker.APC.DeviceData.PositionSetPoint * alarmLow; alarmHigh = (float)checker.APC.DeviceData.PositionSetPoint * alarmHigh; } if (checker.Parameter.IsWarningEnable && checker.Parameter.WarningTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.WarningDelayDetectTimeS * 1000) checker.ToleranceCheckerWarning.Monitor(checker.APC.DeviceData.PositionFeedback, checker.APC.DeviceData.PositionSetPoint - warningLow, checker.APC.DeviceData.PositionSetPoint + warningHigh, checker.Parameter.WarningTime); if (checker.Parameter.IsAlarmEnable && checker.Parameter.AlarmTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.AlarmDelayDetectTimeS * 1000) checker.ToleranceCheckerAlarm.Monitor(checker.APC.DeviceData.PositionFeedback, checker.APC.DeviceData.PositionSetPoint - alarmLow, checker.APC.DeviceData.PositionSetPoint + alarmHigh, checker.Parameter.AlarmTime); if (checker.ToleranceCheckerAlarm.Trig || checker.ToleranceCheckerWarning.Trig) { var range = ""; var time = ""; var command = checker.Parameter.AlarmCommand; if (checker.ToleranceCheckerAlarm.Trig) { range = $"({checker.APC.DeviceData.PositionSetPoint - alarmLow},{checker.APC.DeviceData.PositionSetPoint + alarmHigh})"; time = $"{checker.Parameter.AlarmTime:F1}"; checker.APC.APCAngleToleranceAlarm.Set($"APC angle out of range {range} {unit} in {time} seconds"); command = checker.Parameter.AlarmCommand; } else if (checker.ToleranceCheckerWarning.Trig) { range = $"({checker.APC.DeviceData.PositionSetPoint - warningLow},{checker.APC.DeviceData.PositionSetPoint + warningHigh})"; time = $"{checker.Parameter.WarningTime:F1}"; checker.APC.APCAngleToleranceWarning.Set($"APC angle out of range {range} {unit} in {time} seconds"); command = checker.Parameter.WarningCommand; } ProcessAlarmConditionErrorCommand(command); } } else { warningLow = (float)checker.APC.DeviceData.PressureSetPoint * warningLow; warningHigh = (float)checker.APC.DeviceData.PressureSetPoint * warningHigh; alarmLow = (float)checker.APC.DeviceData.PressureSetPoint * alarmLow; alarmHigh = (float)checker.APC.DeviceData.PressureSetPoint * alarmHigh; var alarmToleranceAlarm = checker.APC.APCPressure2ToleranceAlarm; var alarmToleranceWarning = checker.APC.APCPressure2ToleranceWarning; var pressureFeedback = checker.APC.DeviceData.Pressure2Feedback; if (i==0) { alarmToleranceAlarm = checker.APC.APCPressure1ToleranceAlarm; alarmToleranceWarning = checker.APC.APCPressure1ToleranceWarning; pressureFeedback = checker.APC.DeviceData.Pressure1Feedback; } if (checker.Parameter.IsWarningEnable && checker.Parameter.WarningTime > 0) checker.ToleranceCheckerWarning.Monitor(pressureFeedback, checker.APC.DeviceData.PressureSetPoint - warningLow, checker.APC.DeviceData.PressureSetPoint + warningHigh, checker.Parameter.WarningTime); if (checker.Parameter.IsAlarmEnable && checker.Parameter.AlarmTime > 0) checker.ToleranceCheckerAlarm.Monitor(pressureFeedback, checker.APC.DeviceData.PressureSetPoint - alarmLow, checker.APC.DeviceData.PressureSetPoint + alarmHigh, checker.Parameter.AlarmTime); if (checker.ToleranceCheckerAlarm.Trig || checker.ToleranceCheckerWarning.Trig) { var range = ""; var time = ""; var command = checker.Parameter.AlarmCommand; if (checker.ToleranceCheckerAlarm.Trig) { range = $"({checker.APC.DeviceData.PressureSetPoint - alarmLow},{checker.APC.DeviceData.PressureSetPoint + alarmHigh})"; time = $"{checker.Parameter.AlarmTime:F1}"; alarmToleranceAlarm.Set($"APC Press{i+1} out of range {range} {unit} in {time} seconds"); command = checker.Parameter.AlarmCommand; } else if (checker.ToleranceCheckerWarning.Trig) { range = $"({checker.APC.DeviceData.PressureSetPoint - warningLow},{checker.APC.DeviceData.PressureSetPoint + warningHigh})"; time = $"{checker.Parameter.WarningTime:F1}"; alarmToleranceWarning.Set($"APC Press{i+1} out of range {range} {unit} in {time} seconds"); command = checker.Parameter.WarningCommand; } ProcessAlarmConditionErrorCommand(command); } } } } private void MonitorAUXAlarmCondition() { for (int i = 0; i < _auxChecker.Count; i++) { var checker = _auxChecker[i]; if (checker.Parameter.Unit == null) continue; var warningLow = checker.Parameter.WarningLow; var warningHigh = checker.Parameter.WarningHigh; var alarmLow = checker.Parameter.AlarmLow; var alarmHigh = checker.Parameter.AlarmHigh; var unit = ""; var setpoint = 0.0f; var feedback = 0.0f; var display = ""; if (_auxDic != null && _auxDic.ContainsKey(_currentAuxTable)) { foreach (var item in _auxDic[_currentAuxTable]) { if (item == null || checker.AUXIOName != item.IOName) continue; setpoint = (float)item.SetPointConfig.DoubleValue; unit = item.Unit; display = item.DisplayNameConfig.StringValue; feedback = IO.AI[$"{Module}.{item.IOName}"] != null ? IO.AI[$"{Module}.{item.IOName}"].FloatValue : 0; break; } } if (checker.Parameter.Unit.ToLower() == "%sv") { warningLow = (float)setpoint * warningLow / 100.0f; warningHigh = (float)setpoint * warningHigh / 100.0f; alarmLow = (float)setpoint * alarmLow / 100.0f; alarmHigh = (float)setpoint * alarmHigh / 100.0f; } else if (checker.Parameter.Unit.ToLower() == "%fs") { //后续改为scale warningLow = (float)setpoint * warningLow / 100.0f; warningHigh = (float)setpoint * warningHigh / 100.0f; alarmLow = (float)setpoint * alarmLow / 100.0f; alarmHigh = (float)setpoint * alarmHigh / 100.0f; } if (checker.Parameter.IsWarningEnable && checker.Parameter.WarningTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.WarningDelayDetectTimeS * 1000) checker.ToleranceCheckerWarning.Monitor(feedback, setpoint - warningLow, setpoint + warningHigh, checker.Parameter.WarningTime); if (checker.Parameter.IsAlarmEnable && checker.Parameter.AlarmTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.AlarmDelayDetectTimeS * 1000) checker.ToleranceCheckerAlarm.Monitor(feedback, setpoint - alarmLow, setpoint + alarmHigh, checker.Parameter.AlarmTime); if (checker.ToleranceCheckerAlarm.Trig || checker.ToleranceCheckerWarning.Trig) { var range = ""; var time = ""; var ret = AUXAlarmDic.TryGetValue(checker.AUXIndex, out var AUXAlarm); if(ret) { var command = checker.Parameter.AlarmCommand; if (checker.ToleranceCheckerAlarm.Trig) { range = $"({(setpoint - alarmLow).ToString("f3")},{(setpoint + alarmHigh).ToString("f3")})"; time = $"{checker.Parameter.AlarmTime:F1}"; AUXAlarm.Item2.Set($"AUX {display} value out of range {range} {unit} in {time} seconds"); command = checker.Parameter.AlarmCommand; } else if (checker.ToleranceCheckerWarning.Trig) { range = $"({(setpoint - warningLow).ToString("f3")},{(setpoint + warningHigh).ToString("f3")})"; time = $"{checker.Parameter.WarningTime:F1}"; AUXAlarm.Item1.Set($"AUX {display} value out of range {range} {unit} in {time} seconds"); command = checker.Parameter.WarningCommand; } ProcessAlarmConditionErrorCommand(command); } } } } private void MonitorMFCAlarmCondition() { for (int i = 0; i < _mfcChecker.Count; i++) { var checker = _mfcChecker[i]; if (checker.Parameter.Unit == null) continue; var warningLow = checker.Parameter.WarningLow; var warningHigh = checker.Parameter.WarningHigh; var alarmLow = checker.Parameter.AlarmLow; var alarmHigh = checker.Parameter.AlarmHigh; var unit = checker.MFC.Unit; if (checker.Parameter.Unit.ToLower() == "%sv") { warningLow = (float)checker.MFC.SetPoint * warningLow / 100.0f; warningHigh = (float)checker.MFC.SetPoint * warningHigh / 100.0f; alarmLow = (float)checker.MFC.SetPoint * alarmLow / 100.0f; alarmHigh = (float)checker.MFC.SetPoint * alarmHigh / 100.0f; } else if (checker.Parameter.Unit.ToLower() == "%fs") { warningLow = (float)checker.MFC.Scale * warningLow / 100.0f; warningHigh = (float)checker.MFC.Scale * warningHigh / 100.0f; alarmLow = (float)checker.MFC.Scale * alarmLow / 100.0f; alarmHigh = (float)checker.MFC.Scale * alarmHigh / 100.0f; } if (checker.Parameter.IsWarningEnable && checker.Parameter.WarningTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.WarningDelayDetectTimeS * 1000) checker.ToleranceCheckerWarning.Monitor(checker.MFC.FeedBack, checker.MFC.SetPoint - warningLow, checker.MFC.SetPoint + warningHigh, checker.Parameter.WarningTime); if (checker.Parameter.IsAlarmEnable && checker.Parameter.AlarmTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.AlarmDelayDetectTimeS * 1000) checker.ToleranceCheckerAlarm.Monitor(checker.MFC.FeedBack, checker.MFC.SetPoint - alarmLow, checker.MFC.SetPoint + alarmHigh, checker.Parameter.AlarmTime); if (checker.ToleranceCheckerAlarm.Trig || checker.ToleranceCheckerWarning.Trig) { var range = ""; var time = ""; var command = checker.Parameter.AlarmCommand; if (checker.ToleranceCheckerAlarm.Trig) { range = $"({(checker.MFC.SetPoint - alarmLow).ToString("f3")},{(checker.MFC.SetPoint + alarmHigh).ToString("f3")})"; time = $"{checker.Parameter.AlarmTime:F1}"; checker.MFC.AlarmToleranceAlarm.Set($"{Display} flow out of range {range} {unit} in {time} seconds"); command = checker.Parameter.AlarmCommand; } else if (checker.ToleranceCheckerWarning.Trig) { range = $"({(checker.MFC.SetPoint - warningLow).ToString("f3")},{(checker.MFC.SetPoint + warningHigh).ToString("f3")})"; time = $"{checker.Parameter.WarningTime:F1}"; checker.MFC.AlarmToleranceWarning.Set($"{Display} flow out of range {range} {unit} in {time} seconds"); command = checker.Parameter.WarningCommand; } ProcessAlarmConditionErrorCommand(command); } } } private void MonitorHeaterAlarmCondition() { for (int i = 0; i < _heaterChecker.Count; i++) { var checker = _heaterChecker[i]; if (checker.Parameter.Unit == null) continue; if (checker.Parameter.IsWarningEnable && checker.Parameter.WarningTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.WarningDelayDetectTimeS * 1000) checker.ToleranceCheckerWarning.Monitor(checker.Heater.TempFeedback, checker.Heater.TempSetPoint - checker.Parameter.WarningLow, checker.Heater.TempSetPoint + checker.Parameter.WarningHigh, checker.Parameter.WarningTime); if (checker.Parameter.IsAlarmEnable && checker.Parameter.AlarmTime > 0 && checker.DelayTimer.IsRunning && checker.DelayTimer.ElapsedMilliseconds >= checker.Parameter.AlarmDelayDetectTimeS * 1000) checker.ToleranceCheckerAlarm.Monitor(checker.Heater.TempFeedback, checker.Heater.TempSetPoint - checker.Parameter.AlarmLow, checker.Heater.TempSetPoint + checker.Parameter.AlarmHigh, checker.Parameter.AlarmTime); if (checker.ToleranceCheckerAlarm.Trig || checker.ToleranceCheckerWarning.Trig) { var range = ""; var time = ""; var command = checker.Parameter.AlarmCommand; if (checker.ToleranceCheckerAlarm.Trig) { range = $"({checker.Heater.TempSetPoint - checker.Parameter.AlarmLow},{checker.Heater.TempSetPoint + checker.Parameter.AlarmHigh})"; time = $"{checker.Parameter.AlarmTime:F1}"; checker.Heater.AlarmToleranceAlarm.Set($"{Display} temperature out of range {range} °C in {time} seconds"); command = checker.Parameter.AlarmCommand; } else if (checker.ToleranceCheckerWarning.Trig) { range = $"({checker.Heater.TempSetPoint - checker.Parameter.WarningLow},{checker.Heater.TempSetPoint + checker.Parameter.WarningHigh})"; time = $"{checker.Parameter.WarningTime:F1}"; checker.Heater.AlarmToleranceWarning.Set($"{Display} temperature out of range {range} °C in {time} seconds"); command = checker.Parameter.WarningCommand; } ProcessAlarmConditionErrorCommand(command); } } } private void ProcessAlarmConditionErrorCommand(string command) { var recipe = ""; var recipeType = ""; var recipeTable = ""; switch (command) { case "Reset": if (_isAlarmConditionHasRecipeCommand) break; _isAlarmConditionHasRecipeCommand = true; recipe = SC.GetStringValue("System.Recipe.Reset Recipe"); recipeType = "Reset"; CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType); LOG.Write($"Alarm condition: command={command} recipe={recipe}"); break; case "End": if (_isAlarmConditionHasRecipeCommand) break; _isAlarmConditionHasRecipeCommand = true; if(IsProcessing) { //因为要跳到执行最后一步,所以stepNumber需要减一 _processRoutine.JumpCurrentRecipeStep(RecipeRunningInfo.RecipeStepList.Count - 1, RecipeRunningInfo.RecipeStepList[RecipeRunningInfo.RecipeStepList.Count - 1].StepName); } else { if (!RecipeParser.Parse(SC.GetStringValue("PM1.ProcessRecipe"), Module, out var recipeHead, out var recipeSteps, out var reason, "Process")) { PreprocessStartFailedWarning.Set($"Load process recipe {SC.GetStringValue("PM1.ProcessRecipe")} failed, {reason}"); return; } RecipeRunningInfo.MainRecipeName = SC.GetStringValue("PM1.ProcessRecipe"); RecipeRunningInfo.Head = recipeHead; RecipeRunningInfo.RecipeStepList = recipeSteps; CheckToPostMessage((int)MSG.AlarmConditionJumpStep, RecipeRunningInfo.RecipeStepList.Count - 1); } LOG.Write($"Alarm condition: command={command} step name={RecipeRunningInfo.RecipeStepList[RecipeRunningInfo.RecipeStepList.Count - 1].StepName}"); break; case "Hold": if (_isAlarmConditionHasRecipeCommand) break; _isAlarmConditionHasRecipeCommand = true; _processRoutine.PauseRecipe(); LOG.Write($"Alarm condition: command={command}"); break; case "Monitor": LOG.Write($"Alarm condition: command={command}"); break; case "Buzzer": Singleton.Instance.IsAlarmConditionBuzzerOn = true; LOG.Write($"Alarm condition: command={command}"); break; default: if (_isAlarmConditionHasRecipeCommand) break; _isAlarmConditionHasRecipeCommand = true; if (command.StartsWith("JUMP")) { //Jump step //Jump 1: var stepName = command.Replace("JUMP ", ""); if (IsProcessing) { var jumpStepNumber = RecipeRunningInfo.RecipeStepList.FindIndex(x => x.StepName == stepName); if (jumpStepNumber > 0) { _processRoutine.JumpCurrentRecipeStep(jumpStepNumber, stepName); } } else { if (!RecipeParser.Parse(SC.GetStringValue("PM1.ProcessRecipe"), Module, out var recipeHead, out var recipeSteps, out var reason, "Process")) { PreprocessStartFailedWarning.Set($"Load process recipe {SC.GetStringValue("PM1.ProcessRecipe")} failed, {reason}"); return; } RecipeRunningInfo.MainRecipeName = SC.GetStringValue("PM1.ProcessRecipe"); RecipeRunningInfo.Head = recipeHead; RecipeRunningInfo.RecipeStepList = recipeSteps; var jumpStepNumber = RecipeRunningInfo.RecipeStepList.FindIndex(x => x.StepName == stepName); if (jumpStepNumber > 0) { CheckToPostMessage((int)MSG.AlarmConditionJumpStep, jumpStepNumber); } } LOG.Write($"Alarm condition: command={command} step name={stepName}"); } else if (command.StartsWith("CALL")) { //call Alarm recipe //Call 1: var paras = command.Split(':'); if (paras.Length > 0) { recipe = RecipeRunningInfo.Head.AlarmRecipe; recipeType = "Alarm"; recipeTable = paras[0].Replace("CALL", "").Replace(" ", "").Replace(":", "").Replace(":", ""); CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType, recipeTable); LOG.Write($"Alarm condition: command={command} recipe={recipe}"); } } else if (command.StartsWith("ABORT")) { //call Abort recipe //Abort 1: var paras = command.Split(':'); if (paras.Length > 0) { recipe = RecipeRunningInfo.Head.AbortRecipe; recipeType = "Abort"; recipeTable = paras[0].Replace("ABORT", "").Replace(" ", "").Replace(":", "").Replace(":", ""); CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType, recipeTable); LOG.Write($"Alarm condition: command={command} recipe={recipe}"); } } break; } } private List InitAlarmConditionItem(string content) { List items = new List(); if (string.IsNullOrEmpty(content)) return items; var zoneParas = content.Split('|'); foreach (var zonePara in zoneParas) { //U;Alert,True,0,0,℃,5,Monitor;Alarm,True,0,0,℃,6,Buzzer //1;C1-N2-1;Alert,True,0,0,%fs,5,Buzzer;Alarm,True,0,0,%fs,6,Buzzer //1;MS1;Alert,True,0,0,%fs,5,Monitor;Alarm,True,0,0,%fs,6,Monitor AlarmConditionAIParameter item = new AlarmConditionAIParameter(); var array = zonePara.Split(';'); if (array.Length > 2) { item.Name = array[0]; var warningParas = array[array.Length - 2].Split(','); var alarmParas = array[array.Length - 1].Split(','); if (warningParas.Length > 6) { bool.TryParse(warningParas[1], out bool isEnable); float.TryParse(warningParas[2], out float high); float.TryParse(warningParas[3], out float low); item.Unit = warningParas[4]; float.TryParse(warningParas[5], out float time); item.WarningCommand = warningParas[6]; item.IsWarningEnable = isEnable; item.WarningHigh = high; item.WarningLow = low; item.WarningTime = time; } if (warningParas.Length > 7) { float.TryParse(warningParas[7], out float time); item.WarningDelayDetectTimeS = time; } if (alarmParas.Length > 6) { bool.TryParse(alarmParas[1], out bool isEnable); float.TryParse(alarmParas[2], out float high); float.TryParse(alarmParas[3], out float low); item.Unit = alarmParas[4]; float.TryParse(alarmParas[5], out float time); item.AlarmCommand = alarmParas[6]; item.IsAlarmEnable = isEnable; item.AlarmHigh = high; item.AlarmLow = low; item.AlarmTime = time; } if (alarmParas.Length > 7) { float.TryParse(alarmParas[7], out float time); item.AlarmDelayDetectTimeS = time; } } items.Add(item); } return items; } private List InitAlarmConditionDIItem(string content) { List items = new List(); if (string.IsNullOrEmpty(content)) return items; var zoneParas = content.Split('|'); foreach (var zonePara in zoneParas) { //1,Air/N2-7 Pressure Too Low,Alert,False,Buzzer|2,N2-1 Pressure Too Low,Alert,False,End AlarmConditionDIParameter item = new AlarmConditionDIParameter(); var array = zonePara.Split(','); if (array.Length > 4) { item.Name = array[1]; item.IsAlarm = array[2].ToLower() == "alarm"; bool.TryParse(array[3], out bool isEnable); item.IsEnable = isEnable; item.Command = array[4]; } items.Add(item); } return items; } class AlarmConditionChecker { public FurnaceRT.Devices.IoHeater Heater { get; set; } public FurnaceRT.Devices.IoAPC APC { get; set; } public FurnaceRT.Equipments.PMs.Devices.IoMFC MFC { get; set; } public string AUXIOName { get; set; } public int AUXIndex { get; set; } public ToleranceChecker ToleranceCheckerWarning { get; set; } public ToleranceChecker ToleranceCheckerAlarm { get; set; } public AlarmConditionAIParameter Parameter { get; set; } public Stopwatch DelayTimer { get; set; }//N秒过后才检测 } class AlarmConditionTableParameter { public int No { get; set; } public string Name { get; set; } public List HeaterParameterLst { get; set; } public List MFCParameterLst { get; set; } public List APCParameterLst { get; set; } public List AUXParameterLst { get; set; } public List InterlockParameterLst { get; set; } } class AlarmConditionAIParameter { //类似AI的 public string Name { get; set; } public string Unit { get; set; } public string DataPoll { get; set; } public float WarningHigh { get; set; } public float WarningLow { get; set; } public float WarningTime { get; set; } public string WarningCommand { get; set; } public bool IsWarningEnable { get; set; } public float AlarmHigh { get; set; } public float AlarmLow { get; set; } public float AlarmTime { get; set; } public string AlarmCommand { get; set; } public bool IsAlarmEnable { get; set; } public float WarningDelayDetectTimeS { get; set; } = 0;//N秒过后才检测 public float AlarmDelayDetectTimeS { get; set; } = 0;//N秒过后才检测 public AlarmConditionAIParameter Clone(AlarmConditionAIParameter source) { AlarmConditionAIParameter clone = new AlarmConditionAIParameter(); clone.Name = source.Name; clone.Unit = source.Unit; clone.DataPoll = source.DataPoll; clone.WarningHigh = source.WarningHigh; clone.WarningLow = source.WarningLow; clone.WarningTime = source.WarningTime; clone.WarningCommand = source.WarningCommand; clone.IsWarningEnable = source.IsWarningEnable; clone.AlarmHigh = source.AlarmHigh; clone.AlarmLow = source.AlarmLow; clone.AlarmTime = source.AlarmTime; clone.AlarmCommand = source.AlarmCommand; clone.IsAlarmEnable = source.IsAlarmEnable; return clone; } } class AlarmConditionDIParameter { //类似DI的 public string Name { get; set; } public string DataPoll { get; set; } public bool IsAlarm { get; set; } public bool IsEnable { get; set; } public string Command { get; set; } } class AlarmConditionBoatParameter { //Boat load,unload温度判断 public string Name { get; set; } public string DataPoll { get; set; } public bool IsAlarm { get; set; } public bool IsEnable { get; set; } public float AlarmHighLimit { get; set; } } } }