using System; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using VirgoRT.Devices; namespace VirgoRT.Modules.PMs { class GasFlowRoutine : PMRoutineBase, IRoutine { private enum RoutineStep { CheckPressure, StartFlow, StopFlow, CheckStable, End, }; public bool _gasStatus = false; private double _pressureAlarmRange; private double _pressureAlarmTime; //private double _gasFlowAlarmRange; //private double _gasFlowAlarmTime; private double[] _mfcSetPoint = new double[5]; public GasFlowRoutine(JetPM chamber) : base(chamber) { Name = "Flow gas"; bUINotify = true; } public Result Start(params object[] objs) { if (!_chamber.IsFastPumpOpened) { StopFlow2(); Stop("Pump 阀没有打开"); return Result.FAIL; } Reset(); _pressureAlarmRange = SC.GetValue($"{Module}.GasFlowPressureAlarmRange"); _pressureAlarmTime = SC.GetValue($"{Module}.GasFlowPressureAlarmTime"); // open process final valve and flow Notify("Open valve and flow mfc"); _chamber.SetValveOnOff(ValveType.PROCESS, true); int i = 0; foreach (object o in objs) { _mfcSetPoint[i++] = (double)o; } FlowMfc2((int)RoutineStep.StartFlow, _mfcSetPoint); _gasStatus = true; return Result.RUN; } public Result Monitor() { try { //CheckPressure((int)RoutineStep.CheckPressure, "Wait for pressure normally", (int)_pressureAlarmTime, Notify, Stop); if (_chamber.HasGasOutOfRange) { Stop("流气率越界"); _gasStatus = false; return Result.FAIL; } End((int)RoutineStep.End); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { _gasStatus = false; return Result.FAIL; } catch (Exception ex) { Stop(ex.Message); _gasStatus = false; return Result.FAIL; } return Result.DONE; } public void FlowMfc2(int id, double[] mfcValues) { string reason = string.Empty; for (int index = 0; index < mfcValues.Length; index++) { _chamber.FlowGas(index, mfcValues[index]); } } public void StopFlow2() { Notify("Close valve and stop to flow MFC"); _chamber.SetValveOnOff(ValveType.PROCESS, false); _chamber.StopAllGases(); } [Obsolete] public void FlowMfc(int id, double[] mfcValues, int time) { Tuple ret = ExecuteAndWait(id, () => { Notify("Open valve and flow mfc"); string reason = string.Empty; _chamber.SetValveOnOff(ValveType.PROCESS, true); for (int index = 0; index < mfcValues.Length; index++) { if (mfcValues[index] > 0) { _chamber.FlowGas(index, mfcValues[index]); } } return true; }, () => { return _chamber.HasGasOutOfRange; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { _chamber.StopAllGases(); throw new RoutineFaildException(); } else if (ret.Item2 == Result.TIMEOUT) //timeout { _chamber.StopAllGases(); EV.PostAlarmLog(Module, $"MFC not flow normally in {time} seconds"); throw new RoutineFaildException(); } else throw new RoutineBreakException(); } } [Obsolete] public void StopGasFlow(int id) { Tuple ret = Execute(id, () => { Notify("Close valve and stop to flow MFC"); string reason = string.Empty; _chamber.SetValveOnOff(ValveType.PROCESS, false); _chamber.StopAllGases(); return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { _chamber.StopAllGases(); throw new RoutineFaildException(); } else throw new RoutineBreakException(); } } public void CheckStable(int id, string name, int alarmTime) { Tuple ret = ExecuteAndWait(id, () => { Notify(name); delayTimer.Start(0); return true; }, () => { if (_chamber.PressureMode == PressureCtrlMode.TVPressureCtrl) { return _chamber.TargetPressure < _chamber.ChamberPressure; } return delayTimer.GetElapseTime() / 1000 > 10; }, alarmTime * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } else if (ret.Item2 == Result.TIMEOUT) { EV.PostAlarmLog(Module, $"Gas flow pressure not stable in {alarmTime} seconds"); throw new RoutineFaildException(); } else throw new RoutineBreakException(); } } public override void Abort() { this.StopFlow2(); _gasStatus = false; } } }