| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156 | using System;using System.Collections.Generic;using Aitex.Core.Common;using Aitex.Core.RT.Event;using Aitex.Core.Util;using Aitex.Core.RT.SCCore;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 VirgoRT.Devices.EFEM;using VirgoRT.Modules;namespace VirgoRT.Devices{    /// <summary>    /// Base action    /// </summary>    abstract class EfemActionBase : ActionBase    {        protected readonly EfemBase _efem;        private readonly EfemEntity.EfemType _efemType;        public EfemOperation Type { get; protected set; }        protected EfemActionBase() : this(null) { }        protected EfemActionBase(EfemBase efem) : base(ModuleName.EFEM)        {            _efem = efem;            _efemType = (EfemEntity.EfemType)SC.GetValue<int>($"EFEM.EfemType");        }        protected void Send(IEfemMessage msg)        {            if (_efemType == EfemEntity.EfemType.BrooksEFEM)            {                if (_efem.BrooksProxy.Connected || Type == EfemOperation.Home)                {                    var _ = _efem.BrooksProxy.Send(msg);                }            }            else            {                _efem.MsgHandler.Send(msg);            }        }    }    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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string> { 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");        }    }    /// <summary>    ///    /// </summary>    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();            base.OnPostWork(data);            var tower = DEVICE.GetDevice<VirgoSignalTower>("System.SignalTower");            if (tower != null)            {                tower.ResetData();            }         }    }    class HomeModuleAction : EfemAction    {        private string _param;        public HomeModuleAction(EfemBase efem, ModuleName mod, string param) : base(efem, mod)        {            Type = EfemOperation.Home;            this.Module = mod;            _param = param;            IsBackground = ModuleHelper.IsLoadPort(mod);        }        public override void Execute()        {            var parameter = SC.GetValue<int>($"EFEM.EfemType") == 4 ? new List<string> { Constant.ModuleString[this.Module] } : new List<string> { Constant.ModuleString[this.Module], _param };            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = parameter            });            //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)        {            if (ModuleHelper.IsLoadPort(Module))            {                _efem[Module].OnHomed();            }            EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} End");        }    }    class SIGSTATModuleAction : EfemAction    {        private string _param;        public SIGSTATModuleAction(EfemBase efem, ModuleName mod, string param) : base(efem, mod)        {            Type = EfemOperation.SigStatus;            this.Module = mod;            _param = param;        }        public override void Execute()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.GET,                Parameters = new List<string> { 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)        {            if (ModuleHelper.IsLoadPort(Module))            {                _efem[Module].OnHomed();            }            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 = ModuleHelper.IsLoadPort(mod);        }        public override void OnPostWork(string data = null)        {            _efem[Module].OnLoaded();            EV.PostInfoLog(this.Module.ToString(), $"Cmd {this.ID} {this.Type} {Module}:{_efem[Module].CarrierId} 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 = ModuleHelper.IsLoadPort(mod);        }        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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.GET,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.SET,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.GET,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.SET,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.SET,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.GET,                Parameters = new List<string> { "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}, less then 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");                }            }            if(data.Length > 6)            {                if (data[6] == '1')                {                    if (WaferManager.Instance.CheckNoWafer(ModuleName.Buffer, 0))                    {                        WaferManager.Instance.CreateWafer(ModuleName.Buffer, 0, WaferStatus.Normal);                    }                }                else                {                    if (WaferManager.Instance.CheckHasWafer(ModuleName.Buffer, 0))                    {                        EV.PostWarningLog(Module.ToString(), $" {ModuleName.Buffer} slot 1 has wafer information, while EFEM return empty, manually delete if really no wafer");                    }                }            }            if (data.Length > 7)            {                if (data[7] == '1')                {                    if (WaferManager.Instance.CheckNoWafer(ModuleName.Buffer, 1))                    {                        WaferManager.Instance.CreateWafer(ModuleName.Buffer, 1, WaferStatus.Normal);                    }                }                else                {                    if (WaferManager.Instance.CheckHasWafer(ModuleName.Buffer, 1))                    {                        EV.PostWarningLog(Module.ToString(), $" {ModuleName.Buffer} slot 2 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.SET,                Parameters = new List<string> { "CLEAR" }            });            this.Status = ActionStatus.SendCmd;            EV.PostInfoLog(this.Module.ToString(), "Clear EFEM Error");        }    }    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;            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string>                {                    MoveParam.SrcPos.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;            //_bladeTarget = ModuleName.EfemRobot;        }    }     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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string>                {                    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;        }    }     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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string>                {                    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;        }    }    class ExtendAction : EfemAction    {        private ExtendParam ExtParam { get; }        public ExtendPos TargetPosition => ExtParam.Pos;        public ExtendAction(EfemBase efem, ExtendParam ep)            : base(efem, ModuleName.EFEM)        {            Type = EfemOperation.Extend;            ExtParam = ep;            ExtParam.Arm = ep.Arm;        }        public override void Execute()        {            //MOV:EXTEND/LLA03/ARM2;            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string>                {                    ExtParam.Module.ToHWString(),                    //Constant.ExtendPosString[ExtParam.Pos],                    ExtParam.Pos.ToString(),                    Constant.ArmString[ExtParam.Arm]                }            });            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:                Debug.WriteLine($"MNPT:{TargetPosition} 不需要更新 WaferManager 信息");                break;            }        }    }    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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.SET,                Parameters = new List<string>                {                    _isGrip ? "ON":"OFF",                    Constant.ArmString[_blade]                }            });            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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.SET,                Parameters = new List<string> { 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()        {            Send(new EfemMessage            {                Operation = this.Type,                Head = EfemMessage.MsgHead.MOV            });        }    }    class FlipAction : EfemAction    {        private string _orient;        public FlipAction(EfemBase device, ModuleName mod, string orient) : base(device, mod)        {            this.Type = EfemOperation.Flip;            this._orient = orient;        }        public override void Execute()        {            Send(new EfemMessage            {                Operation = Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string> { _orient }            });        }    }    class EmsStopAction : EfemAction    {        public EmsStopAction(EfemBase device, ModuleName mod) : base(device, mod)        {            this.Type = EfemOperation.EmsStop;        }        public override void Execute()        {            Send(new EfemMessage            {                Operation = Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string> {  }            });        }    }    class SetSpeedAction : EfemAction    {        private string _speed;        public SetSpeedAction(EfemBase device, ModuleName mod, string speed) : base(device, mod)        {            this.Type = EfemOperation.SetRobotSpeed;            this._speed = speed;        }        public override void Execute()        {            Send(new EfemMessage            {                Operation = Type,                Head = EfemMessage.MsgHead.MOV,                Parameters = new List<string> { _speed }            });        }    }    class QueryLPStateAction : EfemAction    {        public QueryLPStateAction(EfemBase efem, ModuleName mod) : base(efem, mod)        {            Type = EfemOperation.QueryLPPresence;            this.Module = mod;            IsBackground = true;        }    }}
 |