using System; using System.Collections.Generic; using System.Linq; using System.Text; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using JetVirgoPM.Devices; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Routine; namespace JetVirgoPM.PMs.Routines { class LeakCheckRoutine : PMRoutineBase { private enum LeakCheckStep { PumpDown, CheckDoor, CheckDryPump, CloseAllValve, OpenPumpingValve, OpenPurgeValve, OpenGasFinalValve, ClosePurgeValve, CloseGasFinalValve, OpenMfc1Valve, OpenMfc2Valve, OpenMfc3Valve, OpenMfc4Valve, OpenMfc5Valve, OpenMfc6Valve, CloseMfc1Valve, CloseMfc2Valve, CloseMfc3Valve, CloseMfc4Valve, CloseMfc5Valve, CloseMfc6Valve, StartFlow, StopFlow, RecordStartPressure, RecordEndPressure, PumpDownDelay, StartPressureDelay, EndPressureDelay, ClosePumpValve, LeakCheckDelay, CalcLeakCheck, End, EndLeakCheck, AbortLeakCheck, CheckPressure, OpenVentValve, OpenN2Valve, CloseVentValve, CloseN2Valve }; // Fields private double _beginPressure = 0; private double _endPressure = 0; private double _leakRate; public double LeakRate { get; private set; } private int _leakCheckPumpDownTime; private int _leakCheckWaitTime; private LeakCheckMode _mode; private bool[] _enableGasLineOrN2 = new bool[7]; private string[] _gasLineName = new string[7] { "MfcGas1", "MfcGas2", "MfcGas3", "MfcGas4", "MfcGas5", "MfcGas6", "Vent N2" }; private Dictionary _leakCheckModeMapToText = new Dictionary() { {LeakCheckMode.ChamberOnly.ToString(),"ChamberOnly" }, {LeakCheckMode.ChamberAndGasLine.ToString(),"Chamber To Gasline" }, {LeakCheckMode.ChamberAndGasLineAndFAC.ToString(), "Chamber To FAC" }, {LeakCheckMode.ChamberAndGasBox.ToString(), "Chamber To Gas Box Manual Valve" }, }; private double[] _mfcFlow = new double[6]; private readonly PumpDownRoutine _pumpdownRoutine; private DeviceTimer _delayTimer = new DeviceTimer(); // Properties // public int ElapseTime => (int)(_delayTimer.GetElapseTime() / 1000.0); // Constructor // public LeakCheckRoutine(JetDualPM chamber, PumpDownRoutine _pdRoutine) : base(chamber) { Name = "leak check"; bUINotify = true; _pumpdownRoutine = _pdRoutine; } public void Terminate() { } public RState Start(params object[] objs) { // 预检查 if (CheckLid() == RState.Running && //CheckSlitDoor1() == RState.Running && CheckSlitDoor2() == RState.Running && CheckDryPump() == RState.Running) { _enableGasLineOrN2 = new bool[7]; _mfcFlow = new double[6] { 0.0, 0.0, 0.0, 0.0, 0.0 , 0.0 }; Reset(); _delayTimer.Start(0); try { if (objs.Length == 0) { _leakCheckPumpDownTime = SC.GetValue($"{Module}.Pump.LeakCheckPumpingTime"); _leakCheckWaitTime = SC.GetValue($"{Module}.Pump.LeakCheckWaitTime"); _leakRate = SC.GetValue($"{Module}.Pump.LeakRate"); _mode = LeakCheckMode.ChamberOnly; } else { _leakCheckPumpDownTime = Convert.ToInt32(objs[0].ToString()); _leakCheckWaitTime = Convert.ToInt32(objs[1].ToString()); _mode = (LeakCheckMode)Enum.Parse(typeof(LeakCheckMode), objs[2].ToString()); _leakRate = Convert.ToSingle(objs[3].ToString()); for (int i = 0; i < _enableGasLineOrN2.Length; i++) _enableGasLineOrN2[i] = Convert.ToBoolean(objs[4 + i].ToString()); } for (int i = 0; i < 6; i++) { if (_enableGasLineOrN2[i]) _mfcFlow[i] = SC.GetValue($"{Module}.MfcGas{i + 1}.MfcN2Scale"); } } catch (Exception ex) { LOG.Write(ex); return RState.Failed; } return Runner.Start(_chamber.Module.ToString(), Name); } return RState.Failed; } private string SetGasName() { if (_enableGasLineOrN2 == null || _enableGasLineOrN2.Length == 0 || _mode == LeakCheckMode.ChamberOnly) return string.Empty; var checkSBGasName = new StringBuilder(); for (int i = 0; i < _enableGasLineOrN2.Length; i++) { if (_enableGasLineOrN2[i] && _gasLineName.Length > i) checkSBGasName.Append($"{_gasLineName[i]},"); } return checkSBGasName.Length > 0 ? $"({checkSBGasName.ToString().Trim(',')})" : string.Empty; } public RState Monitor() { Runner.Run(LeakCheckStep.PumpDown, StartPump, CheckPump, _delay_60s) .Run(LeakCheckStep.OpenPurgeValve, OpenPurge, CheckPurgeOpen, _delay_50ms * 10) .Run(LeakCheckStep.OpenGasFinalValve, HOFs.Apply(ExecPurgeOrGasFinalValve, ValveType.PROCESS, true), HOFs.Apply(CheckPurgeOrGasFinalValve, ValveType.PROCESS, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenMfc1Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[0], ValveType.Mfc1, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[0], ValveType.Mfc1, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenMfc2Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[1], ValveType.Mfc2, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[1], ValveType.Mfc2, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenMfc3Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[2], ValveType.Mfc3, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[2], ValveType.Mfc3, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenMfc4Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[3], ValveType.Mfc4, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[3], ValveType.Mfc4, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenMfc5Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[4], ValveType.Mfc5, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[4], ValveType.Mfc5, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenMfc6Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[5], ValveType.Mfc6, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[5], ValveType.Mfc6, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenVentValve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[6], ValveType.FAST_VENT, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[6], ValveType.FAST_VENT, true), _delay_50ms * 10) .Run(LeakCheckStep.OpenN2Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[6], ValveType.N2, true), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[6], ValveType.N2, true), _delay_50ms * 10) .Run(LeakCheckStep.StartFlow, StartFlowMFC, _delay_1s) .Delay(LeakCheckStep.PumpDownDelay, _leakCheckPumpDownTime * 1000) .Run(LeakCheckStep.ClosePumpValve, HOFs.Apply(OpenValve, ValveType.FAST_PUMP, false), HOFs.Apply(CheckValve, ValveType.FAST_PUMP, false), _delay_50ms * 10) .Run(LeakCheckStep.RecordStartPressure, RecordBeginPressure, _delay_1s) .Delay(LeakCheckStep.EndPressureDelay, _leakCheckWaitTime * 1000) .Run(LeakCheckStep.RecordEndPressure, RecordEndPressure, _delay_50ms) .Run(LeakCheckStep.CalcLeakCheck, CalcLeakCheck, _delay_1s) .Run(LeakCheckStep.ClosePurgeValve, HOFs.Apply(ExecPurgeOrGasFinalValve, ValveType.PURGE, false), HOFs.Apply(CheckPurgeOrGasFinalValve, ValveType.PURGE, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseGasFinalValve, HOFs.Apply(ExecPurgeOrGasFinalValve, ValveType.PROCESS, false), HOFs.Apply(CheckPurgeOrGasFinalValve, ValveType.PROCESS, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseMfc1Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[0], ValveType.Mfc1, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[0], ValveType.Mfc1, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseMfc2Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[1], ValveType.Mfc2, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[1], ValveType.Mfc2, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseMfc3Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[2], ValveType.Mfc3, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[2], ValveType.Mfc3, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseMfc4Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[3], ValveType.Mfc4, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[3], ValveType.Mfc4, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseMfc5Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[4], ValveType.Mfc5, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[4], ValveType.Mfc5, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseMfc6Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[5], ValveType.Mfc6, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[5], ValveType.Mfc6, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseVentValve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[6], ValveType.FAST_VENT, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[6], ValveType.FAST_VENT, false), _delay_50ms * 10) .Run(LeakCheckStep.CloseN2Valve, HOFs.Apply(ExecMfcValve, _enableGasLineOrN2[6], ValveType.N2, false), HOFs.Apply(CheckMfcValue, _enableGasLineOrN2[6], ValveType.N2, false), _delay_50ms * 10) .Run(LeakCheckStep.StopFlow, HOFs.WrapAction(_chamber.StopAllGases), NullFun, _delay_1s) .End(LeakCheckStep.End, EndFunc, _delay_50ms); return Runner.Status; } bool CheckPurgeOpen() { if (!_chamber.IsPlus) return CheckPurgeOrGasFinalValve(ValveType.PURGE, true); return true; } bool OpenPurge() { if (!_chamber.IsPlus) return ExecPurgeOrGasFinalValve(ValveType.PURGE, true); return true; } bool StartPump() { return _pumpdownRoutine.Start() == RState.Running; } bool CheckPump() { var result = _pumpdownRoutine.Monitor(); if (result == RState.Failed || result == RState.Timeout) { Runner.Stop($"设置 Pump {_chamber.Name} failed "); return true; } return result == RState.End; } bool ExecPurgeOrGasFinalValve(ValveType vlv, bool isOpen) { if(_mode == LeakCheckMode.ChamberAndGasLine || ((_mode == LeakCheckMode.ChamberAndGasLineAndFAC || _mode == LeakCheckMode.ChamberAndGasBox) && _enableGasLineOrN2.Take(_enableGasLineOrN2.Count() - 1).Any(p => p))) { return OpenValve(vlv, isOpen); } return true; } bool CheckPurgeOrGasFinalValve(ValveType vlv, bool isOpen) { if (_mode == LeakCheckMode.ChamberAndGasLine || ((_mode == LeakCheckMode.ChamberAndGasLineAndFAC || _mode == LeakCheckMode.ChamberAndGasBox) && _enableGasLineOrN2.Take(_enableGasLineOrN2.Count() - 1).Any(p => p))) { return CheckValve(vlv, isOpen); } return true; } bool ExecMfcValve(bool canExec, ValveType vlv, bool isOpen) { if((_mode == LeakCheckMode.ChamberAndGasLineAndFAC || _mode == LeakCheckMode.ChamberAndGasBox) && canExec) { return OpenValve(vlv, isOpen); } return true; } bool CheckMfcValue(bool canExec, ValveType vlv, bool isOpen) { if ((_mode == LeakCheckMode.ChamberAndGasLineAndFAC || _mode == LeakCheckMode.ChamberAndGasBox) && canExec) { return CheckValve(vlv, isOpen); } return true; } bool RecordBeginPressure() { _beginPressure = _chamber.ChamberPressure; Notify($"腔体压力初始值 {_beginPressure} mt"); return true; } bool RecordEndPressure() { _endPressure = _chamber.ChamberPressure; Notify($"腔体压力结束值 {_endPressure} mt"); return true; } bool CalcLeakCheck( ) { LeakRate = (_endPressure - _beginPressure) / (_leakCheckWaitTime / 60.0); if (LeakRate < _leakRate) { Notify($"腔体漏率 [{LeakRate}] mt/min, 低于 [{_leakRate}] mt/min"); LeakCheckResultManager.Instance.AddLeakCheck(Module, DateTime.Now, ElapseTime, (int)_beginPressure, (int)_endPressure, LeakRate, LeakCheckStatus.Succeed.ToString(), _leakCheckModeMapToText[_mode.ToString()] + SetGasName()); return true; } Stop($"腔体漏率 [{LeakRate}] mt/min, 高于 [{_leakRate}] mt/min"); LeakCheckResultManager.Instance.AddLeakCheck(Module, DateTime.Now, ElapseTime, (int)_beginPressure, (int)_endPressure, LeakRate, LeakCheckStatus.Failed.ToString(), _leakCheckModeMapToText[_mode.ToString()] + SetGasName()); return false; } bool StartFlowMFC() { if(_mode == LeakCheckMode.ChamberAndGasLineAndFAC || _mode == LeakCheckMode.ChamberAndGasBox) { for (int index = 0; index < _mfcFlow.Length; index++) { _chamber.FlowGas(index, _mfcFlow[index]); } } return true; } public void DeleteLeadCheck(object[] args) { LeakCheckResultManager.Instance.Delete(Module, args[0].ToString()); } public override void Abort() { try { _chamber.CloseValves(); LeakCheckResultManager.Instance.AddLeakCheck(Module, DateTime.Now, ElapseTime, (int)_beginPressure, (int)_chamber.ChamberPressure, 0, LeakCheckStatus.Aborted.ToString(), _leakCheckModeMapToText[_mode.ToString()] + SetGasName()); } catch (Exception ex) { LOG.Write(ex); } } } }