using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using PunkHPX8_RT.Dispatch; using MECF.Framework.Common.Equipment; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Schedulers { public class SchedulerPlatingCellTimeManager: Singleton { #region 内部变量 private ConcurrentDictionary> _platingCellScheduleTimeDic = new ConcurrentDictionary>(); #endregion /// /// 计算PlatingCell已经使用次数 /// /// /// /// public int CalculatePlatingCellUsed(string platingCell,SchedulerModulePartTime platingCellPartTime) { int usedCount = _platingCellScheduleTimeDic.ContainsKey(platingCell) ? _platingCellScheduleTimeDic[platingCell].Count : 0; return platingCellPartTime.GetModuleUsedCount(platingCell) + usedCount; } /// /// 按照计划时间排序 /// /// /// public List ResetModuleOrderBySchedulerEndTime(List modules) { List schedulerModuleUses = new List(); foreach (IModuleEntity module in modules) { SchedulerModuleEndTime moduleEndTime = new SchedulerModuleEndTime(); moduleEndTime.ModuleName = module.Module; if (_platingCellScheduleTimeDic.ContainsKey(module.Module.ToString())) { List schedulerTimes = _platingCellScheduleTimeDic[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 platingCell) { if (_platingCellScheduleTimeDic.ContainsKey(platingCell)) { List schedulerTimes = _platingCellScheduleTimeDic[platingCell].OrderBy(O=>O.ScheduleStartTime).ToList(); if (schedulerTimes.Count != 0) { return schedulerTimes.Last(); } else { return null; } } else { return null; } } /// /// 增加 /// /// /// /// /// public void AddPlatingCellScheduler(string platingCell,string waferHolderId,int schedulerIndex,DateTime schedulerStartTime,int processTimeLength,bool writePlatingCellLog=true) { if (!_platingCellScheduleTimeDic.ContainsKey(platingCell)) { SchedulerTime platingCellTime = new SchedulerTime(); platingCellTime.WaferHolderId = waferHolderId; platingCellTime.ScheduleStartTime = schedulerStartTime; platingCellTime.ProcessTimeLength = processTimeLength; platingCellTime.SchedulerIndex = schedulerIndex; List schedulerPlatingCellTimes = new List(); schedulerPlatingCellTimes.Add(platingCellTime); _platingCellScheduleTimeDic.TryAdd(platingCell, schedulerPlatingCellTimes); } else { List schedulerPlatingCellTimes = _platingCellScheduleTimeDic[platingCell]; if(schedulerPlatingCellTimes.Find(O=>O.WaferHolderId==waferHolderId&&O.SchedulerIndex==schedulerIndex) == null) { SchedulerTime platingCellTime = new SchedulerTime(); platingCellTime.WaferHolderId = waferHolderId; platingCellTime.ScheduleStartTime = schedulerStartTime; platingCellTime.ProcessTimeLength = processTimeLength; platingCellTime.SchedulerIndex = schedulerIndex; schedulerPlatingCellTimes.Add(platingCellTime); } } if (writePlatingCellLog) { WritePlatingCellSchedulerTimeLog(); } LOG.WriteLog(eEvent.INFO_METAL, platingCell, $"add wafer shuttle {waferHolderId} scheduler {schedulerIndex} platingCell {platingCell} in scheduler time"); } /// /// 写PlatingCell调度时间轴日志 /// public void WritePlatingCellSchedulerTimeLog() { List keys = _platingCellScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerPlatingCellTimes = _platingCellScheduleTimeDic[key].OrderBy(O=>O.ScheduleStartTime).ToList(); foreach (SchedulerTime item in schedulerPlatingCellTimes) { DateTime startTime = item.ScheduleStartTime; DateTime endTime = startTime.AddSeconds(item.ProcessTimeLength); LOG.WriteLog(eEvent.INFO_METAL, key, $"wafer shuttle {item.WaferHolderId} scheduler {item.SchedulerIndex} platingCell {key} start time {startTime} end time {endTime} processLength {item.ProcessTimeLength} s"); } } } /// /// 更新PlatingCell实际启动时间 /// /// /// public void UpdatePlatingCellStartTime(string platingCell,string waferHolderId,int schedulerIndex,DateTime startTime) { if (_platingCellScheduleTimeDic.ContainsKey(platingCell)) { List schedulerPlatingCellTimes= _platingCellScheduleTimeDic[platingCell]; SchedulerTime schedulerPlatingCellTime=schedulerPlatingCellTimes.Find(O=>O.WaferHolderId==waferHolderId&&O.SchedulerIndex==schedulerIndex); if (schedulerPlatingCellTime != null) { schedulerPlatingCellTime.StartTime = startTime; if (schedulerPlatingCellTime.StartTime > schedulerPlatingCellTime.ScheduleStartTime) { LOG.WriteLog(eEvent.INFO_METAL, platingCell, $"wafer shuttle {waferHolderId} scheduler {schedulerIndex} platingCell {platingCell} start time {startTime} after scheduler start time {schedulerPlatingCellTime.ScheduleStartTime}"); double interSeconds = schedulerPlatingCellTime.StartTime.Subtract(schedulerPlatingCellTime.ScheduleStartTime).TotalSeconds; schedulerPlatingCellTime.ScheduleStartTime = schedulerPlatingCellTime.StartTime; DelayPlatingCellSchedulerStartTime(waferHolderId,schedulerIndex, interSeconds); SchedulerQdrTimeManager.Instance.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_METAL, platingCell, $"update wafer shuttle {waferHolderId} scheduler {schedulerIndex} platingCell {platingCell} start time {startTime}"); } } } /// /// 延后platingCell后续时间 /// /// /// /// public void DelayPlatingCellSchedulerStartTime(string waferHolderId,int schedulerIndex,double seconds) { List keys = _platingCellScheduleTimeDic.Keys.ToList(); foreach(string key in keys) { List schedulerTimes= _platingCellScheduleTimeDic[key]; List postSchedulerTimes= schedulerTimes.FindAll(O => O.WaferHolderId == waferHolderId && O.SchedulerIndex > schedulerIndex); foreach(SchedulerTime schedulerTime in postSchedulerTimes) { schedulerTime.ScheduleStartTime=schedulerTime.ScheduleStartTime.AddSeconds(seconds); } } } /// /// 是否为第一个PlatingCell /// /// /// /// private bool IsFirstPlatingCell(string waferHolderId,int scheduleIndex) { return false; } /// /// 移除 /// /// public void RemovePlatingCellStartTime(string platingCell,string waferHolderId,int schedulerIndex) { if (_platingCellScheduleTimeDic.ContainsKey(platingCell)) { List schedulerPlatingCellTimes = _platingCellScheduleTimeDic[platingCell]; SchedulerTime schedulerPlatingCellTime = schedulerPlatingCellTimes.Find(O => O.WaferHolderId == waferHolderId && O.SchedulerIndex == schedulerIndex); if (schedulerPlatingCellTime != null) { LOG.WriteLog(eEvent.INFO_RINSE, platingCell, $"remove wafer shuttle {waferHolderId} scheduler {schedulerIndex} platingCell {platingCell} in scheduler time"); schedulerPlatingCellTimes.Remove(schedulerPlatingCellTime); } if (schedulerPlatingCellTimes.Count == 0) { _platingCellScheduleTimeDic.TryRemove(platingCell, out schedulerPlatingCellTimes); LOG.WriteLog(eEvent.INFO_METAL, platingCell, $"delete wafer shuttle {waferHolderId} scheduler {schedulerIndex} platingCell {platingCell} in scheduler time"); } } } /// /// 检验PlatingCell是否冲突 /// /// /// /// /// public (bool conflict,string waferHolderId,int schedluerIndex) CheckPlatingCellConflict(string platingCell,string waferHolderId, DateTime schedulerStartTime, int processTimeLength) { if (!_platingCellScheduleTimeDic.ContainsKey(platingCell)) { return (false, "", -1); } List schedulerPlatingCellTimes= _platingCellScheduleTimeDic[platingCell]; foreach(SchedulerTime item in schedulerPlatingCellTimes) { if (item.WaferHolderId == waferHolderId) { continue; } //if (WaferHolderManager.Instance.HasWaferHolder(platingCell)) //{ // WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolder(platingCell); // if (waferHolderInfo==null) // { // return (true, "", -1); // } // WaferHolderTask waferHolderTask= WaferHolderTaskManager.Instance.GetWaferHolderTaskByWaferHolderId(waferHolderInfo.Id); // if (waferHolderTask != null) // { // return (true, waferHolderInfo.Id, waferHolderTask.GetCurrentSchedulerIndex()); // } // return (true, "", -1); //} bool result=CheckPlatingCellTimeConflict(item,schedulerStartTime, processTimeLength); if (result) { return (true,item.WaferHolderId,item.SchedulerIndex); } } return (false, "", -1); } /// /// 判定时间是否冲突 /// /// /// /// /// private bool CheckPlatingCellTimeConflict(SchedulerTime schedulerPlatingCellTime, DateTime schedulerStartTime, int processTimeLength) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); DateTime schedulerEndTime = schedulerStartTime.AddSeconds(processTimeLength); DateTime platingCellEndTime = schedulerPlatingCellTime.ScheduleStartTime.AddSeconds(schedulerPlatingCellTime.ProcessTimeLength); DateTime platingCellStartTime= schedulerPlatingCellTime.ScheduleStartTime; if (schedulerStartTime > platingCellEndTime.AddSeconds(transporterTransferSeconds)) { return false; } if (schedulerEndTime.AddSeconds(transporterTransferSeconds) < platingCellStartTime) { return false; } return true; } /// /// 清除所有 /// public void RemoveAll() { List keys = _platingCellScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerTimes = _platingCellScheduleTimeDic[key]; schedulerTimes.Clear(); } _platingCellScheduleTimeDic.Clear(); LOG.Write(eEvent.INFO_RINSE,"System", "Remove all platingCell scheduler time"); } /// /// 计算数量 /// /// /// public DateTime CalculateSchedulerEndTime(string platingCell) { if (_platingCellScheduleTimeDic.ContainsKey(platingCell)) { DateTime dateTime = DateTime.MinValue; foreach(var item in _platingCellScheduleTimeDic[platingCell]) { DateTime startTime = item.ScheduleStartTime; if (startTime.AddSeconds(item.ProcessTimeLength) > dateTime) { dateTime= startTime.AddSeconds(item.ProcessTimeLength); } } return dateTime; } else { return DateTime.MinValue; } } /// /// 是否包含 /// /// /// public bool ContainedPlatingCell(string platingCell) { return _platingCellScheduleTimeDic.ContainsKey(platingCell); } } }