Merge branch 'feature/optimize-autotransfer' into develop
This commit is contained in:
commit
f468afd9a6
|
@ -11,6 +11,8 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
{
|
||||
private Random _rd = new Random();
|
||||
|
||||
private readonly object _syncRoot = new object();
|
||||
|
||||
public ObservableCollection<NotifiableIoItem> DiItemList { get; set; }
|
||||
public ObservableCollection<NotifiableIoItem> DoItemList { get; set; }
|
||||
public ObservableCollection<NotifiableIoItem> AiItemList { get; set; }
|
||||
|
@ -62,6 +64,8 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
//}
|
||||
|
||||
void Init()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (DiItemList == null)
|
||||
{
|
||||
|
@ -155,6 +159,7 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDefaultValue()
|
||||
{
|
||||
|
@ -163,7 +168,8 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
|
||||
protected override bool OnTimer()
|
||||
{
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (DiItemList != null)
|
||||
{
|
||||
foreach (var notifiableIoItem in DiItemList)
|
||||
|
@ -172,6 +178,7 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
{
|
||||
IO.DI[notifiableIoItem.Name].Value = notifiableIoItem.BoolValue;
|
||||
}
|
||||
|
||||
notifiableIoItem.BoolValue = IO.DI[notifiableIoItem.Name].Value;
|
||||
notifiableIoItem.InvokePropertyChanged("BoolValue");
|
||||
}
|
||||
|
@ -216,27 +223,31 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
{
|
||||
var ioBuffers = IoManager.Instance.GetDiBuffer(_source);
|
||||
if (ioBuffers != null)
|
||||
{ foreach (var ioBuffer in ioBuffers)
|
||||
{
|
||||
foreach (var ioBuffer in ioBuffers)
|
||||
{
|
||||
if (plcBuffer.Offset == ioBuffer.Key)
|
||||
{
|
||||
plcBuffer.BoolValue = ioBuffer.Value;
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PLC --> IO
|
||||
if (plcBuffer.Type == IoType.DO)
|
||||
{
|
||||
var ioBuffers = IoManager.Instance.GetDoBuffer(_source);
|
||||
if (ioBuffers!=null)
|
||||
{ foreach (var buffer in ioBuffers)
|
||||
if (ioBuffers != null)
|
||||
{
|
||||
foreach (var buffer in ioBuffers)
|
||||
{
|
||||
if (plcBuffer.Offset == buffer.Key)
|
||||
{
|
||||
IoManager.Instance.SetDoBuffer(_source, plcBuffer.Offset, plcBuffer.BoolValue);
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//IO修改 ---> PLC
|
||||
|
@ -249,9 +260,11 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
{
|
||||
if (plcBuffer.Offset == buffer.Key)
|
||||
{
|
||||
plcBuffer.ShortValue = Array.ConvertAll<short, ushort>(buffer.Value,x=>(ushort)x);
|
||||
plcBuffer.ShortValue =
|
||||
Array.ConvertAll<short, ushort>(buffer.Value, x => (ushort)x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
// PLC --> IO
|
||||
|
@ -259,21 +272,22 @@ namespace MECF.Framework.Simulator.Core.IoProviders
|
|||
{
|
||||
var ioBuffers = IoManager.Instance.GetAoBuffer(_source);
|
||||
if (ioBuffers != null)
|
||||
{ foreach (var buffer in ioBuffers)
|
||||
{
|
||||
foreach (var buffer in ioBuffers)
|
||||
{
|
||||
if (plcBuffer.Offset == buffer.Key)
|
||||
{
|
||||
IoManager.Instance.SetAoBuffer(_source, plcBuffer.Offset, Array.ConvertAll<ushort, short>(plcBuffer.ShortValue, x => (short)x));
|
||||
}
|
||||
}}
|
||||
IoManager.Instance.SetAoBuffer(_source, plcBuffer.Offset,
|
||||
Array.ConvertAll<ushort, short>(plcBuffer.ShortValue, x => (short)x));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -482,7 +482,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据左侧选项查询数据
|
||||
/// 根据DataLog界面左侧项目树中选择的项目查询数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static DataSet SearchDataBaseAsync(
|
||||
|
@ -497,6 +497,50 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
|
|||
{
|
||||
// 遍历模组
|
||||
foreach (var module in modules)
|
||||
{
|
||||
// 如果当前根节点下没有被选中的终端节点,则忽略
|
||||
if (module.ChildNodes.FirstOrDefault(x => (bool)x.HasTerminalSelected) == null)
|
||||
continue;
|
||||
|
||||
if (module.ToString() != "IO")
|
||||
{
|
||||
// 如果不是IO节点,则根节点名即为数据库名=
|
||||
var dt = SearchSingleDbTable(module, dateRange, cancellation, progressReporter);
|
||||
if (dt != null)
|
||||
ds.Tables.Add(dt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果节点名是IO,则数据库使用IO.[二级节点名]作为表名,例如IO.PM1\IO.PM2\IO.TM\IO.System
|
||||
var subNodes = module.ChildNodes;
|
||||
|
||||
foreach (var subNode in subNodes)
|
||||
{
|
||||
if (subNode.ChildNodes.FirstOrDefault(x => (bool)x.HasTerminalSelected) == null)
|
||||
continue;
|
||||
|
||||
var dt = SearchSingleDbTable(subNode, dateRange, cancellation, progressReporter);
|
||||
if (dt != null)
|
||||
ds.Tables.Add(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IO节点在数据库中的表名比较特殊,需要特殊处理。
|
||||
/// </summary>
|
||||
/// <param name="module"></param>
|
||||
/// <param name="dateRange"></param>
|
||||
/// <param name="cancellation"></param>
|
||||
/// <param name="progressReporter"></param>
|
||||
/// <returns></returns>
|
||||
private static DataTable SearchSingleDbTable(TreeNode module, DateRangeHelper dateRange,
|
||||
CancellationTokenSource cancellation = null,
|
||||
IProgress<ProgressUpdatingEventArgs> progressReporter = null)
|
||||
{
|
||||
var sql = new StringBuilder();
|
||||
//! 因为数据库中按天拆表,无法一次性查询数据,需使用UNION合并多表查询,因此此处按天拼接SQL表达式
|
||||
|
@ -507,17 +551,9 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
|
|||
var ts = dateRange.Diff;
|
||||
for (var day = 0; day <= ts.Days; day++)
|
||||
{
|
||||
// 检查表名是否存在,否则SQL执行出错。
|
||||
var tblName = $"{dateRange.Start.AddDays(day):yyyyMMdd}.{module}";
|
||||
if (module.ToString() == "IO")
|
||||
{
|
||||
var node = module.ChildNodes.FirstOrDefault(x => (bool)x.HasTerminalSelected);
|
||||
tblName = $"{dateRange.Start.AddDays(day):yyyyMMdd}.{node}";
|
||||
}else if (module.ToString() != "PM1")
|
||||
{
|
||||
tblName = $"{dateRange.Start.AddDays(day):yyyyMMdd}.System";
|
||||
}
|
||||
|
||||
// 检查表名是否存在,否则SQL执行出错。
|
||||
if (CheckTableExists(tblName))
|
||||
{
|
||||
|
||||
|
@ -541,12 +577,10 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
|
|||
// 所有表名不可用,可能是日期范围错误
|
||||
if (sql.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
return null;
|
||||
}
|
||||
|
||||
sql.Append(
|
||||
$" where \"time\" between {dateRange.Start.Ticks} and {dateRange.End.Ticks} order by InternalTimeStamp asc");
|
||||
|
||||
progressReporter?.Report(new ProgressUpdatingEventArgs(20, 100,
|
||||
$"Querying {dateRange}..."));
|
||||
|
||||
|
@ -561,13 +595,10 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
|
|||
|
||||
//! 返回的 DataTable 可能不存在,原因是上述代码自动生成的表明可能不存在。
|
||||
if (dataTable == null)
|
||||
continue;
|
||||
dataTable.TableName = module.Name;
|
||||
ds.Tables.Add(dataTable);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
return ds;
|
||||
dataTable.TableName = module.Name;
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Aitex.Core.RT.Device;
|
||||
using Aitex.Core.RT.Event;
|
||||
using Aitex.Core.RT.Routine;
|
||||
|
@ -142,6 +143,8 @@ namespace Mainframe.LLs.Routines
|
|||
EndLoop((int)RoutineStep.StopLoop);
|
||||
|
||||
}
|
||||
|
||||
TimeDelay((int)RoutineStep.TimeDelay2, 3);
|
||||
}
|
||||
catch (RoutineBreakException)
|
||||
{
|
||||
|
@ -149,15 +152,23 @@ namespace Mainframe.LLs.Routines
|
|||
}
|
||||
catch (RoutineFaildException)
|
||||
{
|
||||
UnlockPump2();
|
||||
return Result.FAIL;
|
||||
}
|
||||
|
||||
|
||||
var result = Result.DONE;
|
||||
if (_tmIoInterLock.SetLLPurgeRoutineRunning(false, out var reason) == false)
|
||||
{
|
||||
EV.PostWarningLog(Module,
|
||||
$"Unable to perform {nameof(_tmIoInterLock.SetLLPurgeRoutineRunning)}, {reason}");
|
||||
result = Result.FAIL;
|
||||
}
|
||||
|
||||
UnlockPump2();
|
||||
|
||||
Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
|
||||
_tmIoInterLock.DoLLCyclePurgeRoutineRunning = false;
|
||||
return Result.DONE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Abort()
|
||||
|
|
|
@ -149,6 +149,7 @@
|
|||
<Compile Include="UnLoads\Routines\UnLoadLiftRoutine.cs" />
|
||||
<Compile Include="UnLoads\Routines\UnLoadPrepareTransferRoutine.cs" />
|
||||
<Compile Include="UnLoads\Routines\UnLoadPumpRoutine.cs" />
|
||||
<Compile Include="UnLoads\Routines\UnLoadCoolingAndPurgeRoutine.cs" />
|
||||
<Compile Include="UnLoads\Routines\UnLoadPurgeRoutine.cs" />
|
||||
<Compile Include="UnLoads\Routines\UnLoadSeparateRoutine.cs" />
|
||||
<Compile Include="UnLoads\Routines\UnLoadServoToRoutine.cs" />
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Aitex.Core.RT.Event;
|
||||
using Aitex.Core.RT.Routine;
|
||||
using Aitex.Core.RT.SCCore;
|
||||
using MECF.Framework.Common.Equipment;
|
||||
|
||||
namespace Mainframe.UnLoads.Routines
|
||||
{
|
||||
public class UnLoadCoolingAndPurgeRoutine : UnLoadBaseRoutine
|
||||
{
|
||||
enum RoutineStep
|
||||
{
|
||||
SlowPump,
|
||||
FastPump,
|
||||
PumpDelay,
|
||||
CloseFastValve,
|
||||
CloseSlowValve,
|
||||
SlowVent,
|
||||
FastVent,
|
||||
VentDelay,
|
||||
CloseFastVentValve,
|
||||
CloseSlowVentValve,
|
||||
StartLoop,
|
||||
LoopPump,
|
||||
LoopVent,
|
||||
StopLoop,
|
||||
TimeDelay1,
|
||||
TimeDelay2
|
||||
}
|
||||
|
||||
private int _purgeCount;
|
||||
private int _routineTimeOut;
|
||||
private double _pumpSwitchPressure;
|
||||
private double _pumpBasePressure;
|
||||
private int _pumpDelayTime;
|
||||
private int _pumpTimeOut;
|
||||
private double _ventBasePressure;
|
||||
private int _ventDelayTime;
|
||||
private int _ventTimeOut;
|
||||
private int _coolingTimeInSec;
|
||||
|
||||
|
||||
private readonly Stopwatch _swTimer = new Stopwatch();
|
||||
private readonly Stopwatch _swCooling = new Stopwatch();
|
||||
|
||||
public UnLoadCoolingAndPurgeRoutine()
|
||||
{
|
||||
Module = ModuleName.UnLoad.ToString();
|
||||
Name = "CoolingAndPurge";
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override Result Start(params object[] objs)
|
||||
{
|
||||
Reset();
|
||||
|
||||
|
||||
if (objs.Length == 3
|
||||
&& int.TryParse(objs[0].ToString(), out int coolingTime)
|
||||
&& int.TryParse(objs[1].ToString(), out int purgeCount)
|
||||
&& int.TryParse(objs[2].ToString(), out int pumpDelayTime))
|
||||
{
|
||||
_coolingTimeInSec = coolingTime;
|
||||
_purgeCount = purgeCount;
|
||||
_pumpDelayTime = pumpDelayTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
_coolingTimeInSec = SC.GetValue<int>("UnLoad.CoolingTimeFallback");
|
||||
_purgeCount = SC.GetValue<int>("UnLoad.Purge.CyclePurgeCount");
|
||||
_pumpDelayTime = SC.GetValue<int>("UnLoad.Purge.PumpDelayTime");
|
||||
}
|
||||
|
||||
_routineTimeOut = SC.GetValue<int>("UnLoad.Purge.RoutineTimeOut");
|
||||
_pumpSwitchPressure = SC.GetValue<double>("UnLoad.Pump.SlowFastPumpSwitchPressure");
|
||||
_pumpBasePressure = SC.GetValue<double>("UnLoad.Purge.PumpBasePressure");
|
||||
_pumpTimeOut = SC.GetValue<int>("UnLoad.Purge.PumpTimeOut");
|
||||
_ventBasePressure = SC.GetValue<double>("UnLoad.Purge.VentBasePressure");
|
||||
_ventDelayTime = SC.GetValue<int>("UnLoad.Purge.VentDelayTime");
|
||||
_ventTimeOut = _pumpTimeOut;
|
||||
|
||||
LockPump2(out var reason);
|
||||
|
||||
if (!UnLoadDevice.CheckLidClose())
|
||||
{
|
||||
EV.PostAlarmLog(Module, $"can not purge, lid is open");
|
||||
return Result.FAIL;
|
||||
}
|
||||
if (!TMDevice.SetFastPumpValve(false, out reason))
|
||||
{
|
||||
EV.PostAlarmLog(Module, $"can not purge, TM fast pump value can not close");
|
||||
return Result.FAIL;
|
||||
}
|
||||
if (!TMDevice.CheckSlitValveClose(ModuleHelper.Converter(UnLoadDevice.Module)))
|
||||
{
|
||||
EV.PostAlarmLog(Module, $"Can not purge, slit valve is open");
|
||||
return Result.FAIL;
|
||||
}
|
||||
if (!TMDevice.SetTmToLLVent(false, out _))
|
||||
{
|
||||
EV.PostAlarmLog(Module, $"can not vent,can not close v85!");
|
||||
}
|
||||
|
||||
if (!TmIoInterLock.SetUnloadPurgeRoutineRunning(true, out reason))
|
||||
{
|
||||
EV.PostAlarmLog(Module, $"can not purge,{reason}");
|
||||
return Result.FAIL;
|
||||
}
|
||||
if (SC.GetValue<bool>("System.IsATMMode"))
|
||||
{
|
||||
return Result.DONE;
|
||||
}
|
||||
|
||||
_swTimer.Restart();
|
||||
_swCooling.Restart();
|
||||
|
||||
Notify("CoolingAnd Purge Start");
|
||||
return Result.RUN;
|
||||
}
|
||||
|
||||
|
||||
public override Result Monitor()
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckRoutineTimeOut();
|
||||
|
||||
if (_purgeCount > 0)
|
||||
{
|
||||
Loop((int)RoutineStep.StartLoop, _purgeCount);
|
||||
|
||||
SlowPump((int)RoutineStep.SlowPump, _pumpSwitchPressure, _pumpTimeOut);
|
||||
FastPump((int)RoutineStep.FastPump, _pumpBasePressure, _pumpTimeOut);
|
||||
TimeDelay((int)RoutineStep.PumpDelay, _pumpDelayTime);
|
||||
CloseFastPumpValve((int)RoutineStep.CloseFastValve);
|
||||
CloseSlowPumpValve((int)RoutineStep.CloseSlowValve);
|
||||
|
||||
TimeDelay((int)RoutineStep.TimeDelay1, 1);
|
||||
|
||||
SlowVent((int)RoutineStep.SlowVent, _ventBasePressure, _ventTimeOut);
|
||||
CloseVentValve((int)RoutineStep.CloseSlowVentValve);
|
||||
|
||||
TimeDelay((int)RoutineStep.VentDelay, _ventDelayTime);
|
||||
EndLoop((int)RoutineStep.StopLoop);
|
||||
}
|
||||
|
||||
TimeDelay((int)RoutineStep.TimeDelay2, 3);
|
||||
|
||||
CheckCoolingDone();
|
||||
}
|
||||
catch (RoutineBreakException)
|
||||
{
|
||||
return Result.RUN;
|
||||
}
|
||||
catch (RoutineFaildException)
|
||||
{
|
||||
return Result.FAIL;
|
||||
}
|
||||
|
||||
var result = Result.DONE;
|
||||
if (TmIoInterLock.SetUnloadPurgeRoutineRunning(false, out var reason) == false)
|
||||
{
|
||||
EV.PostWarningLog(Module, $"Unable to perform {nameof(TmIoInterLock.SetUnloadPurgeRoutineRunning)}, {reason}");
|
||||
result = Result.FAIL;
|
||||
}
|
||||
|
||||
UnlockPump2();
|
||||
|
||||
Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Abort()
|
||||
{
|
||||
TmIoInterLock.SetUnloadPurgeRoutineRunning(false, out _);
|
||||
base.Abort();
|
||||
}
|
||||
|
||||
private void CheckRoutineTimeOut()
|
||||
{
|
||||
if (_routineTimeOut > 10)
|
||||
{
|
||||
if ((int)(_swTimer.ElapsedMilliseconds / 1000) > _routineTimeOut)
|
||||
{
|
||||
EV.PostAlarmLog(Module, $"Routine TimeOut! over {_routineTimeOut} s");
|
||||
throw (new RoutineFaildException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckCoolingDone()
|
||||
{
|
||||
if (_swCooling.Elapsed.TotalSeconds > _coolingTimeInSec)
|
||||
{
|
||||
_swCooling.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
throw new RoutineBreakException();
|
||||
}
|
||||
|
||||
|
||||
public int GetRemainedTime()
|
||||
{
|
||||
if (_swCooling.IsRunning)
|
||||
return _coolingTimeInSec - (int)(_swCooling.Elapsed.TotalSeconds);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Aitex.Core.RT.Event;
|
||||
using Aitex.Core.RT.Routine;
|
||||
using Aitex.Core.RT.SCCore;
|
||||
|
@ -136,6 +137,8 @@ namespace Mainframe.UnLoads.Routines
|
|||
TimeDelay((int)RoutineStep.VentDelay, _ventDelayTime);
|
||||
EndLoop((int)RoutineStep.StopLoop);
|
||||
}
|
||||
|
||||
TimeDelay((int)RoutineStep.TimeDelay2, 3);
|
||||
}
|
||||
catch (RoutineBreakException)
|
||||
{
|
||||
|
@ -143,14 +146,20 @@ namespace Mainframe.UnLoads.Routines
|
|||
}
|
||||
catch (RoutineFaildException)
|
||||
{
|
||||
UnlockPump2();
|
||||
return Result.FAIL;
|
||||
}
|
||||
TmIoInterLock.SetUnloadPurgeRoutineRunning(false, out _);
|
||||
|
||||
var result = Result.DONE;
|
||||
if (TmIoInterLock.SetUnloadPurgeRoutineRunning(false, out var reason) == false)
|
||||
{
|
||||
EV.PostWarningLog(Module, $"Unable to perform {nameof(TmIoInterLock.SetUnloadPurgeRoutineRunning)}, {reason}");
|
||||
result = Result.FAIL;
|
||||
}
|
||||
|
||||
UnlockPump2();
|
||||
|
||||
Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
|
||||
return Result.DONE;
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Abort()
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Mainframe.UnLoads
|
|||
OpenDoor,
|
||||
CloseDoor,
|
||||
Cooling,
|
||||
CoolingAndPurge,
|
||||
Separating,
|
||||
Grouping,
|
||||
}
|
||||
|
@ -55,6 +56,7 @@ namespace Mainframe.UnLoads
|
|||
OpenDoor,
|
||||
CloseDoor,
|
||||
Cooling,
|
||||
CoolingAndPurge,
|
||||
SetOnline,
|
||||
SetOffline,
|
||||
ToInit,
|
||||
|
@ -144,6 +146,7 @@ namespace Mainframe.UnLoads
|
|||
private UnLoadPrepareTransferRoutine _prepareTransferRoutine;
|
||||
//private UnLoadLiftRoutine _liftRoutine;
|
||||
private UnLoadCoolingRoutine _unloadCoolingRoutine;
|
||||
private UnLoadCoolingAndPurgeRoutine _unloadCoolingAndPurgeRoutine;
|
||||
private UnLoadSeparateRoutine _unloadSeparateRoutine;
|
||||
private UnLoadLeakCheckRoutine _unloadLeakCheckRoutine;
|
||||
|
||||
|
@ -192,6 +195,7 @@ namespace Mainframe.UnLoads
|
|||
_prepareTransferRoutine = new UnLoadPrepareTransferRoutine();
|
||||
_unloadSeparateRoutine = new UnLoadSeparateRoutine();
|
||||
_unloadCoolingRoutine = new UnLoadCoolingRoutine();
|
||||
_unloadCoolingAndPurgeRoutine = new UnLoadCoolingAndPurgeRoutine();
|
||||
_unloadLeakCheckRoutine = new UnLoadLeakCheckRoutine();
|
||||
}
|
||||
|
||||
|
@ -244,6 +248,11 @@ namespace Mainframe.UnLoads
|
|||
Transition(STATE.Purge, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
|
||||
Transition(STATE.Purge, MSG.Abort, FsmAbortTask, STATE.Idle);
|
||||
|
||||
//CoolingAndPurge
|
||||
Transition(STATE.Idle, MSG.CoolingAndPurge, FsmStartCoolingAndPurge, STATE.CoolingAndPurge);
|
||||
Transition(STATE.CoolingAndPurge, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
|
||||
Transition(STATE.CoolingAndPurge, MSG.Abort, FsmAbortTask, STATE.Idle);
|
||||
|
||||
//Leak Check
|
||||
Transition(STATE.Idle, MSG.LeakCheck, FsmStartLeakCheck, STATE.LeakCheck);
|
||||
Transition(STATE.LeakCheck, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
|
||||
|
@ -332,7 +341,7 @@ namespace Mainframe.UnLoads
|
|||
DATA.Subscribe($"{Name}.CurrentRoutineLoop", () => CurrentRoutineLoop, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
||||
DATA.Subscribe($"{Name}.CurrentRoutineLoopTotal", () => CurrentRoutineLoopTotal, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
||||
|
||||
DATA.Subscribe($"{Name}.RemainedCoolingTime", () => _unloadCoolingRoutine.GetRemainedTime());
|
||||
DATA.Subscribe($"{Name}.RemainedCoolingTime", () => _unloadCoolingAndPurgeRoutine.GetRemainedTime());
|
||||
|
||||
|
||||
/*
|
||||
|
@ -543,6 +552,14 @@ namespace Mainframe.UnLoads
|
|||
return ret == Result.RUN;
|
||||
}
|
||||
|
||||
private bool FsmStartCoolingAndPurge(object[] param)
|
||||
{
|
||||
Result ret = StartRoutine(_unloadCoolingAndPurgeRoutine, param);
|
||||
if (ret == Result.FAIL || ret == Result.DONE)
|
||||
return false;
|
||||
return ret == Result.RUN;
|
||||
}
|
||||
|
||||
private bool FsmStartCooling(object[] param)
|
||||
{
|
||||
_unloadCoolingRoutine.Init((int)param[0]);
|
||||
|
@ -590,6 +607,14 @@ namespace Mainframe.UnLoads
|
|||
return (int)FSM_MSG.NONE;
|
||||
}
|
||||
|
||||
public override int InvokeCoolingAndPurge(int timeInSec, int purgeLoopCount, int purgePumpDelay)
|
||||
{
|
||||
if (CheckToPostMessage((int)MSG.CoolingAndPurge, timeInSec, purgeLoopCount, purgePumpDelay))
|
||||
return (int)MSG.CoolingAndPurge;
|
||||
|
||||
return (int)FSM_MSG.NONE;
|
||||
}
|
||||
|
||||
public override int InvokeVent()
|
||||
{
|
||||
if (CheckToPostMessage((int)MSG.Vent))
|
||||
|
|
|
@ -42,6 +42,9 @@ namespace Mainframe.UnLoads
|
|||
public abstract bool CheckReadyForMap(ModuleName robot, Hand blade, out string reason);
|
||||
|
||||
public abstract int InvokeCooling(int time);
|
||||
|
||||
public abstract int InvokeCoolingAndPurge(int time, int purgeLoopCount, int purgePumpDelay);
|
||||
|
||||
public abstract int InvokeVent();
|
||||
public abstract int InvokePump();
|
||||
public abstract int InvokePurge(params object[] objs);
|
||||
|
|
|
@ -1459,8 +1459,6 @@
|
|||
|
||||
<configs name="Purge">
|
||||
<config default="3" name="CyclePurgeCount" description="吹扫的循环次数" max="1000" min="0" paramter="" tag="" unit="次" type="Integer" />
|
||||
<config default="1" name="CyclePurgeCountAfterWaferPlaced" description="当Tray来自TMRobot时,Wafer放好后的吹扫的循环次数" max="1000" min="0" paramter="" tag="" unit="次" type="Integer" />
|
||||
<config default="10" name="PurgeDelayTimeAfterWaferPlaced" description="当Tray来自TMRobot时,Wafer放好后的吹扫抽气延时" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />
|
||||
<config default="0" name="PumpBasePressure" description="抽气的底压" max="1000" min="0" paramter="" tag="" unit="mbar" type="Double" />
|
||||
<config default="10" name="PumpDelayTime" description="抽气到底压后,继续抽气多长时间" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />
|
||||
<config default="100" name="PumpTimeOut" description="抽气超时时间" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />
|
||||
|
@ -1507,6 +1505,7 @@
|
|||
<config default="10" name="HomeTimeout" description="home time out" max="600" min="1" paramter="" tag="" unit="s" type="Integer" />
|
||||
<config default="10" name="LiftMoveTimeOut" description="LiftMoveTimeOut" max="600" min="1" paramter="" tag="" unit="s" type="Integer" />
|
||||
<config default="10" name="ClawMoveTimeOut" description="ClawMoveTimeOut" max="600" min="1" paramter="" tag="" unit="s" type="Integer" />
|
||||
<config default="200" name="CoolingTimeFallback" description="当Sequence设定的Cooling时间无效时,回落到此时间" max="600" min="1" paramter="" tag="" unit="s" type="Integer" />
|
||||
|
||||
<configs name="Home">
|
||||
<config default="250" name="RoutineTimeOut" description="Routine超时时间" max="3000" min="0" paramter="" tag="" unit="s" type="Integer" />
|
||||
|
|
|
@ -1632,6 +1632,7 @@ namespace SicRT.Modules
|
|||
|
||||
private void MonitorLoadTask()
|
||||
{
|
||||
|
||||
// 如果是第一次喂Wafer进来,或第一次检测到Wafer被取走,则重置Load腔状态。
|
||||
if (_load.FirstDetectWaferArrive(0) || _load.FirstDetectWaferLeave(0))
|
||||
{
|
||||
|
@ -1654,23 +1655,8 @@ namespace SicRT.Modules
|
|||
return;
|
||||
}
|
||||
|
||||
// 如果Group后还未Purge,先执行Purge
|
||||
if (!_load.HasPurgedAfterGrouped && _load.CheckWaferTrayGrouped())
|
||||
{
|
||||
if (_load.CheckWaferNextStepIsThis(ModuleName.LoadLock, 0)
|
||||
&& !_unload.IsInPumping)
|
||||
{
|
||||
// Group以后执行吹扫动作
|
||||
_load.PurgeAfterGrouped(_load.GetWaferPurgeCount(0), _load.GetWaferPumpDelayTime(0));
|
||||
_load.GetWaferInfo(0).NextSequenceStep++;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果没Purge过,啥也不干
|
||||
if (_load.HasPurgedAfterGrouped == false)
|
||||
if (_load.HasPurged == false)
|
||||
return;
|
||||
|
||||
// 有Wafer和石墨盘,等待TM来取
|
||||
|
@ -1722,16 +1708,8 @@ namespace SicRT.Modules
|
|||
|| (_buffer.HasTray(1) && _buffer.NoWafer(1))
|
||||
|| (_buffer.HasTray(2) && _buffer.NoWafer(2)))
|
||||
{
|
||||
// TMRobot放Tray前先Purge
|
||||
if (!_load.HasPurgedAfterWaferPlaced && !_unload.IsInPumping)
|
||||
{
|
||||
var cycle = SC.GetValue<int>($"{ModuleName.LoadLock}.Purge.CyclePurgeCountAfterWaferPlaced");
|
||||
var delay = SC.GetValue<int>($"{ModuleName.LoadLock}.Purge.PurgeDelayTimeAfterWaferPlaced");
|
||||
_load.PurgeAfterWaferPlaced(cycle, delay);
|
||||
}
|
||||
|
||||
// 如果还没Purge,阻止TMRobot放Tray
|
||||
if (!_load.HasPurgedAfterWaferPlaced)
|
||||
if (!_load.HasPurged)
|
||||
return;
|
||||
|
||||
if (!_load.IsReadyForPlace(ModuleName.TMRobot, 0)
|
||||
|
@ -1766,14 +1744,21 @@ namespace SicRT.Modules
|
|||
_unload.ResetPurgedAndSeparatedStatus();
|
||||
}
|
||||
|
||||
// 如果Load等着TMRobot来拿盘,先保障Load
|
||||
if (_load.HasWafer(0) && _load.HasTray(0) && !_tmRobot.HasTray(0) && !_tmRobot.HasWafer(0))
|
||||
return;
|
||||
|
||||
// TM把Wafer和Tray放如UnLoad后,先冷却,再分离,然后取Tray前Purge
|
||||
if (_unload.HasWafer(0) && _unload.HasTray(0))
|
||||
{
|
||||
// 如果没冷却,先冷却
|
||||
if (!_unload.CheckCoolingCompleted())
|
||||
{
|
||||
GetWaferSequenceCoolingTime(_unload.Module, 0, out int coolingTime);
|
||||
_unload.Cooling(true, coolingTime);
|
||||
GetWaferSequenceCoolingTime(_unload.Module, 0, out var coolingTime);
|
||||
_unload.CoolingAndPurge(
|
||||
true,
|
||||
coolingTime, _unload.GetWaferPurgeCount(0),
|
||||
_unload.GetWaferPumpDelayTime(0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1840,6 +1825,14 @@ namespace SicRT.Modules
|
|||
}
|
||||
else // 如果UnLoad里啥也没有,则准备好下次TMRobot喂 W&T
|
||||
{
|
||||
|
||||
// 优先保证Load腔Purge和PrepareTransfer
|
||||
if ((!_tmRobot.IsReadyForPlace(ModuleName.UnLoad, 0) && _load.CheckWaferNeedProcess(0))
|
||||
|| _aligner.CheckWaferNeedProcess(0)
|
||||
|| _waferRobot.CheckWaferNeedProcess(0)
|
||||
|| GetCurrentTrayCount() <= 1)
|
||||
return;
|
||||
|
||||
// 如果Wafer取完后还没有Purge,先Purge
|
||||
if (!_unload.CheckPurgedAfterWaferPicked() && !_load.IsInPumping)
|
||||
{
|
||||
|
@ -2021,10 +2014,27 @@ namespace SicRT.Modules
|
|||
if (!_tmRobot.IsAvailable)
|
||||
return;
|
||||
|
||||
//place TMRobot有Tray无Wafer, Load无Tray
|
||||
canPlace = _tmRobot.HasTray(0) && _tmRobot.NoWafer(0) && _load.NoTray(0) && _load.HasWafer(0);
|
||||
// TMRobot有Tray无Wafer, Load有Wafer无Tray,准备TMRobot放Tray到Load
|
||||
canPlace = _tmRobot.HasTray(0) && _tmRobot.NoWafer(0)
|
||||
&& _load.NoTray(0) && _load.HasWafer(0);
|
||||
if (canPlace)
|
||||
{
|
||||
// 如果 Wafer还没Purge,先Purge Wafer
|
||||
if (!_load.HasPurged)
|
||||
{
|
||||
if (_load.CheckWaferNextStepIsThis(ModuleName.LoadLock, 0)
|
||||
&& !_unload.IsInPumping)
|
||||
{
|
||||
// Group以后执行吹扫动作
|
||||
_load.Purge(_load.GetWaferPurgeCount(0), _load.GetWaferPumpDelayTime(0));
|
||||
_load.GetWaferInfo(0).NextSequenceStep++;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (_load.IsReadyForPlace(ModuleName.TMRobot, 0) && !_unload.IsInPumping)
|
||||
{
|
||||
if (_tmRobot.Place(_load.Module, 0, Hand.Blade1))
|
||||
|
@ -2042,17 +2052,29 @@ namespace SicRT.Modules
|
|||
return;
|
||||
|
||||
//pick TM无Tray,需要Process,下一个位置没有Tray
|
||||
bool canPick = _tmRobot.NoTray(0) && _load.CheckWaferNeedProcess(0) &&
|
||||
!_load.CheckWaferNextStepIsThis(ModuleName.LoadLock, 0) &&
|
||||
_load.CheckWaferNextStepModuleNoTray(0);
|
||||
bool canPick = _tmRobot.NoTray(0) && _load.CheckWaferNeedProcess(0);
|
||||
if (canPick)
|
||||
{
|
||||
//需要完成组合和Purge
|
||||
// 没组合先组合
|
||||
if (!_load.CheckWaferTrayGrouped())
|
||||
return;
|
||||
|
||||
// 没Purge先Purge
|
||||
if (!_load.HasPurged)
|
||||
{
|
||||
if (_load.CheckWaferNextStepIsThis(ModuleName.LoadLock, 0)
|
||||
&& !_unload.IsInPumping)
|
||||
{
|
||||
// Group以后执行吹扫动作
|
||||
_load.Purge(_load.GetWaferPurgeCount(0), _load.GetWaferPumpDelayTime(0));
|
||||
_load.GetWaferInfo(0).NextSequenceStep++;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (_load.IsReadyForPick(ModuleName.TMRobot, 0) && !_unload.IsInPumping)
|
||||
{
|
||||
if (_tmRobot.Pick(_load.Module, 0, Hand.Blade1))
|
||||
|
@ -2156,19 +2178,25 @@ namespace SicRT.Modules
|
|||
if (!_buffer.IsAvailable)
|
||||
return;
|
||||
|
||||
//place 最后没有新的wafer需要工艺时,完成工艺后的Tray放入Buffer中
|
||||
canPalce = _tmRobot.HasTray(0) && _tmRobot.NoWafer(0);
|
||||
if (canPalce)
|
||||
// TMRobot有Tray没wafer
|
||||
var canPlaceTrayToBuffer =
|
||||
_tmRobot.HasTray(0)
|
||||
&& _tmRobot.NoWafer(0)
|
||||
&& (!_load.CheckWaferNeedProcess(0)
|
||||
|| (_load.CheckWaferNeedProcess(0)
|
||||
&& _trayRobot.HasTray(0)
|
||||
&& _trayRobot.IsReadyForPlace(ModuleName.LoadLock, 0)));
|
||||
if (canPlaceTrayToBuffer)
|
||||
{
|
||||
// TMRobot有Tray,并且Tray已消耗完,Load空,则准备将Tray返回Cassette
|
||||
if (_tmRobot.HasTrayAndExceedProcessCount(0) && _load.NoTray(0) && _load.NoWafer(0))
|
||||
return;
|
||||
|
||||
if (!_tmRobot.CheckWaferNeedProcess(0)
|
||||
&& GetWaferInJobQueue() == null
|
||||
&& !_load.CheckWaferNeedProcess(0)
|
||||
&& !_aligner.CheckWaferNeedProcess(0)
|
||||
&& !_waferRobot.CheckWaferNeedProcess(0))
|
||||
{
|
||||
// 如果Load已经准备好接收Tray,则不要将Tray放如Buffer
|
||||
if (_load.HasWafer(0) && _load.IsReadyForPlace(ModuleName.TMRobot, 0))
|
||||
return;
|
||||
|
||||
|
||||
SlotItem bufferEmptySlot = null;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
|
@ -2192,8 +2220,6 @@ namespace SicRT.Modules
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2251,6 +2277,7 @@ namespace SicRT.Modules
|
|||
continue;
|
||||
}
|
||||
|
||||
// 取Wafer准备送入PM
|
||||
if (_buffer.CheckWaferNextStepModuleNoTray(i))
|
||||
{
|
||||
if (_buffer.IsReadyForPick(ModuleName.TMRobot, i))
|
||||
|
@ -2275,9 +2302,8 @@ namespace SicRT.Modules
|
|||
|
||||
//pick 工艺开始时,如果Buffer中有Tray时,优先取Buffer中的Tray,而不是Cst中Tray
|
||||
canPick = _tmRobot.NoTray(0)
|
||||
&& _load.IsReadyForPlace(ModuleName.TMRobot, 0)
|
||||
&& _load.NoTray(0)
|
||||
//&& _load.HasWafer(0)
|
||||
&& _trayRobot.NoTray(0) && _trayRobot.CheckTaskDone()
|
||||
&& ((GetWaferInJobQueue() != null || _aligner.CheckWaferNeedProcess(0) || _waferRobot.CheckWaferNeedProcess(0)) || _load.CheckWaferNeedProcess(0));
|
||||
if (canPick)
|
||||
{
|
||||
|
@ -2301,7 +2327,7 @@ namespace SicRT.Modules
|
|||
{
|
||||
if (_buffer.HasTray(i) && _buffer.NoWafer(i))
|
||||
{
|
||||
if (_buffer.IsReadyForPick(ModuleName.TMRobot, i) && _load.IsReadyForPlace(ModuleName.TMRobot, 0))
|
||||
if (_buffer.IsReadyForPick(ModuleName.TMRobot, i) && _load.CheckWaferNeedProcess(0))
|
||||
{
|
||||
if (_tmRobot.Pick(_buffer.Module, i, Hand.Blade1))
|
||||
{
|
||||
|
|
|
@ -57,17 +57,12 @@ namespace SicRT.Scheduler
|
|||
_task == TaskType.Pump || _task == TaskType.Purge || _task == TaskType.PrepareTransfer;
|
||||
|
||||
/// <summary>
|
||||
/// 是否执行放Wafer后,TM放Tray前的Purge。
|
||||
/// 是否执行Purge。
|
||||
/// <para>如果Tray来自TMRobot,放完Wafer马上Purge。</para>
|
||||
/// <para>如果Tray来自TrayCassette,放完Tray以后统一Purge。</para>
|
||||
/// </summary>
|
||||
public bool HasPurgedAfterWaferPlaced { get; private set; }
|
||||
public bool HasPurged { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已执行组合后、TM取盘前的Purge.
|
||||
/// <para>无论Tray来自TMRobot还是TrayRobot,Group以后一定要Purge。</para>
|
||||
/// <para>Purge次数使用Sequence中的配置。</para>
|
||||
public bool HasPurgedAfterGrouped { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -157,8 +152,7 @@ namespace SicRT.Scheduler
|
|||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
HasPurgedAfterWaferPlaced = false;
|
||||
HasPurgedAfterGrouped = false;
|
||||
HasPurged = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,20 +189,20 @@ namespace SicRT.Scheduler
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wafer放好后,如果Tray将从TMRobot喂进来,执行此Purge。
|
||||
/// <para>Purge次数有Configuration\LoadLock\Purge中的相关次数决定。</para>
|
||||
/// Purge,次数由Sequence中的设定决定。
|
||||
///<para></para>
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public bool PurgeAfterWaferPlaced(params object[] args)
|
||||
public bool Purge(params object[] args)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
// 如果循环次数为0,则跳过此步骤。
|
||||
if (args is null || (args[0] is int cycle && cycle <= 0))
|
||||
{
|
||||
LogTaskStart(_task, " Purge after wafer placed was ignored since the cycle is zero");
|
||||
HasPurgedAfterGrouped = true;
|
||||
LogTaskStart(_task, " Purge was ignored since the cycle is zero");
|
||||
HasPurged = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -216,39 +210,8 @@ namespace SicRT.Scheduler
|
|||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||||
{
|
||||
_task = TaskType.Purge;
|
||||
LogTaskStart(_task, $" Purge after wafer placed");
|
||||
HasPurgedAfterWaferPlaced = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当Wafer和Tray组合完毕后,执行此Purge。
|
||||
/// <para>组合完毕后无条件支持此Purge,Purge次数有Sequence设定。</para>
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public bool PurgeAfterGrouped(params object[] args)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
// 如果循环次数为0,则跳过此步骤。
|
||||
if (args is null || (args[0] is int cycle && cycle <= 0))
|
||||
{
|
||||
LogTaskStart(_task, " Purge after Grouping was ignored since the cycle is zero");
|
||||
HasPurgedAfterGrouped = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
_entityTaskToken = _ll.InvokePurge(args);
|
||||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||||
{
|
||||
_task = TaskType.Purge;
|
||||
LogTaskStart(_task, $"Purge after grouping");
|
||||
HasPurgedAfterGrouped = true;
|
||||
LogTaskStart(_task, $"Purging");
|
||||
HasPurged = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace SicRT.Modules.Schedulers
|
|||
TransferTarget,
|
||||
|
||||
Cooling,
|
||||
CoolingAndPurge,
|
||||
WarmUp,
|
||||
|
||||
Vent,
|
||||
|
@ -530,6 +531,14 @@ namespace SicRT.Modules.Schedulers
|
|||
}
|
||||
}
|
||||
|
||||
public virtual bool CoolingAndPurge(bool coolingType, int coolingTime, int purgeLoopCount, int purgePumpDelay)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Aligning()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
|
|
|
@ -186,6 +186,24 @@ namespace SicRT.Scheduler
|
|||
}
|
||||
}
|
||||
|
||||
public override bool CoolingAndPurge(bool coolingType, int coolingTime, int purgeLoopCount, int purgePumpDelay)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
_entityTaskToken = _unL.InvokeCoolingAndPurge(coolingTime, purgeLoopCount, purgePumpDelay);
|
||||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||||
{
|
||||
_task = TaskType.CoolingAndPurge;
|
||||
_purgedBefTrayPicking = true;
|
||||
LogTaskStart(_task, $"{Module} cooling&purge {coolingTime} seconds");
|
||||
}
|
||||
|
||||
_coolingCompleted = _entityTaskToken != (int)FSM_MSG.NONE;
|
||||
|
||||
return _entityTaskToken != (int)FSM_MSG.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Cooling(bool coolingType, int coolingTime)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
|
@ -383,26 +401,26 @@ namespace SicRT.Scheduler
|
|||
}
|
||||
}
|
||||
|
||||
public int? GetWaferPurgeCount(int slot)
|
||||
public int GetWaferPurgeCount(int slot)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (!WaferManager.Instance.CheckHasWafer(Module, slot))
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
WaferInfo wafer = WaferManager.Instance.GetWafer(Module, slot);
|
||||
|
||||
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module))
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey("PurgeCount"))
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (int.TryParse(
|
||||
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["PurgeCount"].ToString(),
|
||||
|
@ -411,30 +429,30 @@ namespace SicRT.Scheduler
|
|||
return purgeCount;
|
||||
}
|
||||
|
||||
return null;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int? GetWaferPumpDelayTime(int slot)
|
||||
public int GetWaferPumpDelayTime(int slot)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (!WaferManager.Instance.CheckHasWafer(Module, slot))
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
WaferInfo wafer = WaferManager.Instance.GetWafer(Module, slot);
|
||||
|
||||
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module))
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey("PumpDelayTime"))
|
||||
return null;
|
||||
return 0;
|
||||
|
||||
if (int.TryParse(
|
||||
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["PumpDelayTime"]
|
||||
|
@ -443,7 +461,7 @@ namespace SicRT.Scheduler
|
|||
return pumpDelayTime;
|
||||
}
|
||||
|
||||
return null;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,6 +486,9 @@ namespace SicRT.Scheduler
|
|||
case TaskType.Cooling:
|
||||
ret = _unL.CheckAcked(_entityTaskToken);
|
||||
break;
|
||||
case TaskType.CoolingAndPurge:
|
||||
ret = _unL.CheckAcked(_entityTaskToken);
|
||||
break;
|
||||
case TaskType.Vent:
|
||||
ret = _unL.CheckAcked(_entityTaskToken);
|
||||
break;
|
||||
|
|
|
@ -554,11 +554,11 @@ namespace SicSimulator.Instances
|
|||
|
||||
if (isSlowVent)
|
||||
{
|
||||
if (pressure < 300)
|
||||
if (pressure < 400)
|
||||
{
|
||||
pressure += (2 * _simSpeed);
|
||||
}
|
||||
else if (pressure < 400)
|
||||
else if (pressure < 450)
|
||||
{
|
||||
pressure += (10 * _simSpeed);
|
||||
}
|
||||
|
@ -626,11 +626,11 @@ namespace SicSimulator.Instances
|
|||
|
||||
if (isSlowVent)
|
||||
{
|
||||
if (unloadPressure < 300)
|
||||
if (unloadPressure < 400)
|
||||
{
|
||||
unloadPressure += (2 * _simSpeed);
|
||||
}
|
||||
else if (unloadPressure < 400)
|
||||
else if (unloadPressure < 450)
|
||||
{
|
||||
unloadPressure += (10 * _simSpeed);
|
||||
}
|
||||
|
|
|
@ -820,7 +820,7 @@
|
|||
VerticalContentAlignment="Center"
|
||||
Background="{DynamicResource Table_BG_Title}"
|
||||
BorderBrush="{DynamicResource Table_BD}"
|
||||
Content="ColingTime(s)"
|
||||
Content="CoolingTime(s)"
|
||||
FontFamily="Arial"
|
||||
FontSize="12" />
|
||||
|
||||
|
|
Loading…
Reference in New Issue