using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.Util; using Aitex.Sorter.Common; using EfemDualSchedulerLib.Schedulers; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks; using MECF.Framework.RT.ModuleLibrary.BufferModules; using MECF.Framework.RT.ModuleLibrary.LLModules; using MECF.Framework.RT.ModuleLibrary.SystemModules; namespace EfemDualSchedulerLib.Schedulers { public class SchedulerLoadLock : SchedulerModule { public override bool IsAvailable { get { return _loadLock.IsReady && _loadLock.IsOnline && CheckTaskDone(); } } public override bool IsOnline { get { return _loadLock.IsOnline; } } public override bool IsError { get { return _loadLock.IsError; } } private LoadLockModuleBase _loadLock; public LoadLockModuleBase Entity { get { return _loadLock; } } private ModuleName _taskRobot; private int _taskSlot; private int _entityTaskToken = (int)FSM_MSG.NONE; private EnumTransferType TransferType { get; set; } public SchedulerLoadLock(ModuleName module) : base(module.ToString()) { _loadLock = EquipmentManager.Modules[module] as LoadLockModuleBase; } void OnFieldChanged(object sender, string name, object fieldValue) { if (name == nameof(_loadLock.IsOnline)) { bool v = (bool)fieldValue; if (!v && _task != TaskType.None) { LOG.Warning($"{Module} abort {_task} since offline"); _task = TaskType.None; } } } public void Reset() { _task = TaskType.None; } public override bool PrepareTransfer(ModuleName robot, EnumTransferType type, int slot) { _task = TaskType.PrepareTransfer; _taskRobot = robot; _taskSlot = slot; TransferType = type; _loadLock.PrepareTransfer(robot, Hand.Blade1, slot, type, out string reason); LogTaskStart(_task, $"{robot} {type} slot {slot + 1}"); return _entityTaskToken != (int)FSM_MSG.NONE; } internal bool CheckAtAtm() { //LoadLock deviceLL = DEVICE.GetDevice(_module); //return deviceLL.CheckAtm(); return true; } internal bool CheckAtVacuum() { //LoadLock deviceLL = DEVICE.GetDevice(_module); //return deviceLL.CheckVacuum(); return true; } public override bool IsReadyForPick(ModuleName robot, Hand hand, int slot) { if (!_loadLock.CheckReadyForTransfer(robot, hand, slot, EnumTransferType.Pick, out string reason)) return false; return WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_module), slot); } public override bool IsReadyForPlace(ModuleName robot, Hand hand, int slot) { if (!_loadLock.CheckReadyForTransfer(robot, hand, slot, EnumTransferType.Place, out string reason)) return false; return WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(_module), slot); } public override bool Cooling(int coolingTime) { _task = TaskType.Cooling; //_entityTaskToken = _loadLock.InvokeCooling(coolingTime); LogTaskStart(_task, $"{Module} cooling {coolingTime} seconds"); return _entityTaskToken != (int)FSM_MSG.NONE; } public bool Monitor() { return true; } public bool CheckTaskDone() { bool ret = false; switch (_task) { case TaskType.None: ret = true; break; case TaskType.PrepareTransfer: //ret = _loadLock.CheckReadyForTransfer(_taskRobot, TransferType); break; case TaskType.PreCooling: //ret = _loadLock.IsPreCoolingDone(); break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } } }