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();
}
}
}
}