Browse Source

add metal loop run recipe

chenzk 6 days ago
parent
commit
37b93a17de

+ 10 - 10
CyberX8_MainPages/ViewModels/PMCounterViewModel.cs

@@ -194,18 +194,18 @@ namespace CyberX8_MainPages.ViewModels
                 bool isCMMInstalled = CommonFunction.GetValue<bool>(reservoirUsageDic, $"{Module}.IsCMMInstalled");
                 if (reservoirUsage != null)
                 {
-                    double ReservoirTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalAmpHoursWarningLimit"));
-                    double ReservoirTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalAmpHoursFaultLimit"));
-                    double BathTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalAmpHoursWarningLimit"));
-                    double BathTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalAmpHoursFaultLimit"));
+                    double ReservoirTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.ReservoirTotalAmpHoursWarningLimit"));
+                    double ReservoirTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.ReservoirTotalAmpHoursFaultLimit"));
+                    double BathTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.BathTotalAmpHoursWarningLimit"));
+                    double BathTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.BathTotalAmpHoursFaultLimit"));
                     //double ANBathTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ANBathTotalAmpHoursWarningLimit"));
                     //double ANBathTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ANBathTotalAmpHoursFaultLimit"));
-                    int BathTotalDaysWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalDaysWarningLimit"));
-                    int BathTotalDaysFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalDaysFaultLimit"));
-                    double MembraneTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.MembraneTotalAmpHoursWarningLimit"));
-                    double MembraneTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.MembraneTotalAmpHoursFaultLimit"));
-                    int ReservoirTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalWafersWarningLimit"));
-                    int ReservoirTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalWafersFaultLimit"));         
+                    int BathTotalDaysWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.BathTotalDaysWarningLimit"));
+                    int BathTotalDaysFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.BathTotalDaysFaultLimit"));
+                    double MembraneTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.MembraneTotalAmpHoursWarningLimit"));
+                    double MembraneTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.MembraneTotalAmpHoursFaultLimit"));
+                    int ReservoirTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.ReservoirTotalWafersWarningLimit"));
+                    int ReservoirTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Reservoir.{Module}.ReservoirTotalWafersFaultLimit"));         
                     ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Total Usage(AHr)", Value = $"{reservoirUsage.TotalUsage}", FaultLimit = $"{ReservoirTotalAmpHoursFaultLimit}", WarningLimit = $"{ReservoirTotalAmpHoursWarningLimit}" });
                     ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Bath Usage(AHr)", Value = $"{reservoirUsage.BathUsage}", FaultLimit = $"{BathTotalAmpHoursFaultLimit}", WarningLimit = $"{BathTotalAmpHoursWarningLimit}" });
                     //ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Anolyte Bath Usage(AHr)", Value = $"{reservoirUsage.AnodeUsage}", FaultLimit = $"{ANBathTotalAmpHoursFaultLimit}", WarningLimit = $"{ANBathTotalAmpHoursWarningLimit}" });

+ 10 - 3
CyberX8_RT/Modules/Metal/MetalEntity.cs

@@ -27,6 +27,8 @@ using CyberX8_RT.Devices.Reservoir;
 using CyberX8_RT.Modules.Metal;
 using CyberX8_RT.Modules.Reservoir;
 using CyberX8_RT.Modules;
+using CyberX8_RT.Modules.EFEM;
+using static Mono.Security.X509.X520;
 
 namespace CyberX8_RT.Modules.Metal
 {
@@ -114,6 +116,10 @@ namespace CyberX8_RT.Modules.Metal
         /// 所在reservoir名字
         /// </summary>
         private string _reservoirName;
+        /// <summary>
+        /// 当前完成recipe次数
+        /// </summary>
+        private int _currentCycleTimes;
         #endregion
 
         #region 属性
@@ -540,12 +546,12 @@ namespace CyberX8_RT.Modules.Metal
             if (_metalItem.SubType == STRATUS)
             {
                 _currentRunRecipeRoutine = _standardHotRunRecipeRoutine;
-                result = _standardHotRunRecipeRoutine.Start(recipe, _recipeSide) == RState.Running;
+                result = _standardHotRunRecipeRoutine.Start(recipe, _recipeSide,_cycle) == RState.Running;
             }
             else
             {
                 _currentRunRecipeRoutine = _compactEmbranceRunRecipeRoutine;
-                result = _compactEmbranceRunRecipeRoutine.Start(recipe, _recipeSide) == RState.Running;
+                result = _compactEmbranceRunRecipeRoutine.Start(recipe, _recipeSide, _cycle) == RState.Running;
             }
             if (result)
             {
@@ -553,7 +559,7 @@ namespace CyberX8_RT.Modules.Metal
                 {
                     WaferHolderInfo.MetalModuleName = Module;
                 }
-                _recipeTime = recipe.CalculateRecipeTotalTime();
+                _recipeTime = (recipe.CalculateRecipeTotalTime())*_cycle;
                 _currentRecipe = recipe;
                 if (WaferHolderInfo != null && WaferHolderInfo.SchedulerModules != null && WaferHolderInfo.SchedulerModules.Count != 0)
                 {
@@ -587,6 +593,7 @@ namespace CyberX8_RT.Modules.Metal
                         rsstate = RState.Failed;
                     }
                 }
+                _achievedCycle = _standardHotRunRecipeRoutine.GetCurrentCycle();
             }
             else
             {

+ 5 - 2
CyberX8_RT/Modules/Metal/ReservoirRunRecipeRoutine.cs

@@ -333,7 +333,6 @@ namespace CyberX8_RT.Modules.Metal
                 }
                
             }
