Browse Source

Wafer loadlock delay function.

sangwq 1 year ago
parent
commit
c3ef1d5a6e

+ 23 - 11
Venus/Framework/Common/Jobs/SequenceInfo.cs

@@ -42,12 +42,17 @@ namespace MECF.Framework.Common.Jobs
 
         [DataMember]
         public SequenceLLInOutPath LLInOutPath { get; set; }
+
+        [DataMember]
+
+        public int LLDelayTime { get; set; }
  
         public SequenceInfo(string name)
         {
             Name = name;
             InnerId = Guid.NewGuid();
             LLInOutPath =  SequenceLLInOutPath.DInDOut;
+            LLDelayTime = 0;
             Steps = new List<SequenceStepInfo>();
         }
 
@@ -167,31 +172,38 @@ namespace MECF.Framework.Common.Jobs
 
                     // Loadlock Single In Single Out property check
                     var llSteps = info.Steps.FindAll(item => item.StepModules.Contains(ModuleName.LLA) || item.StepModules.Contains(ModuleName.LLB));
-                    if ((llSteps.Count == 2) && 
-                        (llSteps[0].StepModules.Count == 1 && llSteps[1].StepModules.Count == 1))
+                    if (llSteps.Count == 2)
                     {
-                        if (llSteps[0].StepModules[0] != llSteps[1].StepModules[0])
+                        if (llSteps[0].StepModules.Count == 1 && llSteps[1].StepModules.Count == 1)
                         {
-                            info.LLInOutPath = llSteps[0].StepModules[0] == ModuleName.LLA ? SequenceLLInOutPath.AInBOut : SequenceLLInOutPath.BInAOut;
+                            if (llSteps[0].StepModules[0] != llSteps[1].StepModules[0])
+                            {
+                                info.LLInOutPath = llSteps[0].StepModules[0] == ModuleName.LLA ? SequenceLLInOutPath.AInBOut : SequenceLLInOutPath.BInAOut;
+                            }
+                            else
+                            {
+                                info.LLInOutPath = llSteps[0].StepModules[0] == ModuleName.LLA ? SequenceLLInOutPath.AInAOut : SequenceLLInOutPath.BInBOut;
+                            }
                         }
-                        else
+
+                        if(llSteps[1].StepParameter.ContainsKey("LLDelayTime"))
                         {
-                            info.LLInOutPath = llSteps[0].StepModules[0] == ModuleName.LLA ? SequenceLLInOutPath.AInAOut : SequenceLLInOutPath.BInBOut;
+                            if(int.TryParse((string)llSteps[1].StepParameter["LLDelayTime"], out int delay))
+                            {
+                                info.LLDelayTime = delay;
+                            }
                         }
                     }
                 }
+
                 catch (Exception ex)
                 {
                     LOG.WriteExeption(ex);
                     return null;
                 }
-                return info;
-            }
-            else
-            {
-                return null;
             }
 
+            return info;
         }
     }
 }

+ 3 - 0
Venus/Venus_RT/Devices/EPD/Data/EPDSocketClient.cs

@@ -387,6 +387,9 @@ namespace EPD.Data
 
         public void Start(byte channel, string name)
         {
+            if (string.IsNullOrEmpty(name))
+                return;
+
             var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.Start, length = 256 };
 
             var data = new byte[PacketHeader.Size + 256];

+ 1 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerPM.cs

@@ -478,6 +478,7 @@ namespace Venus_RT.Scheduler
             Recipe recipe = Recipe.Load(recipeContent);
             if (recipe == null)
             {
+                LOG.Write(eEvent.WARN_ROUTER, Module, $"Loading clean recipe: {path} failed");
                 return false;
             }
 

+ 207 - 43
Venus/Venus_RT/Modules/SystemDispatcher.cs

@@ -277,12 +277,12 @@ namespace Venus_RT.Modules
             return RState.Running;
         }
 
-        public virtual void WaferArrived(WaferTask wafer)
+        public virtual void WaferArrived(WaferTask wafer, int slot)
         {
 
         }
 
-        public virtual void WaferLeaved(WaferTask wafer)
+        public virtual void WaferLeaved(WaferTask wafer, int slot)
         {
 
         }
