using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.DBCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Aligners; using MECF.Framework.RT.ModuleLibrary.AlignerModules; using MECF.Framework.RT.ModuleLibrary.LPModules; using MECF.Framework.RT.ModuleLibrary.SystemModules; using static JetEfemLib.Efems.EfemModule; namespace EfemDualSchedulerLib.Schedulers { public class SchedulerAligner : SchedulerModule { public override bool IsAvailable { get { return _aligner.IsReady && _aligner.IsOnline && CheckTaskDone(); } } public override bool IsOnline { get { return _aligner.IsOnline; } } public override bool IsError { get { return _aligner.IsError; } } private AlignerModuleBase _aligner = null; private DeviceTimer _timerCooling = new DeviceTimer(); private float _paramCoolingTime = 0; private EfemType _efemType; private double _angle; public SchedulerAligner(ModuleName module) : base(module.ToString()) { _module = module.ToString(); _aligner = EquipmentManager.Modules[module] as AlignerModuleBase; _efemType = (EfemType)SC.GetValueOrDefault($"EFEM.EfemType"); _angle = SC.GetValueOrDefault("EFEM.Aligner.DefaultNotchDegree"); System.Diagnostics.Trace.Assert(_aligner!=null); } public void NoteJobStart() { } public void NoteJobComplete() { } public bool Monitor() { return true; } public override bool IsReadyForPick(ModuleName robot, Hand blade, int slot) { return _aligner.CheckReadyForTransfer(robot, blade, slot, EnumTransferType.Pick, out _) && WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_module), slot); } public override bool IsReadyForPlace(ModuleName robot, Hand blade, int slot) { return _aligner.CheckReadyForTransfer(robot, blade, slot, EnumTransferType.Place, out _) && WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(_module), slot); } public bool CheckTaskDone() { bool ret = false; switch (_task) { case TaskType.None: ret = true; break; case TaskType.Align: ret = _aligner.IsReady; break; //case TaskType.PrepareTransfer: // ret = _aligner.CheckReadyForTransfer(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick, out _); // break; case TaskType.Cooling: ret = _timerCooling.IsTimeout() && /* _entity.CheckAcked(_token) &&*/ _aligner.IsReady; break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } internal bool CheckReadyRunJob() { return true; } internal bool CheckReadyTransfer() { return _aligner.CheckReadyForTransfer(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick, out _); } internal bool Align(string waferInnerId) { _task = TaskType.Align; if (_efemType == EfemType.FutureEfem3P) { LogTaskStart(_task, $"{Module} Aligning"); WaferDataRecorder.SetWaferNotchAngle(waferInnerId, (float)_angle); return _aligner.Align(_angle); } return true; } public override bool Cooling(int coolingTime) { _task = TaskType.Cooling; LogTaskStart(_task, $"Cooling {coolingTime} seconds"); _paramCoolingTime = coolingTime; _timerCooling.Start(_paramCoolingTime * 1000); return true; } } }