-            
             _datas.Add(data);
         }
         /// <summary>
@@ -1079,9 +1078,13 @@ namespace CyberX8_RT.Modules.Metal
                 LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} Persistent Value Object is not exist");
                 return RState.Failed;
             }
-            _datas.Clear();
             _lotTackTime = DateTime.Now;
             return Runner.Start(Module, "Metal run recipe");
         }
+
+        public void clearLotTrack()
+        {
+            _datas.Clear();
+        }
     }
 }

+ 39 - 4
CyberX8_RT/Modules/Metal/StandardHotRunRecipeRoutine.cs

@@ -25,10 +25,12 @@ namespace CyberX8_RT.Modules.Metal
     {
         private enum RecipeStep
         {
+            LoopStart,
             WaferHolderClampOn,
             RunRecipe,
             RunRecipeWait,
             WaferHolderUnclampOn,
+            LoopEnd,
             End
         }
 
@@ -43,6 +45,14 @@ namespace CyberX8_RT.Modules.Metal
         /// </summary>
         private DepRecipe _recipe;
         /// <summary>
+        /// cycle次数
+        /// </summary>
+        private int _cycle;
+        /// <summary>
+        /// 当前完成的Cycle次数
+        /// </summary>
+        private int _currentCycle;
+        /// <summary>
         /// 单面
         /// </summary>
         private string _side;
@@ -97,15 +107,34 @@ namespace CyberX8_RT.Modules.Metal
         /// <returns></returns>
         public RState Monitor()
         {
-            Runner.Run(RecipeStep.WaferHolderClampOn, () => _device.WaferHolderClampOn("", null), () => _device.MetalDeviceData.WaferHolderClamp, _delay_1s)
-                .Run(RecipeStep.RunRecipe, () => _runRecipeRoutine.Start(new object[] { _recipe, _side }) == RState.Running, _delay_1ms)
-                .WaitWithStopCondition(RecipeStep.RunRecipeWait, () => CommonFunction.CheckRoutineEndState(_runRecipeRoutine), CheckRunRecipeStopStatus, ALL_DAY_MILLOSECONDS)
-                .Run(RecipeStep.WaferHolderUnclampOn, () => _device.WaferHolderClampOff("", null), () => !_device.MetalDeviceData.WaferHolderClamp, _delay_1s)
+            Runner.LoopStart(RecipeStep.LoopStart, "Loop Start Cycle StandardHotRunRecipeRoutine", _cycle, NullFun, _delay_1ms)
+                .LoopRun(RecipeStep.WaferHolderClampOn, () => _device.WaferHolderClampOn("", null), () => _device.MetalDeviceData.WaferHolderClamp, _delay_1s)
+                .LoopRun(RecipeStep.RunRecipe, () => _runRecipeRoutine.Start(new object[] { _recipe, _side }) == RState.Running, _delay_1ms)
+                .LoopRunWithStopStatus(RecipeStep.RunRecipeWait, () => CommonFunction.CheckRoutineEndState(_runRecipeRoutine), CheckRunRecipeStopStatus, ALL_DAY_MILLOSECONDS)
+                .LoopRun(RecipeStep.WaferHolderUnclampOn, () => _device.WaferHolderClampOff("", null), () => !_device.MetalDeviceData.WaferHolderClamp, _delay_1s)
+                .LoopEnd(RecipeStep.LoopEnd, UpdateCycleCount, _delay_1ms)
                 .End(RecipeStep.End, NullFun, _delay_1ms);
 
             return Runner.Status;
         }
         /// <summary>
+        /// 统计完成的Cycle次数
+        /// </summary>
+        /// <returns></returns>
+        private bool UpdateCycleCount()
+        {
+            _currentCycle += 1;
+            return true;
+        }
+        /// <summary>
+        /// 获取当前Cycle次数
+        /// </summary>
+        /// <returns></returns>
+        public int GetCurrentCycle()
+        {
+            return _currentCycle;
+        }
+        /// <summary>
         /// 启动
         /// </summary>
         /// <param name="objs"></param>
@@ -117,11 +146,17 @@ namespace CyberX8_RT.Modules.Metal
             {
                 _side = objs[1].ToString();
             }
+            if (objs.Length > 2)
+            {
+                _cycle = (int)objs[2];
+            }
             _device = DEVICE.GetDevice<StandardHotMetalDevice>(Module);
             if (!CheckPreCondition())
             {
                 return RState.Failed;
             }
+            _currentCycle = 0;
+            _runRecipeRoutine.clearLotTrack();//清除loaTrack里面的历史数据
             return Runner.Start(Module, "Start run recipe");
         }
         /// <summary>