@@ -290,13 +290,24 @@ namespace Venus_RT.Modules
 
     public class PMTask : ModuleTask
     {
+        enum CleanType
+        {
+            IdleClean,
+            PreJobClean,
+            PostJobClean,
+            WTWClean,
+        }
+
         private WaferTask _wafer;
         private SchedulerPM _pmScheduler => Scheduler as SchedulerPM;
-        public ModuleStatus JobCleanStatus { get; set; }
+
+        private string _preJobCleanRecipe;
+        private string _postJobCleanRecipe;
+        private string _wtwCleanRecipe;
+        private Queue<CleanType> _pendingCleanTask = new Queue<CleanType>();
 
         public PMTask(ModuleName pm) : base(pm)
         {
-            JobCleanStatus = ModuleStatus.Idle;
         }
 
         public override RState Run()
@@ -307,9 +318,21 @@ namespace Venus_RT.Modules
                 {
                     case ModuleStatus.Idle:
                         {
-                            if(_wafer == null)
+                            if(WaferManager.Instance.CheckNoWafer(Module, 0))
                             {
-                                if(_pmScheduler.RunIdleCleanTask())  // Check Idle Clean
+                                if (_pendingCleanTask.Count > 0)
+                                {
+                                    var cleanTask = _pendingCleanTask.Dequeue();
+                                    if (cleanTask == CleanType.PostJobClean && !string.IsNullOrWhiteSpace(_postJobCleanRecipe))
+                                    {
+                                        Status = ModuleStatus.WaitPostJobClean;
+                                    }
+                                    else if (cleanTask == CleanType.PreJobClean && !string.IsNullOrWhiteSpace(_preJobCleanRecipe))
+                                    {
+                                        Status = ModuleStatus.WaitPreJobClean;
+                                    }
+                                }
+                                else if (_pmScheduler.RunIdleCleanTask())  // Check Idle Clean
                                 {
                                     Status = ModuleStatus.StartIdleClean;
                                 }
@@ -324,18 +347,53 @@ namespace Venus_RT.Modules
                         break;
                     case ModuleStatus.WaitPreJobClean:
                         {
-
+                            if(WaferManager.Instance.CheckNoWafer(Module, 0))
+                            {
+                                if (_pmScheduler.RunJobCleanTask(_preJobCleanRecipe))
+                                {
+                                    Status = ModuleStatus.StartPreJobClean;
+                                }
+                                else
+                                {
+                                    LOG.Write(eEvent.WARN_ROUTER, Module, $"Run Prejob clean recipe{_preJobCleanRecipe} failed");
+                                    Status = ModuleStatus.Idle;
+                                    _preJobCleanRecipe = string.Empty;
+                                }
+                            }
                         }
                         break;
                     case ModuleStatus.WaitPostJobClean:
                         {
-
+                            if (WaferManager.Instance.CheckNoWafer(Module, 0))
+                            {
+                                if (_pmScheduler.RunJobCleanTask(_postJobCleanRecipe))
+                                {
+                                    Status = ModuleStatus.StartPostJobClean;
+                                }
+                                else
+                                {
+                                    LOG.Write(eEvent.WARN_ROUTER, Module, $"Run Postjob clean recipe{_postJobCleanRecipe} failed");
+                                    Status = ModuleStatus.Idle;
+                                    _postJobCleanRecipe = string.Empty;
+                                }
+                            }
                         }
                         break;
                     
                     case ModuleStatus.WaitWTWClean:
                         {
-
+                            if (WaferManager.Instance.CheckNoWafer(Module, 0))
+                            {if (_pmScheduler.RunJobCleanTask(_wtwCleanRecipe))
+                                {
+                                    Status = ModuleStatus.StartWTWClean;
+                                }
+                                else
+                                {
+                                    LOG.Write(eEvent.WARN_ROUTER, Module, $"Run WTW Wafer clean recipe{_wtwCleanRecipe} failed");
+                                    Status = ModuleStatus.Idle;
+                                    _wtwCleanRecipe = string.Empty;
+                                }
+                            }
                         }
                         break;
                     case ModuleStatus.Processing:
@@ -348,14 +406,55 @@ namespace Venus_RT.Modules
                             }
                         }
                         break;
-                    case ModuleStatus.IdleClean:
                     case ModuleStatus.PreJobClean:
+                        {
+                            _preJobCleanRecipe = string.Empty;
+                            Status = ModuleStatus.Idle;
+                        }
+                        break;
                     case ModuleStatus.PostJobClean:
-                    case ModuleStatus.WTWClean:
                         {
+                            _postJobCleanRecipe = string.Empty;
+                            if (_pendingCleanTask.Count > 0)
+                            {
+                                var cleanTask = _pendingCleanTask.Dequeue();
+                                if(cleanTask == CleanType.PreJobClean && !string.IsNullOrWhiteSpace(_preJobCleanRecipe))
+                                {
+                                    Status = ModuleStatus.WaitPreJobClean;
+                                    break;
+                                }
+                            }
+
                             Status = ModuleStatus.Idle;
                         }
                         break;
+                    case ModuleStatus.WTWClean:
+                        {
+                            if(_pendingCleanTask.Count > 0)
+                            {
+                                var cleanTask = _pendingCleanTask.Dequeue();
+                                if (cleanTask == CleanType.PostJobClean && !string.IsNullOrWhiteSpace(_postJobCleanRecipe))
+                                {
+                                    Status = ModuleStatus.WaitPostJobClean;
+                                }
+                                else if (cleanTask == CleanType.PreJobClean && !string.IsNullOrWhiteSpace(_preJobCleanRecipe))
+                                {
+                                    Status = ModuleStatus.WaitPreJobClean;
+                                }
+                            }
+                            else
+                            {
+                                Status = ModuleStatus.Idle;
+                            }
+
+                            _wtwCleanRecipe = string.Empty;
+                        }
+                        break;
+                    case ModuleStatus.IdleClean:
+                        {
+                            Status = ModuleStatus.Idle; 
+                        }
+                        break;
                 }
             }
             else
