using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using VirgoRT.Scheduler; namespace VirgoRT.Modules.Schedulers { public class SchedulerAligner : SchedulerModule { public override bool IsAvailable { get { return /*_entity.IsIdle &&*//* _entity.IsOnline && */CheckTaskDone(); } } public override bool IsOnline { get { return _efemEntity.IsOnline; } } public override bool IsError { get { return _efemEntity.IsError; } } private EfemEntity _efemEntity = null; private bool _isCooling; private DeviceTimer _timerCooling = new DeviceTimer(); private float _paramCoolingTime = 0; //private int _token; private int _coolingDelayTime; private Stopwatch _timerDelay = new Stopwatch(); private DeviceTimer _timerAligning = new DeviceTimer(); private float _paramAligningTime = 0; public SchedulerAligner(ModuleName chamber) : base(chamber.ToString()) { _efemEntity = Singleton.Instance.EFEM; _isCooling = chamber == ModuleName.Cooling1 || chamber == ModuleName.Cooling2; } public override bool IsReadyForPick(ModuleName robot, int slot, Hand blade) { return WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_module), slot); } public override bool IsReadyForPlace(ModuleName robot, int slot, Hand blade) { return WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(_module), slot); } public override bool Cooling(int time) { _task = TaskType.Cooling; LogTaskStart(_task, $"Cooling {time} seconds" ); _coolingDelayTime = SC.GetValue("EFEM.DelayTimeBeforeLiftDown"); _paramCoolingTime = time ; _timerDelay.Restart(); //_token = _efemEntity.InvokeCooling(Module.ToString(), time); return true;//_token != (int)FSM_MSG.NONE; } public bool Monitor() { return true; } public bool Align(float time) { _task = TaskType.Align; LogTaskStart(_task, "Aligning"); _paramAligningTime = time; _timerAligning.Start(_paramAligningTime * 1000); _timerDelay.Restart(); Singleton.Instance.EFEM.EfemDevice.SetPinDown(Module); //token = _entity.InvokeAlign(Module.ToString(), time); return true;// _token != (int)FSM_MSG.NONE; } public override bool PostTransfer(ModuleName robot, EnumTransferType type, int slot) { StopWaitTransfer(robot); if (type == EnumTransferType.Place) { _task = TaskType.Align; LogTaskStart(_task, $"Waiting {_paramAligningTime} seconds"); _timerAligning.Start(_paramAligningTime * 1000); } return true; } public override bool PostTransfer(ModuleName robot) { StopWaitTransfer(robot); return true; } public bool CheckTaskDone() { bool ret = false; switch (_task) { case TaskType.None: ret = true; break; case TaskType.Align: if (_timerDelay.IsRunning && _timerDelay.ElapsedMilliseconds > 1 * 1000) { _timerDelay.Stop(); } ret = !_timerDelay.IsRunning && _timerAligning.IsTimeout() && /* _entity.CheckAcked(_token) &&*/ _efemEntity.IsIdle && !_efemEntity.EfemDevice.IsBufferPinUp[Module]; break; case TaskType.Cooling: if (_timerDelay.IsRunning && _timerDelay.ElapsedMilliseconds > _coolingDelayTime*1000) { _timerDelay.Stop(); //_efemEntity.InvokeLiftDown(Module.ToString()); Singleton.Instance.EFEM.SetLiftDown(Module); //lift pin down time = 2seconds _timerCooling.Start(_paramCoolingTime * 1000 + 2*1000); break; } ret = !_timerDelay.IsRunning && _timerCooling.IsTimeout() && _efemEntity.IsIdle; break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } } }