| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248 | using System;using Aitex.Core.Common;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.RT.SCCore;using Aitex.Core.Util;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.Schedulers;using MECF.Framework.Common.SubstrateTrackings;using Virgo_DCommon;using Virgo_DRT.Devices;using Virgo_DRT.Modules;using Virgo_DRT.Modules.PMs;namespace Virgo_DRT.Module{    public class PMEntity : Entity, IModuleEntity    {        public enum MSG        {            Home,            Transfer,            PrepareTransfer,            PostTransfer,            Reset,            Abort,            Error,            LaunchPump,            Pump,            Vent,            CyclePurge,            Heat,            TransferHandoff,            StartTransfer,            LeakCheck,            DeleteLeakCheck,            MoveLiftPin,            MoveGuidePin,            Process,            RunRecipe,            PostProcess,            RecipeSkipStep,            RecipeUpdate,            RecipeResume,            RecipePause,            RecipeAbort,            PreProcess,            AutoMode,            ManualMode,            LockLid,            Online,            Offline,            GasFlow,            StopGasFlow,            RfPower,            MaxMsg        }        // ----------------------------Fields--------------------------        //         private readonly JetPM                      _chamber;        private string                              _processStatus;        private DateTime                            _recipeStartTime;         //routine        private readonly VentRoutine                _ventRoutine;        private readonly PumpDownRoutine            _pumpRoutine;        private readonly StartPumpRoutine           _startPumpRoutine;        private readonly TemperatureControlRoutine  _temperatureControlRoutine;        private readonly GasFlowRoutine             _gasFlowRoutine;        private readonly RfPowerRoutine             _rfPowerRoutine;        private readonly CyclePurgeRoutine          _cyclePurgeRoutine;        private readonly ProcessRoutine             _processRoutine;        private readonly PreProcessRoutine          _preProcessRoutine;        private readonly PostProcessRoutine         _postProcessRoutine;        private readonly LeakCheckRoutine           _leakCheckRoutine;        private readonly PMPrepareTransferRoutine   _prepareTrans;        private readonly PMPostTransferRoutine      _postTrans;        private readonly PMHomeRoutine              _home;        private AutoFlag                            _AutoMode;        private bool                                _isOnline;        private DateTime                            _pumpStartTime;        private TimeSpan                            _pumpElapsedTime;        private DateTime                            _rfStartTime;        private DateTime                            _tcStartTime;        private TimeSpan                            _rfElapsedTime;        private TimeSpan                            _tcElapsedTime;        private MovementPosition                    _goalLiftPin;        private ushort                              _ActivatedActionID;        // --------------------------Properties------------------------        //         public ModuleName Module { get; }        public Action<bool, bool> TransferPrepared;        public bool IsIdle        {            get { return fsm.State == (int)PMState.Idle; }        }        public bool IsError        {            get { return fsm.State == (int)PMState.Error; }        }        public bool IsAutoMode => _AutoMode == AutoFlag.Auto;        public int Invoke(string function, params object[] args)        {            switch (function)            {            case "Home":                CheckToPostMessage((int)MSG.Home);                return (int)MSG.Home;            }            return (int)FSM_MSG.NONE;        }        public bool CheckAcked(int msg)        {            return fsm.CheckExecuted(msg);        }        public bool IsInit        {            get { return fsm.State == (int)PMState.Init; }        }        public bool IsBusy        {            get { return !IsInit && !IsError && !IsIdle; }        }        public bool IsProcessing        {            get { return fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess ; }        }        private string PumpTime        {            get            {                if ((fsm.State == (int)PMState.Pumping) || (fsm.State == (int)PMState.PreProcess))                    _pumpElapsedTime = DateTime.Now - _pumpStartTime;                return string.Format("{0}:{1}:{2}", ((int)_pumpElapsedTime.TotalHours).ToString("00"),                    _pumpElapsedTime.Minutes.ToString("00"), _pumpElapsedTime.Seconds.ToString("00"));            }        }        private int StepNo        {            get            {                if ( (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))                {                    return _processRoutine.CurStepNum + 1;                }                return 0;            }        }        private int RecipeSteps        {            get            {                if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))                {                    return _preProcessRoutine.CurrentRecipeStepList.Count;                }                return 0;            }        }        private string RecipeStepName        {            get            {                if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))                {                    return _processRoutine.CurStepComment;                }                return null;            }        }        private double LeakRate        {            get { return _leakCheckRoutine.LeakRate; }        }        private string RecipeName        {            get            {                if ((fsm.State == (int)PMState.PreProcess) || (fsm.State == (int)PMState.Processing) || (fsm.State == (int)PMState.PostProcess))                {                    return _preProcessRoutine.CurrentRecipeRunningName.Split('\\')[1];                }                return null;            }        }        private string RFTime        {            get            {                if (fsm.State == (int)PMState.RfPowering)                    _rfElapsedTime = DateTime.Now - _rfStartTime;                return $"{((int)_rfElapsedTime.TotalHours).ToString("00")}:{_rfElapsedTime.Minutes.ToString("00")}:{_rfElapsedTime.Seconds.ToString("00")}";            }        }        private string TCTime        {            get            {                if (fsm.State == (int)PMState.Heating)                    _tcElapsedTime = DateTime.Now - _tcStartTime;                return $"{((int)_tcElapsedTime.TotalHours).ToString("00")}:{_tcElapsedTime.Minutes.ToString("00")}:{_tcElapsedTime.Seconds.ToString("00")}";            }        }        private TimeSpan _recipeElapsedTime;        public string RecipeElapsedTime        {            get            {                if (fsm.State == (int)PMState.LoadProcessRecipe || fsm.State == (int)PMState.PreProcess                                                                || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess)                    _recipeElapsedTime = DateTime.Now - _recipeStartTime;                return string.Format("{0}:{1}:{2}", ((int)_recipeElapsedTime.TotalHours).ToString("00"),                    _recipeElapsedTime.Minutes.ToString("00"), _recipeElapsedTime.Seconds.ToString("00"));            }        }        public bool IsOnline        {            get { return _isOnline; }        }        // --------------------------Constructor-----------------------        //         public PMEntity(ModuleName module)        {            this.Module = module;            //_chamber = new JetPM(ModuleHelper.Converter(Name));            _chamber = DEVICE.GetDevice<JetPM>(Module.ToString());            LeakCheckResultManager.Instance.Initialize(Module.ToString());            fsm = new StateMachine<PMEntity>(Module.ToString(), (int)PMState.Init, 50);            _ventRoutine        = new VentRoutine(_chamber);            _pumpRoutine        = new PumpDownRoutine(_chamber);            _startPumpRoutine   = new StartPumpRoutine(_chamber);            _temperatureControlRoutine = new TemperatureControlRoutine(_chamber);            _prepareTrans       = new PMPrepareTransferRoutine(_chamber, _ventRoutine);            _postTrans          = new PMPostTransferRoutine(_chamber);            _gasFlowRoutine     = new GasFlowRoutine(_chamber);            _rfPowerRoutine     = new RfPowerRoutine(_chamber, true);            _cyclePurgeRoutine  = new CyclePurgeRoutine(_chamber);            _leakCheckRoutine   = new LeakCheckRoutine(_chamber, _pumpRoutine);            _preProcessRoutine  = new PreProcessRoutine(_chamber, _pumpRoutine);            _processRoutine     = new ProcessRoutine(_chamber);            _postProcessRoutine = new PostProcessRoutine(_chamber, _ventRoutine);            _home               = new PMHomeRoutine(_chamber);            //Idle            EnterExitTransition((int)PMState.Idle,                    FnIdle, (int)FSM_MSG.NONE, null);            //Error            Transition(PMState.Init, MSG.Error,                       FnError, PMState.Error);            Transition(PMState.Init, MSG.Reset,                       null, PMState.Init);            Transition(PMState.Error, MSG.Reset,                      FnReset, PMState.Idle);            AnyStateTransition((int)FSM_MSG.ALARM,                    FnError, (int)PMState.Error);            AnyStateTransition(MSG.AutoMode,                          FnSetAuto, FSM_STATE.SAME);            AnyStateTransition(MSG.ManualMode,                        FnSetManual, FSM_STATE.SAME);            AnyStateTransition(MSG.Online,                            FnSetOnline, FSM_STATE.SAME);            AnyStateTransition(MSG.Offline,                           FnSetOffline, FSM_STATE.SAME);            //Home            EnterExitTransition((int)PMState.Homing,                  FnEnterHome, (int)FSM_MSG.NONE, FnExitHome);            Transition(PMState.Init, MSG.Home,                        FnStartHome, PMState.Homing);            Transition(PMState.Error, MSG.Home,                       FnStartHome, PMState.Homing);            Transition(PMState.Idle, MSG.Home,                        FnStartHome, PMState.Homing);            Transition(PMState.Homing, FSM_MSG.TIMER,                 FnMonitorHome, PMState.Idle);            Transition(PMState.Homing, MSG.Error,                     null, PMState.Init);            Transition(PMState.Homing, MSG.Abort,                     FnAbortTask, PMState.Init);        // Gas Flow sequence            Transition(PMState.Idle, MSG.GasFlow,                     FnStartGasFlow, PMState.GasFlowing);            Transition(PMState.GasFlowing, MSG.GasFlow,               FnStartGasFlow, PMState.GasFlowing);            Transition(PMState.GasFlowing, FSM_MSG.TIMER,             FnGasFlowTimeout, PMState.Idle);            Transition(PMState.GasFlowing, MSG.StopGasFlow,           FnStopGasFlow, PMState.Idle);            Transition(PMState.GasFlowing, MSG.Abort,                 FnAbortGasFlow, PMState.Idle);            //RF Power sequence            Transition(PMState.Idle, MSG.RfPower,                     FnStartRfPower, PMState.RfPowering);            Transition(PMState.GasFlowing, MSG.RfPower,               FnStartRfPower, PMState.RfPowering);            Transition(PMState.RfPowering, FSM_MSG.TIMER,             FnRfPowerTimeout, PMState.Idle);            Transition(PMState.RfPowering, MSG.Abort,                 FnAbortRfPower, PMState.Idle);            // Heat substrate            Transition(PMState.Idle, MSG.Heat,                        FnHeat, PMState.Heating);            Transition(PMState.Heating, FSM_MSG.TIMER,                FnHeatTimeout, PMState.Idle);            Transition(PMState.Heating, MSG.Abort,                    FnAbortHeating, PMState.Idle);            //Launch Pump sequence            Transition(PMState.Idle, MSG.LaunchPump,                  FnLaunchPump, PMState.LaunchingPump);            Transition(PMState.LaunchingPump, FSM_MSG.TIMER,          FnLaunchPumpTimeout, PMState.Idle);            Transition(PMState.LaunchingPump, MSG.Abort,              FnAbortStartPumping, PMState.Idle);            //Pump sequence            Transition(PMState.Idle, MSG.Pump,                        FnStartPumpDown, PMState.Pumping);            Transition(PMState.Venting, MSG.Pump,                     FnVentToPumping, PMState.Pumping);            Transition(PMState.Pumping, FSM_MSG.TIMER,                FnPumpDownTimeout, PMState.Idle);            Transition(PMState.Pumping, MSG.Abort,                    FnAbortPumping, PMState.Idle);            //vent sequence            Transition(PMState.Idle, MSG.Vent,                        FnStartVent, PMState.Venting);            Transition(PMState.Pumping, MSG.Vent,                     FnPumpingToVent, PMState.Venting);            Transition(PMState.Venting, FSM_MSG.TIMER,                FnVentTimeout, PMState.Idle);            Transition(PMState.Venting, MSG.Abort,                    FnAbortVent, PMState.Idle);            // Purge sequence            Transition(PMState.Idle, MSG.CyclePurge,                  FnStartPurge, PMState.Purging);            Transition(PMState.Purging, FSM_MSG.TIMER,                FnPurgeTimeout, PMState.Idle);            Transition(PMState.Purging, MSG.Abort,                    FnAbortPurge, PMState.Idle);            //Leak check sequence            Transition(PMState.Idle, MSG.LeakCheck,                   FnStartLeakCheck, PMState.LeakCheck);            Transition(PMState.Idle, MSG.DeleteLeakCheck,             FnDeleteLeakCheck, PMState.Idle);            Transition(PMState.LeakCheck, FSM_MSG.TIMER,              FnLeakCheckTimeout, PMState.Idle);            Transition(PMState.LeakCheck, MSG.Abort,                  FnAbortLeakCheck, PMState.Idle);        // Transfer            Transition(PMState.Idle, MSG.PrepareTransfer,             FnStartPrepareTransfer, PMState.PrepareTransfer);            Transition(PMState.PrepareTransfer, FSM_MSG.TIMER,        FnPreTransferTimeout, PMState.Idle);            Transition(PMState.PrepareTransfer, MSG.Abort,            FnAbortTask, PMState.Idle);            Transition(PMState.Idle, MSG.PostTransfer,                FnStartPostTransfer, PMState.PostTransfer);            Transition(PMState.PostTransfer, FSM_MSG.TIMER,           FnPostTransferTimeout, PMState.Idle);            Transition(PMState.PostTransfer, MSG.Abort,               FnAbortTask, PMState.Idle);            //EnterExitTransition<PMState, FSM_MSG>(PMState.TransferHandoff, null, FSM_MSG.NONE, fExitTransfer);            //Transition(PMState.Idle, MSG.TransferHandoff,             FnStartTransferHandoff, PMState.TransferHandoff);            //Transition(PMState.TransferHandoff, FSM_MSG.TIMER,        FnHandoffTime, PMState.Idle);            //Transition(PMState.TransferHandoff, MSG.Abort,            FnAbortTask, PMState.Idle);            // lift pin            Transition(PMState.Idle, MSG.MoveLiftPin,                 FnSetLiftpin, PMState.LiftpinMoving);            Transition(PMState.LiftpinMoving, FSM_MSG.TIMER,          FnLiftpinTimeout, PMState.Idle);            // guide pin            Transition(PMState.Idle, MSG.MoveGuidePin,                FnSetGuidePin, PMState.GuidePinMoving);            Transition(PMState.GuidePinMoving, FSM_MSG.TIMER,         FnGuidePinTimeout, PMState.Idle);        // PreProcess sequence            Transition(PMState.Idle, MSG.RunRecipe,                   FnProcessLoadRecipe, PMState.LoadProcessRecipe);            Transition(PMState.LoadProcessRecipe, MSG.PreProcess,     FnStartPreProcess, PMState.PreProcess);            Transition(PMState.LoadProcessRecipe, MSG.Abort,          null, PMState.Idle);            Transition(PMState.LoadProcessRecipe, MSG.Error,          null, PMState.Idle);            Transition(PMState.PreProcess, FSM_MSG.TIMER,             FnPreProcessTimeout, PMState.PreProcess);            Transition(PMState.PreProcess, MSG.Abort,                 FnAbortPreProcess, PMState.Idle);            Transition(PMState.PreProcess, MSG.RecipeAbort,           FnAbortPreProcess, PMState.Idle);            Transition(PMState.PreProcess, MSG.Error,                 FnAbortPreProcess, PMState.Error);            // Process            Transition(PMState.PreProcess, MSG.Process,               FnStartProcess, PMState.Processing);            Transition(PMState.Processing, FSM_MSG.TIMER,             FnProcessTimeout, PMState.Processing);            Transition(PMState.Processing, MSG.Error,                 FnAbortProcess, PMState.Error);            Transition(PMState.Processing, MSG.RecipeAbort,           FnAbortProcess, PMState.PostProcess);            Transition(PMState.Processing, MSG.RecipePause,           FnPauseProcess, PMState.Processing);            Transition(PMState.Processing, MSG.RecipeResume,          FnResumeRecipe, PMState.Processing);            Transition(PMState.Processing, MSG.RecipeUpdate,          FnUpdateRecipe, PMState.Processing);            Transition(PMState.Processing, MSG.RecipeSkipStep,        FnSkipStep, PMState.Processing);            EnterExitTransition<PMState, FSM_MSG>(PMState.Processing, FnEnterProcess, FSM_MSG.NONE, FnExitProcess);            //PostProcess sequence            Transition(PMState.Processing, MSG.PostProcess,           FnStartPostProcess, PMState.PostProcess);            Transition(PMState.PostProcess, FSM_MSG.TIMER,            FnPostProcessTimeout, PMState.Idle);            Transition(PMState.PostProcess, MSG.Abort,                FnAbortPostProcess, PMState.Idle);            Transition(PMState.PostProcess, MSG.RecipeAbort,          FnAbortPostProcess, PMState.Idle);            EnterExitTransition<PMState, FSM_MSG>(PMState.PostProcess, null, FSM_MSG.NONE, fExitPostProcess);            Running = true;        }        protected override bool Init()        {            DATA.Subscribe($"{Module}.FsmState",            () => ((PMState)fsm.State).ToString());            DATA.Subscribe($"{Module}.FsmPrevState",        () => ((PMState)fsm.PrevState).ToString());            DATA.Subscribe($"{Module}.FsmLastMessage", GetFsmLastMessage);            DATA.Subscribe($"{Module}.PMState",             () => fsm.State);            DATA.Subscribe($"{Module}.IsAutoMode",          () => IsAutoMode);            DATA.Subscribe($"{Module}.IsOnline",            () => _isOnline);            DATA.Subscribe($"{Module}.ProcessStatus",       () => _processStatus);            DATA.Subscribe($"{Module}.PumpTime",            () => PumpTime);            DATA.Subscribe($"{Module}.TCTime",              () => TCTime);            DATA.Subscribe($"{Module}.StepNo",              () => StepNo);            DATA.Subscribe($"{Module}.RecipeStepName",      () => RecipeStepName);            DATA.Subscribe($"{Module}.RecipeName",          () => RecipeName);            DATA.Subscribe($"{Module}.LeakRate",            () => LeakRate);            DATA.Subscribe($"{Module}.RecipeSteps",         () => RecipeSteps);            DATA.Subscribe($"{Module}.RecipeProcessTime",   () => RecipeElapsedTime);            DATA.Subscribe($"{Module}.RecipeStepTimeElapsed", () => (_processRoutine.CurStepElpasedTime / 1000).ToString("F0"));            DATA.Subscribe($"{Module}.RecipeStepTimeSetPoint", () => (_processRoutine.CurStepTotalTime / 1000).ToString("F0"));            OP.Subscribe($"{Module}.{RtOperation.GasFlow}",         (cmd, args) => CheckToPostMessage((int)MSG.GasFlow, args));            OP.Subscribe($"{Module}.{RtOperation.RfPower}",         (cmd, args) => CheckToPostMessage((int)MSG.RfPower, args));            OP.Subscribe($"{Module}.{RtOperation.MoveLiftPin}",     (cmd, args) => CheckToPostMessage((int)MSG.MoveLiftPin, args[0]));            OP.Subscribe($"{Module}.{RtOperation.MoveGuidePin}",    (cmd, args) => CheckToPostMessage((int)MSG.MoveGuidePin, args[0], args[1]));            OP.Subscribe($"{Module}.Home",                          (cmd, args) => CheckToPostMessage((int)MSG.Home));            OP.Subscribe($"{Module}.{RtOperation.Reset}",           (cmd, args) => CheckToPostMessage((int)MSG.Reset));            OP.Subscribe($"{Module}.{RtOperation.Abort}",           (cmd, args) => CheckToPostMessage((int)MSG.Abort));            OP.Subscribe($"{Module}.PrepareTransfer",               (cmd, args) => CheckToPostMessage((int)MSG.PrepareTransfer, args[0]));            OP.Subscribe($"{Module}.TransferHandoff",               (cmd, args) => CheckToPostMessage((int)MSG.TransferHandoff, args[0]));            OP.Subscribe($"{Module}.{RtOperation.Pump}",            (cmd, args) => CheckToPostMessage((int)MSG.Pump));            OP.Subscribe($"{Module}.{RtOperation.StartPump}",       (cmd, args) => CheckToPostMessage((int)MSG.LaunchPump));            OP.Subscribe($"{Module}.{RtOperation.Vent}",            (cmd, args) => CheckToPostMessage((int)MSG.Vent));            OP.Subscribe($"{Module}.{RtOperation.Purge}",           (cmd, args) => CheckToPostMessage((int)MSG.CyclePurge));            OP.Subscribe($"{Module}.{RtOperation.LeakCheck}",       (cmd, args) => CheckToPostMessage((int)MSG.LeakCheck, args));            OP.Subscribe($"{Module}.{RtOperation.DeleteLeakCheck}", (cmd, args) => CheckToPostMessage((int)MSG.DeleteLeakCheck, args));            OP.Subscribe($"{Module}.{RtOperation.LockLid}",         (cmd, args) => CheckToPostMessage((int)MSG.LockLid, true));            OP.Subscribe($"{Module}.{RtOperation.UnlockLid}",       (cmd, args) => CheckToPostMessage((int)MSG.LockLid, false));            OP.Subscribe($"{Module}.{RtOperation.RunRecipe}",       (cmd, args) => CheckToPostMessage((int)MSG.RunRecipe, (string)args[0]));            OP.Subscribe($"{Module}.{RtOperation.SkipCurrentStep}", (cmd, args) => CheckToPostMessage((int)MSG.RecipeSkipStep));            OP.Subscribe($"{Module}.{RtOperation.AbortRecipe}",     (cmd, args) => CheckToPostMessage((int)MSG.RecipeAbort));            OP.Subscribe($"{Module}.{RtOperation.PmAuto}",          (cmd, args) => CheckToPostMessage((int)MSG.AutoMode));            OP.Subscribe($"{Module}.{RtOperation.PmManual}",        (cmd, args) => CheckToPostMessage((int)MSG.ManualMode));            OP.Subscribe($"{Module}.{RtOperation.PmOnline}",        (cmd, args) => CheckToPostMessage((int)MSG.Online));            OP.Subscribe($"{Module}.{RtOperation.PmOffline}",       (cmd, args) => CheckToPostMessage((int)MSG.Offline));            OP.Subscribe($"{Module}.{RtOperation.Heat}",            (cmd, args) => CheckToPostMessage((int)MSG.Heat, args[0]));            return true;        }        // Methods        //         private bool CheckToPostMessage(int msg, params object[] args)        {            if (!fsm.FindTransition(fsm.State, msg))            {                EV.PostWarningLog(Module.ToString(), $"{Module} is in { (PMState)fsm.State} state,can not do {(MSG)msg}");                return false;            }            fsm.PostMsg(msg, args);            return true;        }        private bool FnAbortTask(object[] param)        {            //_task.Abort();            return true;        }        private bool FnSetAuto(object[] param)        {            this._AutoMode = AutoFlag.Auto;            return true;        }        private bool FnSetManual(object[] param)        {            if(fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess)            {                EV.PostWarningLog(Module.ToString(), $"{Module} is in {(PMState) fsm.State},can not do SetAutoMode");                return false;            }            this._AutoMode = AutoFlag.Manual;            return true;        }        private bool FnSetOnline(object[] param)        {            this._isOnline = true;            return true;        }        private bool FnSetOffline(object[] param)        {            this._isOnline = false;            return true;        }        #region Gas&RF        private bool FnStartGasFlow(object[] objs)        {            Result ret = _gasFlowRoutine.Start(objs);            if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                return false;  //do noting            }            return true;        }        private bool FnGasFlowTimeout(object[] objs)        {            Result ret = _gasFlowRoutine.Monitor();            if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                PostMsg(MSG.Abort);                return true;            }            return false;        }        private bool FnAbortGasFlow(object[] objs)        {            _gasFlowRoutine.Abort();            return true;        }        private bool FnStopGasFlow(object[] objs)        {            _gasFlowRoutine.StopFlow2();            return true;        }        private bool FnStartRfPower(object[] objs)        {            _rfStartTime = DateTime.Now;            Result ret = _rfPowerRoutine.Start(objs);            if (ret == Result.DONE)            {                return false;            }            if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                return false;  //do noting            }            return true;        }        private bool FnRfPowerTimeout(object[] objs)        {            Result ret = _rfPowerRoutine.Monitor();            if (ret == Result.DONE)                return true;            else if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                //do nothing                  return true;            }            return false;            ;        }        private bool FnAbortRfPower(object[] objs)        {            _rfPowerRoutine.Abort();            if (_gasFlowRoutine._gasStatus)                _gasFlowRoutine.Abort();            return true;        }        private bool FnHeat(object[] objs)        {            _tcStartTime = DateTime.Now;            return _temperatureControlRoutine.Start(objs) == Result.RUN;        }        private bool FnHeatTimeout(object[] param)        {            Result ret = _temperatureControlRoutine.Monitor();            if (ret == Result.DONE)            {                return true;            }            if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                //do nothing                return true;            }            return false;        }        private bool FnAbortHeating(object[] param)        {            _temperatureControlRoutine.Abort();            return true;        }        #endregion Gas&RF        #region Subroutine        private bool FnStartLeakCheck(object[] param)        {            return _leakCheckRoutine.Start(param) == Result.RUN;        }        private bool FnLeakCheckTimeout(object[] param)        {            Result res = _leakCheckRoutine.Monitor();            return res == Result.DONE || res == Result.FAIL;        }        private bool FnDeleteLeakCheck(object[] param)        {            _leakCheckRoutine.DeleteLeadCheck(param);            return true;        }        private bool FnAbortLeakCheck(object[] param)        {            _leakCheckRoutine.Abort();            return true;        }        private bool FnStartVent(object[] param)        {            Result ret = _ventRoutine.Start();            if (ret == Result.DONE)            {                return false;            }            else if (ret == Result.FAIL)            {                return false;  //do noting            }            return true;        }        private bool FnVentTimeout(object[] param)        {            Result ret = _ventRoutine.Monitor();            if (ret == Result.DONE)            {                return true;            }            if (ret == Result.FAIL)            {                //do nothing                return true;            }            return false;        }        private bool FnVentToPumping(object[] param)        {            _ventRoutine.Abort();            return FnStartPumpDown(param);        }        private bool FnAbortVent(object[] param)        {            _ventRoutine.Abort();            return true;        }        private bool FnLaunchPump(object[] param)        {            _pumpStartTime = DateTime.Now;            return _startPumpRoutine.Start() == Result.RUN;        }        private bool FnLaunchPumpTimeout(object[] param)        {            Result ret = _startPumpRoutine.Monitor();            if (ret == Result.DONE)            {                return true;            }            if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                PostMsg(MSG.Abort);                return false;            }            return false;        }        private bool FnAbortStartPumping(object[] param)        {            _startPumpRoutine.Abort();            return true;        }        private bool FnStartPumpDown(object[] param)        {            _pumpStartTime = DateTime.Now;            return _pumpRoutine.Start() == Result.RUN;        }        private bool FnPumpDownTimeout(object[] param)        {            Result ret = _pumpRoutine.Monitor();            if (ret == Result.DONE)            {                return true;            }            if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                //do nothing                return true;            }            return false;        }        private bool FnPumpingToVent(object[] param)        {            _pumpRoutine.Abort();            return FnStartVent(param);        }        private bool FnAbortPumping(object[] param)        {            _pumpRoutine.Abort();            return true;        }        private bool FnStartPurge(object[] param)        {            return _cyclePurgeRoutine.Start(param) == Result.RUN;        }        private bool FnPurgeTimeout(object[] param)        {            Result ret = _cyclePurgeRoutine.Monitor();            if (ret == Result.DONE)            {                return true;            }            else if (ret == Result.FAIL || ret == Result.TIMEOUT)            {                return true;            }            return false;        }        private bool FnAbortPurge(object[] param)        {            _cyclePurgeRoutine.Abort();            return true;        }        #endregion Subroutine        #region Transfer        private bool FnStartPrepareTransfer(object[] param)        {            if (param.Length > 1)                _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), (float)param[1]);            else                _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), 0);            Result ret = _prepareTrans.Start();            if (ret == Result.FAIL || ret == Result.DONE)                return false;            return ret == Result.RUN;        }        private bool FnPreTransferTimeout(object[] param)        {            Result ret = _prepareTrans.Monitor();            if (ret == Result.FAIL)            {                PostMsg(MSG.Abort);                return false;            }            return ret == Result.DONE;        }        private bool FnStartPostTransfer(object[] param)        {            Result ret = _postTrans.Start();            if (ret == Result.FAIL)            {                PostMsg(MSG.Error);                return false;            }            return ret == Result.RUN;        }        private bool FnPostTransferTimeout(object[] param)        {            Result ret = _postTrans.Monitor();            if (ret == Result.FAIL)            {                PostMsg(MSG.Abort);                return false;            }            return ret == Result.DONE;        }        private bool FnSetLiftpin(object[] param)        {            MovementPosition pos = (MovementPosition)param[0];            _ActivatedActionID = (ushort)param[1];            _chamber.SetLiftPin(pos, out _);            EV.PostInfoLog(Module.ToString(), $"执行 lift pin {pos}");            _goalLiftPin = pos;            return true;        }        private bool FnLiftpinTimeout(object[] param)        {            if (_chamber.LiftPinPosition == _goalLiftPin)            {                EV.PostInfoLog(Module.ToString(), $"lift pin 当前位置 {_chamber.LiftPinPosition}");                Singleton<RouteManager>.Instance.EFEM.PostMsg(                    _goalLiftPin == MovementPosition.Up ? EfemEntity.MSG.PMLiftPinUp : EfemEntity.MSG.PMLiftPinDown, _ActivatedActionID);                _goalLiftPin = MovementPosition.Unknown;                _ActivatedActionID = 0;                return true;            }            return false;        }        private bool FnSetGuidePin(object[] param)        {            WaferSize ws = (WaferSize)param[0];            MovementPosition pos = (MovementPosition)param[1];            if (ws == WaferSize.WS3)            {                _chamber.SetGuidePin3Inch(pos);            }            else if (ws == WaferSize.WS4)            {                _chamber.SetGuidePin4Inch(pos);            }            return true;        }        private bool FnGuidePinTimeout(object[] param)        {            return true;        }                #endregion Transfer        #region Process        private bool FnProcessLoadRecipe(object[] param)        {            _processStatus = "Succeed to load recipe";            _recipeStartTime = DateTime.Now;            Result ret = _preProcessRoutine.LoadRecipe(param);            if (ret == Result.DONE)            {                PostMsg(MSG.PreProcess);            }            else if (ret == Result.FAIL)            {                _processStatus = "Failed to load recipe";                return false;            }            return true;        }        private bool FnStartPreProcess(object[] param)        {            _pumpStartTime = DateTime.Now;            //_processStatus = Resources.PMEntity_fStartPreProcess_PreparingRunningRecipe;            Result ret = _preProcessRoutine.Start(param);            if (ret == Result.DONE)            {                return false;            }            if (ret == Result.FAIL || ret == Result.VERIFYFAIL)            {                //_processStatus = Resources.PMEntity_fStartPreProcess_PreparingRunningRecipeFailed;                PostMsg(MSG.Error);                return false;  //do noting            }            WaferManager.Instance.UpdateWaferProcessStatus(this.Module, 0, EnumWaferProcessStatus.InProcess);            return true;        }        private bool FnPreProcessTimeout(object[] param)        {            //_processStatus = Resources.PMEntity_fPreProcess_RunRecipePumpingDown;            Result ret = _preProcessRoutine.Monitor();            if (ret == Result.DONE)            {                PostMsg(MSG.Process,                    _preProcessRoutine.CurrentRecipeBaseName,                    _preProcessRoutine.CurrentRecipeRunningName,                    0,                    _preProcessRoutine.CurrentLotName,                    _preProcessRoutine.CurrentRecipeContent,                    _preProcessRoutine.CurrentRecipeHead,                    _preProcessRoutine.CurrentRecipeStepList);                return true;            }            if (ret == Result.FAIL)            {                //_processStatus = Resources.PMEntity_fPreProcess_RunRecipePumpingDownFailed;                PostMsg(MSG.Error);                return true;            }            return false; ;        }        private bool FnAbortPreProcess(object[] param)        {            //_processStatus = Resources.PMEntity_fAbortPreProcess_RunRecipePumpingDownAborted;            WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);            _preProcessRoutine.Abort();            return true;        }        private bool FnStartProcess(object[] param)        {            //_processStatus = Resources.PMEntity_fStartProcess_StartRunningRecipe;            Result ret = _processRoutine.Start(param);            if (ret == Result.DONE)            {                return true;            }            else if (ret == Result.FAIL || ret == Result.VERIFYFAIL)            {                //_processStatus = Resources.PMEntity_fStartProcess_RunRecipeFailed;                PostMsg(MSG.Error);                return true;  //do noting            }            return true;        }        private bool FnProcessTimeout(object[] param)        {            //_processStatus = Resources.PMEntity_fProcess_RunningRecipe;            Result ret = _processRoutine.Monitor();            {                if (ret == Result.DONE)                {                    PostMsg(MSG.PostProcess, _processRoutine.CurrentRecipeRunningName, _processRoutine.CurrentRecipeContent);                    return true;                }                else if (ret == Result.FAIL)                {                    //_processStatus = Resources.PMEntity_fStartProcess_RunRecipeFailed;                    PostMsg(MSG.Error);                    return true;                }                return false;            }        }        private bool FnAbortProcess(object[] param)        {            //_processStatus = Resources.PMEntity_fAbortProcess_RunningRecipeAborted;            _processRoutine.AbortRecipe();            WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);            Result ret = _postProcessRoutine.Start(new object[] { _processRoutine.CurrentRecipeRunningName, _processRoutine.CurrentRecipeContent });            if (ret == Result.DONE)            {                return false;            }            else if (ret == Result.FAIL)            {                PostMsg(MSG.Error);                //_processStatus = Resources.PMEntity_fAbortProcess_RunRecipeAborted;                return false;  //do noting            }            return true;        }        private bool FnPauseProcess(object[] param)        {            throw new NotImplementedException();        }        private bool FnResumeRecipe(object[] param)        {            throw new NotImplementedException();        }        private bool FnUpdateRecipe(object[] param)        {            throw new NotImplementedException();        }        private bool FnSkipStep(object[] param)        {            _processRoutine.SkipCurrentRecipeStep();            return true;        }        private bool FnExitProcess(object[] param)        {            _processRoutine.Exit();            return true;        }        private bool FnEnterProcess(object[] param)        {            return true;        }        private bool FnStartPostProcess(object[] param)        {            //_processStatus = Resources.PMEntity_fStartPostProcess_RunRecipePostProcess;            Result ret = _postProcessRoutine.Start(param);            if (ret == Result.DONE)            {                return false;            }            else if (ret == Result.FAIL)            {                PostMsg(MSG.Error);                return false;            }            return true;        }        private bool FnPostProcessTimeout(object[] param)        {            //_processStatus = Resources.PMEntity_fPostProcess_RunRecipeCyclePurge;            Result ret = _postProcessRoutine.Monitor();            if (ret == Result.DONE)            {                WaferManager.Instance.UpdateWaferProcessStatus(this.Module, 0, EnumWaferProcessStatus.Completed);                //_processStatus = Resources.PMEntity_fPostProcess_RecipeCompleted;                return true;            }            else if (ret == Result.FAIL)            {                //_processStatus = Resources.PMEntity_fPostProcess_RunRecipeCyclePurgeError;                PostMsg(MSG.Error);                return true;            }            return false;        }        private bool FnAbortPostProcess(object[] param)        {            //_processStatus = Resources.PMEntity_fAbortPostProcess_RecipeAborted;            WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);            _postProcessRoutine.Abort();            return true;        }        private bool fExitPostProcess(object[] objs)        {            _postProcessRoutine.Exit();            //EV.Notify(EventLotFinished, new SerializableDictionary<string, string>()            //{            //    {DVIDName.LotId,  preProcessRoutine.CurrentLotName},            //    {DVIDName.JobId,  preProcessRoutine.CurrentJobName},            //    {DVIDName.RecipeId, preProcessRoutine.CurrentRecipeBaseName }            //});            return true;        }        #endregion PROCESS        private string GetFsmLastMessage()        {            int msg = fsm.LastMsg;            if (msg >= (int)MSG.Home && msg <= (int)MSG.MaxMsg)                return ((MSG)msg).ToString();            if (msg == (int)FSM_MSG.TIMER)                return "Timer";            return msg.ToString();        }        protected override void Term()        {        }        private bool FnReset(object[] param)        {            if ((PMState)fsm.State == PMState.Error)                return true;            return false;        }        public bool Check(int msg, out string reason, object[] objs)        {            reason = "";            return true;        }        public bool IsProcessed()        {            return IsIdle;        }        public bool IsPrepareTransferReady(ModuleName robot, EnumTransferType type, int slot)        {            if (type == EnumTransferType.Pick)            {                return _chamber.CheckEnableTransfer(type);            }            else if (type == EnumTransferType.Place)            {                return _chamber.CheckEnableTransfer(type);            }            return false;        }        public void Home()        {            CheckToPostMessage((int)MSG.Home);        }        private bool FnExitHome(object[] param)        {            return true;        }        private bool FnEnterHome(object[] param)        {            return true;        }        private bool FnStartHome(object[] objs)        {            Result ret = _home.Start();            if (ret == Result.FAIL || ret == Result.DONE)                return false;            return ret == Result.RUN;        }        private bool FnMonitorHome(object[] objs)        {            Result ret = _home.Monitor();            if (ret == Result.FAIL)            {                PostMsg(MSG.Error);                return false;            }            return ret == Result.DONE;        }        private bool fExitTransfer(object[] objs)        {            return true;        }        private bool FnError(object[] objs)        {            Running = false;            if (IsProcessing)            {                WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);            }            return true;        }        private bool FnIdle(object[] objs)        {            Running = false;            return true;        }        public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot)        {            if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString()))                return (int)MSG.PrepareTransfer;            return (int)FSM_MSG.NONE;        }        public int InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot, float temp)        {            if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString(), temp))                return (int)MSG.PrepareTransfer;            return (int)FSM_MSG.NONE;        }        public int InvokePostTransfer(ModuleName robot, EnumTransferType type, int slot)        {            if (CheckToPostMessage((int)MSG.PostTransfer, type.ToString()))                return (int)MSG.PostTransfer;            return (int)FSM_MSG.NONE;        }        public int InvokeProcess(string recipeName)        {            if (CheckToPostMessage((int)MSG.RunRecipe, recipeName))                return (int)MSG.RunRecipe;            return (int)FSM_MSG.NONE;        }        public int InvokePreHeat(float temperature)        {            if (CheckToPostMessage((int)MSG.Heat, (double)temperature))                return (int)MSG.Heat;            return (int)FSM_MSG.NONE;        }        public void InvokeReset()        {            PostMsg((int)MSG.Reset);        }        public void SetAuto()        {            this._AutoMode = AutoFlag.Auto;        }    }}
 |