using System; using System.Collections.Generic; using Aitex.Core.Common; using Aitex.Core.RT.Event; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using VirgoCommon; using VirgoRT.Device; using VirgoRT.Device.YASKAWA; using System.Diagnostics; using System.Threading; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using MECF.Framework.Common.CommonData; using VirgoRT.Devices.EFEM; using VirgoRT.Modules; namespace VirgoRT.Devices { /// /// Base action /// abstract class EfemActionBase : ActionBase { protected readonly EfemBase _efem; public EfemOperation Type { get; protected set; } protected EfemActionBase() : this(null) { } protected EfemActionBase(EfemBase efem) : base(ModuleName.EFEM) { _efem = efem; } } class DelayAction : ActionBase { private readonly DeviceTimer _timer = new DeviceTimer(); private readonly ushort _delayTime; public bool IsDone => _timer.IsTimeout(); public DelayAction(ushort delaytime) : base(ModuleName.System) { this._delayTime = delaytime; } public override void Execute() { _timer.Start(this._delayTime * 1000); } public override void OnPostWork(string data) { EV.PostInfoLog(ModuleName.EFEM.ToString(), $"Delay time [{_delayTime}]"); } } } namespace VirgoRT.Devices.YASKAWA { class EfemAction : EfemActionBase { public EfemAction(EfemBase device, ModuleName mod) : base(device) { } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[this.Module] } }); base.Execute(); _efem.Status = DeviceState.Busy; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} Start"); } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } } /// /// /// class HomeAllAction : EfemAction { public HomeAllAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Home; this.Module = mod; } public override void OnPostWork(string data = null) { _efem[ModuleName.LP1].OnHomed(); _efem[ModuleName.LP2].OnHomed(); (_efem as Efem).MoveInfo.Action = RobotAction.Moving; (_efem as Efem).MoveInfo.BladeTarget = "System"; base.OnPostWork(data); var tower = DEVICE.GetDevice("System.SignalTower"); if (tower != null) { tower.ResetData(); } } } class HomeModuleAction : EfemAction { public HomeModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Home; this.Module = mod; IsBackground = ModuleHelper.IsLoadPort(mod); } public override void OnPostWork(string data = null) { if (ModuleHelper.IsLoadPort(Module)) { _efem[Module].OnHomed(); } (_efem as Efem).MoveInfo.Action = RobotAction.Moving; (_efem as Efem).MoveInfo.BladeTarget = "System"; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } } class LoadModuleAction : EfemAction { public LoadModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Load; this.Module = mod; IsBackground = true; } public override void OnPostWork(string data = null) { _efem[Module].OnLoaded(); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnLoadFailed(data); base.OnError(data); } } class UnloadModuleAction : EfemAction { public UnloadModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Unload; this.Module = mod; IsBackground = true; } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; _efem[Module].OnUnloaded(); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnUnloadFailed(data); base.OnError(data); } } class ReadCarrierIdModuleAction : EfemAction { public ReadCarrierIdModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.CarrierId; this.Module = mod; IsBackground = true; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.GET, Parameters = new List { Constant.ModuleString[this.Module] } }); //base.Execute(); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} Start"); } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; _efem[Module].OnCarrierIDRead(data); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnCarrierIDReadFailed(data); base.OnError(data); } } class WriteCarrierIdModuleAction : EfemAction { private string _id; public WriteCarrierIdModuleAction(EfemBase efem, ModuleName mod, string id) : base(efem, mod) { Type = EfemOperation.CarrierId; this.Module = mod; IsBackground = true; _id = id; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[this.Module], _id } }); //base.Execute(); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} Start"); } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; _efem[Module].OnCarrierIDWrite(_id); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnCarrierIDWriteFailed(_id); base.OnError(data); } } class ReadTagDataModuleAction : EfemAction { public ReadTagDataModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.CarrierId; this.Module = mod; IsBackground = true; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.GET, Parameters = new List { Constant.ModuleString[this.Module] } }); //base.Execute(); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} Start"); } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; _efem[Module].OnTagDataRead(data); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnTagDataReadFailed(data); base.OnError(data); } } class WriteTagDataModuleAction : EfemAction { private string _id; public WriteTagDataModuleAction(EfemBase efem, ModuleName mod, string id) : base(efem, mod) { Type = EfemOperation.CarrierId; this.Module = mod; IsBackground = true; _id = id; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[this.Module], _id } }); //base.Execute(); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} Start"); } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; _efem[Module].OnTagDataWrite(_id); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnTagDataWriteFailed(_id); base.OnError(data); } } class DockModuleAction : EfemAction { public DockModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Dock; this.Module = mod; IsBackground = true; } } class UndockModuleAction : EfemAction { public UndockModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Undock; this.Module = mod; IsBackground = true; } } class ClampModuleAction : EfemAction { private bool _isUnloadClamp; public ClampModuleAction(EfemBase efem, ModuleName mod, bool isUnloadClamp) : base(efem, mod) { Type = EfemOperation.Clamp; this.Module = mod; IsBackground = true; _isUnloadClamp = isUnloadClamp; } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; _efem[Module].OnClamped(_isUnloadClamp); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnClampFailed(data); base.OnError(data); } } class UnclampModuleAction : EfemAction { public UnclampModuleAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Unclamp; this.Module = mod; IsBackground = true; } public override void OnPostWork(string data = null) { _efem.Status = DeviceState.Idle; _efem[Module].OnUnclamped(); EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End"); } public override void OnError(string data = null) { _efem[Module].OnUnclampFailed(data); base.OnError(data); } } class SetThicknessModuleAction : EfemAction { private string _thick; public SetThicknessModuleAction(EfemBase efem, ModuleName mod, string thickness) : base(efem, mod) { Type = EfemOperation.SetThickness; this.Module = mod; IsBackground = true; _thick = thickness; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[this.Module], _thick.ToUpper() } }); //base.Execute(); this.Status = ActionStatus.SendCmd; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} Start"); } } class OrgshAction : EfemAction { public OrgshAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Orgsh; this.Module = mod; } } class TrackAction : EfemAction { public TrackAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.StateTrack; this.Module = mod; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.GET, Parameters = new List { "TRACK" } }); this.Status = ActionStatus.SendCmd; EV.PostInfoLog(this.Module.ToString(), "Query wafer present information"); } public override void OnPostWork(string data) { this.Status = ActionStatus.Completed; //000/111 upperArmWafer, lowerArmWafer, alignerWafer1, alignerWafer2, coolingwafer1,coolingwafer2 if (data.Length != 6) { LOG.Write($"EFEM Track wafer present return invalid value, {data}, should be 6 characters"); return; } //upper arm if (data[0] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1)) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 1, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { EV.PostWarningLog(Module.ToString(), $" {ModuleName.EfemRobot} upper arm has wafer information, while EFEM return empty, manually delete if really no wafer"); } } //lower arm if (data[1] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 0, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { EV.PostWarningLog(Module.ToString(), $" {ModuleName.EfemRobot} lower arm has wafer information, while EFEM return empty, manually delete if really no wafer"); } } //aligner1 if (data[2] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.Aligner1, 0)) { WaferManager.Instance.CreateWafer(ModuleName.Aligner1, 0, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0)) { EV.PostWarningLog(Module.ToString(), $" {ModuleName.Aligner1} has wafer information, while EFEM return empty, manually delete if really no wafer"); } } //aligner2 if (data[3] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.Aligner2, 0)) { WaferManager.Instance.CreateWafer(ModuleName.Aligner2, 0, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner2, 0)) { EV.PostWarningLog(Module.ToString(), $" {ModuleName.Aligner2} has wafer information, while EFEM return empty, manually delete if really no wafer"); } } //cooling1 if (data[4] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.Cooling1, 0)) { WaferManager.Instance.CreateWafer(ModuleName.Cooling1, 0, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.Cooling1, 0)) { EV.PostWarningLog(Module.ToString(), $" {ModuleName.Cooling1} has wafer information, while EFEM return empty, manually delete if really no wafer"); } } //cooling2 if (data[5] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.Cooling2, 0)) { WaferManager.Instance.CreateWafer(ModuleName.Cooling2, 0, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.Cooling2, 0)) { EV.PostWarningLog(Module.ToString(), $" {ModuleName.Cooling2} has wafer information, while EFEM return empty, manually delete if really no wafer"); } } } } class ClearErrorAction : EfemAction { public ClearErrorAction(EfemBase efem) : base(efem, ModuleName.EFEM) { Type = EfemOperation.ClearError; IsBackground = true; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.SET, Parameters = new List { "CLEAR" } }); this.Status = ActionStatus.SendCmd; EV.PostInfoLog(this.Module.ToString(), "清除 EFEM 所有错误"); } } class LoadPortClearErrorAction : EfemAction { public LoadPortClearErrorAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.ClearError; this.Module = mod; IsBackground = true; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.SET, Parameters = new List { "CLEAR", Constant.ModuleString[this.Module] } }); this.Status = ActionStatus.SendCmd; EV.PostInfoLog(this.Module.ToString(), "清除 LoadPort 所有错误"); } } class MapAction : EfemAction { public MapAction(EfemBase efem, ModuleName mod) : base(efem, mod) { Type = EfemOperation.Map; this.Module = mod; } public override void OnPostWork(string data) { _efem[Module].Status = DeviceState.Idle; } } class PickAction : EfemAction { private MoveParam MoveParam { get; } public PickAction(EfemBase efem, MoveParam mp) : base(efem, ModuleName.EFEM) { Type = EfemOperation.Pick; MoveParam = mp; } public override void Execute() { //MOV:LOAD/P113/ARM2; _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV, Parameters = new List { MoveParam.SrcPos.ToHWString(), Constant.ArmString[MoveParam.Arm], MoveParam.WaferSize.ToString() } }); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; } public override void OnPostWork(string data) { if (MoveParam.Arm == Hand.Both) { if (MoveParam.DestModule == ModuleName.EfemRobot) { WaferManager.Instance.WaferMoved(MoveParam.SrcModule, MoveParam.SrcSlot, MoveParam.DestModule, 0); WaferManager.Instance.WaferMoved(MoveParam.SrcModule, MoveParam.SrcSlot + 1, MoveParam.DestModule, 1); } else { WaferManager.Instance.WaferMoved(MoveParam.SrcModule, 0, MoveParam.DestModule, MoveParam.DestSlot); WaferManager.Instance.WaferMoved(MoveParam.SrcModule, 1, MoveParam.DestModule, MoveParam.DestSlot + 1); } } else WaferManager.Instance.WaferMoved(MoveParam.SrcModule, MoveParam.SrcSlot, MoveParam.DestModule, MoveParam.DestSlot); _efem.Status = DeviceState.Idle; //_bladeTarget = ModuleName.EfemRobot; (_efem as Efem).MoveInfo.Action = RobotAction.Moving; } } class PlaceAction : EfemAction { private MoveParam MoveParam { get; } public PlaceAction(EfemBase device, MoveParam mp) : base(device, ModuleName.EFEM) { Type = EfemOperation.Place; MoveParam = mp; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV, Parameters = new List { MoveParam.DestPos.ToHWString(), Constant.ArmString[MoveParam.Arm], MoveParam.WaferSize.ToString() } }); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; } public override void OnPostWork(string data) { WaferManager.Instance.WaferMoved(MoveParam.SrcModule, MoveParam.SrcSlot, MoveParam.DestModule, MoveParam.DestSlot); _efem.Status = DeviceState.Idle; (_efem as Efem).MoveInfo.Action = RobotAction.Moving; } } class GotoAction : EfemAction { private MoveParam MoveParam { get; } public GotoAction(EfemBase device, MoveParam mp) : base(device, ModuleName.EFEM) { Type = EfemOperation.Goto; MoveParam = mp; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV, Parameters = new List { MoveParam.DestPos.ToHWString(), Constant.ArmString[MoveParam.Arm], //MoveParam.WaferSize.ToString() } }); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; } public override void OnPostWork(string data) { _efem.Status = DeviceState.Idle; (_efem as Efem).MoveInfo.Action = RobotAction.Moving; (_efem as Efem).MoveInfo.BladeTarget = MoveParam.DestPos.Module.ToString(); } } class ExtendAction : EfemAction { private ExtendParam ExtParam { get; } public ExtendPos TargetPosition => ExtParam.Pos; private JetPM _pm; public ExtendAction(EfemBase efem, JetPM pm, ExtendParam ep) : base(efem, ModuleName.EFEM) { Type = EfemOperation.Extend; ExtParam = ep; ExtParam.Arm = ep.Arm; _pm = pm; } public override void Execute() { if (_pm != null && !_pm.CheckSlitDoorOpen()) { EV.PostAlarmLog("EFEM", $"{_pm.Module} slit door should be opened"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); return; } //MOV:EXTEND/LLA03/ARM2; _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV, Parameters = new List { ExtParam.Module.ToHWString(), //Constant.ExtendPosString[ExtParam.Pos], ExtParam.Pos.ToString(), Constant.ArmString[ExtParam.Arm], ExtParam.ws.ToString() } }); ; this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; } public override void OnPostWork(string data) { _efem.Status = DeviceState.Idle; switch (TargetPosition) { case ExtendPos.PB: LOG.Write($"robot extend PB put: arm {ExtParam.Arm}, module {ExtParam.Module}"); //WaferManager.Instance.WaferMoved(ModuleName.EfemRobot, (int)ExtParam.Arm, ExtParam.Module, 0); break; case ExtendPos.G4: LOG.Write($"robot extend G4 get: arm {ExtParam.Arm}, module {ExtParam.Module}"); // WaferManager.Instance.WaferMoved(ExtParam.Module, 0, ModuleName.EfemRobot, (int)ExtParam.Arm); break; default: LOG.Write($"MNPT:{TargetPosition} 不需要更新 WaferManager 信息"); break; } (_efem as Efem).MoveInfo.Action = RobotAction.Moving; } } class GripAction : EfemAction { private Hand _blade; private bool _isGrip; public GripAction(EfemBase efem, Hand blade, bool isGrip) : base(efem, ModuleName.EFEM) { Type = EfemOperation.Grip; _blade = blade; _isGrip = isGrip; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ArmString[_blade], _isGrip ? "ON":"OFF" } }); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; } public override void OnPostWork(string data) { _efem.Status = DeviceState.Idle; if (_blade == Hand.Blade1) _efem.GripStateBlade1 = _isGrip ? "ON" : "OFF"; if (_blade == Hand.Blade2) _efem.GripStateBlade2 = _isGrip ? "ON" : "OFF"; } } class LiftAction : EfemAction { // MOV:LIFT/ALIGN1; private bool _isUp; public LiftAction(EfemBase device, ModuleName mod, bool isUp) : base(device, mod) { Type = EfemOperation.Lift; Module = mod; _isUp = isUp; IsBackground = true; (device as Efem).IsBufferPinUp[mod] = !isUp; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[this.Module], _isUp ? "UP" : "DOWN" } }); this.Status = ActionStatus.SendCmd; _efem.Status = DeviceState.Busy; EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} Start"); } public override void OnPostWork(string data) { _efem.Status = DeviceState.Idle; (_efem as Efem).IsBufferPinUp[Module] = _isUp; } } class AlignAction : EfemAction { private WaferSize _ws { get; } public AlignAction(EfemBase device, ModuleName mod, WaferSize size) : base(device, mod) { Type = EfemOperation.Align; this.Module = mod; this._ws = size; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Module.ToHWString(), this._ws.ToString() } }); this.Status = ActionStatus.SendCmd; } public override void OnPostWork(string data) { } } class LedAction : EfemAction { private LightType Light { get; } private LightStatus LtStatus { get; } public LedAction(EfemBase device, LightType lt, LightStatus st) : base(device, ModuleName.EFEM) { Type = EfemOperation.Light; Light = lt; LtStatus = st; IsBackground = true; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.STOWER, Light.ToString(), LtStatus.ToString() } }); _efem.Status = DeviceState.Busy; this.Status = ActionStatus.SendCmd; //EV.PostInfoLog(this.Module.ToString(), $"CMD[{this.ID}], Set {this.Light} = {LtStatus}"); } public override void OnPostWork(string data) { } } class AbortAction : EfemAction { public AbortAction(EfemBase efem) : base(efem, ModuleName.EFEM) { Type = EfemOperation.Abort; } public override void Execute() { _efem.MsgHandler.Send(new EfemMessage { Operation = this.Type, Head = EfemMessage.MsgHead.MOV }); } } }