using Aitex.Core.Common;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Jobs;
using MECF.Framework.Common.SubstrateTrackings;
using MECF.Framework.Common.WaferHolder;
using CyberX8_Core;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Loader;
using CyberX8_RT.Modules.PUF;
using CyberX8_RT.Schedulers;
using CyberX8_RT.Schedulers.EfemRobot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.Schedulers;
using System.Windows;
using MECF.Framework.RT.Core.Equipments;
using CyberX8_RT.Modules.SRD;
namespace CyberX8_RT.Dispatch
{
public enum WaferTaskState
{
Created,
Processing,
End,
Paused,
Error
}
///
/// WaferTask完成
///
///
public delegate void WaferTaskComplete(string id);
///
/// WaferTask开始
///
///
public delegate void WaferTaskStart(string id);
public class WaferTask
{
#region 内部变量
///
/// 调度步骤
///
private List _schedulerSequences;
///
/// 当前步骤索引
///
private int _currentSequenceIndex = 0;
///
/// PUF实例
///
private PUFEntity _pufEntity;
///
/// 是否开始执行
///
private bool _isStart = false;
///
/// 暂停时的索引
///
private int _pausedIndex = -1;
///
/// 日志trigger
///
private R_TRIG _sequenceConditionTrigger = new R_TRIG();
///
/// 错误上升触发
///
private R_TRIG _sequenceErrorTigger = new R_TRIG();
#endregion
#region 属性
///
/// Wafer信息
///
public string WaferId { get; set; }
///
/// 状态
///
public WaferTaskState State { get; private set; }
///
/// 匹配WaferTask
///
public string MateWaferTask { get; set; }
///
/// 调度集合
///
public List SchedulerSequences { get { return _schedulerSequences; } }
#endregion
#region 事件
///
/// 任务完成事件
///
public event WaferTaskComplete OnTaskComplete;
///
/// 任务启动
///
public event WaferTaskStart OnTaskStart;
#endregion
///
/// 构造函数
///
///
///
public WaferTask(WaferInfo waferInfo,PUFEntity pufEntity, List schedulerSequences)
{
this.WaferId = waferInfo.WaferID;
_schedulerSequences = schedulerSequences;
State = WaferTaskState.Created;
_pufEntity = pufEntity;
}
///
/// 执行
///
public void Run()
{
if (State == WaferTaskState.Error)
{
return;
}
if (_currentSequenceIndex >= _schedulerSequences.Count)
{
State = WaferTaskState.End;
if (OnTaskComplete != null)
{
OnTaskComplete(WaferId);
}
return;
}
SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End)
{
State = WaferTaskState.End;
if(OnTaskComplete!=null)
{
OnTaskComplete(WaferId);
}
return;
}
if (!_isStart)
{
bool preCondition = CheckStartCondition();
if (!preCondition)
{
return;
}
_isStart = true;
WaferTaskManager.Instance.RemoveWaferIdMatchWaferHolderTaskDic(WaferId);
}
//暂停中
if(sequence.State==RState.Init&&_currentSequenceIndex>=_pausedIndex&&_pausedIndex!=-1)
{
return;
}
if(sequence.IsWaitNotify)
{
if (sequence.State == RState.End)
{
_currentSequenceIndex++;
}
return;
}
if(sequence.MaterialType==MaterialType.WaferHolder)
{
if(sequence.State==RState.End)
{
_currentSequenceIndex++;
}
return;
}
if (_currentSequenceIndex < _schedulerSequences.Count)
{
if (sequence.State == RState.Init)
{
string reason = "";
bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex,sequence.Parameters,WaferId,ref reason);
_sequenceConditionTrigger.CLK = !sequeceCondition;
if (sequeceCondition)
{
bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters,sequence.SynchronousModuleMessages);
if (result)
{
if (State == WaferTaskState.Created)
{
State = WaferTaskState.Processing;
if(OnTaskStart!=null)
{
OnTaskStart(WaferId);
}
}
sequence.State = RState.Running;
sequence.StartTime = DateTime.Now;
LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}");
}
}
else
{
if (_sequenceConditionTrigger.Q)
{
LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}");
if (sequence.SchedulerModule.Module == ModuleName.EfemRobot)
{
AnalyseSchedulerSrdState(sequence);
}
}
}
}
else if (sequence.State == RState.Running)
{
bool hasMatched=!string.IsNullOrEmpty(WaferTaskManager.Instance.GetMatchWaferIdByWaferId(this.WaferId));
sequence.SchedulerModule.MonitorProcess(sequence,hasMatched);
_sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError;
if (sequence.SchedulerModule.IsIdle)
{
sequence.EndTime = DateTime.Now;
sequence.State = RState.End;
sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence complete, time length {sequence.ProcessMilliSeconds}");
_currentSequenceIndex++;
}
}
else if(sequence.State==RState.End)
{
LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence is End");
_currentSequenceIndex++;
}
}
}
///
/// 分析错误状态下的调度
///
private void AnalyseSchedulerSrdState(SchedulerSequence sequence)
{
if(!(sequence.Parameters is MoveItem))
{
return;
}
MoveItem moveItem = sequence.Parameters as MoveItem;
bool exsitSRD = false;
if (moveItem.DestinationType == ModuleType.SRD)
{
SRDEntity srdEntity1 = Singleton.Instance.GetModule(ModuleName.SRD1.ToString());
if (srdEntity1 != null&&(srdEntity1.IsBusy||srdEntity1.IsIdle)&&srdEntity1.IsAuto)
{
exsitSRD = true;
return;
}
SRDEntity srdEntity2 = Singleton.Instance.GetModule(ModuleName.SRD2.ToString());
if (srdEntity2 != null && (srdEntity2.IsBusy || srdEntity2.IsIdle) && srdEntity2.IsAuto)
{
exsitSRD = true;
return;
}
if (!exsitSRD)
{
WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferId);
if (waferInfo == null || waferInfo.IsEmpty)
{
return;
}
WaferManager.Instance.UpdateWaferProcessStatus(moveItem.SourceModule, moveItem.SourceSlot, EnumWaferProcessStatus.MisSrdProcess);
MaterialTrackerManager.Instance.UpdateModuleMaterial(moveItem.SourceModule.ToString());
LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {EnumWaferProcessStatus.MisSrdProcess}");
moveItem.DestinationModule = (ModuleName)waferInfo.OriginStation;
moveItem.DestinationSlot = waferInfo.OriginSlot;
moveItem.DestinationType = ModuleType.LoadPort;
LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} has no avaible srd changed to {moveItem.DestinationModule}.{moveItem.DestinationSlot}");
for(int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
{
SchedulerSequence item = _schedulerSequences[i];
item.State = RState.End;
LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} skip {i + 1} sequence {item.ModuleType}");
}
}
}
}
///
/// 释放资源
///
public void Dispose()
{
_schedulerSequences.Clear();
}
///
/// 检验前置条件
///
///
private bool CheckStartCondition()
{
EfemEntity efemEntity = Singleton.Instance.EFEM;
if(!efemEntity.IsIdle)
{
return false;
}
SchedulerRobot schedulerEfemRobot = (SchedulerRobot)SchedulerManager.Instance.GetScheduler(ModuleName.EfemRobot);
if(schedulerEfemRobot==null)
{
return false;
}
if(!schedulerEfemRobot.IsIdle)
{
return false;
}
if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot,0))
{
return false;
}
if(WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0))
{
return false;
}
if(!_pufEntity.IsIdle)
{
return false;
}
//PUF B面无Wafer
if(WaferManager.Instance.CheckHasWafer(_pufEntity.Module,1))
{
return false;
}
//if(!WaferHolderManager.Instance.HasWaferHolder("Loader"))
//{
// return false;
//}
LoaderEntity loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
if (loaderEntity == null)
{
return false;
}
if(loaderEntity.IsBusy&&loaderEntity.State!=(int)LOADERSTATE.WaitForUnload)
{
return false;
}
if(!string.IsNullOrEmpty(MateWaferTask))
{
WaferTask mateTask=WaferTaskManager.Instance.GetWaferTask(MateWaferTask);
if(mateTask!=null)
{
if(mateTask.State==WaferTaskState.Created)
{
return false;
}
}
}
//WaferHolderTask waferHolderTask = WaferTaskManager.Instance.GetWaferHolderTaskByWaferId(WaferId);
//if (waferHolderTask != null)
//{
// if(waferHolderTask.State==WaferHolderTaskState.Created||waferHolderTask.State==WaferHolderTaskState.Error)
// {
// return false;
// }
//}
return true;
}
///
/// 同步更新Loader工序完成
///
public void UpdateLoaderSchedulerSequenceComplete()
{
SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex];
if (schedulerSequence != null)
{
if (schedulerSequence.ModuleType == ModuleType.PUF&&schedulerSequence.IsWaitNotify)
{
bool forward = (bool)schedulerSequence.Parameters;
if (!forward)
{
schedulerSequence.StartTime = DateTime.Now;
schedulerSequence.EndTime = DateTime.Now;
schedulerSequence.State = RState.End;
schedulerSequence.ProcessMilliSeconds = schedulerSequence.EndTime.Subtract(schedulerSequence.StartTime).TotalMilliseconds;
LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} {_currentSequenceIndex + 1} puf sequence task synchronize notify complete");
}
}
}
}
///
/// 暂停
///
public void Pause()
{
_pausedIndex = _currentSequenceIndex;
}
///
/// 恢复
///
public void Resume()
{
_pausedIndex = -1;
}
///
/// 移除SRD调度
///
public void RemoveSrdScheduler()
{
WaferInfo waferInfo=WaferManager.Instance.GetWaferByWaferId(WaferId);
if (waferInfo != null && waferInfo.WaferType == WaferType.Production&&waferInfo.ProcessJob!=null
&&waferInfo.ProcessJob.SequenceRecipe!=null)
{
if (SequenceRecipeManager.Instance.IsContainedSrd(waferInfo.ProcessJob.SequenceRecipe))
{
for(int i=_currentSequenceIndex;i<_schedulerSequences.Count;i++)
{
SchedulerSequence item= _schedulerSequences[i];
if(item.ModuleType==ModuleType.SRD&&i+1<_schedulerSequences.Count&&i>0)
{
SchedulerSequence preSequence = _schedulerSequences[i - 1];
SchedulerSequence nextSequence = _schedulerSequences[i + 1];
if (preSequence.ModuleName == ModuleName.EfemRobot&&nextSequence.ModuleName==ModuleName.EfemRobot)
{
MoveItem moveItem=preSequence.Parameters as MoveItem;
MoveItem nextMoveItem=nextSequence.Parameters as MoveItem;
moveItem.DestinationModule = nextMoveItem.DestinationModule;
moveItem.DestinationSlot= nextMoveItem.DestinationSlot;
moveItem.DestinationType= nextMoveItem.DestinationType;
_schedulerSequences.RemoveAt(i + 1);
_schedulerSequences.RemoveAt(i);
LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Wafer {WaferId} remove SRD Scheduler");
}
break;
}
}
}
}
}
///
/// 步骤是否进入Loader及之后
///
///
public bool IsSchedulerForward()
{
//0-EfemRobot,1-Aligner,2-EfemRobot,3-Puf(正向),4-PUF(工艺结束返回)
return _currentSequenceIndex < 4;
}
}
}