using Aitex.Common.Util;
using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using CyberX8_Core;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Dryer;
using CyberX8_RT.Modules.Loader;
using CyberX8_RT.Modules.Prewet;
using CyberX8_RT.Modules.Rinse;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.RecipeCenter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Schedulers.Rinse
{
public class SchedulerRinse : SchedulerModule
{
#region 内部变量
private RinseEntity _rinseEntity;
private bool _isStartRunRecipe = false;
#endregion
#region 属性
///
/// 是否空闲
///
public override bool IsIdle
{
get { return _state == RState.End; }
}
///
/// 是否错误
///
public override bool IsError
{
get { return _state == RState.Failed || _state == RState.Timeout; }
}
#endregion
///
/// 构造函数
///
///
public SchedulerRinse(ModuleName moduleName) : base(moduleName.ToString())
{
_rinseEntity = Singleton.Instance.GetModule(moduleName.ToString());
}
///
/// 执行
///
///
///
public override bool RunProcess(object recipe, object parameter, List syncModuleMessages)
{
if (!(recipe is QdrRecipe))
{
_state = RState.Failed;
LOG.WriteLog(eEvent.ERR_RINSE, Module.ToString(), "recipe is invalid");
return false;
}
_isStartRunRecipe = false;
QdrRecipe qdrRecipe = (QdrRecipe)recipe;
bool result = _rinseEntity.CheckToPostMessage(eEvent.ERR_RINSE, Module.ToString(), (int)RinseMsg.RunRecipe, qdrRecipe,1);
if (result)
{
_state = RState.Running;
}
return result;
}
///
/// 监控执行
///
///
public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
{
if (!_isStartRunRecipe)
{
_isStartRunRecipe = _rinseEntity.State == (int)RinseState.RunReciping;
}
if (_rinseEntity.IsError)
{
_state = RState.Failed;
_isStartRunRecipe = false;
}
if (_isStartRunRecipe && _rinseEntity.IsIdle)
{
_state = RState.End;
_isStartRunRecipe = false;
}
if(_rinseEntity.State==(int)RinseState.RunRecipeComplete||_rinseEntity.State==(int)RinseState.KeepWeting)
{
if (schedulerSequence.NextModuleType != ModuleType.Metal)
{
NotifyRinseComplete();
}
else
{
bool exsitEnableCell = false;
DepRecipe depRecipe = schedulerSequence.NextRecipe as DepRecipe;
ModuleName moduleName = SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry,
Module.ToString(),schedulerSequence.SequenceType,ref exsitEnableCell);
if (moduleName != ModuleName.Unknown)
{
IModuleEntity moduleEntity = Singleton.Instance.GetModule(moduleName.ToString());
if (SchedulerSequenceManager.Instance.CheckMetalCellRecipeTimeAvaible(moduleEntity, depRecipe))
{
NotifyRinseComplete();
}
else
{
NotifyRinseKeepWet();
}
}
else
{
if (exsitEnableCell)
{
NotifyRinseKeepWet();
}
else
{
NotifyRinseComplete();
}
}
}
}
return true;
}
///
/// 通知Rinse完成
///
private void NotifyRinseComplete()
{
_rinseEntity.CheckToPostMessage(eEvent.INFO_RINSE, Module.ToString(), (int)RinseMsg.RecipeComplete);
}
///
/// 通知Rinse准备Keep Wet
///
private void NotifyRinseKeepWet()
{
if (_rinseEntity.State == (int)RinseState.KeepWeting)
{
return;
}
_rinseEntity.CheckToPostMessage(eEvent.WARN_PREWET, Module.ToString(),
(int)RinseMsg.Keepwet);
}
///
/// 检验前置条件
///
///
///
///
public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter, string materialId,ref string reason)
{
if (_state == RState.Running)
{
reason = "scheduler module is already running";
return false;
}
if (_rinseEntity.IsBusy)
{
reason = $"{_rinseEntity.Module} is busy";
return false;
}
if(_rinseEntity.WaferHolderInfo==null)
{
reason = $"{_rinseEntity.Module} has no wafer shuttle";
return false;
}
if (_rinseEntity.WaferHolderInfo.Id != materialId)
{
reason = $"{_rinseEntity.Module} wafer shuttle {_rinseEntity.WaferHolderInfo.Id} is not matched with {materialId}";
return false;
}
return true;
}
}
}