This repository has been archived on 2023-03-29. You can view files and clone it, but cannot push or open issues or pull requests.
Sic02/Modules/Mainframe/TMs/TMSlitValveRoutine.cs

880 lines
31 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Device.Unit;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Mainframe.LLs;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Servo.NAIS;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
using SicPM.Devices;
namespace Mainframe.TMs
{
public class TMSlitValveRoutine : TMBaseRoutine
{
enum RoutineStep
{
ChamberBalance,
OpenTMToLLVent,
OpenTMToPMV70,
CheckPressureCondition,
SetSlitValve,
SetSlowVentValve,
SetM40,
LLRoutine,
Delay,
Delay1, Delay2, Delay3, Delay4,
CloseTMToLLVent,
CloseTMToPMV70,
PumpDownToBase,
CheckConfinementIsDown,
SetConfinementRingUp,
SetConfinementRingDown,
SetPostTransfer,
SetPmPreTrasfer,
SetV77,
SetV77Close,
SetTmMfc,
WaitTempBelow900,
WaitPVTempBelowSet,
CheckPressureCondition1,
WaitPMIdle
}
private int _timeout;
private SicTM _tm;
private LoadLock _ll;
private IoValve PMToTm_V70;
private IoPressure _pmPT1;
private IoConfinementRing _confinementRing;
private SicPM.Devices.SicServo _sicServo;
private NAISServo _naisServo;
SicPM.Devices.IoInterLock _pmIoInterLock;
SicPM.Devices.IoTC _tc1;
private string _paramTarget;
private bool _paramIsOpen;
private bool _confinementIsDown = false;
//private TMPumpWithTurboRoutine _pumpDownRoutine;
private TMPressureBalanceRoutine _balanceRoutine;
private TMPressureBalancePidRoutine _pidBalanceRoutine;
private TMPressureBalancePidRoutine _pidAwaysRoutine;
private LoadLockServoTo _llVentTo;
private IoMFC _m40;
private bool _needPressureBalance;
private bool _userPidBalance;
private int _timeOutV70;
private int _timeOutV85;
private int _rotationStopTimeout = 120;
private double _maxPressureDiffOpenSlitValve;
private bool _isAtmMode;
private bool _isLockLock;
private bool _isPMA;
private int _tmV77DelayTime = 5;
private double _tmMfcFlow = 10;
private bool _pmPostTrasferNeedEnableHeat = true;
private bool _preTransferPSUEnable = false;
//private SCConfigItem _scPVInnerTempLimit;
//private SCConfigItem _scPVMiddleTempLimit;
//private SCConfigItem _scPVOuterTempLimit;
private double _pmPVInnerTempLimit = 0;
private double _pmPVMiddleTempLimit = 0;
private double _pmPVOuterTempLimit = 0;
public TMSlitValveRoutine()
{
Module = ModuleName.TM.ToString();
Name = "Slit Valve";
_tm = DEVICE.GetDevice<SicTM>($"{ ModuleName.System.ToString()}.{ ModuleName.TM.ToString()}");
_ll = DEVICE.GetDevice<SicLoadLock>($"{ModuleName.LoadLock}.{ModuleName.LoadLock}");
PMToTm_V70 = DEVICE.GetDevice<IoValve>("PM1.V70");
_m40 = DEVICE.GetDevice<IoMFC>($"TM.Mfc40");
_confinementRing = DEVICE.GetDevice<IoConfinementRing>("PM1.ConfinementRing");
_sicServo= DEVICE.GetDevice<SicPM.Devices.SicServo>("PM1.PMServo");
_pmIoInterLock = DEVICE.GetDevice<SicPM.Devices.IoInterLock>($"PM1.PMInterLock");
_tc1= DEVICE.GetDevice<SicPM.Devices.IoTC>($"PM1.TC1");
if (SC.GetConfigItem("NAISServo.EnableDevice").BoolValue)
{
_naisServo = DEVICE.GetDevice<NAISServo>($"PM1.NAISServo");
}
}
public void Init(string module,bool isOpen,bool needEnableHeat)
{
_pmPostTrasferNeedEnableHeat = needEnableHeat;
Init(module, isOpen);
}
public void Init(string module, bool isOpen)
{
_paramTarget = module;
_paramIsOpen = isOpen;
Name = isOpen ? "Open Slit Valve" : "Close Slit Valve";
//_pumpDownRoutine = new TMPumpWithTurboRoutine();
_balanceRoutine = new TMPressureBalanceRoutine();
_pidBalanceRoutine = new TMPressureBalancePidRoutine();
_pidAwaysRoutine = new TMPressureBalancePidRoutine();
_llVentTo = new LoadLockServoTo(ModuleName.LoadLock);
_balanceRoutine.Init(ModuleHelper.Converter(module));
_pidBalanceRoutine.Init(ModuleHelper.Converter(module));
_pidAwaysRoutine.Init(ModuleHelper.Converter(module), true);
_needPressureBalance = SC.GetValue<bool>("TM.NeedPressureBalance");
_userPidBalance= SC.GetValue<bool>("TM.PressureBalanceUsePid");
}
public override Result Start(params object[] objs)
{
Reset();
if ((_paramIsOpen && TMDevice.CheckSlitValveOpen(ModuleHelper.Converter(_paramTarget)))
|| (!_paramIsOpen && TMDevice.CheckSlitValveClose(ModuleHelper.Converter(_paramTarget))))
{
string message = _paramIsOpen ? "open" : "close";
if (TMDevice.GetSlitValve(ModuleHelper.Converter(_paramTarget)) != null)
EV.PostWarningLog(Module, $"{_paramTarget} slit valve already {message}");
return Result.DONE;
}
_tm.CloseAllVentPumpValue();
_isLockLock = ModuleHelper.IsLoadLock(_paramTarget);
_isPMA = ModuleHelper.Converter(_paramTarget) == ModuleName.PM1 || ModuleHelper.Converter(_paramTarget) == ModuleName.PMA;
if (_paramIsOpen)
{
bool isAtmMode = SC.GetValue<bool>("System.IsATMMode");
if (ModuleHelper.IsLoadLock(_paramTarget))
{
LoadLock ll = DEVICE.GetDevice<LoadLock>($"{_paramTarget}.{_paramTarget}");
if (isAtmMode)
{
if (!ll.CheckAtm())
{
EV.PostWarningLog(Module, $"can not open slit valve, running in ATM mode, but {_paramTarget} not in ATM");
return Result.FAIL;
}
}
else
{
if (!ll.CheckVacuum())
{
EV.PostWarningLog(Module, $"can not open slit valve, {_paramTarget} not in vacuum");
return Result.FAIL;
}
}
}
if (ModuleHelper.IsPm(_paramTarget))
{
//PM pm = DEVICE.GetDevice<PM>(_paramTarget);
_pmPT1 = DEVICE.GetDevice<IoPressure>($"{_paramTarget}.PT1");
double atmBase = SC.GetValue<double>($"PM.AtmPressureBase");
double vacBase = SC.GetValue<double>($"PM.VacuumPressureBase");
if (WaferManager.Instance.CheckHasWafer(ModuleName.PM1, 0))
{
_pmPVInnerTempLimit = SC.GetValue<double>($"PM.PM1.Heater.PickPVInnerTempLimit");
_pmPVMiddleTempLimit = SC.GetValue<double>($"PM.PM1.Heater.PickPVMiddleTempLimit");
_pmPVOuterTempLimit = SC.GetValue<double>($"PM.PM1.Heater.PickPVOuterTempLimit");
}
else
{
_pmPVInnerTempLimit = SC.GetValue<double>($"PM.PM1.Heater.PlacePVInnerTempLimit");
_pmPVMiddleTempLimit = SC.GetValue<double>($"PM.PM1.Heater.PlacePVMiddleTempLimit");
_pmPVOuterTempLimit = SC.GetValue<double>($"PM.PM1.Heater.PlacePVOuterTempLimit");
}
if (isAtmMode)
{
//if (!pm.CheckAtm())
if (_pmPT1.FeedBack < atmBase)
{
EV.PostWarningLog(Module, $"can not open slit valve, running in ATM mode, but {_paramTarget} not in ATM");
return Result.FAIL;
}
}
else
{
//if (!pm.CheckVacuum())
if (_pmPT1.FeedBack > vacBase)
{
EV.PostWarningLog(Module, $"can not open slit valve, {_paramTarget} not in vacuum");
return Result.FAIL;
}
}
}
ModuleName[] slitValveModules = new ModuleName[]
{
//ModuleName.LLA, ModuleName.LLB, ModuleName.PM1,
// ModuleName.PM2, ModuleName.PM3, ModuleName.PM4
ModuleName.LoadLock,ModuleName.PM1,
};
foreach (var slitValveModule in slitValveModules)
{
if (slitValveModule.ToString() == _paramTarget)
continue;
if (!_tm.CheckSlitValveClose(slitValveModule))
{
EV.PostWarningLog(Module, $"can not open slit valve {_paramTarget}, {slitValveModule} slit valve not closed, can not open at same time");
return Result.FAIL;
}
}
}
if (ModuleHelper.IsLoadLock(_paramTarget))
{
_needPressureBalance = SC.GetValue<bool>("TM.PressureBalance.EnableLL");
}
else if (ModuleHelper.IsPm(_paramTarget))
{
_needPressureBalance = SC.GetValue<bool>($"TM.PressureBalance.Enable{_paramTarget}");
}
else
{
EV.PostAlarmLog(Module, $"did not define balance enable option for {_paramTarget}");
return Result.FAIL;
}
_maxPressureDiffOpenSlitValve = SC.GetValue<double>("TM.MaxPressureDiffOpenSlitValve");
_timeout = SC.GetValue<int>("System.SlitValveMotionTimeout");
_isAtmMode = SC.GetValue<bool>("System.IsATMMode");
_timeOutV70 = SC.GetValue<int>($"TM.V70Timeout");
_timeOutV85 = SC.GetValue<int>($"TM.V85Timeout");
_tmV77DelayTime= SC.GetValue<int>($"TM.OpenSlitValveDelayTimeAfterV77");
_tmMfcFlow = SC.GetValue<double>($"TM.MFCFlowWhenV77Open");
_preTransferPSUEnable = SC.GetValue<bool>($"PM.PM1.PreTransferPSUEnable");
Notify("Start");
return Result.RUN;
}
public override Result Monitor()
{
try
{
if (_isLockLock)
{
if (_paramIsOpen)
{
if (_userPidBalance)
{
ExecuteRoutine((int)RoutineStep.ChamberBalance, _pidBalanceRoutine);
}
else
{
ExecuteRoutine((int)RoutineStep.ChamberBalance, _balanceRoutine);
}
if (_needPressureBalance && !_isAtmMode)
{
TimeDelay((int)RoutineStep.Delay2, 1);
ExecuteRoutine((int)RoutineStep.LLRoutine, _llVentTo);
SetTmToLoadLockVent((int)RoutineStep.OpenTMToLLVent, true, _tm, _paramTarget, _timeOutV85);
}
CheckPressureCondition((int)RoutineStep.CheckPressureCondition, _tm, _paramTarget);
}
SetSlitValve((int)RoutineStep.SetSlitValve, TMDevice, _paramTarget, _paramIsOpen, _timeout);
SetTmToLoadLockVent((int)RoutineStep.CloseTMToLLVent, false, _tm, _paramTarget, _timeOutV85);
}
else if (_isPMA)
{
if (_paramIsOpen)
{
SetPreTransfer((int)RoutineStep.SetPmPreTrasfer, _rotationStopTimeout);//旋转停止,加热停止
if (!_preTransferPSUEnable)
{
WaitPVTempratureBelowSet((int)RoutineStep.WaitPVTempBelowSet, 600);
}
WaitTempratureBelow900((int)RoutineStep.WaitTempBelow900, 600);
if (_needPressureBalance && !_isAtmMode)
{
if (_userPidBalance)
{
ExecuteRoutine((int)RoutineStep.ChamberBalance, _pidBalanceRoutine);
}
else
{
ExecuteRoutine((int)RoutineStep.ChamberBalance, _balanceRoutine);
}
SetTmMfc((int)RoutineStep.SetTmMfc, _tmMfcFlow);
SetPmToTmV70((int)RoutineStep.OpenTMToPMV70, true, _tm, _paramTarget, _timeOutV70);
SetSlowVentValve((int)RoutineStep.SetV77, _tm, _paramIsOpen, _timeout);
TimeDelay((int)RoutineStep.Delay1, _tmV77DelayTime); //5秒可配置
}
CheckPressureCondition((int)RoutineStep.CheckPressureCondition, _tm, _paramTarget);
}
SetSlitValve((int)RoutineStep.SetSlitValve, TMDevice, _paramTarget, _paramIsOpen, _timeout);
if (!_paramIsOpen)
{
//关闭闸板阀需要关闭V77
SetSlowVentValve((int)RoutineStep.SetV77Close, _tm, _paramIsOpen, _timeout);
}
SetPmToTmV70((int)RoutineStep.CloseTMToPMV70, false, _tm, _paramTarget, _timeOutV70);
TimeDelay((int)RoutineStep.Delay2, 2);
if (_paramIsOpen)
{
WaitPMIdle((int)RoutineStep.WaitPMIdle, 20);
SetConfinementRingDown((int)RoutineStep.SetConfinementRingDown, 80); //隔热罩下降
TimeDelay((int)RoutineStep.Delay3, 2);
}
if (!_paramIsOpen)
{
SetPostTransfer((int)RoutineStep.SetPostTransfer, _pmPostTrasferNeedEnableHeat);
TimeDelay((int)RoutineStep.Delay4, 2);
}
}
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException)
{
return Result.FAIL;
}
Notify("Finished");
return Result.DONE;
}
public override void Abort()
{
PMToTm_V70.TurnValve(false, out string reason);
_tm.CloseAllVentPumpValue();
}
/// <summary>
/// 打开或关闭V85
/// </summary>
/// <param name="id"></param>
/// <param name="isOpen"></param>
/// <param name="timeDelay"></param>
private void SetTmToLoadLockVent(int id,bool isOpen, TM tm, string module, int timeDelay)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify((isOpen ? "Open" : "Close") + " TM to LoadLock Vent");
if (!_tm.SetTmToLLVent(isOpen, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
double tmPressure = tm.ChamberPressure;
double targetPressure = 0.0;
if (ModuleHelper.IsLoadLock(_paramTarget))
{
targetPressure = _ll.ChamberPressure;
}
else
{
Stop($"{module} not define pressure condition");
return false;
}
return Math.Abs(tmPressure - targetPressure) <= _maxPressureDiffOpenSlitValve;
},
timeDelay * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"can not complete in {timeDelay} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetPmToTmV70(int id, bool isOpen, TM tm, string module, int timeDelay)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"set V70 " + (isOpen ? "Open" : "Close"));
if (!PMToTm_V70.TurnValve(isOpen, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
double tmPressure = tm.ChamberPressure;
double targetPressure = 0.0;
if (ModuleHelper.IsPm(_paramTarget))
{
targetPressure = DEVICE.GetDevice<SicPM.Devices.IoPressure>($"{module}.PT1").FeedBack;
}
else
{
Stop($"{module} not define pressure condition");
return false;
}
return Math.Abs(tmPressure - targetPressure) <= _maxPressureDiffOpenSlitValve;
},
timeDelay * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"can not complete in {timeDelay} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetSlitValve(int id, TM tm, string module, bool isOpen, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"set slit valve {module} " + (isOpen ? "Open" : "Close"));
if (!tm.SetSlitValve(ModuleHelper.Converter(module), isOpen, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return isOpen ? tm.CheckSlitValveOpen(ModuleHelper.Converter(module)) : tm.CheckSlitValveClose(ModuleHelper.Converter(module));
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"can not complete in {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CheckPressureCondition(int id, TM tm, string target)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"check pressure condition to open {target} slit valve");
double tmPressure = tm.ChamberPressure;
double targetPressure = 0.0;
if (ModuleHelper.IsLoadLock(_paramTarget))
{
targetPressure = _ll.ChamberPressure;
}
else if (ModuleHelper.IsPm(_paramTarget))
{
targetPressure = DEVICE.GetDevice<SicPM.Devices.IoPressure>($"{target}.PT1").FeedBack;
}
else
{
Stop($"{target} not define pressure condition");
return false;
}
double pressureDiff = Math.Abs(tmPressure - targetPressure);
if (pressureDiff > _maxPressureDiffOpenSlitValve)
{
Stop($"pressure difference {pressureDiff:F3} between TM and {target} exceed tolerance {_maxPressureDiffOpenSlitValve}");
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetSlowVentValve(int id, SicTM tm, bool isOpen, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
string op = isOpen ? "Open" : "Close";
Notify($"{op} Slow Vent Valve");
if (!tm.SetSlowVentValve(isOpen, out string reason))
{
Stop(reason);
return false;
}
return true;
}, () =>
{
return tm.CheckSlowVentValve(isOpen);
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set Slow Vent Valve timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetTmMfc(int id, double flow)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Set TM MFC flow to {flow} ");
_tm.SetVentMfc(flow, out string reason);
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetConfinementRingUp(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Set Confinement RingUp");
OP.DoOperation($"{_paramTarget}.ServoUp");
return true;
}, () =>
{
if (_naisServo != null)
{
return _confinementRing.IsUp && _naisServo.IsStbOff;
}
else
{
return _confinementRing.IsUp;
}
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set Confinement RingUp timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void WaitPMIdle(int id,int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
return true;
}, () =>
{
string pm1Status= DATA.Poll($"PM1.Status") == null ? "" : DATA.Poll($"PM1.Status").ToString();
return pm1Status == "ProcessIdle" || pm1Status == "Idle";
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Wait PM Idle timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetConfinementRingDown(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Set Confinement RingDown");
OP.DoOperation($"{_paramTarget}.ServoDown");
return true;
}, () =>
{
return _confinementRing.IsDown;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set Confinement RingDown timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CheckConfinementIsDown(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
_confinementIsDown = _confinementRing.IsDown;
Notify("Servo Statue is " + (_confinementIsDown ? "Down" : "Up"));
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetPostTransfer(int id,bool postTransferEnableHeat)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Set PostTransfer");
OP.DoOperation($"{_paramTarget}.PostTransfer",new object[] { postTransferEnableHeat });
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void SetPreTransfer(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Set PreTransfer");
OP.DoOperation($"{_paramTarget}.PreTransfer");
return true;
}, () =>
{
return _sicServo.ActualSpeedFeedback == 0;
}, timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT) //timeout
{
Stop($"Set PreTransfer timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
private void WaitTempratureBelow900(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Wait DiHeaterTempBelow900CSW");
return true;
},
() =>
{
if (_pmIoInterLock != null)
{
return _pmIoInterLock.DiHeaterTempBelow900CSW;
}
else
{
return true;
}
},
timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT)
{
Stop($"Wait PM Temprature below 900 timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
private void WaitPVTempratureBelowSet(int id, int timeout)
{
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
{
Notify($"Wait PV1Temp below{_pmPVInnerTempLimit}℃ and PV2Temp below{_pmPVMiddleTempLimit}℃ and PV3Temp below{_pmPVOuterTempLimit}℃");
return true;
},() =>
{
if (_tc1 != null && _pmPVOuterTempLimit>0 && _pmPVMiddleTempLimit>0 && _pmPVOuterTempLimit>0)
{
return _tc1.L1PVFeedBack < _pmPVInnerTempLimit && _tc1.L2PVFeedBack < _pmPVMiddleTempLimit && _tc1.L3PVFeedBack < _pmPVOuterTempLimit;
}
else
{
return true;
}
},
timeout * 1000);
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else if (ret.Item2 == Result.TIMEOUT)
{
Stop($"Wait PM Temprature below 900 timeout, over {timeout} seconds");
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
}
}