using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using CyberX8_RT.Dispatch; using CyberX8_RT.Dispatch; using CyberX8_RT.Schedulers.Transporter; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.WaferHolder; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Schedulers { public class SchedulerWaferHolderTimeManager : Singleton { #region /// /// WaferHolder 模块时间轴字点 /// private Dictionary _waferHolderTimeDic = new Dictionary(); #endregion /// /// 返回调度字典 /// /// public Dictionary GetWaferHolderTimeDic() { return _waferHolderTimeDic; } /// /// 增加 /// /// /// /// /// /// public void AddWaferHolderTime(string waferHolderId, string module,ModuleType moduleType, int schedulerIndex, DateTime schedulerStartTime, int processTimeLength) { SchedulerWaferHolderTime schedulerWaferHolderTime = null; if (_waferHolderTimeDic.ContainsKey(waferHolderId)) { schedulerWaferHolderTime = _waferHolderTimeDic[waferHolderId]; } else { schedulerWaferHolderTime = new SchedulerWaferHolderTime(); schedulerWaferHolderTime.WaferHolderId = waferHolderId; schedulerWaferHolderTime.ModuleTimes = new List(); _waferHolderTimeDic[waferHolderId] = schedulerWaferHolderTime; } SchedulerWaferHolderModuleTime moduleTime = schedulerWaferHolderTime.ModuleTimes.Find(O => O.Module == module && O.SchedulerIndex == schedulerIndex); if (moduleTime == null) { moduleTime = new SchedulerWaferHolderModuleTime(); moduleTime.Module = module; moduleTime.SchedulerIndex = schedulerIndex; moduleTime.ScheduleStartTime = schedulerStartTime; moduleTime.ProcessTimeLength = processTimeLength; moduleTime.ModuleType = moduleType; schedulerWaferHolderTime.ModuleTimes.Add(moduleTime); } } /// /// 是否包含 /// /// /// public bool Contained(string waferHolder) { return _waferHolderTimeDic.ContainsKey(waferHolder); } /// /// 移除 /// /// public void RemoveWaferHolderTime(string waferHolderId) { if (_waferHolderTimeDic.ContainsKey(waferHolderId)) { _waferHolderTimeDic.Remove(waferHolderId); } } /// /// 写Dryer调度时间轴日志 /// public void WriteSchedulerTimeLog(string waferHolderId) { if (!_waferHolderTimeDic.ContainsKey(waferHolderId)) { return; } SchedulerWaferHolderTime waferHolderTime = _waferHolderTimeDic[waferHolderId]; List schedulerWaferHolderModuleTimes= waferHolderTime.ModuleTimes.OrderBy(O => O.SchedulerIndex).ToList(); foreach (var item in schedulerWaferHolderModuleTimes) { DateTime startTime = item.ScheduleStartTime; if (item.StartTime != DateTime.MinValue) { startTime = item.StartTime; } DateTime endTime = startTime.AddSeconds(item.ProcessTimeLength); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"wafer shuttle {waferHolderId} scheduler {item.SchedulerIndex} module {item.Module} start time {startTime} end time {endTime} processLength {item.ProcessTimeLength} s"); } } /// /// 移除所有WaferHolder dryer时间轴 /// public void RemoveAllWaferHolderDryerCell(string waferHolderId) { List waferHolderIds = _waferHolderTimeDic.Keys.ToList(); foreach (string key in waferHolderIds) { RemoveWaferHolderDryerCell(key,waferHolderId); } } /// /// 移除指定WaferHolder dryer时间轴 /// /// private void RemoveWaferHolderDryerCell(string waferHolderId,string errorWaferHolderId) { WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolderInfoById(waferHolderId); if (waferHolderInfo == null) { return; } if (!_waferHolderTimeDic.ContainsKey(waferHolderId)) { return; } WaferHolderTask waferHolderTask = WaferHolderTaskManager.Instance.GetWaferHolderTaskByWaferHolderId(waferHolderId); if (waferHolderTask == null) { return; } int sequenceIndex = waferHolderTask.GetCurrentSchedulerIndex(); SchedulerSequence schedulerSequence = waferHolderTask.GetCurrentSchedulerSequence(); int dryerSequenceIndex = sequenceIndex; if (waferHolderId != errorWaferHolderId) { if (schedulerSequence.ModuleType == ModuleType.Dryer) { return; } if (sequenceIndex == waferHolderTask.SchedulerSequences.Count - 1) { return; } for (int i = waferHolderTask.SchedulerSequences.Count - 1; i >= 0; i--) { SchedulerSequence dryerSequence = waferHolderTask.SchedulerSequences[i]; if (dryerSequence.ModuleType == ModuleType.Dryer) { dryerSequenceIndex = i; break; } } } else { dryerSequenceIndex = sequenceIndex; } SchedulerWaferHolderTime waferHolderTime = _waferHolderTimeDic[waferHolderId]; SchedulerWaferHolderModuleTime lastModuleTime = waferHolderTime.ModuleTimes[waferHolderTime.ModuleTimes.Count - 1]; DateTime lastEndTime = lastModuleTime.ScheduleStartTime.AddSeconds(lastModuleTime.ProcessTimeLength); for (int i = waferHolderTime.ModuleTimes.Count - 1; i >= 0; i--) { SchedulerWaferHolderModuleTime moduleTime = waferHolderTime.ModuleTimes[i]; if (moduleTime.SchedulerIndex == dryerSequenceIndex) { RemoveModuleTime(moduleTime.ModuleType, moduleTime.Module, waferHolderId, moduleTime.SchedulerIndex); RemoveWaferTaskScheduler(waferHolderTask, moduleTime.SchedulerIndex); waferHolderTime.ModuleTimes.RemoveAt(i); RemoveLastTransporterScheduler(dryerSequenceIndex, waferHolderTask, waferHolderTime); break; } } if (waferHolderId == errorWaferHolderId) { waferHolderTime.ResProcessLength = lastModuleTime.ProcessTimeLength; } else { waferHolderTime.ResProcessLength = lastEndTime.Subtract(DateTime.Now).TotalSeconds; } //dryer索引前面QDR索引 waferHolderTime.LastSequenceIndex = waferHolderTime.ModuleTimes[waferHolderTime.ModuleTimes.Count-1].SchedulerIndex; } /// /// 移除上一个transporter调度 /// /// /// private void RemoveLastTransporterScheduler(int dryerIndex,WaferHolderTask waferHolderTask, SchedulerWaferHolderTime waferHolderTime) { int transporterIndex = -1; for(int i = dryerIndex - 1; i >= 0; i--) { SchedulerSequence sequence = waferHolderTask.SchedulerSequences[i]; if (sequence.State == CyberX8_Core.RState.End) { continue; } if (sequence.ModuleName == ModuleName.Transporter1) { transporterIndex = i; break; } } if (transporterIndex == -1) { return; } int index= waferHolderTime.ModuleTimes.FindIndex(O => O.SchedulerIndex == transporterIndex); if (index == -1) { return; } SchedulerWaferHolderModuleTime moduleTime = waferHolderTime.ModuleTimes[index]; RemoveModuleTime(moduleTime.ModuleType, moduleTime.Module, waferHolderTime.WaferHolderId, moduleTime.SchedulerIndex); RemoveWaferTaskScheduler(waferHolderTask, moduleTime.SchedulerIndex); waferHolderTime.ModuleTimes.RemoveAt(index); } /// /// 移除其他WaferHolder后续的cell时间轴 /// /// public void RemoveOtherWaferHolderAfterCell(string waferHolderId,bool isRemoveCurrentSequence) { List waferHolderIds = _waferHolderTimeDic.Keys.ToList(); foreach(string key in waferHolderIds) { RemoveWaferHolderAfterCell(key,waferHolderId,isRemoveCurrentSequence); } } /// /// 移除WaferHolder后绪Cell时间轴 /// /// private void RemoveWaferHolderAfterCell(string waferHolderId,string errorWaferHolderId,bool isRemoveCurrentSequence) { WaferHolderInfo waferHolderInfo=WaferHolderManager.Instance.GetWaferHolderInfoById(waferHolderId); if (waferHolderInfo == null) { return; } if (!_waferHolderTimeDic.ContainsKey(waferHolderId)) { return; } string location = waferHolderInfo.CurrentLocation; ModuleName moduleName=(ModuleName)Enum.Parse(typeof(ModuleName), location); WaferHolderTask waferHolderTask=WaferHolderTaskManager.Instance.GetWaferHolderTaskByWaferHolderId(waferHolderId); if (waferHolderTask == null) { return; } int sequenceIndex = waferHolderTask.GetCurrentSchedulerIndex(); SchedulerSequence schedulerSequence = waferHolderTask.GetCurrentSchedulerSequence(); if (schedulerSequence.ModuleType == ModuleType.Transporter) { sequenceIndex = sequenceIndex + 1; } SchedulerWaferHolderTime waferHolderTime = _waferHolderTimeDic[waferHolderId]; SchedulerWaferHolderModuleTime lastModuleTime = waferHolderTime.ModuleTimes[waferHolderTime.ModuleTimes.Count - 1]; DateTime lastEndTime = lastModuleTime.ScheduleStartTime.AddSeconds(lastModuleTime.ProcessTimeLength); int errorLeftSeconds = 0; //出错模块计算剩余时长 if (waferHolderId == errorWaferHolderId) { List sequences = waferHolderTask.SchedulerSequences; for (int i = 0; i < waferHolderTime.ModuleTimes.Count; i++) { SchedulerWaferHolderModuleTime moduleTime = waferHolderTime.ModuleTimes[i]; if (moduleTime.SchedulerIndex > sequenceIndex) { SchedulerSequence sequence = sequences[moduleTime.SchedulerIndex]; if (sequence.State == CyberX8_Core.RState.End) { continue; } errorLeftSeconds += CalculateSequenceProcessTime(sequence); } if (isRemoveCurrentSequence&&moduleTime.SchedulerIndex==sequenceIndex) { SchedulerSequence sequence = sequences[moduleTime.SchedulerIndex]; errorLeftSeconds += CalculateSequenceProcessTime(sequence); } } } for (int i = waferHolderTime.ModuleTimes.Count-1; i >=0; i--) { SchedulerWaferHolderModuleTime moduleTime=waferHolderTime.ModuleTimes[i]; if (moduleTime.SchedulerIndex > sequenceIndex) { RemoveModuleTime(moduleTime.ModuleType, moduleTime.Module, waferHolderId, moduleTime.SchedulerIndex); RemoveWaferTaskScheduler(waferHolderTask, moduleTime.SchedulerIndex); waferHolderTime.ModuleTimes.RemoveAt(i); } if (waferHolderId == errorWaferHolderId) { if (!isRemoveCurrentSequence) { if (moduleTime.SchedulerIndex == sequenceIndex) { moduleTime.ProcessTimeLength = (int)DateTime.Now.Subtract(moduleTime.ScheduleStartTime).TotalSeconds; } } else { if (moduleTime.SchedulerIndex == sequenceIndex) { RemoveModuleTime(moduleTime.ModuleType, moduleTime.Module, waferHolderId, moduleTime.SchedulerIndex); waferHolderTime.ModuleTimes.RemoveAt(i); } else if(moduleTime.SchedulerIndex == sequenceIndex - 1) { RemoveModuleTime(moduleTime.ModuleType, moduleTime.Module, waferHolderId, moduleTime.SchedulerIndex); waferHolderTime.ModuleTimes.RemoveAt(i); } } } } //剩余未处理总时长 if (waferHolderId != errorWaferHolderId) { waferHolderTime.ResProcessLength = lastEndTime.Subtract(DateTime.Now).TotalSeconds; waferHolderTime.LastSequenceIndex = sequenceIndex; } else { waferHolderTime.ResProcessLength = errorLeftSeconds; if (isRemoveCurrentSequence) { waferHolderTime.LastSequenceIndex = sequenceIndex - 2; } else { waferHolderTime.LastSequenceIndex = sequenceIndex; } } } /// /// 计算调度Sequence时长 /// /// /// private int CalculateSequenceProcessTime(SchedulerSequence sequence) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); if (sequence.ModuleType == ModuleType.Transporter) { return transporterTransferSeconds; } else if (sequence.ModuleType == ModuleType.Metal) { if(sequence.Recipe is DepRecipe) { DepRecipe depRecipe = (DepRecipe)sequence.Recipe; return depRecipe.CalculateRecipeTotalTime(); } } else if (sequence.ModuleType == ModuleType.Rinse) { if(sequence.Recipe is QdrRecipe) { QdrRecipe qdrRecipe = (QdrRecipe)sequence.Recipe; return qdrRecipe.CalculateRunRecipeTime(); } } else if (sequence.ModuleType == ModuleType.Dryer) { if(sequence.Recipe is HvdRecipe) { HvdRecipe hvdRecipe = (HvdRecipe)sequence.Recipe; return hvdRecipe.DryTime; } } return 0; } /// /// 移除WaferHolder任务调度 /// /// /// private void RemoveWaferTaskScheduler(WaferHolderTask waferHolderTask,int sequenceIndex) { SchedulerSequence preSequence = waferHolderTask.GetSchedulerSequenceByIndex(sequenceIndex - 1); if (preSequence.ModuleName != ModuleName.Transporter1) { return; } if(!(preSequence.Parameters is TransporterAction)) { return; } TransporterAction action=preSequence.Parameters as TransporterAction; WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter; waferHolderMoveItem.DestModule = ModuleName.Unknown; SchedulerSequence sequence=waferHolderTask.GetSchedulerSequenceByIndex(sequenceIndex); sequence.ModuleName = ModuleName.Unknown; sequence.SchedulerModule = null; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"wafer shuttle {waferHolderTask.WaferHolderInfo.Id} scheduler {sequenceIndex} module changed to unkown"); } /// /// 移除模块时间轴 /// /// /// /// /// private void RemoveModuleTime(ModuleType moduleType,string module,string waferHolderId,int sequenceIndex) { switch (moduleType) { case ModuleType.Metal: SchedulerMetalTimeManager.Instance.RemoveMetalStartTime(module, waferHolderId, sequenceIndex); break; case ModuleType.Rinse: SchedulerQdrTimeManager.Instance.RemoveQdrStartTime(module, waferHolderId, sequenceIndex); break; case ModuleType.Dryer: SchedulerDryerTimeManager.Instance.RemoveDryerStartTime(module, waferHolderId, sequenceIndex); break; case ModuleType.Transporter: if (module == ModuleName.Transporter1.ToString()) { SchedulerTransporterTimeManager.Instance.RemoveTransporterStartTime(module, waferHolderId, sequenceIndex); } break; default: break; } } /// /// 所有WaferHolder重新调度 /// public void ResetScheduler(string waferHolderId,DateTime startTime) { List waferHolderIds = _waferHolderTimeDic.Keys.ToList(); List schedulerWaferHolderTimes = new List(); foreach(var key in waferHolderIds) { //过滤已经到了Dryer的WaferShuttle if (key != waferHolderId) { WaferHolderTask waferHolderTask = WaferHolderTaskManager.Instance.GetWaferHolderTaskByWaferHolderId(key); if (waferHolderTask == null) { continue; } SchedulerSequence currentSequence = waferHolderTask.GetCurrentSchedulerSequence(); if (currentSequence.ModuleType == ModuleType.Dryer) { continue; } } SchedulerWaferHolderTime schedulerWaferHolderTime = _waferHolderTimeDic[key]; schedulerWaferHolderTimes.Add(schedulerWaferHolderTime); } List resetWaferHolderTimeLst= schedulerWaferHolderTimes.OrderBy(O => O.ResProcessLength).ToList(); foreach(SchedulerWaferHolderTime item in resetWaferHolderTimeLst) { SchedulerWaferHolderModuleTime moduleTime= item.ModuleTimes.Find(O => O.SchedulerIndex == item.LastSequenceIndex); if (moduleTime == null) { continue; } DateTime dateTime = DateTime.MinValue; if (waferHolderId == item.WaferHolderId) { dateTime = startTime; } else { dateTime=moduleTime.ScheduleStartTime.AddSeconds(moduleTime.ProcessTimeLength); } ResetSchedulerWaferHolder(item.WaferHolderId,dateTime,item.LastSequenceIndex+1); } } /// /// 重新调度 /// /// private void ResetSchedulerWaferHolder(string waferHolderId,DateTime startTime,int sequenceIndex) { WaferHolderTask waferHolderTask = WaferHolderTaskManager.Instance.GetWaferHolderTaskByWaferHolderId(waferHolderId); if (waferHolderTask == null) { return; } List sequences = waferHolderTask.SchedulerSequences; bool result= SchedulerModuleTimeManager.Instance.ConfirmAllMetalQdrAndDryer(sequences, waferHolderId, sequenceIndex, false,startTime); if (!result) { LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"wafer shuttle {waferHolderTask.WaferHolderInfo.Id} scheduler {sequenceIndex} reset scheduler failed"); } } /// /// 清除所有数据 /// public void RemoveAllWaferHolder() { List keys = _waferHolderTimeDic.Keys.ToList(); foreach (string item in keys) { SchedulerWaferHolderTime moduleTime = _waferHolderTimeDic[item]; moduleTime.Dispose(); } _waferHolderTimeDic.Clear(); } /// /// 延后metal后续时间 /// /// /// /// public void DelayWaferHolderSchedulerStartTime(string waferHolderId, int schedulerIndex, double seconds) { if (_waferHolderTimeDic.ContainsKey(waferHolderId)) { SchedulerWaferHolderTime waferHolderTime = _waferHolderTimeDic[waferHolderId]; List moduleTimes = waferHolderTime.ModuleTimes.FindAll(O => O.SchedulerIndex >= schedulerIndex); foreach (var item in moduleTimes) { item.ScheduleStartTime = item.ScheduleStartTime.AddSeconds(seconds); } WriteSchedulerTimeLog(waferHolderId); } } /// /// 获取WaferHolder模块调度起始时间 /// /// /// /// /// public DateTime GetWaferHolderModuleSchedulerStartTime(string waferHolderId,string module,int schedulerIndex) { if (!_waferHolderTimeDic.ContainsKey(waferHolderId)) { return DateTime.MinValue; } SchedulerWaferHolderTime waferHolderTime = _waferHolderTimeDic[waferHolderId]; SchedulerWaferHolderModuleTime waferHolderModuleTime= waferHolderTime.ModuleTimes.Find(O => O.SchedulerIndex == schedulerIndex && O.Module == module); if (waferHolderModuleTime == null) { return DateTime.MinValue; } return waferHolderModuleTime.ScheduleStartTime; } } }