| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056 | using Aitex.Core.RT.Log;using Aitex.Core.Util;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.SubstrateTrackings;using MECF.Framework.Common.WaferHolder;using CyberX8_Core;using CyberX8_RT.Modules.Loader;using CyberX8_RT.Modules.PUF;using CyberX8_RT.Modules;using CyberX8_RT.Schedulers;using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Documents;using Aitex.Core.Common;using MECF.Framework.Common.CommonData;using MECF.Framework.Common.Jobs;using Aitex.Core.RT.Fsm;using MECF.Framework.Common.RecipeCenter;using MECF.Framework.Common.ToolLayout;using Aitex.Core.RT.Routine;using CyberX8_RT.Schedulers.Transporter;namespace CyberX8_RT.Dispatch{    public enum WaferHolderTaskState    {        Created,        Processing,        End,        Error,        Canceled    }    /// <summary>    /// WaferHolder    /// </summary>    /// <param name="info"></param>    /// <param name="schedulerSequence"></param>    public delegate void WaferHolderSchedulerComplete(WaferHolderInfo info, SchedulerSequence schedulerSequence);    /// <summary>    /// WaferHolderTask完成    /// </summary>    /// <param name="id"></param>    public delegate void WaferHolderTaskComplete(string id);    public class WaferHolderTask    {        #region 内部变量        /// <summary>        /// 调度步骤        /// </summary>        private List<SchedulerSequence> _schedulerSequences;        /// <summary>        /// 当前步骤索引        /// </summary>        private int _currentSequenceIndex = 0;        /// <summary>        /// PUF实例        /// </summary>        private PUFEntity _puf1Entity;        /// <summary>        /// PUF实例        /// </summary>        private PUFEntity _puf2Entity;        /// <summary>        /// 是否开始执行        /// </summary>        private bool _isStart = false;        /// <summary>        /// 暂停时的索引        /// </summary>        private int _pausedIndex = -1;        /// <summary>        /// 错误上升触发        /// </summary>        private R_TRIG _sequenceErrorTigger = new R_TRIG();        /// <summary>        /// Sequence类型        /// </summary>        private string _sequenceType = "";        /// <summary>        /// FA回复        /// </summary>        private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback();        #endregion        #region 属性        /// <summary>        /// ID         /// </summary>        public string ID { get;private set; }           /// <summary>        /// WaferHolder属性        /// </summary>        public WaferHolderInfo WaferHolderInfo { get;private set; }        /// <summary>        /// Process Job信息        /// </summary>        public ProcessJobInfo ProcessJobInfo { get;private set; }        /// <summary>        /// 状态        /// </summary>        public WaferHolderTaskState State { get; private set; }        /// <summary>        /// 步骤完成事件        /// </summary>        public event WaferHolderSchedulerComplete OnSchedulerComplete;        /// <summary>        /// 任务完成事件        /// </summary>        public event WaferHolderTaskComplete OnTaskComplete;        /// <summary>        /// 调度集合        /// </summary>        public List<SchedulerSequence> SchedulerSequences { get { return _schedulerSequences; } }        #endregion        /// <summary>        /// 构造函数        /// </summary>        /// <param name="waferHolderInfo"></param>        /// <param name="schedulerSequences"></param>        public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo)        {            ID=Guid.NewGuid().ToString();            WaferHolderInfo=waferHolderInfo;            WaferHolderInfo.Status = WaferHolderStatus.Normal;            if (processJobInfo != null)            {                WaferHolderInfo.SequenceId = processJobInfo.SequenceRecipe.Ppid;                WaferHolderInfo.SequenceRecipe = processJobInfo.SequenceRecipe;                _sequenceType = processJobInfo.SequenceRecipe.SequenceType;                WaferHolderInfo.CurrentControlJobId = processJobInfo.ControlJobName;                WaferHolderInfo.LotId = processJobInfo.LotName;            }            else            {                AnalyseProductionProcessJobInfo();            }            ProcessJobInfo=processJobInfo;            State = WaferHolderTaskState.Created;            _puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());            _puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());        }        /// <summary>        /// 初始化调度步骤        /// </summary>        /// <param name="schedulers"></param>        public void InitialSchedulers(List<SchedulerSequence> schedulers)        {            _schedulerSequences = schedulers;        }        /// <summary>        /// 分析生产片的ProcessJob信息        /// </summary>        private void AnalyseProductionProcessJobInfo()        {            if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId))            {                WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);                if (waferAInfo != null && waferAInfo.WaferType == WaferType.Production)                {                    ProcessJobInfo = waferAInfo.ProcessJob;                    _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;                    WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;                    WaferHolderInfo.LotId = ProcessJobInfo.LotName;                    WaferHolderInfo.SequenceRecipe = ProcessJobInfo.SequenceRecipe;                    return;                }            }            if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId))            {                WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);                if (waferBInfo != null && waferBInfo.WaferType == WaferType.Production)                {                    ProcessJobInfo = waferBInfo.ProcessJob;                    _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;                    WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;                    WaferHolderInfo.LotId = ProcessJobInfo.LotName;                    WaferHolderInfo.SequenceRecipe = ProcessJobInfo.SequenceRecipe;                }            }        }        /// <summary>        /// 执行        /// </summary>        public void Run()        {            if(_currentSequenceIndex>=_schedulerSequences.Count)            {                State = WaferHolderTaskState.End;                if(OnTaskComplete!=null)                {                    OnTaskComplete(ID);                }                FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);                LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");                return;            }            if (!_isStart)            {                bool preCondition = CheckStartCondition();                if (!preCondition)                {                    return;                }                LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} prepare Start {_currentSequenceIndex + 1} sequence");                _isStart = true;                if (WaferHolderInfo.SchedulerModules == null)                {                    WaferHolderInfo.SchedulerModules = new List<string>();                }                WaferHolderInfo.SchedulerModules.Clear();            }            SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];            //暂停中            if (sequence.State == RState.Init && _currentSequenceIndex >= _pausedIndex && _pausedIndex != -1)            {                return;            }            if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End)            {                State=WaferHolderTaskState.End;                if (OnTaskComplete != null)                {                    OnTaskComplete(ID);                }                FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);                LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");                return;            }            if(_currentSequenceIndex<_schedulerSequences.Count)            {                if(sequence.State==RState.Init)                {                    if(sequence.SchedulerModule==null)                    {                        return;                    }                    if(!BufferWaferHolderJudgeResource(sequence))                    {                        return;                    }                    string reason = "";                    bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex, sequence.Parameters,WaferHolderInfo.Id,ref reason);                    if (sequeceCondition)                    {                        bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters, sequence.SynchronousModuleMessages);                        if (result)                        {                            if (State == WaferHolderTaskState.Created)                            {                                State = WaferHolderTaskState.Processing;                                FaModuleNotifier.Instance.NotifyWaferShuttleJobStart(WaferHolderInfo);                            }                            sequence.State = RState.Running;                            sequence.StartTime = DateTime.Now;                            LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}");                        }                        else                        {                                                       if (sequence.ModuleName == ModuleName.Transporter1&&sequence.NextModuleType==ModuleType.Metal)                            {                                if (!CheckAfterMetalAvaible())                                {                                    LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} has no avaible metal");                                    TransporterAction action = sequence.Parameters as TransporterAction;                                    if (action.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)                                    {                                        WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;                                        waferHolderMoveItem.DestModuleType = ModuleType.Dryer;                                        waferHolderMoveItem.DestModule = ModuleName.Unknown;                                        LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} next sequence changed to dryer");                                    }                                }                            }                        }                    }                    else                    {                        _sequenceErrorTigger.CLK = !sequeceCondition;                        if (_sequenceErrorTigger.Q)                        {                            LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}");                        }                    }                }                else if(sequence.State==RState.Running)                {                    sequence.SchedulerModule.MonitorProcess(sequence,false);                    _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError;                    if (sequence.SchedulerModule.IsError)                    {                        //用于LoadTransporter取的WaferHolder Id不一致,则取消当前WaferHolderTask                        if (sequence.ModuleName == ModuleName.Transporter2)                        {                            LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,task canceled");                            State = WaferHolderTaskState.Canceled;                            return;                        }                        if (_sequenceErrorTigger.Q)                        {                            AnalyseSchedulerErrorState(sequence);                        }                    }                    else if(sequence.SchedulerModule.IsIdle)                    {                        sequence.EndTime = DateTime.Now;                        sequence.State = RState.End;                        sequence.ProcessMilliSeconds=sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;                        if(sequence.IsProcessSequece)                        {                            UpdateWaferHolderProcessingStatus();                        }                        if(sequence.IsLastProcessSequence)                        {                            UpdateWaferHolderProcessComplete();                        }                        if (OnSchedulerComplete != null)                        {                            OnSchedulerComplete(WaferHolderInfo, sequence);                        }                        UpdateLoaderToBufferWaferHolderToloaderStatus(sequence);                        LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");                        _currentSequenceIndex++;                         AutoChangeLoaderTransporterScheduler();                        //检验rinse后面是否存在可用的Metal                        if (sequence.ModuleType == ModuleType.Rinse)                        {                            AnalyseRinseAfterMetalAvaible(sequence);                        }                        else if (sequence.ModuleType == ModuleType.Prewet)                        {                            AnalysePrewetAfterMetalAvaible(sequence);                        }                    }                }                else if (sequence.State == RState.End)                {                    LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence is End");                    _currentSequenceIndex++;                }            }        }        /// <summary>        /// 更新任务结束        /// </summary>        public void UpdateDryerLastSchedulerComplete()        {            SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];            sequence.EndTime = DateTime.Now;            sequence.State = RState.End;            sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;            LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex+1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");            State = WaferHolderTaskState.End;            if (OnTaskComplete != null)            {                OnTaskComplete(ID);            }            LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");        }        /// <summary>        /// 更新从Loader到Buffer的WaferHolder更新为不可以拉回至Loader        /// </summary>        /// <param name="sequence"></param>        private void UpdateLoaderToBufferWaferHolderToloaderStatus(SchedulerSequence sequence)        {            string currentLocation = WaferHolderInfo.CurrentLocation;            if(!Enum.TryParse(currentLocation,out ModuleName locationName))            {                return;            }            if (!ModuleHelper.IsBuffer(locationName))            {                return;            }            if (sequence.ModuleName == ModuleName.Transporter2)            {                TransporterAction transporterAction = sequence.Parameters as TransporterAction;                if (transporterAction.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)                {                    WaferHolderMoveItem waferHolderMoveItem = transporterAction.Parameter as WaferHolderMoveItem;                    if (waferHolderMoveItem.SourceModule == ModuleName.Loader1 && waferHolderMoveItem.DestModuleType == ModuleType.Buffer)                    {                        WaferHolderInfo.IsToLoader = false;                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to false;");                    }                    else if (waferHolderMoveItem.DestModuleType == ModuleType.Buffer && waferHolderMoveItem.SourceModuleType != ModuleType.Loader)                    {                        WaferHolderInfo.IsToLoader = true;                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true;");                    }                }            }        }        /// <summary>        /// 分析错误状态下的调度        /// </summary>        private void AnalyseSchedulerErrorState(SchedulerSequence sequence)        {            if (sequence.ModuleType == ModuleType.Prewet)            {                AnalyseSchedulerPrewetErrorState(sequence);            }            else if (sequence.ModuleType == ModuleType.Dryer)            {                AnalyseSchedulerDryerErrorState(sequence);            }            else if (sequence.ModuleType == ModuleType.Rinse)            {                AnalyseSchedulerRinseErrorState(sequence);            }            else if (sequence.ModuleType == ModuleType.Metal)            {                AnalyseSchedulerMetalErrorState(sequence);            }        }        /// <summary>        /// 判定Buffer中WaferHolder的后面工序是否存在可用资源,不存在的话,则Task直接结束        /// </summary>        /// <param name="sequence"></param>        private bool BufferWaferHolderJudgeResource(SchedulerSequence sequence)        {            string currentLocation = WaferHolderInfo.CurrentLocation;            if (Enum.TryParse(currentLocation, out ModuleName moduleName))            {                //当前WaferHolder处于Buffer中,当前步骤不是第一步,当前调度模块为transporter2                if (ModuleHelper.IsBuffer(moduleName)&&_currentSequenceIndex!=0&&sequence.ModuleName==ModuleName.Transporter2)                {                    if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(WaferHolderInfo.SequenceRecipe, false))                    {                        for (int i = _currentSequenceIndex; i < _schedulerSequences.Count; i++)                        {                            SchedulerSequence item = _schedulerSequences[i];                            item.State = RState.End;                        }                        _currentSequenceIndex = _schedulerSequences.Count - 1;                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} exist no avaible cell");                        WaferHolderInfo.IsToLoader = true;                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true");                        RemoveWaferHolderSRDScheduler();                        UpdateWaferHolderMisProcessedStatus();                        return false;                    }                }            }            return true;        }        /// <summary>        /// 检验Prewet后面的Metal是否存在可用        /// </summary>        private void AnalysePrewetAfterMetalAvaible(SchedulerSequence schedulerSequence)        {            //获取可用的Metal以及Rinse                        if (!CheckAfterMetalAvaible())            {                LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after prewet");                SkipAfterMetal(schedulerSequence,true);                RemoveWaferHolderSRDScheduler();                UpdateWaferHolderMisProcessedStatus();                //SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex];                //if (nextSchedulerSequence.ModuleName != ModuleName.Transporter1)                //{                //    return;                //}                //WaferHolderMoveItem waferHolderMoveItem = nextSchedulerSequence.Parameters as WaferHolderMoveItem;                //waferHolderMoveItem.DestModuleType = ModuleType.Dryer;                //waferHolderMoveItem.DestModule = ModuleName.Unknown;            }        }        /// <summary>        /// 检验Rinse后面的Metal是否存在可用        /// </summary>        /// <returns></returns>        private void AnalyseRinseAfterMetalAvaible(SchedulerSequence schedulerSequence)        {                        //获取可用的Metal以及Rinse                        if(!CheckAfterMetalAvaible())            {                LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after rinse");                SkipAfterMetal(schedulerSequence,true);                RemoveWaferHolderSRDScheduler();                UpdateWaferHolderMisProcessedStatus();            }        }        /// <summary>        /// 检验后续Metal可用性        /// </summary>        /// <returns></returns>        private bool CheckAfterMetalAvaible()        {            for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)            {                SchedulerSequence sequence = _schedulerSequences[i];                if (sequence.ModuleType != ModuleType.Metal)                {                    continue ;                }                if (sequence.Recipe == null || !(sequence.Recipe is DepRecipe))                {                    continue;                }                DepRecipe depRecipe = (DepRecipe)sequence.Recipe;                bool result= SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, sequence.SequenceType,sequence.WaferSize);                if (!result)                {                    return false;                }            }            return true;        }        #region Analyse ErrorState Scheduler        /// <summary>        /// Prewet出错重新调度        /// </summary>        /// <param name="sequence"></param>        private void AnalyseSchedulerPrewetErrorState(SchedulerSequence sequence)        {            SkipAfterSchedulerToDry(ModuleName.Transporter2);            sequence.State = RState.End;            sequence.EndTime = DateTime.Now;            sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;            RemoveWaferHolderSRDScheduler();            UpdateWaferHolderMisProcessedStatus();            LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Prewet meet error,scheduler changed to transporter2");        }        /// <summary>        /// 路过后面调度直接至Dryer        /// </summary>        private void SkipAfterSchedulerToDry(ModuleName transporterName)        {            for (int i = _currentSequenceIndex=1; i < _schedulerSequences.Count; i++)            {                SchedulerSequence item = _schedulerSequences[i];                if (item.ModuleName != ModuleName.Transporter1)                {                    item.State = RState.End;                    item.ProcessMilliSeconds = 0;                }                else                {                    if (item.Parameters is TransporterAction)                    {                        TransporterAction action= (TransporterAction)item.Parameters;                        if (action.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)                        {                            WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;                            if (waferHolderMoveItem.DestModuleType == ModuleType.Dryer)                            {                                _currentSequenceIndex = i;                                item.SchedulerModule = SchedulerManager.Instance.GetScheduler(transporterName);                                waferHolderMoveItem.SourceModule = ModuleName.Prewet1;                                waferHolderMoveItem.SourceModuleType = ModuleType.Prewet;                                break;                            }                            else                            {                                item.State = RState.End;                                item.ProcessMilliSeconds = 0;                            }                        }                    }                }            }        }        /// <summary>        /// Dryer出错重新调度,上一步调度修改为transporter2,同时tranporter2搬运源目标为当前Module,目标类型也是Dryer        /// </summary>        /// <param name="sequence"></param>        private void AnalyseSchedulerDryerErrorState(SchedulerSequence sequence)        {            if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType,ModuleType.Dryer)!=ModuleName.Unknown)            {                sequence.State = RState.Init;                SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();                preSchedulerSequence.State = RState.Init;                preSchedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(ModuleName.Transporter2);                TransporterAction action = preSchedulerSequence.Parameters as TransporterAction;                if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)                {                    return;                }                WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;                waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;                waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;                waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;                waferHolderMoveItem.DestModule = ModuleName.Unknown;                sequence.SchedulerModule = null;                _currentSequenceIndex--;                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler changed to transporter2");            }            else            {                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler has no avaible dryer");            }        }        /// <summary>        /// Rinse出错重新调度,回退至上一步调度        /// </summary>        /// <param name="sequence"></param>        private void AnalyseSchedulerRinseErrorState(SchedulerSequence sequence)        {            ModuleName metalName = SchedulerSequenceManager.Instance.GetPreMetalModuleName(_currentSequenceIndex, _schedulerSequences);            if (metalName == ModuleName.Unknown)            {                return;            }            if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType, ModuleType.Rinse,metalName) != ModuleName.Unknown)            {                sequence.State = RState.Init;                SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();                preSchedulerSequence.State = RState.Init;                TransporterAction action = preSchedulerSequence.Parameters as TransporterAction;                if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)                {                    return;                }                WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;                waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;                waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;                waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;                waferHolderMoveItem.DestModule = ModuleName.Unknown;                sequence.SchedulerModule = null;                _currentSequenceIndex--;                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,scheduler changed to transporter1");            }            else            {                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,rescheduler has no avaible rinse");            }        }        /// <summary>        /// Metal出错重新调度,回退至上一步调度        /// </summary>        /// <param name="sequence"></param>        private void AnalyseSchedulerMetalErrorState(SchedulerSequence sequence)        {            //当前步骤结束,WaferHolder状态            UpdateWaferHolderErrorStatus();            sequence.EndTime = DateTime.Now;            sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;            sequence.State = RState.End;            LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Metal meet error,rescheduler changed to next module");            //跳过后面的metal            SkipAfterMetal(sequence,false);            //移除SRD调度            RemoveWaferHolderSRDScheduler();            _currentSequenceIndex++;        }        /// <summary>        /// 跳过后面的Metal        /// </summary>        private void SkipAfterMetal(SchedulerSequence schedulerSequence,bool isSetLastSequenceSourceModule)        {            int startIndex = -1;            int endIndex = -1;            //从下一个Metal直到碰到Dryer            for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)            {                SchedulerSequence item = _schedulerSequences[i];                if (item.ModuleType == ModuleType.Metal && startIndex == -1)                {                    startIndex = i;                }                if (item.ModuleType == ModuleType.Dryer)                {                    endIndex = i - 1;//Dryer前一步骤为Transporter,保留Dryer前面的transporter                    break;                }            }            //将后面的Metal的步骤直接跳过,包含gh g 后面的transporter            if (startIndex != -1)            {                for (int i = startIndex - 1; i < endIndex; i++)                {                    SchedulerSequence item = _schedulerSequences[i];                    item.State = RState.End;                    LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} skip {i+1} sequence {item.ModuleType}");                }            }            //是否设置最后调度的源模块            if (isSetLastSequenceSourceModule)            {                SchedulerSequence lastSchedulerSequence = _schedulerSequences[endIndex];                if (lastSchedulerSequence.ModuleType == ModuleType.Transporter)                {                    TransporterAction action = lastSchedulerSequence.Parameters as TransporterAction;                    if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)                    {                        return;                    }                    WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;                    if (schedulerSequence.SchedulerModule != null)                    {                        waferHolderMoveItem.SourceModule = schedulerSequence.ModuleName;                        waferHolderMoveItem.SourceModuleType = schedulerSequence.ModuleType;                    }                }            }        }        /// <summary>        /// 移除SRD调度        /// </summary>        private void RemoveWaferHolderSRDScheduler()        {            WaferTask waferATask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferAId);            if (waferATask != null)            {                waferATask.RemoveSrdScheduler();            }            WaferTask waferBTask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferBId);            if (waferBTask != null)            {                waferBTask.RemoveSrdScheduler();            }        }        #endregion        /// <summary>        /// 自动更新LoaderTransporter的工序        /// </summary>        private void AutoChangeLoaderTransporterScheduler()        {            if(_currentSequenceIndex>=_schedulerSequences.Count)            {                return;            }            if(_currentSequenceIndex+2>=_schedulerSequences.Count)            {                return;            }            SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex];            if (schedulerSequence == null)            {                return;            }            if(schedulerSequence.ModuleName==ModuleName.Transporter2)            {                if (schedulerSequence.Parameters == null || !(schedulerSequence.Parameters is TransporterAction))                {                    return;                }                TransporterAction action = (TransporterAction)schedulerSequence.Parameters;                if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)                {                    return;                }                WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter;                if(waferHolderMoveItem.DestModuleType!=ModuleType.Buffer)                {                    return;                }                SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex + 1];                if(nextSchedulerSequence.ModuleName!=ModuleName.Transporter2)                {                    return;                }                if(nextSchedulerSequence.Parameters==null||!(nextSchedulerSequence.Parameters is TransporterAction))                {                    return;                }                TransporterAction nextAction = nextSchedulerSequence.Parameters as TransporterAction;                if (nextAction.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)                {                    return;                }                WaferHolderMoveItem nextWaferHolderMoveItem = (WaferHolderMoveItem)nextAction.Parameter;                if(nextWaferHolderMoveItem.DestModule==ModuleName.Unknown)                {                    if (ProcessJobInfo != null && ProcessJobInfo.SequenceRecipe != null)                    {                        //后面不存在资源,搬运至Buffer中,而不是进后面cell                        if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))                        {                            return;                        }                    }                    if (CheckBufferHasUnProcessedWaferHolder())                    {                        return;                    }                    //若Buffer后面的cell存在资源,则直接搬运至Cell中                    ModuleName avaibleModuleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(nextWaferHolderMoveItem.DestModuleType,_sequenceType);                    if(avaibleModuleName==ModuleName.Unknown)                    {                        return;                    }                    else                    {                        schedulerSequence.State = RState.End;                        _currentSequenceIndex++;                        nextWaferHolderMoveItem.DestModule = avaibleModuleName;                        nextWaferHolderMoveItem.SourceModule = ModuleName.Loader1;                        nextWaferHolderMoveItem.SourceModuleType = ModuleType.Loader;                        UpdateNextSequenceModule(_currentSequenceIndex + 1,avaibleModuleName);                      }                }                else if(nextWaferHolderMoveItem.DestModule==ModuleName.Loader1)                {                    LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());                    if(loaderEntity==null)                    {                        return;                    }                    if(loaderEntity.WaferHolderInfo!=null)                    {                        return;                    }                    if(loaderEntity.IsBusy)                    {                        return;                    }                    schedulerSequence.State = RState.End;                    _currentSequenceIndex++;                    nextWaferHolderMoveItem.SourceModule = waferHolderMoveItem.SourceModule;                    nextWaferHolderMoveItem.SourceModuleType = waferHolderMoveItem.SourceModuleType;                }            }        }        /// <summary>        /// 检验Buffer中是否存在未处理的WaferHolder        /// </summary>        /// <returns></returns>        private bool CheckBufferHasUnProcessedWaferHolder()        {            List<string> bufferModules = BufferItemManager.Instance.InstalledModules;            foreach (string module in bufferModules)            {                WaferHolderInfo item = WaferHolderManager.Instance.GetWaferHolder(module);                if (item == null)                {                    continue;                }                if (string.IsNullOrEmpty(item.WaferAId))                {                    continue;                }                if (string.IsNullOrEmpty(item.WaferBId))                {                    continue;                }                WaferInfo waferA=WaferManager.Instance.GetWaferByWaferId(item.WaferAId);                if (waferA == null)                {                    continue;                }                if (waferA.ProcessState == EnumWaferProcessStatus.Idle&&waferA.WaferType==WaferType.Production)                {                    return true;                }                WaferInfo waferB = WaferManager.Instance.GetWaferByWaferId(item.WaferBId);                if(waferB == null)                {                    continue;                }                if (waferB.ProcessState == EnumWaferProcessStatus.Idle && waferB.WaferType == WaferType.Production)                {                    return true;                }            }            return false;        }        /// <summary>        /// 更新下一工序的调度模块        /// </summary>        /// <param name="sequenceIndex"></param>        /// <param name="moduleName"></param>        private void UpdateNextSequenceModule(int sequenceIndex,ModuleName moduleName)        {            if(sequenceIndex<_schedulerSequences.Count)            {                SchedulerSequence schedulerSequence = _schedulerSequences[sequenceIndex];                if(schedulerSequence!=null&&schedulerSequence.SchedulerModule==null)                {                    schedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);                    schedulerSequence.ModuleName = moduleName;                }            }        }        /// <summary>        /// 更新WaferHolder工序完成Wafer状态        /// </summary>        private void UpdateWaferHolderProcessComplete()        {            if (WaferHolderInfo.Status != WaferHolderStatus.Completed)            {                UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Completed);                WaferHolderInfo.Status = WaferHolderStatus.Completed;                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");            }            MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);        }        /// <summary>        /// 更新WaferHolder工序正在加工        /// </summary>        private void UpdateWaferHolderProcessingStatus()        {            if (WaferHolderInfo.Status == WaferHolderStatus.Normal)            {                UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.InProcess);                WaferHolderInfo.Status = WaferHolderStatus.Processing;                LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");                MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);            }        }        /// <summary>        /// 更新WaferHolder工序错误状态        /// </summary>        /// <param name="sequence"></param>        private void UpdateWaferHolderErrorStatus()        {            UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Failed);            WaferHolderInfo.Status = WaferHolderStatus.Failed;            MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);        }        /// <summary>        /// 更新WaferHolder工序MisProcessed状态        /// </summary>        /// <param name="sequence"></param>        private void UpdateWaferHolderMisProcessedStatus()        {            UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.MisProcessed);            WaferHolderInfo.Status = WaferHolderStatus.MisProcessed;            MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);        }        /// <summary>        /// 更新WaferHolder处理状态        /// </summary>        /// <param name="sequence"></param>        /// <param name="processStatus"></param>        private void UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus processStatus)        {            if (Enum.TryParse(WaferHolderInfo.CurrentLocation, out ModuleName moduleName))            {                if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId))                {                    WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);                    if (waferInfo != null && waferInfo.WaferType == WaferType.Production)                    {                        WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 0, processStatus);                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");                    }                }                if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId))                {                    WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);                    if (waferInfo != null && waferInfo.WaferType == WaferType.Production)                    {                        WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 1, processStatus);                        LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");                    }                }            }        }        /// <summary>        /// 检验前置条件        /// </summary>        /// <returns></returns>        private bool CheckStartCondition()        {            LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());                       if (loaderEntity.WaferHolderInfo != null)            {                return false;            }            //if (ProcessJobInfo != null)            //{            //    if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))            //    {            //        _currentSequenceIndex = _schedulerSequences.Count;            //        LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"WaferHolder {WaferHolderInfo.Id} start scheduler meet no avaible cell");            //        return false;            //    }            //}            return true;        }        /// <summary>        /// 释放资源        /// </summary>        public void Dispose()        {            _schedulerSequences.Clear();        }        /// <summary>        /// 暂停        /// </summary>        public void Pause()        {            _pausedIndex = _currentSequenceIndex;        }        /// <summary>        /// 恢复        /// </summary>        public void Resume()        {            _pausedIndex = -1;        }        /// <summary>        /// 获取当前调度阶段        /// </summary>        /// <returns></returns>        public SchedulerSequence GetCurrentSchedulerSequence()        {            return GetSchedulerSequenceByIndex(_currentSequenceIndex);        }        /// <summary>        /// 获取前一个调度阶段        /// </summary>        /// <returns></returns>        public SchedulerSequence GetPreSchedulerSequence()        {            return GetSchedulerSequenceByIndex(_currentSequenceIndex-1);        }        /// <summary>        /// 根据索引获取调度阶段对象        /// </summary>        /// <param name="index"></param>        /// <returns></returns>        private SchedulerSequence GetSchedulerSequenceByIndex(int index)        {            if (index == -1 || index >= _schedulerSequences.Count)            {                return null;            }            return _schedulerSequences[index];        }        /// <summary>        /// 是否调度完成Loader调度        /// </summary>        /// <returns></returns>        public bool IsNotPassLoader()        {            return _currentSequenceIndex <= 1;        }    }}
 |