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 时间/次数/膜厚限制 if (wafer.WaferType == WaferType.SD) { var maintenanceItemCarrierUseFreq = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.SDCarrierUseFreq.ToString()); var maintenanceItemWaferThickness = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.SDWaferThickness.ToString()); var maintenanceItemWaferUserTime = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.SDWaferUserTime.ToString()); if (maintenanceItemCarrierUseFreq.StartValue > 0 && wafer.UseCount > maintenanceItemCarrierUseFreq.StartValue && wafer.UseCount < maintenanceItemCarrierUseFreq.LimitValue) { if (maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemCarrierUseFreq, false, wafer.UseCount.ToString(), maintenanceItemCarrierUseFreq.StartValue.ToString(), maintenanceItemCarrierUseFreq.LimitValue.ToString()); Singleton.Instance.SDWaferTypeUseCountWarning.Set(msg); } } if (maintenanceItemWaferUserTime.StartValue > 0 && wafer.UseTime > maintenanceItemWaferUserTime.StartValue && wafer.UseTime < maintenanceItemWaferUserTime.LimitValue) { if (maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferUserTime, true, currentValue, minValue, maxValue); Singleton.Instance.SDWaferTypeUseTimeWarning.Set(msg); } } if (maintenanceItemWaferThickness.StartValue > 0 && wafer.UseThick > maintenanceItemWaferThickness.StartValue && wafer.UseThick < maintenanceItemWaferThickness.LimitValue) { if (maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferThickness, false, wafer.UseThick.ToString(), maintenanceItemWaferThickness.StartValue.ToString(), maintenanceItemWaferThickness.LimitValue.ToString()); Singleton.Instance.SDWaferTypeThicknessWarning.Set(msg); } } if (maintenanceItemCarrierUseFreq.StartValue > 0 && wafer.UseCount >= maintenanceItemCarrierUseFreq.LimitValue) { if (maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemCarrierUseFreq, false, wafer.UseCount.ToString(), maintenanceItemCarrierUseFreq.StartValue.ToString(), maintenanceItemCarrierUseFreq.LimitValue.ToString()); Singleton.Instance.SDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemCarrierUseFreq, true); if (string.IsNullOrEmpty(maintenanceItemCarrierUseFreq.AssociationProcessRecipeName)) { Singleton.Instance.SDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.SDWaferTypeUseCountAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemCarrierUseFreq.AssociationProcessRecipeName, RecipeExecEntryEnum.SDWaferRangeTrigger); LOG.Info($"{msg} Trigger {maintenanceItemCarrierUseFreq.AssociationProcessRecipeName}"); return Result.FAIL; } } if (maintenanceItemWaferUserTime.StartValue > 0 && wafer.UseTime >= maintenanceItemWaferUserTime.LimitValue) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferUserTime, true, currentValue, minValue, maxValue); if (maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { Singleton.Instance.SDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { if (string.IsNullOrEmpty(maintenanceItemWaferUserTime.AssociationProcessRecipeName)) { Singleton.Instance.SDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.SDWaferTypeUseTimeAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemWaferUserTime.AssociationProcessRecipeName, RecipeExecEntryEnum.SDWaferRangeTrigger); LOG.Info($"{msg} Trigger {maintenanceItemWaferUserTime.AssociationProcessRecipeName}"); return Result.FAIL; } } if (maintenanceItemWaferThickness.StartValue > 0 && wafer.UseThick >= maintenanceItemWaferThickness.LimitValue) { if (maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferThickness, false, wafer.UseThick.ToString(), maintenanceItemWaferThickness.StartValue.ToString(), maintenanceItemWaferThickness.LimitValue.ToString()); Singleton.Instance.SDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferThickness, true); if (string.IsNullOrEmpty(maintenanceItemWaferThickness.AssociationProcessRecipeName)) { Singleton.Instance.SDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.SDWaferTypeThicknessAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemWaferThickness.AssociationProcessRecipeName, RecipeExecEntryEnum.SDWaferRangeTrigger); LOG.Info($"{msg} Trigger {maintenanceItemWaferThickness.AssociationProcessRecipeName}"); return Result.FAIL; } } } #endregion #region ED if (wafer.WaferType == WaferType.ED) { var maintenanceItemCarrierUseFreq = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.FDCarrierUseFreq.ToString()); var maintenanceItemWaferThickness = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.FDWaferThickness.ToString()); var maintenanceItemWaferUserTime = ScheduleMaintenanceDataManager.Instance.GetItem(MaintenanceItemEnum.FDWaferUserTime.ToString()); if (maintenanceItemCarrierUseFreq.StartValue > 0 && wafer.UseCount > maintenanceItemCarrierUseFreq.StartValue && wafer.UseCount < maintenanceItemCarrierUseFreq.LimitValue) { if (maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemCarrierUseFreq, false, wafer.UseCount.ToString(), maintenanceItemCarrierUseFreq.StartValue.ToString(), maintenanceItemCarrierUseFreq.LimitValue.ToString()); Singleton.Instance.FDWaferTypeUseCountWarning.Set(msg); } } if (maintenanceItemWaferUserTime.StartValue > 0 && wafer.UseTime > maintenanceItemWaferUserTime.StartValue && wafer.UseTime < maintenanceItemWaferUserTime.LimitValue) { if (maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferUserTime, true, currentValue, minValue, maxValue); Singleton.Instance.FDWaferTypeUseTimeWarning.Set(msg); } } if (maintenanceItemWaferThickness.StartValue > 0 && wafer.UseThick > maintenanceItemWaferThickness.StartValue && wafer.UseThick < maintenanceItemWaferThickness.LimitValue) { if (maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString() || maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferThickness, false, wafer.UseThick.ToString(), maintenanceItemWaferThickness.StartValue.ToString(), maintenanceItemWaferThickness.LimitValue.ToString()); Singleton.Instance.FDWaferTypeThicknessWarning.Set(msg); } } if (maintenanceItemCarrierUseFreq.StartValue > 0 && wafer.UseCount >= maintenanceItemCarrierUseFreq.LimitValue) { if (maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemCarrierUseFreq, false, wafer.UseCount.ToString(), maintenanceItemCarrierUseFreq.StartValue.ToString(), maintenanceItemCarrierUseFreq.LimitValue.ToString()); Singleton.Instance.FDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemCarrierUseFreq.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemCarrierUseFreq); if (string.IsNullOrEmpty(maintenanceItemCarrierUseFreq.AssociationProcessRecipeName)) { Singleton.Instance.FDWaferTypeUseCountAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.FDWaferTypeUseCountAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemCarrierUseFreq.AssociationProcessRecipeName, RecipeExecEntryEnum.EDWaferRangeTrigger); LOG.Info($"{msg} Trigger {maintenanceItemCarrierUseFreq.AssociationProcessRecipeName}"); return Result.FAIL; } } if (maintenanceItemWaferUserTime.StartValue > 0 && wafer.UseTime >= maintenanceItemWaferUserTime.LimitValue) { var currentValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.CurrentValue.ToString()); var minValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.StartValue.ToString()); var maxValue = DateTimeUtil.SecondToHHmmss(maintenanceItemWaferUserTime.LimitValue.ToString()); var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferUserTime, true, currentValue, minValue, maxValue); if (maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { Singleton.Instance.FDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemWaferUserTime.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { if (string.IsNullOrEmpty(maintenanceItemWaferUserTime.AssociationProcessRecipeName)) { Singleton.Instance.FDWaferTypeUseTimeAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.FDWaferTypeUseTimeAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemWaferUserTime.AssociationProcessRecipeName, RecipeExecEntryEnum.EDWaferRangeTrigger); LOG.Info($"{msg} Trigger {maintenanceItemWaferUserTime.AssociationProcessRecipeName}"); return Result.FAIL; } } if (maintenanceItemWaferThickness.StartValue > 0 && wafer.UseThick >= maintenanceItemWaferThickness.LimitValue) { if (maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.AlarmReport.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferThickness, false, wafer.UseThick.ToString(), maintenanceItemWaferThickness.StartValue.ToString(), maintenanceItemWaferThickness.LimitValue.ToString()); Singleton.Instance.FDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } else if (maintenanceItemWaferThickness.MaintenanceProcessing == MaintenanceProcessingCommandEnum.JobAutoStart.ToString()) { var msg = pm.GetAlarmWarningMsg(maintenanceItemWaferThickness, true); if (string.IsNullOrEmpty(maintenanceItemWaferThickness.AssociationProcessRecipeName)) { Singleton.Instance.FDWaferTypeThicknessAlarm.Set(msg); return Result.FAIL; } Singleton.Instance.FDWaferTypeThicknessAlarm.Set(msg); pm.TriggerJobAutoStart(maintenanceItemWaferThickness.AssociationProcessRecipeName, RecipeExecEntryEnum.EDWaferRangeTrigger); LOG.Info($"{msg} Trigger {maintenanceItemWaferThickness.AssociationProcessRecipeName}"); return Result.FAIL; } } } #endregion } #endregion } } pm.CheckBoatRecipeThicknessMoreThan( out var boatRecipeThicknessIsPause); if (boatRecipeThicknessIsPause) return Result.FAIL; 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() { } } }