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 SchedulerTransporterTimeManager : Singleton { #region 内部变量 private ConcurrentDictionary> _transScheduleTimeDic = new ConcurrentDictionary>(); #endregion /// /// 增加 /// /// /// /// /// public void AddTransporterScheduler(string transporter,string waferHolderId,int schedulerIndex,DateTime schedulerStartTime,bool writeQdrLog=true) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); if (!_transScheduleTimeDic.ContainsKey(transporter)) { SchedulerTime transporterTime = new SchedulerTime(); transporterTime.WaferHolderId = waferHolderId; transporterTime.ScheduleStartTime = schedulerStartTime; transporterTime.ProcessTimeLength = transporterTransferSeconds; transporterTime.SchedulerIndex = schedulerIndex; List schedulerTransporterTimes = new List(); schedulerTransporterTimes.Add(transporterTime); _transScheduleTimeDic.TryAdd(transporter, schedulerTransporterTimes); } else { List schedulerTransporterTimes = _transScheduleTimeDic[transporter]; if(schedulerTransporterTimes.Find(O=>O.WaferHolderId==waferHolderId&&O.SchedulerIndex==schedulerIndex) == null) { SchedulerTime transTime = new SchedulerTime(); transTime.WaferHolderId = waferHolderId; transTime.ScheduleStartTime = schedulerStartTime; transTime.ProcessTimeLength = transporterTransferSeconds; transTime.SchedulerIndex = schedulerIndex; schedulerTransporterTimes.Add(transTime); } } if (writeQdrLog) { WriteTransporterSchedulerTimeLog(); } LOG.WriteLog(eEvent.INFO_TRANSPORTER, transporter, $"add wafer shuttle {waferHolderId} scheduler {schedulerIndex} {transporter} in scheduler time"); } /// /// 写Transporter调度时间轴日志 /// /// /// public void WriteTransporterSchedulerTimeLog() { List keys = _transScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerTransporterTimes = _transScheduleTimeDic[key]; List reOrderTransporterTimes = schedulerTransporterTimes.OrderBy(O => O.ScheduleStartTime).ToList(); foreach (SchedulerTime item in reOrderTransporterTimes) { DateTime startTime = item.ScheduleStartTime; DateTime endTime = startTime.AddSeconds(item.ProcessTimeLength); LOG.WriteLog(eEvent.INFO_TRANSPORTER, key, $"wafer shuttle {item.WaferHolderId} scheduler {item.SchedulerIndex} transporter {key} start time {startTime} end time {endTime} processLength {item.ProcessTimeLength} s"); } } } /// /// 更新Transporter实际启动时间 /// /// /// public void UpdateTransporterStartTime(string transporter,string waferHolderId,int schedulerIndex,DateTime startTime) { if (_transScheduleTimeDic.ContainsKey(transporter)) { List schedulerTransporterTimes= _transScheduleTimeDic[transporter]; SchedulerTime schedulerTransporterTime=schedulerTransporterTimes.Find(O=>O.WaferHolderId==waferHolderId&&O.SchedulerIndex==schedulerIndex); if (schedulerTransporterTime != null) { schedulerTransporterTime.StartTime = startTime; LOG.WriteLog(eEvent.INFO_RINSE, transporter, $"update wafer shuttle {waferHolderId} scheduler {schedulerIndex} {transporter} start time {startTime}"); } } } /// /// 延后metal后续时间 /// /// /// /// public void DelayTransporterSchedulerStartTime(string waferHolderId, int schedulerIndex, double seconds) { List keys = _transScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerTimes = _transScheduleTimeDic[key]; List postSchedulerTimes = schedulerTimes.FindAll(O => O.WaferHolderId == waferHolderId && O.SchedulerIndex > schedulerIndex); foreach (SchedulerTime schedulerTime in postSchedulerTimes) { schedulerTime.ScheduleStartTime = schedulerTime.ScheduleStartTime.AddSeconds(seconds); } } } /// /// 是否已经包含 /// /// /// /// /// public bool Contained(string transporter,string waferHolderId,int schedulerIndex) { if (_transScheduleTimeDic.ContainsKey(transporter)) { List schedulerTimes= _transScheduleTimeDic[transporter]; return schedulerTimes.Find(O=>O.WaferHolderId==waferHolderId&&O.SchedulerIndex==schedulerIndex)!=null; } else { return false; } } /// /// 移除 /// /// public void RemoveTransporterStartTime(string transporter,string waferHolderId,int schedulerIndex) { if (_transScheduleTimeDic.ContainsKey(transporter)) { List schedulerTransporterTimes = _transScheduleTimeDic[transporter]; SchedulerTime schedulerTransporterTime = schedulerTransporterTimes.Find(O => O.WaferHolderId == waferHolderId && O.SchedulerIndex == schedulerIndex); if (schedulerTransporterTime != null) { LOG.WriteLog(eEvent.INFO_TRANSPORTER, transporter, $"remove wafer shuttle {waferHolderId} scheduler {schedulerIndex} transporter {transporter} in scheduler time"); schedulerTransporterTimes.Remove(schedulerTransporterTime); } if (schedulerTransporterTimes.Count == 0) { _transScheduleTimeDic.TryRemove(transporter, out schedulerTransporterTimes); LOG.WriteLog(eEvent.INFO_TRANSPORTER, transporter, $"delete wafer shuttle {waferHolderId} scheduler {schedulerIndex} transporter {transporter} in scheduler time"); } } } /// /// 检验Transporter是否冲突 /// /// /// /// /// public (bool conflict,string waferHolderId,int schedluerIndex) CheckTransporterConflict(string transporter,string waferHolderId, DateTime schedulerStartTime) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); if (!_transScheduleTimeDic.ContainsKey(transporter)) { return (false, "", -1); } List schedulerTransporterTimes= _transScheduleTimeDic[transporter]; foreach(SchedulerTime item in schedulerTransporterTimes) { if (item.WaferHolderId == waferHolderId) { continue; } bool result=CheckTransporterTimeConflict(item,schedulerStartTime); if (result) { return (true,item.WaferHolderId,item.SchedulerIndex); } } return (false, "", -1); } /// /// 判定时间是否冲突 /// /// /// /// /// private bool CheckTransporterTimeConflict(SchedulerTime schedulerTransporterTime, DateTime schedulerStartTime) { int transporterTransferSeconds = SC.GetValue("Transporter.TransporterTransferSeconds"); DateTime schedulerEndTime = schedulerStartTime.AddSeconds(transporterTransferSeconds); DateTime transporterStartTime= schedulerTransporterTime.ScheduleStartTime; DateTime transporterEndTime = schedulerTransporterTime.ScheduleStartTime.AddSeconds(schedulerTransporterTime.ProcessTimeLength); if (schedulerStartTime > transporterEndTime) { return false; } if (schedulerEndTime < transporterStartTime) { return false; } return true; } /// /// 清除所有 /// public void RemoveAll() { List keys = _transScheduleTimeDic.Keys.ToList(); foreach (string key in keys) { List schedulerTimes = _transScheduleTimeDic[key]; schedulerTimes.Clear(); } _transScheduleTimeDic.Clear(); LOG.Write(eEvent.INFO_RINSE,"System", "Remove all transporter scheduler time"); } /// /// 获取当前Transporter1的调度情况 /// /// /// public (string waferHolderId,int sequenceIndex) GetCurrentTransporter1Scheduler(DateTime dateTime) { if (!_transScheduleTimeDic.ContainsKey(ModuleName.Transporter1.ToString())) { return ("", -1); } List schedulerTimes=_transScheduleTimeDic[(ModuleName.Transporter1.ToString())]; foreach (SchedulerTime item in schedulerTimes) { bool conflict = CheckTransporterTimeConflict(item, dateTime); if (conflict) { return (item.WaferHolderId,item.SchedulerIndex); } } return ("", -1); } } }