using System; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.Utilities; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.ModuleLibrary.LPModules; namespace FutureEfemLib.LPs { public class LoadPortModule : LoadPortModuleBase, IE87CallBack { public enum STATE { NotInstall, NotConnected, Init, Idle, Homing, Loading, Unloading, Error, ReadingCarrierId, Clamp, Unclamp, Dock, Undock, OpenDoor, CloseDoor, Map, InTransfer, } public enum MSG { Disconnected, Connected, Home, Reset, Init, Error, Abort, InTransfer, TransferComplete, Load, Unload, ReadCarrierId, Clamp, Map, CloseDoor, OpenDoor, Undock, Dock, Unclamp, ToInit, ToIdle, } public override bool IsReady { get { return FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); } } public override bool IsError { get { return FsmState == (int)STATE.Error; } } public override bool IsInit { get { return FsmState == (int)STATE.Init; } } public override bool IsLoaded { get { return LPDevice.DoorState ==FoupDoorState.Open; } } public override bool IsUnloaded { get { return LPDevice.DoorState ==FoupDoorState.Close; } } public override bool IsClamped { get { return LPDevice.ClampState == FoupClampState.Close; } } public override bool IsUnclamped { get { return LPDevice.ClampState == FoupClampState.Open; } } public event Action OnEnterError; public FutureEfemLoadPort LPDevice { get { return _lpDevice; } } private RorzeEfem _efemDevice; private FutureEfemLoadPort _lpDevice; private LoadPortHomeRoutine _home; private LoadPortCloseDoorRoutine _closeDoor; private LoadPortClampRoutine _clamp; private LoadPortDockRoutine _dock; private LoadPortMapRoutine _map; private LoadPortOpenDoorRoutine _openDoor; private LoadPortReadCarrierIdRoutine _readCarrierId; private LoadPortGetMapInfoRoutine _MapDT; private LoadPortUnclampRoutine _unclamp; private LoadPortUndockRoutine _undock; private LoadPortLoadRoutine _load; private bool _isInit; private bool _jobDone; public LoadPortModule(ModuleName module) : base(25) { Name = module.ToString(); Module = module.ToString(); IsOnline = false; } public override bool Initialize() { InitRoutine(); InitDevice(); InitFsm(); InitOp(); InitData(); return base.Initialize(); } private void InitRoutine() { _home = new LoadPortHomeRoutine(this); _closeDoor = new LoadPortCloseDoorRoutine(this); _clamp = new LoadPortClampRoutine(this); _dock = new LoadPortDockRoutine(this); _map = new LoadPortMapRoutine(this); _openDoor = new LoadPortOpenDoorRoutine(this); _readCarrierId = new LoadPortReadCarrierIdRoutine(this); _unclamp = new LoadPortUnclampRoutine(this); _undock = new LoadPortUndockRoutine(this); _MapDT = new LoadPortGetMapInfoRoutine(this); _load = new LoadPortLoadRoutine(this); } public void InitDevice() { _efemDevice = DEVICE.GetDevice($"{ModuleName.System}.{ModuleName.EFEM}"); _lpDevice = DEVICE.GetDevice($"{Module}"); (_lpDevice as LoadPort).LPCallBack = this; } private void InitData() { DATA.Subscribe($"{Module}.Status", () => StringFsmStatus); DATA.Subscribe($"{Module}.IsOnline", () => IsOnline); DATA.Subscribe($"{Module}.JobDone", () => { if (!_lpDevice.IsPlacement) _jobDone = false; if (!_jobDone || !_lpDevice.IsPlacement) return false; //if (SC.GetValue("System.Job.BuzzerTimeWhenJobDone") >= 0 // && _timerNotifyJobDone.ElapsedMilliseconds > SC.GetValue("System.Job.BuzzerTimeWhenJobDone") * 1000) // return false; return _jobDone; }); } private void InitOp() { OP.Subscribe($"{Name}.Home", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Home); }); OP.Subscribe($"{Name}.Abort", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Abort); }); OP.Subscribe($"{Name}.Reset", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Reset); }); OP.Subscribe($"{Name}.ReadCarrierId", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.ReadCarrierId); }); OP.Subscribe($"{Name}.Load", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Load); }); OP.Subscribe($"{Name}.Unload", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Unload); }); OP.Subscribe($"{Name}.Clamp", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Clamp); }); OP.Subscribe($"{Name}.Unclamp", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Unclamp); }); OP.Subscribe($"{Name}.Dock", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Dock); }); OP.Subscribe($"{Name}.Undock", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Undock); }); OP.Subscribe($"{Name}.OpenDoor", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.OpenDoor); }); OP.Subscribe($"{Name}.CloseDoor", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.CloseDoor); }); OP.Subscribe($"{Name}.Map", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Map); }); } private void InitFsm() { EnumLoop.ForEach((item) => { MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { MapMessage((int)item, item.ToString()); }); EnableFsm(50, IsInstalled ? STATE.Init : STATE.NotInstall); //Error AnyStateTransition(MSG.Error, FsmOnError, STATE.Error); Transition(STATE.Error, MSG.Reset, FsmReset, STATE.Idle); EnterExitTransition(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError); //Init Transition(STATE.Init, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Error, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Idle, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Homing, FSM_MSG.TIMER, FsmMonitorHomeTask, STATE.Idle); Transition(STATE.Homing, MSG.Error, null, STATE.Init); Transition(STATE.Homing, MSG.Abort, FsmAbortTask, STATE.Init); EnterExitTransition(STATE.Idle, FsmEnterIdle, FSM_MSG.NONE, FsmExitIdle); AnyStateTransition(MSG.ToInit, FsmToInit, STATE.Init); AnyStateTransition(MSG.ToIdle, FsmToIdle, STATE.Idle); //load Transition(STATE.Idle, MSG.Load, FsmStartLoad, STATE.Loading); Transition(STATE.Loading, FSM_MSG.TIMER, FsmMonitorLoadTask, STATE.Idle); Transition(STATE.Loading, MSG.Abort, FsmAbortTask, STATE.Idle); //unload Transition(STATE.Idle, MSG.Unload, FsmStartUnload, STATE.Unloading); Transition(STATE.Unloading, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Unloading, MSG.Abort, FsmAbortTask, STATE.Idle); //read carrier id Transition(STATE.Idle, MSG.ReadCarrierId, FsmStartReadCarrierId, STATE.ReadingCarrierId); Transition(STATE.ReadingCarrierId, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.ReadingCarrierId, MSG.Abort, FsmAbortTask, STATE.Idle); //clamp Transition(STATE.Idle, MSG.Clamp, FsmStartClamp, STATE.Clamp); Transition(STATE.Clamp, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Clamp, MSG.Abort, FsmAbortTask, STATE.Idle); //unclamp Transition(STATE.Idle, MSG.Unclamp, FsmStartUnclamp, STATE.Unclamp); Transition(STATE.Unclamp, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Unclamp, MSG.Abort, FsmAbortTask, STATE.Idle); //dock Transition(STATE.Idle, MSG.Dock, FsmStartDock, STATE.Dock); Transition(STATE.Dock, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Dock, MSG.Abort, FsmAbortTask, STATE.Idle); //undock Transition(STATE.Idle, MSG.Undock, FsmStartUndock, STATE.Undock); Transition(STATE.Undock, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Undock, MSG.Abort, FsmAbortTask, STATE.Idle); //open door Transition(STATE.Idle, MSG.OpenDoor, FsmStartOpenDoor, STATE.OpenDoor); Transition(STATE.OpenDoor, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.OpenDoor, MSG.Abort, FsmAbortTask, STATE.Idle); //close door Transition(STATE.Idle, MSG.CloseDoor, FsmStartCloseDoor, STATE.CloseDoor); Transition(STATE.CloseDoor, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.CloseDoor, MSG.Abort, FsmAbortTask, STATE.Idle); //map Transition(STATE.Idle, MSG.Map, FsmStartMap, STATE.Map); Transition(STATE.Map, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Map, MSG.Abort, FsmAbortTask, STATE.Idle); Transition(STATE.Idle, MSG.Disconnected, null, STATE.NotConnected); Transition(STATE.Idle, MSG.InTransfer, null, STATE.InTransfer); Transition(STATE.InTransfer, MSG.InTransfer, null, STATE.InTransfer); Transition(STATE.InTransfer, MSG.TransferComplete, null, STATE.Idle); Transition(STATE.InTransfer, MSG.Abort, null, STATE.Idle); Transition(STATE.NotConnected, MSG.Connected, null, STATE.Idle); } public override bool Home(out string reason) { if (!CheckToPostMessage((int)MSG.Home)) { reason = $"Can not home in {StringFsmStatus} status"; return false; } reason = string.Empty; return true; } public override void NoteJobStart() { _jobDone = false; } public override void NoteJobComplete() { _jobDone = true; } public override bool Load() { return CheckToPostMessage((int)MSG.Load); } public override bool Unload() { return CheckToPostMessage((int)MSG.Unload); } public override bool Clamp() { return CheckToPostMessage((int)MSG.Clamp); } public override bool Unclamp() { return CheckToPostMessage((int)MSG.Unclamp); } public void NotJobStart() { _lpDevice.SetIndicator(IndicatorType.Busy, IndicatorState.ON); } public void NotJobComplete() { _lpDevice.SetIndicator(IndicatorType.Busy, IndicatorState.OFF); _lpDevice.SetIndicator(IndicatorType.Complete, IndicatorState.ON); } public override void Reset() { if (IsError) { CheckToPostMessage((int)MSG.Reset); } } public override bool PrepareTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { reason = string.Empty; return true; } public override bool TransferHandoff(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { reason = string.Empty; return true; } public override bool PostTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { reason = string.Empty; return true; } public override bool CheckReadyForTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { return _lpDevice.IsEnableTransferWafer(out reason) && IsReady && _lpDevice.DoorState == FoupDoorState.Open; } public override bool CheckReadyForMap(ModuleName robot, Hand blade, out string reason) { return _lpDevice.IsEnableMapWafer(out reason) && IsReady && _lpDevice.DoorState == FoupDoorState.Open; } public override void NoteTransferStart(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType) { CheckToPostMessage(MSG.InTransfer); } public override void NoteTransferStop(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType) { if (FsmState == (int)STATE.InTransfer) CheckToPostMessage(MSG.TransferComplete); } public void CarrierArrive() { //_lpDevice.SetIndicator(IndicatorType.Busy, IndicatorState.OFF); //_lpDevice.SetIndicator(IndicatorType.Complete, IndicatorState.OFF); _jobDone = false; } public void CarrerRemove(string carrierID) { //_lpDevice.SetIndicator(IndicatorType.Busy, IndicatorState.OFF); //_lpDevice.SetIndicator(IndicatorType.Complete, IndicatorState.OFF); _jobDone = false; } public void CarrierIDReadSuccess(string carrierID) { } public void CarrierIDReadFail() { } public void MappingComplete(string carrierID, string slotmap) { } public void LoadportError(string errorcode) { } public void LoadComplete() { } public void UnloadComplete() { } public void OnLPHomed() { PostMsg(MSG.ToIdle); } public void OnE84HandoffStart(bool isload) { } public void OnE84HandoffComplete(bool isload) { } //重新连接了EFEM,重置数据 public void ResetData() { _lpDevice.SetIndicator(IndicatorType.Busy, IndicatorState.OFF); _lpDevice.SetIndicator(IndicatorType.Complete, IndicatorState.OFF); _lpDevice.ResetData(); } private bool FsmReset(object[] param) { if (!_efemDevice.Connection.IsConnected) { _efemDevice.Connect(); return false; } if (!_isInit) { PostMsg(MSG.ToInit); return false; } if (_lpDevice.IsError) { EV.PostWarningLog(Module, $"{Module} in error, home to recover"); PostMsg(MSG.ToInit); return false; } return true; } private bool FsmOnError(object[] param) { if (FsmState == (int)STATE.Error) { return false; } AbortRoutine(); if (FsmState == (int)STATE.Init) return false; return true; } private bool FsmExitIdle(object[] param) { return true; } private bool FsmEnterIdle(object[] param) { return true; } private bool FsmExitError(object[] param) { return true; } private bool FsmEnterError(object[] param) { if (OnEnterError != null) OnEnterError(Module); return true; } private bool FsmAbortTask(object[] param) { AbortRoutine(); return true; } private bool FsmStartHome(object[] param) { Result ret = StartRoutine(_home); if (ret == Result.FAIL || ret == Result.DONE) return false; _isInit = false; return ret == Result.RUN; } private bool FsmMonitorHomeTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } if (ret == Result.DONE) { _isInit = true; return true; } return false; } private bool FsmToInit(object[] param) { return true; } private bool FsmToIdle(object[] param) { _lpDevice.Initalized = true; _lpDevice.OnHomed(); return true; } private bool FsmMonitorLoadTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } if (ret == Result.DONE) { IsOnline = true; _lpDevice.DockState = FoupDockState.Docked; LPDevice.OnLoaded(); } return ret == Result.DONE; } private bool FsmMonitorTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } if (ret == Result.DONE) { LPDevice.OnUnloaded(); } return ret == Result.DONE; } private bool FsmStartLoad(object[] param) { //QueueRoutine.Clear(); //QueueRoutine.Enqueue(_clamp); ////QueueRoutine.Enqueue(_dock); //QueueRoutine.Enqueue(_openDoor); ////QueueRoutine.Enqueue(_map); //QueueRoutine.Enqueue(_MapDT); //Result ret = StartRoutine(); Result ret = StartRoutine(_load); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartUnload(object[] param) { IsOnline = false; QueueRoutine.Clear(); QueueRoutine.Enqueue(_closeDoor); //QueueRoutine.Enqueue(_undock); //QueueRoutine.Enqueue(_unclamp); Result ret = StartRoutine(); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartMap(object[] param) { Result ret = StartRoutine(_map); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartCloseDoor(object[] param) { Result ret = StartRoutine(_closeDoor); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartOpenDoor(object[] param) { Result ret = StartRoutine(_openDoor); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartUndock(object[] param) { Result ret = StartRoutine(_undock); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartDock(object[] param) { Result ret = StartRoutine(_dock); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartUnclamp(object[] param) { Result ret = StartRoutine(_unclamp); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartClamp(object[] param) { Result ret = StartRoutine(_clamp); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartReadCarrierId(object[] param) { Result ret = StartRoutine(_readCarrierId); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } } }