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.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.OperationCenter; using System; using System.Collections; using System.Diagnostics; using System.Linq; namespace FurnaceRT.Equipments.PMs { public partial class PMModule { private SCConfigItem _configAutoControlCoolingValve; private SCConfigItem _configVacuumSensorPressure; private SCConfigItem _configAutoControlChiller; private SCConfigItem _chillerTurnOffIfTempBelow; private SCConfigItem _chillerTurnOnIfTempAbove; private PeriodicJob _threadMonitor; private bool _vac1; private bool _vac2; private bool _vac3; private Stopwatch _vac1Timer = new Stopwatch(); private Stopwatch _vac2Timer = new Stopwatch(); private Stopwatch _vac3Timer = new Stopwatch(); private int _vac1PumpTimeS = 120; private int _vac2PumpTimeS = 120; private int _vac3PumpTimeS = 120; private int _foolProofTime = 5; private DeviceTimer _plcFoolProofTime = null; private RD_TRIG _trigPLCConnected = null; private void InitInterlock() { OP.AddCheck($"{Module}.{Name}.Disconnect", new CheckPlcConnect(this)); //OP.AddCheck($"{ChamberDoor.Module}.{ChamberDoor.Name}.Open", new CheckOpenDoor(this)); if (SC.ContainsItem("System.PLCConnectSensorFoolTime")) _foolProofTime = SC.GetValue("System.PLCConnectSensorFoolTime"); _configAutoControlCoolingValve = SC.GetConfigItem($"PM.{Module}.AutoControlCoolingValve"); _configVacuumSensorPressure = SC.GetConfigItem($"PM.{Module}.VacuumSensorPressure"); _configAutoControlChiller = SC.GetConfigItem($"PM.{Module}.Chiller.EnableAutoAdjust"); _chillerTurnOffIfTempBelow = SC.GetConfigItem($"PM.{Module}.Chiller.TurnOffIfTempBelow"); _chillerTurnOnIfTempAbove = SC.GetConfigItem($"PM.{Module}.Chiller.TurnOnIfTempAbove"); if (SensorPLCHeartBeatPC != null) { _trigPLCConnected = new RD_TRIG(); _plcFoolProofTime = new DeviceTimer(); _plcFoolProofTime.Start((_foolProofTime + 2) * 1000);//首次 } _threadMonitor = new PeriodicJob(100, OnTimer, "interlock thread", true); } private void InitUserDefineInterlock() { //DATA.Subscribe($"{Module}.Heater1", () => 100);//自定义的Interlock limit InterlockManager.Instance.UserDefineInterlockHandler += UserDefineInterlockHandler; InterlockManager.Instance.UserDefineInterlocks += UserDefineInterlocks; //DATA.Subscribe("UserDefineInterlock", () => InterlockManager.Instance.UserDefineFlagCurrentValues); //DATA.Subscribe("UserDefineCurrent", () => InterlockManager.Instance.UserDefineCurrentValues); } //自定义的interlock action private bool UserDefineInterlocks(string name) { switch (name) { case "PM1.Heater1": return true; } return false; } //设置自定义的interlock action private bool UserDefineInterlockHandler(string name, object value) { switch(name) { case "PM1.Heater1": //设置Heater的值 return true; } return false; } private class CheckOpenDoor : IInterlockChecker { private PMModule _pm; public CheckOpenDoor(PMModule pm) { _pm = pm; } public bool CanDo(out string reason, object[] args) { if (_pm.ChamberPressure < SC.GetValue("PM.AtmPressureBase")) { reason = $"{_pm.Module} chamber pressure {_pm.ChamberPressure:F3} Torr less than {SC.GetValue("PM.AtmPressureBase")} [PM.AtmPressureBase], can not open door"; return false; } reason = string.Empty; return true; } } private class CheckPlcConnect : IInterlockChecker { private PMModule _pm; public CheckPlcConnect(PMModule pm) { _pm = pm; } public bool CanDo(out string reason, object[] args) { if (_pm.IsBusy) { reason = $"{_pm.Module} is in {_pm.StringFsmStatus} status, can not disconnect, should be idle"; return false; } reason = string.Empty; return true; } } public bool OnTimer() { try { MonitorN2Purge(); MonitorAux(); MonitorFfu(); lock (_alarmConditionLocker) { MonitorAlarmCondition(); } if (!IsProcessing && TrigVGUnitConversion != null && SC.GetStringValue($"{Module}.APC.PressureUnit").ToLower() == "pa") { TrigVGUnitConversion.SetTrigger(SC.GetStringValue($"{Module}.APC.PressureUnit").ToLower() == "pa", out _); } //MonitorVAC1(); //MonitorVAC2(); //MonitorVAC3(); MonitorPLCConnected(); //foreach (var item in _inCommandLst) //{ // if (item == null) // continue; // if (!_inCommandTirgs.ContainsKey(item.Name)) // { // _inCommandTirgs.Add(item.Name, new RD_TRIG()); // } // _inCommandTirgs[item.Name].CLK = item.Value; //} //if (_inCommandTirgs[SensorHECPowerONSW.Name].R) //{ // _trigTHPowerEN.SetTrigger(true, out _); // _trigHECPowerONLamp.SetTrigger(true, out _); //} //if (_inCommandTirgs[SensorHECPowerONSW.Name].T) //{ //} //if (_inCommandTirgs[SensorTHBreakOK.Name].R) //{ //} //if (_inCommandTirgs[SensorTHBreakOK.Name].T) //{ // _trigTHPowerEN.SetTrigger(false, out _); // _trigHECPowerONLamp.SetTrigger(false, out _); //} ProcessAlarmSignal(); //if (IV2Valve.Status != SensorVG2LOW.Value) // IV2Valve.TurnValve(SensorVG2LOW.Value, out _); //if (IV2Valve.Status != SensorVG2LOW.Value) // VV2Valve.TurnValve(SensorTubeOverPressure.Value, out _); if (IsInit || !IsInstalled) return true; //cooling 阀门 if (_configAutoControlCoolingValve == null || _configAutoControlCoolingValve.BoolValue) { //if (ElectricalCoolingValve.Status != MainChiller.IsRunning) // ElectricalCoolingValve.TurnValve(MainChiller.IsRunning, out _); //if (MicrowaveCoolingValve.Status != MainChiller.IsRunning) // MicrowaveCoolingValve.TurnValve(MainChiller.IsRunning, out _); //if (ChamberLidCoolingValve.Status != MainChiller.IsRunning) // ChamberLidCoolingValve.TurnValve(MainChiller.IsRunning, out _); } //auto control chiller if (_configAutoControlChiller != null && _configAutoControlChiller.BoolValue && _chillerTurnOffIfTempBelow != null && _chillerTurnOnIfTempAbove != null) { //if (!MainChiller.HasAlarm) //{ // if (MainChiller.IsRunning && (ChamberHeater1.Feedback < _chillerTurnOffIfTempBelow.DoubleValue)) // { // if (!MainChiller.SetMainPowerOnOff(false, out string reason)) // { // LOG.Write(reason); // } // }else if (!MainChiller.IsRunning && (ChamberHeater1.Feedback > _chillerTurnOnIfTempAbove.DoubleValue)) // { // if (!MainChiller.SetMainPowerOnOff(true, out string reason)) // { // LOG.Write(reason); // } // } //} } //压力保护计 double pressure = 3.0; if (_configVacuumSensorPressure != null) pressure = _configVacuumSensorPressure.DoubleValue; if (pressure > 30.0) pressure = 30.0; //bool canOpen = ChamberMonitorPressureGauge.Value < pressure; //if (VacuumSensorValve.Status != canOpen) //{ // VacuumSensorValve.TurnValve(canOpen, out _); //} ////interlock ignore //SignalExhaustAlarm.SetIgnoreError(SC.GetValue($"PM.{Module}.Signal.IgnoreExhaustAlarm")); } catch (Exception ex) { LOG.Write(ex); } return true; } private void MonitorPLCConnected() { if (SensorPLCHeartBeatPC != null) { _trigPLCConnected.CLK = SensorPLCHeartBeatPC.Value; if (_trigPLCConnected.T || _trigPLCConnected.R) { _plcFoolProofTime.Start(_foolProofTime * 1000); } if (_plcFoolProofTime.IsTimeout()) { _plcFoolProofTime.Stop(); SensorPLCConnectedAlarm?.Set($"Connected Status keep {_trigPLCConnected.CLK} out of {_foolProofTime}s"); } } } private void ProcessAlarmSignal() { bool isTrig = false; foreach (var signal in _alarmSignals) { if (signal.RrigSignalOn.T && signal.IsAlarmAutoRecovery) { var item = _triggeredAlarmList.FirstOrDefault(x => x.EventEnum == signal.AlarmTriggered.EventEnum); if (item != null) { item.Reset(); _triggeredAlarmList.Remove(item); EV.ClearAlarmEvent(item.EventEnum); } isTrig = true; signal.AlarmRecovery?.Set(); } } if (isTrig) { int count = 0; var alarms = EV.GetAlarmEvent(); foreach (var alarm in alarms) { if (alarm.Level == EventLevel.Alarm && alarm.Source == Name) count++; } if (count == 0) CheckToPostMessage((int)MSG.Reset); } } private void MonitorVAC1() { if (_vac1Timer == null) _vac1Timer = new Stopwatch(); if (ValveAV24.Status) { _vac1 = false; if (_vac1Timer.IsRunning) _vac1Timer.Stop(); } if(!ValveAV9.Status && !ValveAV16.Status && !ValveAV20.Status && !ValveAV24.Status && ValveAV26.Status && (ValveAV33.Status || ValveAV35.Status) && ValveAV83.Status && ValveAV71.Status && (APC.ModeFeedback == 0 || APC.ModeFeedback == 6) &&//0=idle;6=full open SensorVG11Status.Value && !AlarmSignalVG11HighAlarm.Value) { if (!_vac1Timer.IsRunning) _vac1Timer.Restart(); if(_vac1Timer.ElapsedMilliseconds > _vac1PumpTimeS * 1000) _vac1 = true; } else { if (_vac1Timer.IsRunning) _vac1Timer.Stop(); } } private void MonitorVAC2() { if (_vac2Timer == null) _vac2Timer = new Stopwatch(); if (ValveAV9.Status) { _vac2 = false; if (_vac2Timer.IsRunning) _vac2Timer.Stop(); } if (!ValveAV9.Status && !ValveAV16.Status && !ValveAV20.Status && !ValveAV24.Status && ValveAV12.Status && ValveAV14.Status && ValveAV28.Status && ValveAV29.Status && ValveAV36.Status && ValveAV37.Status && ValveAV81.Status && ValveAV71.Status && (APC.ModeFeedback == 0 || APC.ModeFeedback == 6) &&//0=idle;6=full open SensorVG11Status.Value && !AlarmSignalVG11HighAlarm.Value) { if (!_vac2Timer.IsRunning) _vac2Timer.Restart(); if (_vac2Timer.ElapsedMilliseconds > _vac2PumpTimeS * 1000) _vac2 = true; } else { if (_vac2Timer.IsRunning) _vac2Timer.Stop(); } } private void MonitorVAC3() { if (_vac3Timer == null) _vac3Timer = new Stopwatch(); if (ValveAV16.Status || ValveAV20.Status) { _vac3 = false; if (_vac3Timer.IsRunning) _vac3Timer.Stop(); } if (!ValveAV9.Status && !ValveAV16.Status && !ValveAV20.Status && !ValveAV24.Status && ValveAV18.Status && ValveAV22.Status && ValveAV38.Status && ValveAV39.Status && ValveAV82.Status && ValveAV71.Status && (APC.ModeFeedback == 0 || APC.ModeFeedback == 6) &&//0=idle;6=full open SensorVG11Status.Value && !AlarmSignalVG11HighAlarm.Value) { if (!_vac3Timer.IsRunning) _vac3Timer.Restart(); if (_vac3Timer.ElapsedMilliseconds > _vac3PumpTimeS * 1000) _vac3 = true; } else { if (_vac3Timer.IsRunning) _vac3Timer.Stop(); } } } }