Browse Source

Job Clean function, not finished.

sangwq 1 year ago
parent
commit
7d93bf0076

+ 43 - 0
Venus/Framework/Common/Jobs/SequenceInfo.cs

@@ -28,6 +28,17 @@ namespace MECF.Framework.Common.Jobs
         [DataMember]
         public string Name { get; set; }
 
+        [DataMember]
+        public string PreCleanRecipe { get; set; }
+
+        [DataMember]
+        public string WTWCleanRecipe { get; set; }
+
+        [DataMember]
+        public string PostCleanRecipe { get; set; }
+
+        [DataMember]
+        public List<ModuleName> PMs { get; set; }
 
         [DataMember]
         public string ThicknessType { get; set; }
@@ -45,6 +56,23 @@ namespace MECF.Framework.Common.Jobs
             LLInOutPath =  SequenceLLInOutPath.DInDOut;
             Steps = new List<SequenceStepInfo>();
         }
+
+        public string GetRecipe(ModuleName pm)
+        {
+            if (!ModuleHelper.IsPm(pm))
+                return string.Empty;
+
+            string attr = $"{pm}Recipe";
+            foreach (var step in Steps)
+            {
+                if(step.StepModules.Contains(pm))
+                {
+                    return (string)step.StepParameter[attr];
+                }
+            }
+
+            return string.Empty;
+        }
     }
 
     public class SequenceInfoHelper
@@ -138,6 +166,21 @@ namespace MECF.Framework.Common.Jobs
                                 stepInfo.AlignAngle = angle;
                                 continue;
                             }
+
+                            if(attr.Name == "PreClean")
+                            {
+                                info.PreCleanRecipe = attr.Value;
+                            }
+
+                            if(attr.Name == "WTWClean")
+                            {
+                                info.WTWCleanRecipe = attr.Value;
+                            }
+
+                            if(attr.Name == "PostClean")
+                            {
+                                info.PostCleanRecipe = attr.Value;
+                            }
                         }
 
                         info.Steps.Add(stepInfo);

+ 0 - 5
Venus/Framework/Common/Jobs/SequenceStepInfo.cs

@@ -20,11 +20,6 @@ namespace MECF.Framework.Common.Jobs
             StepModules = new List<ModuleName>();
             StepParameter = new Dictionary<string, object>();
         }
-
-
-
     }
-
-
     
 }

+ 1 - 1
Venus/Framework/Common/SCCore/SC.cs

@@ -48,7 +48,7 @@ namespace Aitex.Core.RT.SCCore
         public static void SetItemValueFromString(string name, string value)
         {
             if (Manager != null)
-                Manager.SetItemValueFromString(name, value);
+                 Manager.SetItemValueFromString(name, value);
         }
 
         public static SCConfigItem GetConfigItem(string name)

+ 1 - 1
Venus/Framework/Common/SCCore/SystemConfigManager.cs

@@ -380,7 +380,7 @@ namespace MECF.Framework.Common.SCCore
 
         public void SetItemValueFromString(string name, string value)
         {
-            if (InitializeItemValue(_items[name], value))
+             if (InitializeItemValue(_items[name], value))
             {
                 GenerateDataFile();
             }

+ 2 - 1
Venus/Venus_MainPages/Sequence/SequenceColumnBuilder.cs

@@ -73,7 +73,8 @@ namespace Venus_MainPages.Sequence
                             //IsReadOnly = true,
                             ControlName = node.Attributes["Name"].Value,
                             DisplayName = node.Attributes["DisplayName"].Value,
-                            RecipeProcessType = node.Attributes["Parameter"].Value,
+                            
+                            //RecipeProcessType = node.Attributes["Parameter"].Value,
                             StringCellTemplate = "TemplateRecipeSelection",
                             StringHeaderTemplate = "ParamTemplate",
                         };

+ 14 - 12
Venus/Venus_MainPages/ViewModels/SequenceViewModel.cs