@@ -383,21 +482,56 @@ namespace Venus_RT.Modules
             return RState.Running;
         }
 
-        public override void WaferArrived(WaferTask wafer)
+        public override void WaferArrived(WaferTask wafer, int slot)
         {
             _wafer = wafer;
             Status = ModuleStatus.WaitProcess;
         }
 
-        public override void WaferLeaved(WaferTask wafer)
+        public override void WaferLeaved(WaferTask wafer, int slot)
         {
-            if(!string.IsNullOrEmpty(_wafer.wtwCleanRecipe.Trim()))
+            if(!string.IsNullOrWhiteSpace(_wafer.wtwCleanRecipe.Trim()))
             {
                 Status = ModuleStatus.WaitWTWClean;
+                _wtwCleanRecipe = _wafer.wtwCleanRecipe;
+            }
+            else if(_pendingCleanTask.Count > 0)
+            {
+                var cleanTask = _pendingCleanTask.Dequeue();
+                if (cleanTask == CleanType.PostJobClean && !string.IsNullOrWhiteSpace(_postJobCleanRecipe))
+                {
+                    Status = ModuleStatus.WaitPostJobClean;
+                }
+                else if (cleanTask ==  CleanType.PreJobClean && !string.IsNullOrWhiteSpace(_preJobCleanRecipe))
+                {
+                    Status = ModuleStatus.WaitPreJobClean;
+                }
             }
 
             _wafer = null;
         }
+
+        public void InvokePreJobClean(string preJobClean)
+        {
+            _preJobCleanRecipe = preJobClean;
+            _pendingCleanTask.Enqueue(CleanType.PreJobClean);
+        }
+
+        public bool IsPreJobCleanDone()
+        {
+            return !_pendingCleanTask.Contains(CleanType.PreJobClean) && string.IsNullOrWhiteSpace(_preJobCleanRecipe);
+        }
+
+        public void InvokePostJobClean(string postJobClean)
+        {
+            _postJobCleanRecipe = postJobClean;
+            _pendingCleanTask.Enqueue(CleanType.PostJobClean);
+        }
+
+        public bool IsPostJobCleanDone()
+        {
+            return !_pendingCleanTask.Contains(CleanType.PostJobClean) && string.IsNullOrWhiteSpace(_postJobCleanRecipe);
+        }
     }
 
     public class AlignerTask : ModuleTask
@@ -433,13 +567,13 @@ namespace Venus_RT.Modules
             return RState.Running;
         }
 
-        public override void WaferArrived(WaferTask wafer)
+        public override void WaferArrived(WaferTask wafer, int slot)
         {
             _wafer = wafer;
             Status = ModuleStatus.WaitAlign;
         }
 
