using System; using System.Collections.Generic; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Job; using Aitex.Core.RT.SCCore; using Aitex.RT.Properties; using Aitex.Triton160.Common; using Aitex.Core.RT.Log; using Aitex.Core.RT.Event; using Aitex.Core.Util; using Aitex.Triton160.RT.Device; using Aitex.Triton160.RT.Module; using Aitex.Platform; using Aitex.Core.RT.Routine; using Aitex.Core.RT.RecipeCenter; using Aitex.Core.RT.Device.Unit; using System.Drawing; namespace Aitex.Triton160.RT.Routine.Process { public class PreProcess : CommonRoutine { public enum Routine { DelayForTest, CheckDoor, CheckDryPump, CloseAllVavle, OpenPumpingValve, CheckVAC, SetRfMatchMode, SetElectrodeTemp, End, } //Recipe public string CurrentRecipeBaseName { get; private set; } public string CurrentRecipeRunningName { get; private set; } public string CurrentRecipeContent { get; private set; } public string CurrentLotName { get; set; } public string CurrentJobName { get; set; } public string CurrentUserId { get; set; } public List CurrentRecipeStepList { get; set; } public RecipeHead CurrentRecipeHead { get; set; } private double BasePressure { get { if (CurrentRecipeHead!= null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.BasePressure)) { double setpoint = Convert.ToDouble(CurrentRecipeHead.BasePressure); if (setpoint > 0 && setpoint < 750000) return setpoint; } } return SC.GetValue(SCName.System_PumpBasePressure); } } private double PumpDownLimit { get { if (CurrentRecipeHead != null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.PumpDownLimit)) { double setpoint = Convert.ToDouble(CurrentRecipeHead.PumpDownLimit); if (setpoint > 0 && setpoint < 600) return setpoint; } } return SC.GetValue(SCName.System_PumpTimeLimit); } } //Recipe //private int _rfMatchModeDuringProcess; public PreProcess(string module, string name) { Module = module; Name = name; Display = "Pre Process"; } public bool Initialize() { InitCommon(); return true; } public void Terminate() { } public Result LoadRecipe(params object[] param) { CurrentRecipeBaseName = (string)param[0]; CurrentRecipeContent = (string)param[1]; CurrentLotName = (string) param[2]; CurrentJobName = param.Length > 3 ? (string) param[3] : ""; CurrentUserId = param.Length > 4 ? (string)param[4] : ""; CurrentRecipeRunningName = string.Format("{0}-{1}", DateTime.Now.ToString("yyyyMMddHHmmss"), CurrentRecipeBaseName); List recipeSteps = null; RecipeHead recipeHead = null; if (!Recipe.Parse(CurrentRecipeContent, out recipeHead, out recipeSteps)) { Stop(string.Format(Resources.PreProcess_LoadRecipe_LoadRecipe0Failed, CurrentRecipeRunningName)); return Result.FAIL; } CurrentRecipeStepList = recipeSteps; CurrentRecipeHead = recipeHead; return Result.DONE; } public Result Start(params object[] param) { try { if (BasePressure <=0 || BasePressure >= 760000) { Stop(string.Format(Resources.PreProcess_Start_BasePressure0NotValid, BasePressure)); return Result.FAIL; } if (PumpDownLimit <= 0.01 || PumpDownLimit >= 600) { Stop(string.Format(Resources.PreProcess_Start_PumpDownLimit0NotValid, PumpDownLimit)); return Result.FAIL; } if (DeviceModel.StatisticsPumpOnTime != null && DeviceModel.StatisticsPumpOnTime.IsPMNeeded && DeviceModel.StatisticsPumpOnTime.EnableAlarm) { Stop(string.Format(Resources.PreProcess_Start_CanNotRunRecipeBecausePumpPMNeeded)); return Result.FAIL; } if (DeviceModel.StatisticsRfOnTime != null && DeviceModel.StatisticsRfOnTime.IsPMNeeded && DeviceModel.StatisticsRfOnTime.EnableAlarm) { Stop(string.Format(Resources.PreProcess_Start_CanNotRunRecipeBecauseRFPMNeeded)); return Result.FAIL; } //每个Process Run 都对应唯一的Guid JobInfo job = JobManager.Instance.StartJob(); job.RecipeBaseName = CurrentRecipeBaseName; job.RecipeRunningName = CurrentRecipeRunningName; job.JobResult = JobStatus.Preprocessing; job.ProcessModuleName = ModuleName.System.ToString(); job.ProcessStartTime = DateTime.Now; job.LotId = CurrentLotName; Singleton.Instance.CurrentRunningJob = job; Reset(); UpdateSCValue(); //_rfMatchModeDuringProcess = SC.GetValue(SCName.System_RfMatchModeDuringProcess ); //if (_rfMatchModeDuringProcess == (int)TritonRfMatchMode.Auto) //{ // EV.PostMessage(Module, EventEnum.ProcessRFMatchModeSetToAuto); //} //依据工艺部门的要求,工艺处理开始时间从Recipe Header开始运行就进行计时 Singleton.Instance.BeginNewProcess(job); RecipeFileManager.Instance.SaveRecipeHistory(ModuleName.System.ToString(), CurrentRecipeRunningName, CurrentRecipeContent); } catch (Exception ex) { LOG.Write(ex, String.Format("Preprocess Start has exception")); throw (ex); } return Result.RUN; } public Result Monitor() { try { //检查Door CheckDoor((int)Routine.CheckDoor, Resources.PumpDownRoutine_Monitor_CheckDoorStatus, Notify, Stop); //检查 Dry Pump CheckDryPump((int)Routine.CheckDryPump, Resources.PumpDownRoutine_Monitor_CheckPumpStatus, Notify, Stop); //关闭所有阀门 CloseAllValve((int)Routine.CloseAllVavle, Resources.PumpDownRoutine_Monitor_CloseAllTheValves, 10, Notify, Stop); //打开 OpenPumpingValve((int)Routine.OpenPumpingValve, Resources.PumpDownRoutine_Monitor_OpenPumpingValve, 10, Notify, Stop); //检查VAC CheckVAC((int)Routine.CheckVAC, Resources.PreProcess_Monitor_CheckChamberPressure, BasePressure, (int)PumpDownLimit, Notify, Stop); //设置RF Match Mode //SetRfMatchMode((int)Routine.SetRfMatchMode, string.Format(Resources.PreProcess_Monitor_SetRFMatchMode, _rfMatchModeDuringProcess==(int)TritonRfMatchMode.Manual ? "Manual" : "Auto"), _rfMatchModeDuringProcess); End((int)Routine.End, Resources.PreProcess_Monitor_PreprocessFinished, Notify, Stop); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } catch (Exception ex) { LOG.Write(ex, String.Format("Preprocess Monitor has exception")); throw (ex); } return Result.DONE; } public void Exit() { //string reason; //update processing end time // Singleton.Instance.EndRecipeProcess(Singleton.Instance.CurrentRecipeRunGuid, SusceptorStatus.Processed); //恢复特殊Recipe的运行标志 } private new void Notify(string message) { Singleton.Instance.AddRecord(Singleton.Instance.CurrentRunningJob.RecipeRunId, CarrierDataType.PreProcessStep, "", "Prepare running recipe:" + message); EV.PostMessage(Module, EventEnum.PreProcessInfo, Module, message); } private new void Stop(string message) { //ProcessRecorder.AddRecord(Reactor.CurrentRecipeRunGuid, CarrierDataType.PreProcessErrorEnd, "", "工艺程序前准备:异常结束," + failReason); if (Singleton.Instance.CurrentRunningJob != null) Singleton.Instance.AddRecord(Singleton.Instance.CurrentRunningJob.RecipeRunId, CarrierDataType.PreProcessErrorEnd, "", "Prepare running recipe:stopped for exception," + message); EV.PostMessage(Module, EventEnum.PrepareProcessErr, Module, message); EV.PostPopDialogMessage(EventLevel.Alarm, string.Format("{0} running failed", Module), string.Format(Resources.PreProcess_Stop_Recipe0RNFailedReason1, CurrentRecipeRunningName, message)); } public new Result Abort() { base.Abort(); string reason; IoValve valve = DeviceModel.ValveChamberPumping; if (valve != null && !valve.TurnValve(false, out reason)) { LOG.Write(string.Format("can not close valve {0}, {1}", valve.Name, reason)); } return Result.DONE; } } }