using Aitex.Core.RT.Routine; using MECF.Framework.Common.Equipment; using System; using Aitex.Core.RT.SCCore; using FurnaceRT.Equipments.PMs.Routines; using System.Collections.Generic; using FurnaceRT.Equipments.Systems; using Aitex.Core.Util; using MECF.Framework.Common.SubstrateTrackings; using System.Linq; using Aitex.Core.Common; using MECF.Framework.Common.CommonData.EnumData; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Utilities; using Aitex.Core.RT.Log; namespace FurnaceRT.Equipments.PMs.RecipeExecutions { public class PreProcess : PMBaseRoutine, IRoutine { public enum Routine { ToReadyProcessState, Pump, PinDown, } private string _recipeName; private int _liftTimeout; private bool _isProcessRecipe; public PreProcess(ModuleName module, PMModule pm) : base(module, pm) { Module = module.ToString(); Name = "PreProcess"; } public void Init(string recipeName, bool isProcessRecipe = true) { _recipeName = recipeName; _isProcessRecipe = isProcessRecipe; } public override Result Start(params object[] objs) { RecipeHead recipeHead; List recipeSteps; Dictionary> abortRecipe; Dictionary abortRecipeName; Dictionary> subRecipe; Dictionary subRecipeName; string reason = string.Empty; if (_isProcessRecipe) { if (!RecipeParser.Parse(_recipeName, Module, out recipeHead, out recipeSteps, out reason, "Process")) { PMModule.PreprocessStartFailedWarning.Set($"Load process recipe {_recipeName} failed, {reason}"); return Result.FAIL; } #region MyRegion var isScheduleMaintenance = SC.ContainsItem("System.EnableScheduleMaintenance") && SC.GetValue("System.EnableScheduleMaintenance"); if (isScheduleMaintenance) { var pm = (Singleton.Instance.Modules[ModuleName.PM1] as PMModule); pm.GetAllDBRecord(); var wafers = WaferManager.Instance.GetWafers(ModuleName.PM1); if (wafers != null && wafers.Count() > 0) { foreach (var wafer in wafers) { if (wafer == null || wafer.IsEmpty || (wafer.WaferType != WaferType.SD && wafer.WaferType != WaferType.ED)) continue; #region New if (isScheduleMaintenance) { #region SD Dummy 时间/次数/膜厚限制 var maintenanceItemSDCarrierUseFreq = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.SDCarrierUseFreq.ToString()); var maintenanceItemSDWaferThickness = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.SDWaferThickness.ToString()); var maintenanceItemSDWaferUserTime = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.SDWaferUserTime.ToString()); if (wafer.WaferType == WaferType.SD && maintenanceItemSDCarrierUseFreq.StartValue > 0 && wafer.UseCount > maintenanceItemSDCarrierUseFreq.StartValue && wafer.UseCount < maintenanceItemSDCarrierUseFreq.LimitValue) { if (maintenanceItemSDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemSDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemSDCarrierUseFreq); Singleton.Instance.SDWaferTypeUseCountWarning.Set(msg); } } if (wafer.WaferType == WaferType.SD && maintenanceItemSDWaferUserTime.StartValue > 0 && wafer.UseTime > maintenanceItemSDWaferUserTime.StartValue && wafer.UseTime < maintenanceItemSDWaferUserTime.LimitValue) { if (maintenanceItemSDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemSDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemSDWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemSDWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemSDWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemSDWaferUserTime, true, currentValue, minValue, maxValue); Singleton.Instance.SDWaferTypeUseTimeWarning.Set(msg); } } if (wafer.WaferType == WaferType.SD && maintenanceItemSDWaferThickness.StartValue > 0 && wafer.UseThick > maintenanceItemSDWaferThickness.StartValue && wafer.UseThick < maintenanceItemSDWaferThickness.LimitValue) { if (maintenanceItemSDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemSDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString() ) { var msg = pm.GetAlarmWarningMsg(maintenanceItemSDWaferThickness); Singleton.Instance.SDWaferTypeThicknessWarning.Set(msg); } } if (wafer.WaferType == WaferType.SD && maintenanceItemSDCarrierUseFreq.StartValue > 0 && wafer.UseCount >= maintenanceItemSDCarrierUseFreq.LimitValue) { if (maintenanceItemSDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemSDCarrierUseFreq); Singleton.Instance.SDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemSDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemSDCarrierUseFreq, true); if (string.IsNullOrEmpty(maintenanceItemSDCarrierUseFreq.AssociationProcessRecipeName)) { Singleton.Instance.SDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.SDWaferTypeUseCountAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemSDCarrierUseFreq.AssociationProcessRecipeName); LOG.Info($"{msg} Trigger {maintenanceItemSDCarrierUseFreq.AssociationProcessRecipeName}"); return Result.FAIL; } } if (wafer.WaferType == WaferType.SD && maintenanceItemSDWaferUserTime.StartValue > 0 && wafer.UseTime >= maintenanceItemSDWaferUserTime.LimitValue) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemSDWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemSDWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemSDWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemSDWaferUserTime, true, currentValue, minValue, maxValue); if (maintenanceItemSDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { Singleton.Instance.SDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemSDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { if (string.IsNullOrEmpty(maintenanceItemSDWaferUserTime.AssociationProcessRecipeName)) { Singleton.Instance.SDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.SDWaferTypeUseTimeAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemSDWaferUserTime.AssociationProcessRecipeName); LOG.Info($"{msg} Trigger {maintenanceItemSDWaferUserTime.AssociationProcessRecipeName}"); return Result.FAIL; } } if (wafer.WaferType == WaferType.SD && maintenanceItemSDWaferThickness.StartValue > 0 && wafer.UseThick >= maintenanceItemSDWaferThickness.LimitValue) { if (maintenanceItemSDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemSDWaferThickness); Singleton.Instance.SDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemSDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemSDWaferThickness, true); if (string.IsNullOrEmpty(maintenanceItemSDWaferThickness.AssociationProcessRecipeName)) { Singleton.Instance.SDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.SDWaferTypeThicknessAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemSDWaferThickness.AssociationProcessRecipeName); LOG.Info($"{msg} Trigger {maintenanceItemSDWaferThickness.AssociationProcessRecipeName}"); return Result.FAIL; } } #endregion #region ED var maintenanceItemEDCarrierUseFreq = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.FDCarrierUseFreq.ToString()); var maintenanceItemEDWaferThickness = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.FDWaferThickness.ToString()); var maintenanceItemEDWaferUserTime = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.FDWaferUserTime.ToString()); if (wafer.WaferType == WaferType.ED && maintenanceItemEDCarrierUseFreq.StartValue > 0 && wafer.UseCount > maintenanceItemEDCarrierUseFreq.StartValue && wafer.UseCount < maintenanceItemEDCarrierUseFreq.LimitValue) { if (maintenanceItemEDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()|| maintenanceItemEDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString() ) { var msg = pm.GetAlarmWarningMsg(maintenanceItemEDCarrierUseFreq); Singleton.Instance.FDWaferTypeUseCountWarning.Set(msg); } } if (wafer.WaferType == WaferType.ED && maintenanceItemEDWaferUserTime.StartValue > 0 && wafer.UseTime > maintenanceItemEDWaferUserTime.StartValue && wafer.UseTime < maintenanceItemEDWaferUserTime.LimitValue) { if (maintenanceItemEDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()|| maintenanceItemEDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString() ) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemEDWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemEDWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemEDWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemEDWaferUserTime, true, currentValue, minValue, maxValue); Singleton.Instance.FDWaferTypeUseTimeWarning.Set(msg); } } if (wafer.WaferType == WaferType.ED && maintenanceItemEDWaferThickness.StartValue > 0 && wafer.UseThick > maintenanceItemEDWaferThickness.StartValue && wafer.UseThick < maintenanceItemEDWaferThickness.LimitValue) { if (maintenanceItemEDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()|| maintenanceItemEDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemEDWaferThickness); Singleton.Instance.FDWaferTypeThicknessWarning.Set(msg); } } if (wafer.WaferType == WaferType.ED && maintenanceItemEDCarrierUseFreq.StartValue > 0 && wafer.UseCount >= maintenanceItemEDCarrierUseFreq.LimitValue) { if (maintenanceItemEDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemEDCarrierUseFreq); Singleton.Instance.FDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemEDCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemEDCarrierUseFreq); if (string.IsNullOrEmpty(maintenanceItemEDCarrierUseFreq.AssociationProcessRecipeName)) { Singleton.Instance.FDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.FDWaferTypeUseCountAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemEDCarrierUseFreq.AssociationProcessRecipeName); LOG.Info($"{msg} Trigger {maintenanceItemEDCarrierUseFreq.AssociationProcessRecipeName}"); return Result.FAIL; } } if (wafer.WaferType == WaferType.ED && maintenanceItemEDWaferUserTime.StartValue > 0 && wafer.UseTime >= maintenanceItemEDWaferUserTime.LimitValue) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemEDWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemEDWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemEDWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemEDWaferUserTime, true, currentValue, minValue, maxValue); if (maintenanceItemEDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { Singleton.Instance.FDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemEDWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { if (string.IsNullOrEmpty(maintenanceItemEDWaferUserTime.AssociationProcessRecipeName)) { Singleton.Instance.FDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.FDWaferTypeUseTimeAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemEDWaferUserTime.AssociationProcessRecipeName); LOG.Info($"{msg} Trigger {maintenanceItemEDWaferUserTime.AssociationProcessRecipeName}"); return Result.FAIL; } } if (wafer.WaferType == WaferType.ED && maintenanceItemEDWaferThickness.StartValue > 0 && wafer.UseThick >= maintenanceItemEDWaferThickness.LimitValue) { if (maintenanceItemEDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemEDWaferThickness); Singleton.Instance.FDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemEDWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemEDWaferThickness, true); if (string.IsNullOrEmpty(maintenanceItemEDWaferThickness.AssociationProcessRecipeName)) { Singleton.Instance.FDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.FDWaferTypeThicknessAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemEDWaferThickness.AssociationProcessRecipeName); LOG.Info($"{msg} Trigger {maintenanceItemEDWaferThickness.AssociationProcessRecipeName}"); return Result.FAIL; } } #endregion } #endregion } } pm.CheckRecipeThicknessMoreThan(_recipeName, out var isPause); if (isPause) return Result.FAIL; pm.CheckRecipeExecuteFreqMoreThan(_recipeName, out var isPause1); if (isPause1) return Result.FAIL; foreach (var item in recipeSteps) { pm.CheckRecipeStepFreqMoreThan(item.StepName, out var isPause2); if (isPause2) return Result.FAIL; pm.CheckRecipeStepTimeMoreThan(item.StepName, out var isPause3); if (isPause3) return Result.FAIL; pm.CheckRecipeStepGroupThicknessMoreThan(item.StepName, out var isPause4); if (isPause4) return Result.FAIL; } } #endregion PMModule.RecipeRunningInfo.MainRecipeName = _recipeName; PMModule.RecipeRunningInfo.Head = recipeHead; PMModule.RecipeRunningInfo.RecipeStepList = recipeSteps; PMModule.RecipeRunningInfo.ExecRecipeType = recipeSteps.Count > 0 ? recipeSteps[0].RecipeType : string.Empty; } Reset(); Notify($"Start"); return Result.RUN; } public override Result Monitor() { try { //ToReadyProcessState((int)Routine.ToReadyProcessState, PMModule, _liftTimeout); //ExecuteRoutine((int)Routine.Pump, _pumpRoutine); //MovePinDown((int)Routine.PinDown, PMModule, _liftTimeout); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } return Result.DONE; } public override void Abort() { } } }