using Aitex.Core.RT.Fsm; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using PunkHPX8_RT.Modules; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.RecipeCenter; using SecsGem.Core.ItemModel; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Schedulers { public class SchedulerModuleTimeManager : Singleton { /// /// 确定后面所有Metal、Qdr和Dryer资源 /// /// /// /// /// /// /// public bool ConfirmAllMetalQdrAndDryer(List schedulerSequences, string waferHolderId, int sequenceIndex,bool checkConflict,DateTime startTime) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); var avaibleResults = AnalyseAfterAvaibleCell(schedulerSequences, startTime, waferHolderId, sequenceIndex,checkConflict); if (!avaibleResults.success) { return false; } if (avaibleResults.results.Count == 0 && avaibleResults.rinseResults.Item2 == ModuleName.Unknown && avaibleResults.dryerResults.Item2 == ModuleName.Unknown) { return false; } SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime(); SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime(); SchedulerModulePartTime dryerPartTime = new SchedulerModulePartTime(); //处理metal和Rinse for (int i = 0; i < avaibleResults.results.Count; i++) { var item = avaibleResults.results[i]; int index = item.Item1; SchedulerSequence sequence = schedulerSequences[index]; if (sequence.State == PunkHPX8_Core.RState.End) { continue; } if (sequence.ModuleName != ModuleName.Transporter1) { continue; } SchedulerSequence metalSequence = schedulerSequences[index + 1]; if (metalSequence.ModuleType != ModuleType.Metal) { continue; } DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe; QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe; int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime(); int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime(); DateTime metalStartTime = item.Item4.AddSeconds(transporterTransferSeconds); if (metalSequence.SchedulerModule == null) { metalSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item2); metalSequence.ModuleName = item.Item2; } if (!checkConflict) { SchedulerTime lastSchedulerTime = SchedulerMetalTimeManager.Instance.GetLastSchedulerTime(item.Item2.ToString()); DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, metalPartTime, item.Item2.ToString(), depRecipeTimeLength, transporterTransferSeconds); if (lastSchedulerEndTime > metalStartTime) { metalStartTime = lastSchedulerEndTime; } } SchedulerMetalTimeManager.Instance.AddMetalScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime, depRecipeTimeLength, false); SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item2.ToString(), ModuleType.Metal, index + 1, metalStartTime, depRecipeTimeLength); metalPartTime.AddScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime, depRecipeTimeLength); if (index + 3 >= schedulerSequences.Count) { continue; } //增加了transporter时间轴 SchedulerTransporterTimeManager.Instance.AddTransporterScheduler(ModuleName.Transporter1.ToString(), waferHolderId, index + 2, metalStartTime.AddSeconds(depRecipeTimeLength), false); SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, ModuleName.Transporter1.ToString(), ModuleType.Transporter, index + 2, metalStartTime.AddSeconds(depRecipeTimeLength), transporterTransferSeconds); SchedulerSequence qdrSequence = schedulerSequences[index + 3]; if (qdrSequence.ModuleType != ModuleType.Rinse) { continue; } if (qdrSequence.SchedulerModule == null) { qdrSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item3); qdrSequence.ModuleName = item.Item3; } DateTime schedulerQdrStartTime = SchedulerQdrTimeManager.Instance.CalculateQdrSchedulerStartTime(metalStartTime, depRecipeTimeLength); if (!checkConflict) { SchedulerTime lastSchedulerTime = SchedulerQdrTimeManager.Instance.GetLastSchedulerTime(item.Item3.ToString()); DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, qdrPartTime, item.Item3.ToString(), qdrRecipeTimeLength, transporterTransferSeconds); if (lastSchedulerEndTime > schedulerQdrStartTime) { schedulerQdrStartTime = lastSchedulerEndTime; } } SchedulerQdrTimeManager.Instance.AddQdrScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength, false); SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item3.ToString(),ModuleType.Rinse, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength); qdrPartTime.AddScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength); //增加了transporter时间轴 SchedulerTransporterTimeManager.Instance.AddTransporterScheduler(ModuleName.Transporter1.ToString(), waferHolderId, index + 4, schedulerQdrStartTime.AddSeconds(qdrRecipeTimeLength), false); SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, ModuleName.Transporter1.ToString(), ModuleType.Transporter, index + 4, schedulerQdrStartTime.AddSeconds(qdrRecipeTimeLength), transporterTransferSeconds); } //处理单独Rinse if (avaibleResults.rinseResults.Item2 != ModuleName.Unknown) { int transporterIndex = avaibleResults.rinseResults.Item1; SchedulerSequence transporterSequence = schedulerSequences[transporterIndex]; if (transporterSequence.State != PunkHPX8_Core.RState.End) { //增加了transporter时间轴 SchedulerTransporterTimeManager.Instance.AddTransporterScheduler(ModuleName.Transporter1.ToString(), waferHolderId, transporterIndex, avaibleResults.rinseResults.Item3, false); SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, ModuleName.Transporter1.ToString(), ModuleType.Transporter, transporterIndex, avaibleResults.rinseResults.Item3, transporterTransferSeconds); } } //处理Dryer if (avaibleResults.dryerResults.Item2 != ModuleName.Unknown) { int transporterIndex = avaibleResults.dryerResults.Item1; SchedulerSequence transporterSequence = schedulerSequences[transporterIndex]; } SchedulerMetalTimeManager.Instance.WriteMetalSchedulerTimeLog(); SchedulerQdrTimeManager.Instance.WriteQdrSchedulerTimeLog(); SchedulerDryerTimeManager.Instance.WriteDryerSchedulerTimeLog(); SchedulerTransporterTimeManager.Instance.WriteTransporterSchedulerTimeLog(); SchedulerWaferHolderTimeManager.Instance.WriteSchedulerTimeLog(waferHolderId); qdrPartTime.Dispose(); metalPartTime.Dispose(); dryerPartTime.Dispose(); return true; } /// /// 获取最新调度时间 /// /// /// /// /// /// /// private DateTime GetModuleLastSchedulerEndTime(SchedulerTime schedulerTime,SchedulerModulePartTime partTime,string module,int recipeLength,int transporterTransferSeconds) { DateTime lastSchedulerEndTime = DateTime.MinValue; if (schedulerTime != null) { lastSchedulerEndTime = schedulerTime.ScheduleStartTime.AddSeconds(recipeLength).AddSeconds(transporterTransferSeconds); } DateTime lastPartTime = partTime.GetLastSchedulerTime(module); if (lastPartTime.AddSeconds(transporterTransferSeconds) > lastSchedulerEndTime) { lastSchedulerEndTime = lastPartTime.AddSeconds(transporterTransferSeconds); } return lastSchedulerEndTime; } /// /// 分析后面所有Cell可用资源 /// sequenceIndex为transporter对应的索引 /// /// /// /// /// public (bool success,List<(int, ModuleName, ModuleName, DateTime)> results, (int, ModuleName, DateTime) rinseResults,(int, ModuleName, DateTime) dryerResults) AnalyseAfterAvaibleCell(List schedulerSequences, DateTime startTime, string waferHolderId, int sequenceIndex,bool checkConflict) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); List<(int, ModuleName, ModuleName, DateTime)> results = new List<(int, ModuleName, ModuleName, DateTime)>(); var dryerResults = new ValueTuple(); dryerResults.Item2 = ModuleName.Unknown; var rinseResults = new ValueTuple(); rinseResults.Item2 = ModuleName.Unknown; SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime(); SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime(); for (int i = sequenceIndex; i < schedulerSequences.Count; i++) { SchedulerSequence sequence = schedulerSequences[i]; if (sequence.State == PunkHPX8_Core.RState.End) { continue; } if (sequence.ModuleName != ModuleName.Transporter1) { continue; } SchedulerSequence metalSequence = schedulerSequences[i + 1]; if (metalSequence.Recipe == null || !(metalSequence.Recipe is DepRecipe)) { continue; } DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe; QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe; int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime(); int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime(); startTime = startTime.AddSeconds(transporterTransferSeconds).AddSeconds(depRecipeTimeLength) .AddSeconds(transporterTransferSeconds).AddSeconds(qdrRecipeTimeLength); i += 3; } metalPartTime.Dispose(); qdrPartTime.Dispose(); return (true, results,rinseResults, dryerResults); } } }