|
@@ -120,6 +120,18 @@ namespace CyberX8_RT.Modules.Metal
|
|
|
/// 当前完成recipe次数
|
|
|
/// </summary>
|
|
|
private int _currentCycleTimes;
|
|
|
+ /// <summary>
|
|
|
+ /// 当前recipe是否完成
|
|
|
+ /// </summary>
|
|
|
+ private bool _isCurrentReceipeComplete;
|
|
|
+ /// <summary>
|
|
|
+ /// 当前wafershuttle开始浸泡时间
|
|
|
+ /// </summary>
|
|
|
+ private DateTime _currentWaferShuttleStartSoakTime;
|
|
|
+ /// <summary>
|
|
|
+ /// Wafershuttle最大浸泡时间
|
|
|
+ /// </summary>
|
|
|
+ private int _waferShuttleSoakMaxTime;
|
|
|
#endregion
|
|
|
|
|
|
#region 属性
|
|
@@ -250,7 +262,10 @@ namespace CyberX8_RT.Modules.Metal
|
|
|
_metalItem = MetalItemManager.Instance.GetMetalItem(Module.ToString());
|
|
|
|
|
|
_reservoirName = ReservoirItemManager.Instance.GetReservoirByMetal(Module.ToString());
|
|
|
- _reservoirDevice = DEVICE.GetDevice<StandardHotReservoirDevice>($"{_reservoirName}");
|
|
|
+ _reservoirDevice = DEVICE.GetDevice<StandardHotReservoirDevice>($"{_reservoirName}");
|
|
|
+
|
|
|
+ _isCurrentReceipeComplete = false;
|
|
|
+ _waferShuttleSoakMaxTime = SC.GetValue<int>($"Metal.WaferShuttleSoakMaxTime");
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 初始化Routine
|
|
@@ -319,6 +334,7 @@ namespace CyberX8_RT.Modules.Metal
|
|
|
Transition(MetalState.Idle, MetalMsg.RunRecipe, RunRecipe, MetalState.RunReciping);
|
|
|
Transition(MetalState.WaitForRunRecipe, MetalMsg.RunRecipe, RunRecipe, MetalState.RunReciping);
|
|
|
Transition(MetalState.RunReciping, FSM_MSG.TIMER, RunRecipeMonitor, MetalState.Idle);
|
|
|
+ Transition(MetalState.Idle, FSM_MSG.TIMER, MetalCompleteSoakTimeMonitor, MetalState.Idle);
|
|
|
Transition(MetalState.RunReciping, MetalMsg.Abort, AbortRecipe, MetalState.Abort);
|
|
|
|
|
|
//Current Short Test
|
|
@@ -395,6 +411,32 @@ namespace CyberX8_RT.Modules.Metal
|
|
|
DATA.Subscribe($"{Module}.AnodeBWafers.WarningLimit", () => SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersWarningLimit"), SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
DATA.Subscribe($"{Module}.AnodeBWafers.FaultLimit", () => SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersFaultLimit"), SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
}
|
|
|
+
|
|
|
+ /// Metal完成recipe后监控wafershuttle浸泡时间
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="param"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private bool MetalCompleteSoakTimeMonitor(object[] param)
|
|
|
+ {
|
|
|
+ if (WaferHolderInfo != null)
|
|
|
+ {
|
|
|
+ double sockSeconds = (DateTime.Now - _currentWaferShuttleStartSoakTime).TotalSeconds;
|
|
|
+ if (_isCurrentReceipeComplete && sockSeconds > _waferShuttleSoakMaxTime * 60)
|
|
|
+ {
|
|
|
+ if (!AlarmListManager.Instance.IsContainDataWarn(Module.ToString(), "MetalSockTime"))
|
|
|
+ {
|
|
|
+ AlarmListManager.Instance.AddWarn(Module.ToString(),
|
|
|
+ $"MetalSockTime", $"Current waferShuttle:{WaferHolderInfo.Id} sock time is over waferShuttleSoakMaxTime:{_waferShuttleSoakMaxTime} minutes");
|
|
|
+ LOG.WriteLog(eEvent.WARN_METAL, Module.ToString(), $"Current waferShuttle:{WaferHolderInfo.Id} sock time is over waferShuttleSoakMaxTime:{_waferShuttleSoakMaxTime} minutes");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _isCurrentReceipeComplete = false; //wafershuttle拿走后重置当前recipe是否完成变量
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
/// <summary>
|
|
|
/// 进入错误状态
|
|
|
/// </summary>
|
|
@@ -645,6 +687,8 @@ namespace CyberX8_RT.Modules.Metal
|
|
|
resDevice.SetExportCMMUsage();
|
|
|
}
|
|
|
WaferHolderInfo.LastMetalRecipeCompleteTime = DateTime.Now;
|
|
|
+ _isCurrentReceipeComplete = true;
|
|
|
+ _currentWaferShuttleStartSoakTime = DateTime.Now;
|
|
|
}
|
|
|
_runrecipeElapsedTime = 0;
|
|
|
|