-        public override void WaferLeaved(WaferTask wafer)
+        public override void WaferLeaved(WaferTask wafer, int slot)
         {
             _wafer = null;
         }
@@ -507,6 +641,11 @@ namespace Venus_RT.Modules
                 return int.MaxValue;
             }
         }
+
+        public override void WaferArrived(WaferTask wafer, int slot)
+        {
+            Scheduler.WaferArrived(slot);
+        }
     }
 
     class SystemDispatcher : ICycle
@@ -581,6 +720,9 @@ namespace Venus_RT.Modules
 
         public RState Start(params object[] objs)
         {
+            _efemRobotSingleArmOption = SC.GetValue<int>("EFEM.SingleArmOption");
+            _tmRobotSingleArmOption = SC.GetValue<int>("TM.SingleArmOption");
+
             return RState.Running;
         }
 
@@ -608,7 +750,8 @@ namespace Venus_RT.Modules
         }
 
 
-        public bool CreateJob(Dictionary<string, object> param,out string reason)
+
+        public bool CreateJob(Dictionary<string, object> param, out string reason)
         {
             reason = "";
             _isCycleMode = SC.GetValue<bool>("System.IsCycleMode");
@@ -722,7 +865,7 @@ namespace Venus_RT.Modules
             if (seqSlotWafers.Count == 0)
             {
                 reason = $"job has not assign wafer";
-                LOG.Write(eEvent.WARN_ROUTER, ModuleName.System,reason );
+                LOG.Write(eEvent.WARN_ROUTER, ModuleName.System, reason);
                 _faCallback.JobCreateFailed(module, lotId, jobId, "");
                 return false;
             }
@@ -909,7 +1052,7 @@ namespace Venus_RT.Modules
         }
 
 
-        public bool StartJob(string jobName,out string reason)
+        public bool StartJob(string jobName, out string reason)
         {
             reason = "";
             ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
@@ -1204,7 +1347,7 @@ namespace Venus_RT.Modules
                                     var pmTask = _dictModuleTask[pm] as PMTask;
                                     if(pmTask != null)
                                     {
-                                        pmTask.JobCleanStatus = ModuleStatus.WaitPreJobClean;
+                                        pmTask.InvokePreJobClean(cj.PreJobClean);
                                     }
                                 }
                             }
@@ -1219,7 +1362,7 @@ namespace Venus_RT.Modules
                 {
                     if (cj.JetState == EnumJetCtrlJobState.PreJobClean)
                     {
-                        if (IsJobCleanDone(cj))
+                        if (IsPreJobCleanDone(cj))
                         {
                             ActiveControlJob(cj);
                         }
@@ -1237,14 +1380,14 @@ namespace Venus_RT.Modules
                                     var pmTask = _dictModuleTask[pm] as PMTask;
                                     if (pmTask != null)
                                     {
-                                        pmTask.JobCleanStatus = ModuleStatus.WaitPostJobClean;
+                                        pmTask.InvokePostJobClean(cj.PostJobClean);
                                     }
                                 }
                             }
                         }
 
                         // control job complete