@@ -484,19 +484,21 @@ namespace Venus_MainPages.ViewModels
 
             if (dialog.ShowDialog() == true)
             {
-                param.Value = dialog.FullPath;
+                //param.Value = dialog.FullPath;
                 //param.Value = $"{param.PrefixPath}\\" + dialog.FullPath;
-                param.FileName = param.Value;
-                //string path = param.Value;
-                //int index = path.LastIndexOf("\\");
-                //if (index > -1)
-                //{
-                //    param.FileName = path.Substring(index + 1);
-                //}
-                //else
-                //{
-                //    param.FileName = path;
-                //}
+                //param.FileName = param.Value;
+                string path = dialog.FullPath;
+                int index = path.LastIndexOf("\\");
+                if (index > -1)
+                {
+                    param.FileName = path.Substring(index + 1);
+                    param.Value = path.Substring(index + 1);
+                }
+                else
+                {
+                    param.FileName = path;
+                    param.Value = path;
+                }
 
                 param.IsSaved = false;
             }

+ 5 - 1
Venus/Venus_RT/Config/SequenceFormat.xml

@@ -5,7 +5,7 @@
       <Item Name="Position" DisplayName="Position" InputType="ReadOnlySelection" >
         <Selection Name="Aligner" DisplayName="Aligner" Parameter="AlignerSelection,AlignAngle" />
         <Selection Name="LL" DisplayName="LL" Parameter="LLSelection" />
-        <Selection Name="PM" DisplayName="PM" Parameter="PMSelection,PMARecipe,PMBRecipe,PMCRecipe,PMDRecipe" />
+        <Selection Name="PM" DisplayName="PM" Parameter="PMSelection,PMARecipe,PMBRecipe,PMCRecipe,PMDRecipe,PreClean,WTWClean,PostClean" />
         <!--<Selection Name="Cooling" DisplayName="Cooling" Parameter="CoolingSelection,CoolingTime" />-->
       </Item>
     </Catalog>
@@ -53,6 +53,10 @@
       <Item Name="PMDRecipe" DisplayName="PMD Recipe" InputType="RecipeSelection" Parameter="PMD"    Min="0" Max="999999"  />
 
       <Item Name="AlignAngle" DisplayName="Align Angle" InputType="NumInput"   Min="0" Max="359"  />
+		
+      <Item Name="PreClean" DisplayName="Pre Clean" InputType="RecipeSelection"     Min="0" Max="999999"  />
+      <Item Name="WTWClean" DisplayName="WTW Clean" InputType="RecipeSelection"     Min="0" Max="999999"  />
+      <Item Name="PostClean" DisplayName="Post Clean" InputType="RecipeSelection"   Min="0" Max="999999"  />
 
 
 		<!--<Item Name="CoolingTime" DisplayName="Cooling Time(s)" InputType="NumInput"   Min="0" Max="360"  />-->

File diff suppressed because it is too large
+ 27 - 64
Venus/Venus_RT/Config/System.sccfg


+ 36 - 7
Venus/Venus_RT/Modules/AutoCycle.cs

@@ -47,6 +47,21 @@ namespace Venus_RT.Modules
         StartProcess,
         Processing,
 
+        StartIdleClean,
+        IdleClean,
+
+        WaitPreJobClean,
+        StartPreJobClean,
+        PreJobClean,
+
+        WaitPostJobClean,
+        StartPostJobClean,
+        PostJobClean,
+
+        WaitWTWClean,
+        StartWTWClean,
+        WTWClean,
+
         // Align Status
         WaitAlign,
         StartAlign,
@@ -1003,8 +1018,21 @@ namespace Venus_RT.Modules
                                 }
                                 break;
                             case MovingStatus.Processing:
+                            case MovingStatus.IdleClean:
                                 mod.Value.MovingStatus = MovingStatus.Idle;
                                 break;
+                            case MovingStatus.Idle:
+                                {
+                                    if(WaferManager.Instance.CheckNoWafer(mod.Key, 0))
+                                    {
+                                        var pmScheduler = _vacSchedulers[mod.Key] as SchedulerPM;
+                                        if(pmScheduler.RunIdleCleanTask())
+                                        {
+                                            mod.Value.MovingStatus = MovingStatus.StartIdleClean;
+                                        }
+                                    }
+                                }
+                                break;
                         }
                     }
                     else
