using Aitex.Core.Common; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; 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 FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.Systems; using System; namespace FurnaceRT.Equipments.Schedulers { public class SchedulerPM : SchedulerModule { public override bool IsAvailable { get { return _pm.IsReady && _pm.IsOnline && CheckTaskDone(); } } public override bool IsOnline { get { return _pm.IsOnline; } } public override bool IsError { get { return _pm.IsError; } } private PMModuleBase _pm = null; private ModuleName _taskRobot; private EnumTransferType _taskTransferType; private int _taskSlot; private DeviceTimer _timer = new DeviceTimer(); public DateTime RecipeStartTime => _recipeStartTime; private DateTime _recipeStartTime; public SchedulerPM(ModuleName chamber) : base(chamber.ToString()) { _pm = Singleton.Instance.Modules[chamber] as PMModuleBase; //System.Diagnostics.Trace.Assert(_pm!=null); } public override bool IsReadyForPick(ModuleName robot, int slot) { return _pm.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Pick, out _) && WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_module), 0); } public override bool IsReadyForPlace(ModuleName robot, int slot) { return _pm.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Place, out _) && WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(_module), 0); } public override bool PrepareTransfer(ModuleName robot, EnumTransferType type, int slot) { _task = TaskType.PrepareTransfer; _taskRobot = robot; _taskSlot = slot; _taskTransferType = type; if (!_pm.PrepareTransfer(robot, Hand.Blade1, slot, type, out string reason)) { LOG.Write(reason); return false; } LogTaskStart(_task, $"{robot} {type} slot {slot + 1}"); return true; } public bool IsPrepareTransfer(ModuleName robot, EnumTransferType type, int slot) { return _task == TaskType.PrepareTransfer && _taskRobot == robot && _taskSlot == slot && _taskTransferType == type; } public override bool Process(string recipeName, bool isCleanRecipe, bool withWafer) { _task = TaskType.Process; _recipeStartTime = DateTime.Now; if (!_pm.Process(recipeName, isCleanRecipe, withWafer, out string reason)) { LOG.Write(reason); return false; } LogTaskStart(_task, $"recipe: {recipeName}, clean: {isCleanRecipe}, with wafer: {withWafer}"); return true; } public override bool Standby(string recipeName) { _task = TaskType.Standby; if (!_pm.Standby(recipeName, out string reason)) { LOG.Write(reason); } LogTaskStart(_task, $"recipe: {recipeName}"); return true; } public bool CheckStandbyCondition() { return _pm.CheckStandbyCondition(); } public bool CheckTaskDone() { bool ret = false; switch (_task) { case TaskType.None: case TaskType.Standby: ret = true; break; case TaskType.PrepareTransfer: ret = _pm.CheckReadyForTransfer(_taskRobot, Hand.Blade1, _taskSlot, _taskTransferType, out _); break; case TaskType.Process: ret = _pm.IsReady; break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } public bool Monitor() { return true; } } }