| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608 | using System;using System.Collections.Generic;using System.Threading;using System.Diagnostics;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 Aitex.RT.Device.Custom;using Aitex.Sorter.Common;using MECF.Framework.Common.DataCenter;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.Schedulers;using MECF.Framework.Common.SubstrateTrackings;using VirgoCommon;using VirgoRT.Devices;using VirgoRT.Modules;using VirgoRT.Modules.PMs;namespace VirgoRT.Module{    public class RecipeRunningInfo    {        public Guid InnerId { get; set; }        public RecipeHead Head { get; set; }        public List<RecipeStep> RecipeStepList { get; set; }        public string RecipeName { get; set; }        public DateTime BeginTime { get; set; }        public DateTime EndTime { get; set; }        public int StepNumber { get; set; }        public string StepName { get; set; }        public double StepTime { get; set; }        public double StepElapseTime { get; set; }        public double TotalTime { get; set; }        public double TotalElapseTime { get; set; }    }    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,            WaitLiftpin,            MoveGuidePin,            MFCVerification,            AllMFCVerification,            Clean,            CleanReady,            Process,            RunRecipe,            PostProcess,            RecipeSkipStep,            RecipeUpdate,            RecipeResume,            RecipePause,            RecipeAbort,            PreProcess,            AutoMode,            ManualMode,            LockLid,            Online,            Offline,            GasFlow,            StopGasFlow,            RfPower,            MaxMsg        }        // ----------------------------Fields--------------------------        //         private int _bigWafer = 0;        private int _midWafer = 0;        private int _smallWafer = 0;        private bool _enableBias;        private int _liftpinDelayTime = 0;        private StatsDataItem _statProcessedWafer;        private StatsDataItemRFAndPump _statRfOnTime;        private StatsDataItemRFAndPump _statBiasRfOnTime;        private StatsDataItemRFAndPump _statPumpOnTime;        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 CleanRoutine               _cleanRoutine;        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 readonly PMMfcVerificationRoutine   _mfcVerification;        private readonly PMAllMfcVerificationRoutine _allMfcVerification;        private AutoFlag                            _AutoMode;        private bool                                _isOnline;        private bool                                _isAlarm;        private DateTime                            _pumpStartTime;        private TimeSpan                            _pumpElapsedTime;        private DateTime                            _rfStartTime;        private DateTime                            _tcStartTime;        private TimeSpan                            _rfElapsedTime;        private TimeSpan                            _tcElapsedTime;        private MovementPosition                    _goalLiftPin;        private ushort                              _ActivatedActionID;        private Stopwatch                           _LifpinSleepTimer;        private bool                                _EnableResetChamberError;        // --------------------------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 RecipeRunningInfo RecipeRunningInfo        {            get            {                return _recipeRunningInfo;            }        }        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 DateTime _leakCheckStartTime;        private TimeSpan _leakCheckElapsedTime;        private string LeakCheckElapseTime        {            get            {                if ((fsm.State == (int)PMState.LeakCheck))                    _leakCheckElapsedTime = DateTime.Now - _leakCheckStartTime;                return string.Format("{0}:{1}:{2}", ((int)_leakCheckElapsedTime.TotalHours).ToString("00"),                    _leakCheckElapsedTime.Minutes.ToString("00"), _leakCheckElapsedTime.Seconds.ToString("00"));            }        }        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 double RecipeTotalElapsedSeconds        {            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 _recipeElapsedTime.TotalSeconds;            }        }        public bool IsOnline        {            get { return _isOnline; }        }        private RecipeRunningInfo _recipeRunningInfo = new RecipeRunningInfo();        // --------------------------Constructor-----------------------        //         public PMEntity(ModuleName module)        {            this.Module = module;            //_chamber = new JetPM(ModuleHelper.Converter(Name));            _smallWafer = SC.GetValue<int>($"System.SmallWafer");            _midWafer = SC.GetValue<int>($"System.MidWafer");            _bigWafer = SC.GetValue<int>($"System.BigWafer");            _enableBias = SC.GetValue<bool>($"{Module}.BiasRf.EnableBiasRF");            _EnableResetChamberError = SC.GetValue<bool>($"{Module}.EnableResetError");            _chamber = DEVICE.GetDevice<JetPM>(Module.ToString());            _isAlarm = false;            _LifpinSleepTimer = new Stopwatch();            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);            _cleanRoutine       = new CleanRoutine(_chamber);            _preProcessRoutine  = new PreProcessRoutine(_chamber, _pumpRoutine);            _processRoutine     = new ProcessRoutine(_chamber, this);            _postProcessRoutine = new PostProcessRoutine(_chamber, _ventRoutine);            _home               = new PMHomeRoutine(_chamber);            _mfcVerification    = new PMMfcVerificationRoutine(_chamber, _pumpRoutine);            _allMfcVerification = new PMAllMfcVerificationRoutine(_chamber, _pumpRoutine);                        //Idle            EnterExitTransition((int)PMState.Idle,                  FnIdle,                         (int)FSM_MSG.NONE, null);            EnterExitTransition<PMState, FSM_MSG>(PMState.Error,    fEnterError,                    FSM_MSG.NONE, null);            //Error            Transition(PMState.Init, MSG.Error,                     FnError,                        PMState.Error);            Transition(PMState.Error, MSG.Reset,                    FnReset,                        PMState.Idle);            AnyStateTransition(FSM_MSG.WARNING,                     fWarning,                       FSM_STATE.SAME);            AnyStateTransition((int)FSM_MSG.ALARM,                  fAlarm,                         (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.Error);            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);            //MFC verification            Transition(PMState.Idle,        MSG.MFCVerification,    FnStartMFCVerification,         PMState.MFCVerification);            Transition(PMState.MFCVerification, FSM_MSG.TIMER,      FnMFCVerificationTimeout,       PMState.Idle);            Transition(PMState.MFCVerification, MSG.Abort,          FnAbortMFCVerification,         PMState.Idle);            //MFC verification            Transition(PMState.Idle,        MSG.AllMFCVerification, FnStartAllMFCVerification,      PMState.AllMFCVerification);            Transition(PMState.AllMFCVerification, FSM_MSG.TIMER,   FnAllMFCVerificationTimeout,    PMState.Idle);            Transition(PMState.AllMFCVerification, MSG.Abort,       FnAbortAllMFCVerification,      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);            // lift pin            Transition(PMState.Idle,            MSG.MoveLiftPin,    FnSetLiftpin,                   PMState.LiftpinMoving);            Transition(PMState.Idle,            MSG.WaitLiftpin,    null,                           PMState.LiftpinWaiting);            Transition(PMState.LiftpinWaiting,  FSM_MSG.TIMER,      FnWaitLiftpinTimeout,           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);            // PreClean sequence            Transition(PMState.Idle,        MSG.Clean,              FnPreClean,                     PMState.PreClean);            Transition(PMState.PreClean,    FSM_MSG.TIMER,          FnPreCleanTimeout,              PMState.LoadProcessRecipe);            // 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}.IsAlarm",            () => _isAlarm);            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}.LeakCheckElapseTime", () => LeakCheckElapseTime);            DATA.Subscribe($"{Module}.SmallWafer",          () => _smallWafer);            DATA.Subscribe($"{Module}.BigWafer",            () => _bigWafer);            DATA.Subscribe($"{Module}.MidWafer",            () => _midWafer);            DATA.Subscribe($"{Module}.RecipeSteps",         () => RecipeSteps);            DATA.Subscribe($"{Module}.RecipeProcessTime",   () => RecipeElapsedTime);            DATA.Subscribe($"{Module}.RecipeTotalElapsedSeconds", () => RecipeTotalElapsedSeconds);            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], 0, true));            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], "", true));            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]));            OP.Subscribe($"{Module}.{RtOperation.MFCVerification}", (cmd, args) => CheckToPostMessage((int)MSG.MFCVerification, args));            OP.Subscribe($"{Module}.{RtOperation.AllMFCVerification}", (cmd, args) => CheckToPostMessage((int)MSG.AllMFCVerification, args));            StatsDataManager.Instance.Subscribe($"{Module}.ProcessedWaferCount", "Processed Wafer Count", 0);            StatsDataManager.Instance.Subscribe($"{Module}.RfOnTime", "Rf On Time");            if (_enableBias)                StatsDataManager.Instance.Subscribe($"{Module}.BiasRfOnTime", "Bias  Rf On Time");            StatsDataManager.Instance.Subscribe($"{Module}.PumpOnTime", "Pump On Time");            _statProcessedWafer = StatsDataManager.Instance.GetItem($"{Module}.ProcessedWaferCount");            _statRfOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.RfOnTime");            if (_enableBias)                _statBiasRfOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.BiasRfOnTime");            _statPumpOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.PumpOnTime");            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;            if (IsOnline)            {                EV.PostWarningLog(Module.ToString(), $"{Module} is online,change to offline due to the chamber change to manual mode");                this._isOnline = false;            }            return true;        }        private bool FnSetOnline(object[] param)        {            if (!IsAutoMode)            {                EV.PostWarningLog(Module.ToString(), $"{Module} in manual mode,can not set online.");                return false;            }            if (!_chamber.CheckSlitDoorClose())            {                EV.PostWarningLog(Module.ToString(), $"{Module} slit door is open,can not set online.");                return false;            }            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)        {            _leakCheckStartTime = DateTime.Now;            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 FnStartMFCVerification(object[] param)        {            _mfcVerification.Init((string)param[0], (float)param[1], (int)param[2]);            return _mfcVerification.Start(param) == Result.RUN;        }        private bool FnMFCVerificationTimeout(object[] param)        {            Result res = _mfcVerification.Monitor();            return res == Result.DONE || res == Result.FAIL;        }        private bool FnAbortMFCVerification(object[] param)        {            _mfcVerification.Abort();            return true;        }        private bool FnStartAllMFCVerification(object[] param)        {            _allMfcVerification.Init((string[])param[0], (bool[])param[1]);            return _allMfcVerification.Start(param) == Result.RUN;        }        private bool FnAllMFCVerificationTimeout(object[] param)        {            Result res = _allMfcVerification.Monitor();            return res == Result.DONE || res == Result.FAIL;        }        private bool FnAbortAllMFCVerification(object[] param)        {            _allMfcVerification.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 > 2)                _prepareTrans.Init((EnumTransferType)Enum.Parse(typeof(EnumTransferType), (string)param[0]), (float)param[1], (WaferSize)param[2]);            else 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(param);            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];            bool isPick = (bool)param[2];            _goalLiftPin = pos;            _liftpinDelayTime = SC.GetValue<int>(isPick ?  $"{Module}.PinDownDelayTimePick" : $"{Module}.PinDownDelayTimePlace") * 1000;            if (_liftpinDelayTime > 0)            {                _LifpinSleepTimer.Restart();                CheckToPostMessage((int)MSG.WaitLiftpin);                return false;            }            _chamber.SetLiftPin(pos, out _);            EV.PostInfoLog(Module.ToString(), $"Set lift pin {pos}");            return true;        }        private bool FnWaitLiftpinTimeout(object[] param)        {            if (_LifpinSleepTimer.ElapsedMilliseconds > _liftpinDelayTime)            {                _chamber.SetLiftPin(_goalLiftPin, out _);                EV.PostInfoLog(Module.ToString(), $"Set lift pin {_goalLiftPin}");                _LifpinSleepTimer.Reset();                return true;            }            return false;        }        private bool FnLiftpinTimeout(object[] param)        {            if (_chamber.LiftPinPosition == _goalLiftPin)            {                EV.PostInfoLog(Module.ToString(), $"lift pin current value {_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];            _chamber.SetGuidePin(ws, pos);             return true;        }        private bool FnGuidePinTimeout(object[] param)        {            return true;        }        private bool FnPreClean(object[] param)        {            _cleanRoutine.param = param;            _chamber.SetSlitDoor(false, out _);            return true;        }        private bool FnPreCleanTimeout(object[] param)        {            if (_chamber.IsSlitDoorClosed)            {                if (!FnProcessLoadRecipe(_cleanRoutine.param))                {                    EV.PostAlarmLog(_chamber.Module.ToString(), "Clean recipe read failed");                    PostMsg(FSM_MSG.ALARM);                    return false;                }                return true;            }            return false;        }        #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);            _processRoutine.Abort();            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)        {            return true;        }        private bool FnResumeRecipe(object[] param)        {            return true;        }        private bool FnUpdateRecipe(object[] param)        {            return true;          }        private bool FnSkipStep(object[] param)        {            _processRoutine.SkipCurrentRecipeStep();            return true;        }        private bool FnExitProcess(object[] param)        {            //_statProcessedWafer            StatsDataManager.Instance.Increase(_statProcessedWafer.Name);            _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 (!_EnableResetChamberError)                return false;            _isAlarm = false;            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, Hand blade)        {            if (type == EnumTransferType.Pick)            {                return _chamber.CheckEnableTransfer(type, WaferManager.Instance.GetWafer(_chamber.Module, 0).Size);            }            else if (type == EnumTransferType.Place)            {                return _chamber.CheckEnableTransfer(type, WaferManager.Instance.GetWafer(robot, (int)blade).Size);            }            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;            }            if (ret == Result.DONE && _isAlarm)                _isAlarm = false;            return ret == Result.DONE;        }        private bool fExitTransfer(object[] objs)        {            return true;        }        private bool fEnterError(object[] objs)        {            //if (IsProcessMode)            //{            //    EV.Notify(EventLotFinished, new SerializableDictionary<string, string>()            //    {            //        {DVIDName.LotId,  preProcessRoutine.CurrentLotName},            //        {DVIDName.JobId,  preProcessRoutine.CurrentJobName},            //        {DVIDName.RecipeId, preProcessRoutine.CurrentRecipeBaseName }            //    });            //}            _chamber.GeneratorPowerOn(false);            _chamber.GeneratorBiasPowerOn(false);            _chamber.StopAllGases();            return true;        }        private bool FnError(object[] objs)        {            Running = false;            if (((PMState)fsm.State == PMState.Processing) || ((PMState)fsm.State == PMState.PreProcess)                 || ((PMState)fsm.State == PMState.Homing) || ((PMState)fsm.State == PMState.LoadProcessRecipe))                return false;            if (IsProcessing)            {                WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);            }            return true;        }        private bool fWarning(object[] objs)        {            //IsWarning = false;            return true;        }        private bool fAlarm(object[] objs)        {            _isAlarm = true;            if (fsm.State == (int)PMState.Init)                return false;            if (fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.PostProcess)            {                PostMsg(MSG.Error);                return false;            }            //IsAlarm = true;            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 InvokePrepareTransfer(ModuleName robot, EnumTransferType type, int slot, float temp, WaferSize size)        {            if (CheckToPostMessage((int)MSG.PrepareTransfer, type.ToString(), temp, size))                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 InvokeClean(string recipeName, string waferID, bool withWafer)        {            if (CheckToPostMessage((int)MSG.Clean, recipeName, waferID, withWafer))            {                return (int)MSG.Clean;            }            return (int)FSM_MSG.NONE;        }        public int InvokeProcess(string recipeName, string waferID, bool withWafer)        {            if (CheckToPostMessage((int)MSG.RunRecipe, recipeName, waferID, withWafer))                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;        }        #region EndPoint        public bool CheckEndPoint()        {            EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");            if (epd == null)                return false;            return epd.IsEnd;        }        public void StartEndPoint(string config, int index)        {            EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");            if (epd == null)                return;            epd.StepStart(config, index);        }        public void StopEndPoint()        {            EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");            if (epd == null)                return;            epd.StepStop();        }        public void EndPointRecipeStop()        {            EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");            if (epd == null)                return;            epd.RecipeStop();        }        public void EndPointRecipeStart(string recipeName)        {            EPDDevice epd = DEVICE.GetDevice<EPDDevice>($"{Module}.EPD");            if (epd == null)                return;            epd.RecipeStart(recipeName);        }        #endregion    }}
 |