-                        if (IsAllProcessJobComplete(cj) && (!IsCtrlJobNeedPostClean(cj) || cj.JetState == EnumJetCtrlJobState.PostJobClean && IsJobCleanDone(cj)))
+                        if (IsAllProcessJobComplete(cj) && (!IsCtrlJobNeedPostClean(cj) || cj.JetState == EnumJetCtrlJobState.PostJobClean && IsPostJobCleanDone(cj)))
                         {
                             cj.JetState = EnumJetCtrlJobState.Completed;
 
@@ -1320,6 +1463,7 @@ namespace Venus_RT.Modules
                 {
                     _cycledCount++;
 
+                    LOG.Write(eEvent.EV_ROUTER, ModuleName.System, $"Cycle Count: {_cycledCount}, Total Processed Wafer: {_cycledWafer}, Throughput: {_throughput}");
                     if (_cycledCount < _cycleSetPoint)
                     {
                         foreach (var cj in _lstControlJobs)
@@ -1468,12 +1612,12 @@ namespace Venus_RT.Modules
 
         private bool IsCtrlJobNeedPreClean(ControlJobInfo cj)
         {
-            return cj.PreJobClean.Trim().Length > 0;
+            return !string.IsNullOrWhiteSpace(cj.PreJobClean);
         }
 
         private bool IsCtrlJobNeedPostClean(ControlJobInfo cj)
         {
-            return cj.PostJobClean.Trim().Length > 0;
+            return !string.IsNullOrWhiteSpace(cj.PostJobClean.Trim());
         }
 
         private List<ModuleName> GetWaitPreCleanPMsByCtrlJob(ControlJobInfo cj)
@@ -1494,13 +1638,26 @@ namespace Venus_RT.Modules
             return pmlist;
         }
 
-        private bool IsJobCleanDone(ControlJobInfo cj)
+        private bool IsPreJobCleanDone(ControlJobInfo cj)
         {
             var pms = GetWaitPreCleanPMsByCtrlJob(cj);
             foreach(var pm in pms)
             {
                 var pmTask = _dictModuleTask[pm] as PMTask;
-                if (pmTask.JobCleanStatus != ModuleStatus.Idle)
+                if (!pmTask.IsPreJobCleanDone())
+                    return false;
+            }
+
+            return true;
+        }
+
+        private bool IsPostJobCleanDone(ControlJobInfo cj)
+        {
+            var pms = GetWaitPreCleanPMsByCtrlJob(cj);
+            foreach (var pm in pms)
+            {
+                var pmTask = _dictModuleTask[pm] as PMTask;
+                if (!pmTask.IsPostJobCleanDone())
                     return false;
             }
 
@@ -1509,12 +1666,12 @@ namespace Venus_RT.Modules
 
         private void WaferArrived(WaferTask wafer, MoveItem item)
         {
-            _dictModuleTask[item.DestinationModule].WaferArrived(wafer);
+            _dictModuleTask[item.DestinationModule].WaferArrived(wafer, item.DestinationSlot);
         }
 
         private void WaferLeaved(WaferTask wafer, MoveItem item)
         {
-            _dictModuleTask[item.SourceModule].WaferLeaved(wafer);
+            _dictModuleTask[item.SourceModule].WaferLeaved(wafer, item.DestinationSlot);
         }
 
         private ModuleName GetComingAvailablePM()
@@ -1553,12 +1710,12 @@ namespace Venus_RT.Modules
                 {
                     foreach (var wafer in cj.LotWafers)
                     {
-                        if (wafer.IsEmpty)
+                        if (wafer.IsEmpty || wafer.ProcessJob == null)
                             continue;
 
                         if (wafer.ProcessJob.Sequence.PMs.Contains(pm) && wafer.ProcessState == EnumWaferProcessStatus.Idle && !_lstWaferTasks.Exists(task => task.sourceMod == (ModuleName)wafer.OriginStation && task.sourceSlot == wafer.OriginSlot))
                         {
-                            CreateWaferTasks(wafer, pm);
+                            CreateWaferTasks(wafer, pm,  wafer.ProcessJob.Sequence.LLDelayTime);
                             return;
                         }
                     }
@@ -1566,20 +1723,26 @@ namespace Venus_RT.Modules
             }
         }
 
-        private void CreateWaferTasks(WaferInfo wafer, ModuleName pm)
+        private void CreateWaferTasks(WaferInfo wafer, ModuleName pm, int LLDeayTime)
         {
             var recipeName = wafer.ProcessJob.Sequence.GetRecipe(pm);
             var recipeContent = RecipeFileManager.Instance.LoadRecipe(pm.ToString(), recipeName, false, RecipeType.Process.ToString());
             Recipe recipe = Recipe.Load(recipeContent);
+            int temperature = 0;
+            if(int.TryParse(recipe.Header.Temperature, out int temp))
+            {
+                temperature = temp;
+            }
             var waferTask = new WaferTask((ModuleName)wafer.OriginStation,
                                             wafer.OriginSlot,
                                             pm,
-                                            0,
+                                            temperature,
                                             (float)Convert.ToDouble(recipe.Header.Temperature),
                                             wafer.InnerId,
                                             recipeName,
                                             wafer.ProcessJob.Sequence.WTWCleanRecipe,
-                                            wafer.ProcessJob.Sequence.LLInOutPath, 0);
+                                            wafer.ProcessJob.Sequence.LLInOutPath, 
+                                            LLDeayTime);
 
             waferTask.OnWaferArrived += WaferArrived;
             waferTask.OnWaferLeaved += WaferLeaved;
@@ -2595,7 +2758,7 @@ namespace Venus_RT.Modules
                     {
                         var pmActions = new List<MoveItem>();
                         var pmWafer = _lstWaferTasks.Find(wafer => (wafer.movingStatus == RState.End || wafer.movingStatus == RState.Init) && wafer.currentMod == robotWafers[0].destMod && ModuleHelper.IsLoadPort(wafer.destMod));
-                        if (pmWafer != null && string.IsNullOrEmpty(pmWafer.wtwCleanRecipe.Trim()))
+                        if (pmWafer != null && string.IsNullOrWhiteSpace(pmWafer.wtwCleanRecipe))
                         {
                             int pickSlot = 1 - robotWafers[0].currentSlot;
                             pmWafer.RouteTo(ModuleName.TMRobot, pickSlot);
@@ -2719,7 +2882,7 @@ namespace Venus_RT.Modules
                 {
                     var pmActions = new List<MoveItem>();
                     var pmWafer = _lstWaferTasks.Find(wafer => (wafer.movingStatus == RState.End || wafer.movingStatus == RState.Init) && wafer.currentMod == robotWafers[0].destMod && ModuleHelper.IsLoadPort(wafer.destMod));
-                    if (pmWafer != null && string.IsNullOrEmpty(pmWafer.wtwCleanRecipe.Trim()))
+                    if (pmWafer != null && string.IsNullOrWhiteSpace(pmWafer.wtwCleanRecipe))
                     {
                         int pickSlot = 1 - robotWafers[0].currentSlot;
                         pmWafer.RouteTo(ModuleName.TMRobot, pickSlot);
@@ -3007,11 +3170,12 @@ namespace Venus_RT.Modules
 
             var hands = GetEFEMFreeHand();
             // return Aligner wafer
-            if(WaferManager.Instance.CheckHasWafer(ModuleName.Aligner, 0) && hands.Count > 0)
+            var aligner = ModuleHelper.InstalledModules.Where(mod => ModuleHelper.IsAligner(mod)).ToList();
+            if(aligner.Count > 0 && WaferManager.Instance.CheckHasWafer(aligner.First(), 0) && hands.Count > 0)
             {
-                var wafer = WaferManager.Instance.GetWafer(ModuleName.Aligner, 0);
-                _efemSchdActions.Enqueue(new List<MoveItem> { new MoveItem(ModuleName.Aligner, 0, ModuleName.TMRobot, (int)hands.First(), hands.First()) });
-                _efemSchdActions.Enqueue(new List<MoveItem> { new MoveItem(ModuleName.TMRobot, (int)hands.First(), (ModuleName)wafer.OriginStation, wafer.OriginSlot, hands.First()) });
+                var wafer = WaferManager.Instance.GetWafer(aligner.First(), 0);
+                _efemSchdActions.Enqueue(new List<MoveItem> { new MoveItem(aligner.First(), 0, ModuleName.EfemRobot, (int)hands.First(), hands.First()) });
+                _efemSchdActions.Enqueue(new List<MoveItem> { new MoveItem(ModuleName.EfemRobot, (int)hands.First(), (ModuleName)wafer.OriginStation, wafer.OriginSlot, hands.First()) });
                 return;
             }
 
@@ -3129,14 +3293,14 @@ namespace Venus_RT.Modules
                     {
                         string attr = $"{module}Recipe";
                         if (stepInfo.StepParameter.ContainsKey(attr)
-                            && !string.IsNullOrEmpty((string)stepInfo.StepParameter[attr]))
+                            && !string.IsNullOrWhiteSpace((string)stepInfo.StepParameter[attr]))
                         {
                             var recipeName = (string)stepInfo.StepParameter[attr];
-                            if (!string.IsNullOrEmpty(recipeName))
+                            if (!string.IsNullOrWhiteSpace(recipeName))
                             {
                                 var recipeContent =
                                     RecipeFileManager.Instance.LoadRecipe($"{module}", recipeName, false, "Process");
-                                if (string.IsNullOrEmpty(recipeContent))
+                                if (string.IsNullOrWhiteSpace(recipeContent))
                                 {
                                     reason = $"Can not find recipe file{recipeName}";
                                     return false;