using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using CyberX8_RT.Dispatch; using CyberX8_RT.Modules.Metal; using CyberX8_RT.Modules.Rinse; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.WaferHolder; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Schedulers { public class SchedulerQdrTimeManager: Singleton { #region 内部变量 private ConcurrentDictionary> _qdrScheduleTimeDic = new ConcurrentDictionary>(); #endregion /// /// 重置 /// /// /// public List ResetModuleOrder(List modules,SchedulerModulePartTime qdrPartTime) { List schedulerModuleUses = new List(); foreach (string module in modules) { SchedulerModuleUse moduleUse = new SchedulerModuleUse(); moduleUse.ModuleName = (ModuleName)Enum.Parse(typeof(ModuleName),module); int partUsedCount = qdrPartTime.GetModuleUsedCount(module); moduleUse.Used = _qdrScheduleTimeDic.ContainsKey(module.ToString()) ? _qdrScheduleTimeDic[module].Count+partUsedCount : 0+ partUsedCount; schedulerModuleUses.Add(moduleUse); } List results = schedulerModuleUses.OrderBy(O => O.Used).Select(O => O.ModuleName).ToList(); return results; } /// /// 按照计划时间排序 /// /// /// public List ResetModuleOrderBySchedulerEndTime(List modules,SchedulerModulePartTime partTime) { List schedulerModuleUses = new List(); foreach (string module in modules) { SchedulerModuleEndTime moduleEndTime = new SchedulerModuleEndTime(); moduleEndTime.ModuleName = (ModuleName)Enum.Parse(typeof(ModuleName), module); if (_qdrScheduleTimeDic.ContainsKey(module)) { List schedulerTimes = _qdrScheduleTimeDic[module].OrderBy(O => O.ScheduleStartTime).ToList(); SchedulerTime lastSchedulerTime = schedulerTimes.Last(); DateTime lastSchedulerEndTime = lastSchedulerTime.ScheduleStartTime.AddSeconds(lastSchedulerTime.ProcessTimeLength); DateTime partEndTime = partTime.GetLastSchedulerTime(module); if (partEndTime > lastSchedulerEndTime) { moduleEndTime.SchedulerEndTime = partEndTime; } else { moduleEndTime.SchedulerEndTime = lastSchedulerEndTime; } } else { moduleEndTime.SchedulerEndTime = DateTime.MinValue; } schedulerModuleUses.Add(moduleEndTime); } List results = schedulerModuleUses.OrderBy(O => O.SchedulerEndTime).Select(O => O.ModuleName).ToList(); return results; } /// /// 按照计划时间排序 /// /// /// public List ResetModuleOrderBySchedulerEndTime(List modules) { List schedulerModuleUses = new List(); foreach (IModuleEntity module in modules) { SchedulerModuleEndTime moduleEndTime = new SchedulerModuleEndTime(); moduleEndTime.ModuleName = module.Module; if (_qdrScheduleTimeDic.ContainsKey(module.Module.ToString())) { List schedulerTimes = _qdrScheduleTimeDic[module.Module.ToString()].OrderBy(O => O.ScheduleStartTime).ToList(); SchedulerTime lastSchedulerTime = schedulerTimes.Last(); DateTime lastSchedulerEndTime = lastSchedulerTime.ScheduleStartTime.AddSeconds(lastSchedulerTime.ProcessTimeLength); moduleEndTime.SchedulerEndTime = lastSchedulerEndTime; } else { moduleEndTime.SchedulerEndTime = DateTime.MinValue; } schedulerModuleUses.Add(moduleEndTime); } List results = schedulerModuleUses.OrderBy(O => O.SchedulerEndTime).Select(O => O.ModuleName).ToList(); return results; } /// /// 获取最后的时间轴对象 /// /// /// public SchedulerTime GetLastSchedulerTime(string metal) { if (_qdrScheduleTimeDic.ContainsKey(metal)) { List schedulerTimes = _qdrScheduleTimeDic[metal].OrderBy(O=>O.ScheduleStartTime).ToList(); if (schedulerTimes.Count != 0) { return schedulerTimes.Last(); } else { return null; } } else { return null; } } /// /// 增加 /// /// /// /// /// public void AddQdrScheduler(string qdr,string waferHolderId,int schedulerIndex,DateTime schedulerStartTime,int processTimeLength,bool writeQdrLog=true) { if (!_qdrScheduleTimeDic.ContainsKey(qdr)) { SchedulerTime qdrTime = new SchedulerTime(); qdrTime.WaferHolderId = waferHolderId; qdrTime.ScheduleStartTime = schedulerStartTime; qdrTime.ProcessTimeLength = processTimeLength; qdrTime.SchedulerIndex = schedulerIndex; List schedulerQdrTimes = new List(); schedulerQdrTimes.Add(qdrTime); _qdrScheduleTimeDic.TryAdd(qdr, schedulerQdrTimes); } else { List schedulerQdrTimes = _qdrScheduleTimeDic[qdr]; if(schedulerQdrTimes.Find(O=>O.WaferHolderId==waferHolderId&&O.SchedulerIndex==schedulerIndex) == null) { SchedulerTime qdrTime = new SchedulerTime(); qdrTime.WaferHolderId = waferHolderId; qdrTime.ScheduleStartTime = schedulerStartTime; qdrTime.ProcessTimeLength = processTimeLength; qdrTime.SchedulerIndex = schedulerIndex; schedulerQdrTimes.Add(qdrTime); } } if (writeQdrLog) { WriteQdrSchedulerTimeLog(); } LOG.WriteLog(eEvent.INFO_RINSE, qdr, $"add wafer shuttle {waferHolderId} scheduler {schedulerIndex} qdr {qdr} in scheduler time"); } /// /// 写Qdr调度时间轴日志 /// /// /// public void WriteQdrSchedulerTimeLog() { List keys = _qdrScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerQdrTimes = _qdrScheduleTimeDic[key].OrderBy(O=>O.ScheduleStartTime).ToList(); foreach (SchedulerTime item in schedulerQdrTimes) { DateTime startTime = item.ScheduleStartTime; DateTime endTime = startTime.AddSeconds(item.ProcessTimeLength); LOG.WriteLog(eEvent.INFO_RINSE, key, $"wafer shuttle {item.WaferHolderId} scheduler {item.SchedulerIndex} qdr {key} start time {startTime} end time {endTime} processLength {item.ProcessTimeLength} s"); } } } /// /// 更新QDR实际启动时间 /// /// /// public void UpdateQdrStartTime(string qdr,string waferHolderId,int schedulerIndex,DateTime startTime) { if (_qdrScheduleTimeDic.ContainsKey(qdr)) { List schedulerQdrTimes= _qdrScheduleTimeDic[qdr]; SchedulerTime schedulerQdrTime=schedulerQdrTimes.Find(O=>O.WaferHolderId==waferHolderId&&O.SchedulerIndex==schedulerIndex); if (schedulerQdrTime != null) { schedulerQdrTime.StartTime = startTime; if (schedulerQdrTime.StartTime > schedulerQdrTime.ScheduleStartTime) { LOG.WriteLog(eEvent.INFO_RINSE, qdr, $"wafer shuttle {waferHolderId} scheduler {schedulerIndex} qdr {qdr} start time {startTime} after scheduler start time {schedulerQdrTime.ScheduleStartTime}"); double interSeconds = schedulerQdrTime.StartTime.Subtract(schedulerQdrTime.ScheduleStartTime).TotalSeconds; schedulerQdrTime.ScheduleStartTime = schedulerQdrTime.StartTime; SchedulerMetalTimeManager.Instance.DelayMetalSchedulerStartTime(waferHolderId, schedulerIndex, interSeconds); DelayQdrSchedulerStartTime(waferHolderId, schedulerIndex, interSeconds); SchedulerDryerTimeManager.Instance.DelayDryerSchedulerStartTime(waferHolderId, schedulerIndex, interSeconds); SchedulerTransporterTimeManager.Instance.DelayTransporterSchedulerStartTime(waferHolderId, schedulerIndex, interSeconds); SchedulerWaferHolderTimeManager.Instance.DelayWaferHolderSchedulerStartTime(waferHolderId, schedulerIndex, interSeconds); } LOG.WriteLog(eEvent.INFO_RINSE, qdr, $"update wafer shuttle {waferHolderId} scheduler {schedulerIndex} qdr {qdr} start time {startTime}"); } } } /// /// 延后qdr后续时间 /// /// /// /// public void DelayQdrSchedulerStartTime(string waferHolderId, int schedulerIndex, double seconds) { List keys = _qdrScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerTimes = _qdrScheduleTimeDic[key]; List postSchedulerTimes = schedulerTimes.FindAll(O => O.WaferHolderId == waferHolderId && O.SchedulerIndex > schedulerIndex); foreach (SchedulerTime schedulerTime in postSchedulerTimes) { schedulerTime.ScheduleStartTime = schedulerTime.ScheduleStartTime.AddSeconds(seconds); } } } /// /// 移除 /// /// public void RemoveQdrStartTime(string qdr,string waferHolderId,int schedulerIndex) { if (_qdrScheduleTimeDic.ContainsKey(qdr)) { List schedulerQdrTimes = _qdrScheduleTimeDic[qdr]; SchedulerTime schedulerQdrTime = schedulerQdrTimes.Find(O => O.WaferHolderId == waferHolderId && O.SchedulerIndex == schedulerIndex); if (schedulerQdrTime != null) { LOG.WriteLog(eEvent.INFO_RINSE, qdr, $"remove wafer shuttle {waferHolderId} scheduler {schedulerIndex} qdr {qdr} in scheduler time"); schedulerQdrTimes.Remove(schedulerQdrTime); } if (schedulerQdrTimes.Count == 0) { _qdrScheduleTimeDic.TryRemove(qdr, out schedulerQdrTimes); LOG.WriteLog(eEvent.INFO_RINSE, qdr, $"delete wafer shuttle {waferHolderId} scheduler {schedulerIndex} qdr {qdr} in scheduler time"); } } } /// /// 检验QDR是否冲突 /// /// /// /// /// public (bool conflict,string waferHolderId,int schedluerIndex) CheckQdrConflict(string qdr,string waferHolderId, DateTime schedulerStartTime, int processTimeLength) { if (!_qdrScheduleTimeDic.ContainsKey(qdr)) { return (false, "", -1); } List schedulerQdrTimes= _qdrScheduleTimeDic[qdr]; foreach(SchedulerTime item in schedulerQdrTimes) { if (item.WaferHolderId == waferHolderId) { continue; } //if (WaferHolderManager.Instance.HasWaferHolder(qdr)) //{ // WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolder(qdr); // if (waferHolderInfo!=null) // { // WaferHolderTask waferHolderTask= WaferHolderTaskManager.Instance.GetWaferHolderTaskByWaferHolderId(waferHolderInfo.Id); // if (waferHolderTask != null) // { // return (true, waferHolderInfo.Id, waferHolderTask.GetCurrentSchedulerIndex()); // } // return (true, "", -1); // } // return (true, "", -1); //} bool result=CheckQdrTimeConflict(item,schedulerStartTime, processTimeLength); if (result) { return (true,item.WaferHolderId,item.SchedulerIndex); } } return (false, "", -1); } /// /// 判定时间是否冲突 /// /// /// /// /// private bool CheckQdrTimeConflict(SchedulerTime schedulerQdrTime, DateTime schedulerStartTime, int processTimeLength) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); DateTime schedulerEndTime = schedulerStartTime.AddSeconds(processTimeLength); DateTime qdrEndTime = schedulerQdrTime.ScheduleStartTime.AddSeconds(schedulerQdrTime.ProcessTimeLength); DateTime qdrStartTime= schedulerQdrTime.ScheduleStartTime; if (schedulerStartTime > qdrEndTime.AddSeconds(transporterTransferSeconds)) { return false; } if (schedulerEndTime.AddSeconds(transporterTransferSeconds) < qdrStartTime) { return false; } return true; } /// /// 计算QDR调度预计开始时间 /// /// /// public DateTime CalculateQdrSchedulerStartTime(DateTime dateTime,int depRecipeTimeLength) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); //DEP的Recipe时长+transporter传输时间 return dateTime.AddSeconds(depRecipeTimeLength).AddSeconds(transporterTransferSeconds); } /// /// 清除所有 /// public void RemoveAll() { List keys = _qdrScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerTimes = _qdrScheduleTimeDic[key]; schedulerTimes.Clear(); } _qdrScheduleTimeDic.Clear(); LOG.Write(eEvent.INFO_RINSE,"System", "Remove all qdr scheduler time"); } } }