@@ -1014,6 +1042,9 @@ namespace Venus_RT.Modules
                             case MovingStatus.StartProcess:
                                 mod.Value.MovingStatus = MovingStatus.Processing;
                                 break;
+                            case MovingStatus.StartIdleClean:
+                                mod.Value.MovingStatus = MovingStatus.IdleClean;
+                                break;
                         }
                     }
 
@@ -1959,11 +1990,14 @@ namespace Venus_RT.Modules
             }
         }
 
-        private void PreJobClean(ControlJobInfo cj)
+        private void PreJobClean(ControlJobInfo cj, ProcessJobInfo pj)
         {
             if (cj.IsPreJobCleanDone)
                 return;
 
+            if (cj.ProcessJobNameList.Count > 1)
+                return;
+
             cj.IsPreJobCleanDone = true;
 
             List<SchedulerPM> pms = GetPmNeeded(cj);
@@ -1992,7 +2026,7 @@ namespace Venus_RT.Modules
 
             pj.SetState(EnumProcessJobState.Processing);
 
-            PreJobClean(cj);
+            PreJobClean(cj, pj);
 
             return true;
         }
@@ -2120,11 +2154,6 @@ namespace Venus_RT.Modules
 
         private void CompleteJobClean(ControlJobInfo cj)
         {
-            List<SchedulerPM> pms = GetPmNeeded(cj);
-            foreach (var pm in pms)
-            {
-                pm.CompleteJobClean();
-            }
         }
 
         private void UpdateControlJobStatus()

+ 1 - 1
Venus/Venus_RT/Modules/PMs/VenusRecipeFileContext.cs

