using Aitex.Core.Common; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.DBCore; using MECF.Framework.Common.Jobs; using MECF.Framework.Common.Routine; using MECF.Framework.Common.SubstrateTrackings; using CyberX8_Core; using CyberX8_RT.Modules; using CyberX8_RT.Schedulers; using SecsGem.Core.ItemModel; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.RT.Log; namespace CyberX8_RT.Dispatch { public class JobDispatcher : ICycle { #region 内部变量 /// /// 状态 /// private RState _cycleState = RState.Init; /// /// Cycle计时器 /// private Stopwatch _cycleWatch = new Stopwatch(); #endregion /// /// 是否存在Job /// public bool HasJobRunning => JobProcesser.Instance.ControlJobInfos.Count > 0; /// /// 状态 /// public RState CycleState => _cycleState; /// /// 构造函数 /// public JobDispatcher() { SchedulerManager.Instance.Initialize(); CycleManager.Instance.Initialize(); } public void Abort() { } #region Job /// /// 创建任务 /// /// /// /// public bool CreateJob(Dictionary param, out string reason) { return JobProcesser.Instance.CreateJob(param, out reason); } /// /// 暂停所有任务 /// /// public bool PauseAllJobs() { foreach(var job in JobProcesser.Instance.ControlJobInfos) { bool result = JobProcesser.Instance.PauseJob(job.Name,out string reason); if(!result) { return false; } } _cycleState = RState.Paused; WaferHolderTaskManager.Instance.PauseAllTask(); WaferTaskManager.Instance.PauseAllTask(); return true; } /// /// 暂停Job /// /// /// /// public bool PauseJob(string jobName, out string reason) { bool result = JobProcesser.Instance.PauseJob(jobName, out reason); if(result) { if (!JobProcesser.Instance.ControlJobInfos.Exists(job => job.State == EnumControlJobState.Executing)) _cycleState = RState.Paused; } return result; } /// /// 恢复所有任务 /// /// public bool ResumeAllJobs() { foreach (var job in JobProcesser.Instance.ControlJobInfos) { bool result = JobProcesser.Instance.ResumeJob(job.Name, out string reason); if (!result) { return false; } } WaferHolderTaskManager.Instance.ResumeAllTask(); WaferTaskManager.Instance.ResumeAllTask(); _cycleState = RState.Running; return true; } /// /// 恢复Job /// /// /// /// public bool ResumeJob(string jobName, out string reason) { bool result=JobProcesser.Instance.ResumeJob(jobName, out reason); if(result) { _cycleState = RState.Running; } return result; } /// /// 启动任务 /// /// /// /// /// public bool StartJob(string jobName, out string reason) { bool result = JobProcesser.Instance.StartJob(jobName, out reason); if(result) { ControlJobInfo cj = JobProcesser.Instance.ControlJobInfos.Find(x => x.Name == jobName); if (!_cycleWatch.IsRunning) { _cycleWatch.Restart(); } _cycleState = RState.Running; } return result; } /// /// 停止任务 /// /// /// /// public bool StopJob(string jobName, out string reason) { return JobProcesser.Instance.StopJob(jobName, out reason); } /// /// System Abort /// /// public bool SystemAbort() { JobProcesser.Instance.SystemAbort(); return true; } /// /// 删除所有job /// /// public bool RemoveAllJob() { JobProcesser.Instance.RemoveAllJob(); return true; } #endregion /// /// 检验是否所有任务完成 /// /// public bool CheckAllJobDone() { foreach (var cj in JobProcesser.Instance.ControlJobInfos) { if (cj.State != EnumControlJobState.Completed) return false; } return true; } /// /// 检验是否存在已经完成的任务 /// /// /// public bool CheckJobJustDone(out string sJobName) { foreach (var cj in JobProcesser.Instance.ControlJobInfos) { if (cj.State == EnumControlJobState.Completed && !cj.BeenPosted) { sJobName = $"{cj.Module};{cj.JobWaferSize};{cj.LotName};{cj.LotWafers.Count};{cj.StartTime:T};{cj.EndTime:T}"; cj.BeenPosted = true; return true; } } sJobName = "NULL"; return false; } public RState CheckManualReturnWafer() { return RState.End; } public void Clear() { } public bool ManualReturnWafer(object[] objs) { return true; } /// /// 监控 /// /// public RState Monitor() { UpdateProcessJobStatus(); UpdateControlJobStatus(); CreateWaferHolderTask(); RunWaferHolderTask(); RunWaferTask(); return _cycleState; } public RState ReturnAllWafers() { return RState.Init; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _cycleWatch.Stop(); SchedulerManager.Instance.ResetSchedulerModule(); CycleManager.Instance.InitializeAllLoadPortData(); return RState.Running; } /// /// 更新ProcessJob状态 /// private void UpdateProcessJobStatus() { foreach (var pj in JobProcesser.Instance.ProcessJobInfos) { if (CheckAllWaferReturned(pj, pj.State != EnumProcessJobState.Stopping)) { pj.SetState(EnumProcessJobState.ProcessingComplete); JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0); } } List list = JobProcesser.Instance.GetRecipeStateProcessJobs(EnumProcessJobState.Queued); foreach(var item in list) { if(SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(item.SequenceRecipe, false)) { ActiveProcessJob(item); } else { UpdateProcessJobCanceled(item); } } } /// /// ProcessJob状态修改为canceled /// /// private void UpdateProcessJobCanceled (ProcessJobInfo pj) { foreach (var slot in pj.SlotWafers) { var wafer = WaferManager.Instance.GetWafer(slot.Item1, slot.Item2); if (!wafer.IsEmpty&&wafer.ProcessState==EnumWaferProcessStatus.Idle) { wafer.ProcessState = EnumWaferProcessStatus.Canceled; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"wafer {slot.Item1} slot {slot.Item2} state changed to canceled"); } } pj.SetState(EnumProcessJobState.Canceled); JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Processjob sequence {pj.SequenceRecipe.Ppid} not avaible cell,state changed to canceled"); } /// /// 检验ProcessJob是否所有Wafer已经回到了LoadPort /// /// /// /// private bool CheckAllWaferReturned(ProcessJobInfo pj, bool checkAllProcessed) { bool allWaferReturn = true; foreach (var slot in pj.SlotWafers) { var wafer = WaferManager.Instance.GetWafer(slot.Item1, slot.Item2); if (wafer.IsEmpty || (wafer.ProcessState != EnumWaferProcessStatus.Completed && checkAllProcessed)) { allWaferReturn = false; break; } } return allWaferReturn; } /// /// 更新ControlJob状态 /// private void UpdateControlJobStatus() { if(JobProcesser.Instance.ControlJobInfos==null||JobProcesser.Instance.ControlJobInfos.Count==0) { return; } List runningJobs=JobProcesser.Instance.getRunningControlJobs(); foreach (ControlJobInfo controlJobInfo in runningJobs) { if (IsAllProcessJobComplete(controlJobInfo)) { CycleManager.Instance.UpdateCycleCount(controlJobInfo.Module); if (CycleManager.Instance.GetLoadportCycleCount(controlJobInfo.Module) >= controlJobInfo.CycleNumber) { JobProcesser.Instance.CompleteControlJob(controlJobInfo); FaJobManager.Instance.Complete(controlJobInfo.Name); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{controlJobInfo.Name} complete"); } else { JobProcesser.Instance.RestartControlJob(controlJobInfo); } } } if(CheckAllJobDone()) { _cycleState = RState.End; } } /// /// 是否所有ProcessJob已经完成 /// /// /// private bool IsAllProcessJobComplete(ControlJobInfo cj) { foreach (var pj in JobProcesser.Instance.ProcessJobInfos) { if (pj.ControlJobName == cj.Name) { if (pj.State == EnumProcessJobState.Canceled) { if (!CheckAllWaferReturned(pj, false)) { return false; } } else if (pj.State != EnumProcessJobState.ProcessingComplete) { return false; } } for (int i = 0; i < pj.SlotWafers.Count; i++) { var item = pj.SlotWafers[i]; if (WaferManager.Instance.CheckHasWafer(item.Item1, item.Item2)) { WaferInfo waferInfo = WaferManager.Instance.GetWafer(item.Item1, item.Item2); if(WaferTaskManager.Instance.Contains(waferInfo.WaferID)) { return false; } } } } return true; } /// /// 启动ProcessJob /// /// /// private bool ActiveProcessJob(ProcessJobInfo pj) { if (pj.State == EnumProcessJobState.Queued) { ControlJobInfo cj = JobProcesser.Instance.ControlJobInfos.Find(O => O.Name == pj.ControlJobName); if (cj == null) { return false; } foreach (var pjSlotWafer in pj.SlotWafers) { WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2); wafer.ProcessJob = pj; wafer.NextSequenceStep = 0; WaferDataRecorder.SetPjInfo(wafer.InnerId.ToString(), pj.InnerId.ToString()); } CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module); JobDataRecorder.StartPJ(pj.InnerId.ToString(), carrier.InnerId.ToString(), cj.InnerId.ToString(), pj.Name, cj.Module, cj.Module, pj.SlotWafers.Count); pj.SetState(EnumProcessJobState.Processing); } return true; } /// /// 创建WaferHolder任务 /// private void CreateWaferHolderTask() { if (JobProcesser.Instance.ProcessJobInfos.Count == 0) { return; } //查看Loader之前是否有Wafer(出现场景LoaderTransporter取WaferHolder出现Id不匹配,Loader前面就已经存在了Wafer) WaferInfo waferInfo = WaferHolderTaskManager.Instance.GetPreLoaderHasWafer(); List tmpProcessJobs = new List(); if (waferInfo == null) { var runningProcessJobs = JobProcesser.Instance.GetRecipeStateProcessJobs(EnumProcessJobState.Processing); foreach (var job in runningProcessJobs) { if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(job.SequenceRecipe, false)) { UpdateProcessJobCanceled(job); continue; } if (!CheckProcessJobHasUncompleteWafer(job)) { continue; } tmpProcessJobs.Add(job); } } else { if (waferInfo.ProcessJob != null) { tmpProcessJobs.Add(waferInfo.ProcessJob); } } if (tmpProcessJobs.Count != 0) { WaferHolderTaskManager.Instance.CreateWaferHolderTask(tmpProcessJobs); } else { WaferHolderTaskManager.Instance.CreateDummyWaferHolderTask(); } } /// /// 检验ProcessJob是否存在未加工的Wafer /// /// /// private bool CheckProcessJobHasUncompleteWafer(ProcessJobInfo pj) { for (int i = 0; i < pj.SlotWafers.Count; i++) { var item = pj.SlotWafers[i]; if (WaferManager.Instance.CheckHasWafer(item.Item1, item.Item2)) { WaferInfo waferInfo = WaferManager.Instance.GetWafer(item.Item1, item.Item2); if (waferInfo != null && waferInfo.ProcessState == EnumWaferProcessStatus.Idle) { if (!WaferTaskManager.Instance.Contains(waferInfo.WaferID)) { return true; } } } } return false; } /// /// 运行WaferHolder任务 /// private void RunWaferHolderTask() { WaferHolderTaskDispatcher.Instance.Analyse(); } /// /// 运行Wafer任务 /// private void RunWaferTask() { List waferTasks = WaferTaskManager.Instance.LoadWaferTaskList(); foreach(var item in waferTasks) { item.Run(); } } } }