Sic02-new/Modules/Mainframe/LLs/LoadLockLeakCheckRoutine.cs

630 lines
21 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Diagnostics;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Device.Unit;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Mainframe.Devices;
using MECF.Framework.Common.DBCore;
using MECF.Framework.Common.Equipment;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
namespace Mainframe.LLs
{
public class LoadLockLeakCheckRoutine : ModuleRoutine, IRoutine
{
enum RoutineStep
{
SlowPump,
CloseSlowValve,
FastPump,
PumpDelay,
CloseFastValve,
SlowPump1,
CloseSlowValve1,
FastPump1,
PumpDelay1,
CloseFastValve1,
CheckDoor,
RunPumpRoutine,
ContinuePump,
ClosePumpValve,
DoLeakCheck,
CalcLeakCheck,
StartLoop,
LoopVent,
LoopPump,
StopLoop,
TimeDelay1,
TimeDelay2,
SlowVent, FastVent, CloseFastVentValve, CloseSlowVentValve
}
private int _paramContinuePumpTime;
private int _paramLeakCheckTime;
private double _slowFastPumpSwitchPressure;
private double _slowFastVentSwitchPressure;
private double _pumpBasePressure;
private int _pumpTimeOut;
private int _pumpDelayTime;
private double _ventBasePressure;
private int _ventTimeOut;
private int _ventDelayTime;
private double _beginPressure;
private int _routineTimeOut;
private double _leakSpec;
private int _purgeCount;
private double _beginTime;
private int _calTimes; //第几次计算LeakCheck的值每60秒计算一次
private LoadLock _ll;
private TM _tm;
private Devices.IoPump _pumpType;
private IoInterLock _tmIoInterLock;
private Stopwatch _swTimer = new Stopwatch();
private bool isAtmMode = false;
public int ElapsedTime
{
get { return _swTimer.IsRunning ? (int)(_swTimer.ElapsedMilliseconds / 1000) : 0; }
}
public LoadLockLeakCheckRoutine(ModuleName module)
{
Module = module.ToString();
Name = "LeakCheck";
_ll = DEVICE.GetDevice<LoadLock>($"{Module}.{Module}");
_tm = DEVICE.GetDevice<TM>($"{ModuleName.System.ToString()}.{ModuleName.TM.ToString()}");
_pumpType = DEVICE.GetDevice<Devices.IoPump>($"TM.TMPump");
_tmIoInterLock = DEVICE.GetDevice<IoInterLock>("TM.IoInterLock");
}
internal void Init(int pumpTime, int leakCheckTime)
{
_paramContinuePumpTime = pumpTime;
_paramLeakCheckTime = leakCheckTime;
}
internal void Init()
{
_paramContinuePumpTime = SC.GetValue<int>("LoadLock.LeakCheck.PumpDelayTime");
_paramLeakCheckTime = SC.GetValue<int>("LoadLock.LeakCheck.LeakCheckDelayTime");
}
public Result Start(params object[] objs)
{
Reset();
_swTimer.Restart();
string reason;
if (!_ll.SetFastVentValve(false, out reason) || !_ll.SetSlowVentValve(false, out reason))
{
EV.PostAlarmLog(Module, $"Can not turn off valves, {reason}");
return Result.FAIL;
}
isAtmMode = SC.GetValue<bool>("System.IsATMMode");
_slowFastPumpSwitchPressure = SC.GetValue<double>("LoadLock.Pump.SlowFastPumpSwitchPressure");
_slowFastVentSwitchPressure = SC.GetValue<double>("LoadLock.Vent.SlowFastVentSwitchPressure");
_pumpTimeOut = SC.GetValue<int>("LoadLock.LeakCheck.PumpTimeout");
_pumpBasePressure = SC.GetValue<double>("LoadLock.LeakCheck.PumpBasePressure");
_pumpDelayTime = SC.GetValue<int>("LoadLock.LeakCheck.PumpDelayTime");
_ventTimeOut = SC.GetValue<int>("LoadLock.LeakCheck.VentTimeout");
_ventBasePressure = SC.GetValue<double>("LoadLock.LeakCheck.VentBasePressure");
_ventDelayTime = SC.GetValue<int>("LoadLock.LeakCheck.VentDelayTime");
_routineTimeOut = SC.GetValue<int>("LoadLock.LeakCheck.RoutineTimeOut");
_leakSpec = SC.GetValue<double>("LoadLock.LeakCheck.LeakSpec");
_purgeCount= SC.GetValue<int>("LoadLock.LeakCheck.CyclePurgeCount");
if (_slowFastPumpSwitchPressure < _pumpBasePressure)
{
_slowFastPumpSwitchPressure = _pumpBasePressure;
}
if (_slowFastVentSwitchPressure > _ventBasePressure)
{
_slowFastVentSwitchPressure = _ventBasePressure;
}
if (!_ll.CheckDoorClose())
{
EV.PostAlarmLog(Module, $"Can not leakCheck, door is open");
return Result.FAIL;
}
if (_pumpType.IsAlarm)
{
EV.PostAlarmLog(Module, $"can not leakCheck,TM pump alarm");
return Result.FAIL;
}
if (!_pumpType.IsRunning)
{
EV.PostAlarmLog(Module, $"can not leakCheck,TM pump is not running");
return Result.FAIL;
}
if (!_tm.SetFastPumpValve(false, out reason))
{
EV.PostAlarmLog(Module, $"can not leakCheck, TM fast pump value can not close");
return Result.FAIL;
}
if (!_tm.CheckSlitValveClose(ModuleHelper.Converter(_ll.Module)))
{
EV.PostAlarmLog(Module, $"Can not leakCheck, slit valve is open");
return Result.FAIL;
}
if (!_tmIoInterLock.SetLLLeakCheckRoutineRunning(true, out reason))
{
EV.PostAlarmLog(Module, $"can not leakCheck,{reason}");
return Result.FAIL;
}
Notify("Start");
return Result.RUN;
}
public Result Monitor()
{
try
{
if (isAtmMode)
{
EV.PostInfoLog(Module, $"system in atm mode, {_ll.Module} pump skipped");
return Result.DONE;
}
CheckRoutineTimeOut();
Loop((int)RoutineStep.StartLoop, _purgeCount);
SlowPump((int)RoutineStep.SlowPump, _ll, _slowFastPumpSwitchPressure, _pumpTimeOut);
FastPump((int)RoutineStep.FastPump, _ll, _pumpBasePressure, _pumpTimeOut);
TimeDelay((int)RoutineStep.PumpDelay, _pumpDelayTime);
CloseFastPumpValve((int)RoutineStep.CloseFastValve, _ll);
CloseSlowPumpValve((int)RoutineStep.CloseSlowValve, _ll);
TimeDelay((int)RoutineStep.TimeDelay1, 1);
SlowVent((int)RoutineStep.SlowVent, _ll, _slowFastVentSwitchPressure, _ventTimeOut);
FastVent((int)RoutineStep.FastVent, _ll, _ventBasePressure, _ventTimeOut);
CloseFastVentValve((int)RoutineStep.CloseFastVentValve, _ll);
CloseSlowVentValve((int)RoutineStep.CloseSlowVentValve, _ll);
TimeDelay((int)RoutineStep.TimeDelay2, 1);
EndLoop((int)RoutineStep.StopLoop);
SlowPump((int)RoutineStep.SlowPump1, _ll, _slowFastPumpSwitchPressure, _pumpTimeOut);
FastPump((int)RoutineStep.FastPump1, _ll, _pumpBasePressure, _pumpTimeOut);
TimeDelay((int)RoutineStep.PumpDelay1, _paramContinuePumpTime);
CloseFastPumpValve((int)RoutineStep.CloseFastValve1, _ll);
CloseSlowPumpValve((int)RoutineStep.CloseSlowValve1, _ll);
DoLeakCheck((int)RoutineStep.DoLeakCheck, _paramLeakCheckTime);
CalcLeackCheckPerMinute(_paramLeakCheckTime);
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException)
{
return Result.FAIL;
}
Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
_tmIoInterLock.DoLLLeakCheckRoutineRunning = false;
_swTimer.Stop();
return Result.DONE;
}
public void Abort()
{
Notify($"{Module} leak check aborted");
_tmIoInterLock.DoLLLeakCheckRoutineRunning = false;
_ll.SetSlowPumpValve(false, out _);
_ll.SetFastPumpValve(false, out _);
_swTimer.Stop();
LeakCheckDataRecorder.Add((int)_swTimer.ElapsedMilliseconds / 1000, _beginPressure, _tm.ChamberPressure, 0, Result.FAIL.ToString(), "", Module);
}
private void CheckRoutineTimeOut()
{
if (_routineTimeOut > 10)
{
if ((int)(_swTimer.ElapsedMilliseconds / 1000) > _routineTimeOut)
{
Notify($"Routine TimeOut! over {_routineTimeOut} s");
throw (new RoutineFaildException());
}
}
}
public void SlowPump(int id, LoadLock ll, double switchPressure, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {ll.Name} slow pump valve to {switchPressure} mbar");
if (!_ll.SetSlowPumpValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return ll.ChamberPressure <= switchPressure;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
_ll.SetSlowPumpValve(false, out string _);
Stop($"{ll.Name} pressure can not pump to {switchPressure} in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void FastPump(int id, LoadLock ll, double basePressure, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {ll.Name} fast pump valve to {basePressure} mbar");
if (!_ll.SetFastPumpValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return ll.ChamberPressure <= basePressure;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
_ll.SetSlowPumpValve(false, out string _);
_ll.SetFastPumpValve(false, out string _);
Stop($"{ll.Name} pressure can not pump to {basePressure} in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseSlowPumpValve(int id, LoadLock ll)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Close {ll.Name} slow pump valve");
if (!_ll.SetSlowPumpValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseFastPumpValve(int id, LoadLock ll)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Close {ll.Name} fast pump valve");
if (!_ll.SetFastPumpValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void DoLeakCheck(int id, double time)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Keep pressure for {time} seconds");
_beginTime = _swTimer.ElapsedMilliseconds;
_beginPressure = _ll.ChamberPressure;
_calTimes = 1;
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
//Tuple<bool, Result> ret = Delay(id, () =>
//{
// Notify($"Keep pressure for {time} seconds");
// _beginPressure = _ll.ChamberPressure ; // mbar
// return true;
//}, time * 1000);
//if (ret.Item1)
//{
// if (ret.Item2 == Result.RUN)
// {
// throw (new RoutineBreakException());
// }
//}
}
public void CalcLeackCheckPerMinute(int time)
{
//大于LeakCheck时间,
if ((int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000) >= time)
{
int leakSecond = (int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000);
double endPressure = _ll.ChamberPressure;
double leakSpan = endPressure - _beginPressure;
double leakRate = (endPressure - _beginPressure) / (leakSecond / 60.0);
if (leakRate > _leakSpec)
{
LeakCheckDataRecorder.Add(time, (int)_beginPressure, (int)endPressure, leakRate, Result.FAIL.ToString(), "", Module);
EV.PostInfoLog(Module, $"Leak check result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2}mbar, end: {endPressure:F2}mbar, using {time} seconds, leak rate: {leakRate:F2}");
}
else
{
LeakCheckDataRecorder.Add(time, (int)_beginPressure, (int)endPressure, leakRate, Result.Succeed.ToString(), "", Module);
EV.PostInfoLog(Module, $"Leak check result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2}mbar, end: {endPressure:F2}mbar, using {time} seconds, leak rate: {leakRate:F2}");
}
}
else
{
if ((int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000) >= 60 * _calTimes)
{
_calTimes++;
int leakSecond = (int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000);
double endPressure = _ll.ChamberPressure;
double leakSpan = endPressure - _beginPressure;
double leakRate = (endPressure - _beginPressure) / (leakSecond / 60.0);
if (leakRate > _leakSpec)
{
EV.PostInfoLog(Module, $"Leak check Failed Count {_calTimes - 1}: using {leakSecond} seconds, leak rate: {leakRate:F2} ,Rate over {_leakSpec}");
throw (new RoutineFaildException());
}
EV.PostInfoLog(Module, $"Leak check Count {_calTimes - 1}: using {leakSecond} seconds, leak rate: {leakRate:F2}");
}
throw (new RoutineBreakException());
}
}
public void CalcLeakCheck(int id, int time)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
double endPressure = _ll.ChamberPressure ; //
double leakSpan = endPressure - _beginPressure;
double leakRate = (endPressure - _beginPressure) / (time / 60.0);
if (leakRate > _leakSpec)
{
LeakCheckDataRecorder.Add(time, _beginPressure, endPressure, leakRate, Result.FAIL.ToString(), "", Module);
EV.PostInfoLog(Module,$"{Module} leakcheck result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2} mbar, end: {endPressure:F2} mbar, using {time} seconds, leak rate: {leakRate:F2}");
return false;
}
else
{
LeakCheckDataRecorder.Add(time, _beginPressure, endPressure, leakRate, Result.Succeed.ToString(), "", Module);
EV.PostInfoLog(Module,$"{Module} leakcheck result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2} mbar, end: {endPressure:F2} mbar, using {time} seconds, leak rate: {leakRate:F2}");
return true;
}
});
}
public void SlowVent(int id, LoadLock ll, double switchPressure, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {ll.Name} slow vent valve to {switchPressure} mbar");
if (!_ll.SetSlowVentValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return ll.ChamberPressure >= switchPressure;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
_ll.SetSlowVentValve(false, out string _);
Stop($"{ll.Name} pressure can not vent to {switchPressure} mbar in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void FastVent(int id, LoadLock ll, double basePressure, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Open {ll.Name} fast vent valve to {basePressure} mbar");
if (!_ll.SetFastVentValve(true, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return ll.ChamberPressure >= basePressure;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
_ll.SetSlowVentValve(false, out string _);
_ll.SetFastVentValve(false, out string _);
Stop($"{ll.Name} pressure can not vent to {basePressure} mbar in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseSlowVentValve(int id, LoadLock ll)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Close {ll.Name} slow vent valve");
if (!_ll.SetSlowVentValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CloseFastVentValve(int id, LoadLock ll)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Close {ll.Name} fast vent valve");
if (!_ll.SetFastVentValve(false, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
}
}