@@ -237,7 +237,7 @@ namespace Venus_RT.Modules.PMs
 
                 foreach (var fi in fis)
                 {
-                    string str = fi.FullName.Substring(recipePath.Length);
+                    string str = fi.FullName.Substring(recipePath.Length - 1);
                     str = str.Substring(0, str.LastIndexOf('.'));
                     if (includingUsedRecipe || (!includingUsedRecipe && !str.Contains("HistoryRecipe\\")))
                     {

+ 1 - 1
Venus/Venus_RT/Modules/Schedulers/SchedulerModule.cs

@@ -109,7 +109,7 @@ namespace Venus_RT.Scheduler
 
         protected TaskType _task = TaskType.None;
 
-        protected EnumTransferType _inTransferType;
+        protected EnumTransferType _inTransferType; 
 
         protected int _inTransferSlot;
 

+ 70 - 281
Venus/Venus_RT/Modules/Schedulers/SchedulerPM.cs

@@ -13,12 +13,14 @@ using Aitex.Core.RT.Log;
 using Aitex.Core.RT.SCCore;
 using Aitex.Core.Util;
 using Aitex.Sorter.Common;
+using Aitex.Core.RT.RecipeCenter;
 using Venus_RT.Modules;
 using Venus_RT.Modules.PMs;
 using MECF.Framework.Common.Equipment;
 using MECF.Framework.Common.Schedulers;
 using MECF.Framework.Common.SubstrateTrackings;
 using Venus_RT.Devices;
+using Venus_Core;
 
 namespace Venus_RT.Scheduler
 {
@@ -27,7 +29,7 @@ namespace Venus_RT.Scheduler
     {
         public override bool IsAvailable
         {
-            get { return _entity.IsIdle && (_entity.IsOnline || !Singleton<RouteManager>.Instance.IsAutoMode) && CheckTaskDone() && !_waitCompletejobClean; } // 测试TMCycle, 暂时注释掉 _entity.IsOnline
+            get { return _entity.IsIdle && (_entity.IsOnline || !Singleton<RouteManager>.Instance.IsAutoMode) && CheckTaskDone(); }
 
         }
         public override bool IsOnline
@@ -58,6 +60,13 @@ namespace Venus_RT.Scheduler
         private DeviceTimer _timerProcess = new DeviceTimer();
         private JetPMBase _pm;
 
+        private int _idleCleanOpt = 0;
+        private int _idleCleanHourSetPoint;
+        private int _idleCleanWaferSetPoint;
+        private int _idleCleanWaferCount;
+        private string _idleCleanRecipe;
+        private DateTime _lastRunTime = new DateTime();
+
         private float _paramTemp;
 
         public float Temperature
@@ -75,49 +84,21 @@ namespace Venus_RT.Scheduler
         }
 
 
-        public RD_TRIG IdlePurgeTrig { get; set; }
-        public Stopwatch IdlePurgeTimer { get; set; }
-        public int IdlePurgeTime { get; set; }
-        public int IdlePurgeNextRunTime { get; set; }
-
-        public RD_TRIG IdleCleanTrig { get; set; }
-        public Stopwatch IdleCleanTimer { get; set; }
-        public int IdleCleanTime { get; set; }
-        public int IdleCleanNextRunTime { get; set; }
-
-        private bool _waitPreJobClean;
-        private bool _waitCompletejobClean;
-
-        private R_TRIG _trigIdleCleanFailed = new R_TRIG();
-        private R_TRIG _trigIdlePurgeFailed = new R_TRIG();
-
-        public RD_TRIG PreJobCleanTrig { get; set; }
-        public Stopwatch PreJobCleanTimer { get; set; }
-        public int PreJobCleanTime { get; set; }
-
         public SchedulerPM(ModuleName chamber) : base(chamber.ToString())
         {
             _entity = Singleton<RouteManager>.Instance.GetPM(chamber);
 
             _pm = DEVICE.GetDevice<JetPMBase>(Module.ToString());
 
-
-            IdlePurgeTrig = new RD_TRIG();
-            IdlePurgeTimer = new Stopwatch();
-
-            IdleCleanTrig = new RD_TRIG();
-            IdleCleanTimer = new Stopwatch();
-
-            PreJobCleanTrig = new RD_TRIG();
-            PreJobCleanTimer = new Stopwatch();
-
             EventWaferArrived += WaferArrived;
+
+            LoadIdleCleanOpt();
         }
 
         public void InitClean()
         {
-            DATA.Subscribe($"{Module}.IdlePurgeNextRunTime", () => IdlePurgeNextRunTime);
-            DATA.Subscribe($"{Module}.IdleCleanNextRunTime", () => IdleCleanNextRunTime);
+            //DATA.Subscribe($"{Module}.IdlePurgeNextRunTime", () => IdlePurgeNextRunTime);
+            //DATA.Subscribe($"{Module}.IdleCleanNextRunTime", () => IdleCleanNextRunTime);
         }
 
         public override bool IsReadyForPick(ModuleName robot, int slot, Hand blade)
@@ -325,10 +306,7 @@ namespace Venus_RT.Scheduler
 
         public void PreJobClean()
         {
-            var enableJobClean = SC.GetValue<bool>($"{Module}.JobClean.IsEnabled");
-            var enablePreJobClean = SC.GetValue<bool>($"{Module}.JobClean.EnablePreJobClean");
 
-            _waitPreJobClean = enableJobClean && enablePreJobClean;
         }
 
         public bool PreJobProcess(string recipeName)
@@ -341,13 +319,6 @@ namespace Venus_RT.Scheduler
             return _entityTaskToken != (int)FSM_MSG.NONE;
         }
 
-        public void CompleteJobClean()
-        {
-            var enableJobClean = SC.GetValue<bool>($"{Module}.JobClean.IsEnabled");
-            var enableCompleteJobClean = SC.GetValue<bool>($"{Module}.JobClean.EnableCompleteJobClean");
-
-            _waitCompletejobClean = enableJobClean && enableCompleteJobClean;
-        }
 
         public bool CompleteJobProcess(string recipeName)
         {
@@ -362,281 +333,99 @@ namespace Venus_RT.Scheduler
         private void WaferArrived(object sender, EventArgs e)
         {
             WaferInfo wafer = WaferManager.Instance.GetWafer(Module, 0);
-            string attr = $"{Module}Recipe";
-            string recipeName = string.Empty;
-            if(wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module))
-            {
-                recipeName = (string)wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter[attr];
-            }
-            else
+            string recipeName = wafer.ProcessJob.Sequence.GetRecipe(Module);
+            if(recipeName.Length > 0)
             {
-                recipeName = (string)wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep - 1].StepParameter[attr];
+                Process(recipeName, false, true, wafer);
             }
-
-            Process((string)recipeName, false, true, wafer);
         }
 
         #region clean task
 
-        internal void ResetIdlePurgeTime()
-        {
-            IdlePurgeTimer.Restart();
-        }
-
-        internal void ResetIdleCleanTime()
-        {
-            IdleCleanTimer.Restart();
-        }
-
-        public bool ResetClean(bool resetPurge, bool resetClean, bool jobClean)
-        {
-            if (resetPurge)
-            {
-                IdlePurgeTrig.RST = true;
-                IdlePurgeTimer.Stop();
-                IdlePurgeTime = 0;
-            }
-
-            if (resetClean)
-            {
-                IdleCleanTrig.RST = true;
-                IdleCleanTimer.Stop();
-                IdleCleanTime = 0;
-            }
-
-            if (jobClean)
-            {
-                _waitPreJobClean = false;
-                _waitCompletejobClean = false;
-                PreJobCleanTrig.RST = true;
-                PreJobCleanTimer.Stop();
-            }
-
-            return true;
-        }
-
-        public void MonitorCleanTasks()
+        private void LoadIdleCleanOpt()
         {
-            var hasWafer = WaferManager.Instance.CheckHasWafer(Module, 0);
-            var enablePurge = false;//SC.GetValue<bool>($"{Module}.IdlePurge.IsEnabled");
-            var enableClean = SC.GetValue<bool>($"{Module}.IdleClean.IsEnabled");
-
-            #region Idle Purge
-
-            IdlePurgeTrig.CLK = (IsIdle || _task != TaskType.IdlePurgeProcess) && enablePurge && !hasWafer;
-            if (IdlePurgeTrig.R)
-            {
-                LOG.Write( eEvent.INFO_PM, Module, $"{Module} idle purge start calc elapse time");
-                IdlePurgeTimer.Restart();
-            }
+            // Load Idle Clean Config
+            _idleCleanOpt = SC.GetValue<int>($"{Module}.IdleClean.Option");
+            _idleCleanHourSetPoint = SC.GetValue<int>($"{Module}.IdleClean.IdleCleanTime");
+            _idleCleanWaferSetPoint = SC.GetValue<int>($"{Module}.IdleClean.IdleCleanWaferCount");
+            _idleCleanWaferCount = SC.GetValue<int>($"{Module}.IdleClean.WaferCountSinceLastClean");
+            _idleCleanRecipe = SC.GetStringValue($"{Module}.IdleClean.IdleCleanRecipe");
 
-            if (IdlePurgeTrig.T)
+            string lastRun = SC.GetStringValue($"{Module}.IdleClean.LastRunTime");
+            if (lastRun.Length > 10)
             {
-                LOG.Write(eEvent.INFO_PM, Module, $"{Module} idle purge stopped calc elapse time");
-
-                ResetClean(true, false, false);
-            }
-
-            if (IdlePurgeTimer.IsRunning)
-            {
-                IdlePurgeTime = (int)IdlePurgeTimer.ElapsedMilliseconds / 1000;
-                int idlePurgeTimeSetPoint = SC.GetValue<int>($"{Module}.IdlePurge.IdlePurgeTime");
-                var nextRunTime = idlePurgeTimeSetPoint - IdlePurgeTime;
-                if (nextRunTime < 0)
-                    nextRunTime = 0;
-
-                if (enablePurge)
+                try
                 {
-                    if (nextRunTime <= 0 && IsAvailable)
-                    {
-                        var recipe = SC.GetStringValue($"{Module}.IdlePurge.IdlePurgeRecipe");
-
-                        if (string.IsNullOrEmpty(recipe))
-                        {
-                            _trigIdlePurgeFailed.CLK = true;
-
-                            LOG.Write(eEvent.INFO_PM, Module, $"{Module} Idle purge can not run, recipe is empty");
-                            ResetClean(true, false, false);
-                        }
-                        else if (hasWafer)
-                        {
-                            _trigIdlePurgeFailed.CLK = true;
-
-                            LOG.Write(eEvent.INFO_PM, Module, $"{Module} Idle purge can not run, has wafer");
-                            ResetClean(true, false, false);
-                        }
-                        else
-                        {
-                            _trigIdlePurgeFailed.CLK = false;
-
-                            LOG.Write(eEvent.INFO_PM, Module, $"{Module} Start run idle purge recipe {recipe}");
-                            IdlePurgeProcess("ALD\\Process\\" + recipe);
-                        }
-
-                        if (_trigIdlePurgeFailed.Q)
-                        {
-                            LOG.Write(eEvent.WARN_PM, Module, "Can not run idle purge recipe");
-                        }
-                    }
+                    _lastRunTime = DateTime.Parse(lastRun);
                 }
-                else
+                catch (Exception _)
                 {
-                    nextRunTime = 0;
+                    lastRun = string.Empty;
                 }
-
-                IdlePurgeNextRunTime = nextRunTime;
-            }
-            else
-            {
-                IdlePurgeNextRunTime = 0;
             }
 
-            #endregion
-
-            #region Idle Clean
-
-            IdleCleanTrig.CLK = (IsIdle || _task != TaskType.IdleCleanProcess) && enableClean && !hasWafer;
-            if (IdleCleanTrig.R)
+            if (lastRun.Length <= 10)
             {
-                LOG.Write(eEvent.INFO_PM, Module, $"{Module} idle clean start calc elapse time");
-
-                IdleCleanTimer.Restart();
-            }
-
-            if (IdleCleanTrig.T)
-            {
-                LOG.Write(eEvent.INFO_PM, Module, $"{Module} idle clean stopped calc elapse time");
-
-                ResetClean(false, true, false);
+                _lastRunTime = DateTime.Now;
+                SC.SetItemValueFromString($"{Module}.IdleClean.LastRunTime", _lastRunTime.ToString());
             }
 
-            if (IdleCleanTimer.IsRunning)
-            {
-                IdleCleanTime = (int)IdleCleanTimer.ElapsedMilliseconds / 1000;
-
-                int idleCleanTimeSetPoint = SC.GetValue<int>($"{Module}.IdleClean.IdleCleanTime");
-
-
-                var nextRunTime = idleCleanTimeSetPoint - IdleCleanTime;
-                if (nextRunTime < 0)
-                    nextRunTime = 0;
-
-                if (enableClean)
-                {
-                    if (nextRunTime <= 0 && IsAvailable)
-                    {
-                        var recipe = SC.GetStringValue($"{Module}.IdleClean.IdleCleanRecipe");
-
-                        if (string.IsNullOrEmpty(recipe))
-                        {
-                            _trigIdleCleanFailed.CLK = true;
-
-                            LOG.Write(eEvent.INFO_PM, Module, $"{Module} Idle clean can not run, recipe is empty");
-                            ResetClean(false, true, false);
-                        }
-                        else if (hasWafer)
-                        {
-                            _trigIdleCleanFailed.CLK = true;
-
-                            LOG.Write(eEvent.INFO_PM, Module, $"{Module} Idle clean can not run, has wafer");
-                            ResetClean(false, true, false);
-                        }
-                        else
-                        {
-                            _trigIdleCleanFailed.CLK = false;
-
-                            LOG.Write(eEvent.INFO_PM, Module, $"{Module} Start run idle Clean recipe {recipe}");
-                            IdleCleanProcess($"{Module}\\" + recipe);
-                        }
-
-                        if (_trigIdleCleanFailed.Q)
-                        {
-                            EV.PostWarningLog(Module.ToString(), "Can not run idle clean recipe");
-                        }
-                    }
-                }
-                else
-                {
-                    nextRunTime = 0;
-                }
-
-                IdleCleanNextRunTime = nextRunTime;
-            }
-            else
+            // validate the idle clean recipe name
+            string recipeContent = RecipeFileManager.Instance.LoadRecipe(Module.ToString(), _idleCleanRecipe, false);
+            Recipe recipe = Recipe.Load(recipeContent);
+            if (recipe == null)
             {
-                IdleCleanNextRunTime = 0;
+                _idleCleanRecipe = string.Empty;
             }
+        }
 
-            #endregion
+        public void WaferProcessDone()
+        {
+            _lastRunTime = DateTime.Now;
+            SC.SetItemValueFromString($"{Module}.IdleClean.LastRunTime", _lastRunTime.ToString());
 
-            #region PreJob Clean
+            _idleCleanWaferCount++;
+            SC.SetItemValue($"{Module}.IdleClean.IdleCleanWaferCount", _idleCleanWaferCount);
+        }
+        
+        private void ResetIdleCleanCounter()
+        {
+            _lastRunTime = DateTime.Now;
+            SC.SetItemValueFromString($"{Module}.IdleClean.LastRunTime", _lastRunTime.ToString());
 
-            var enableJobClean = SC.GetValue<bool>($"{Module}.JobClean.IsEnabled");
-            var enablePreJobClean = SC.GetValue<bool>($"{Module}.JobClean.EnablePreJobClean");
-            var enableCompleteJobClean = SC.GetValue<bool>($"{Module}.JobClean.EnableCompleteJobClean");
+            _idleCleanWaferCount = 0;
+            SC.SetItemValue($"{Module}.IdleClean.IdleCleanWaferCount", _idleCleanWaferCount);
+        }
 
-            if (enableJobClean && enableCompleteJobClean && _waitCompletejobClean && IsIdle)
+        public bool RunIdleCleanTask()
+        {
+            if(_idleCleanOpt == 1)
             {
-                var recipe = SC.GetStringValue($"{Module}.JobClean.CompleteJobCleanRecipe");
-
-                if (string.IsNullOrEmpty(recipe))
-                {
-                    EV.PostWarningLog(Module.ToString(), "complete job clean can not run, recipe is empty");
-                }
-                else if (hasWafer)
+                TimeSpan span = DateTime.Now - _lastRunTime;
+                if(span.TotalHours >= _idleCleanHourSetPoint)
                 {
-                    EV.PostWarningLog(Module.ToString(), "complete job clean can not run, has wafer");
+                    Process(_idleCleanRecipe, true, false, null);
+                    ResetIdleCleanCounter();
+                    return true;
                 }
-                else
-                {
-                    EV.PostInfoLog(Module.ToString(), $"Start run complete job clean recipe {recipe}");
-                    CompleteJobProcess($"{Module}\\" + recipe);
-                }
-
-                _waitCompletejobClean = false;
             }
-
-            PreJobCleanTrig.CLK = enableJobClean && enablePreJobClean && IsIdle;
-
-            if (PreJobCleanTrig.R)
-            {
-                PreJobCleanTimer.Restart();
-            }
-
-            if(PreJobCleanTrig.T)
+            else if(_idleCleanOpt == 2)
             {
-                ResetClean(false, false, true);
-            }
-
-            if (PreJobCleanTimer.IsRunning && _waitPreJobClean)
-            {
-                PreJobCleanTime = (int)PreJobCleanTimer.ElapsedMilliseconds / 1000;
-                int PreJobCleanIdleTimeSP = SC.GetValue<int>($"{Module}.JobClean.IdleCleanTime");
-                if(PreJobCleanTime >= PreJobCleanIdleTimeSP)
+                if(_idleCleanWaferCount >= _idleCleanWaferSetPoint)
                 {
-                    var recipe = SC.GetStringValue($"{Module}.JobClean.PreJobCleanRecipe");
-
-                    if (string.IsNullOrEmpty(recipe))
-                    {
-                        EV.PostWarningLog(Module.ToString(), "pre job clean can not run, recipe is empty");
-                    }
-                    else if (hasWafer)
-                    {
-                        EV.PostWarningLog(Module.ToString(), "pre job clean can not run, has wafer");
-                    }
-                    else
-                    {
-                        EV.PostInfoLog(Module.ToString(), $"Start run pre job clean recipe {recipe}");
-                        PreJobProcess($"{Module}\\" + recipe);
-                    }
+                    Process(_idleCleanRecipe, true, false, null);
+                    ResetIdleCleanCounter();
+                    return true;
                 }
             }
 
-            #endregion
+            return false;
         }
 
 
         #endregion
 
+
+
     }
 }