| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.Xml;
 
- using Aitex.Core.Equipment.SusceptorDefine;
 
- using Aitex.Core.RT.Device;
 
- using Aitex.Core.RT.Event;
 
- using Aitex.Core.RT.Log;
 
- using Aitex.Core.RT.OperationCenter;
 
- using Aitex.Core.RT.RecipeCenter;
 
- using Aitex.Core.RT.Routine;
 
- using Aitex.Core.RT.SCCore;
 
- using Aitex.Core.Util;
 
- using MECF.Framework.Common.DBCore;
 
- using MECF.Framework.Common.Equipment;
 
- using VirgoRT.Devices;
 
- using VirgoRT.Module;
 
- namespace VirgoRT.Modules.PMs
 
- {
 
-     class ProcessRoutine : PMRoutineBase
 
-     {
 
-         private enum RecipeEngineState
 
-         {
 
-             Error,
 
-             RecipeCompleted,
 
-             ExecStep,
 
-             TimeWait,
 
-             EndPointWait,
 
-             StepCompleted,
 
-             Paused,
 
-         }
 
-         private object _lockerTotalCycle = new object();
 
-         private Dictionary<string, int> _recipeTotalCycle = new Dictionary<string, int>();
 
-         private DeviceTimer _beginPauseTimer = new DeviceTimer();
 
-         private object _recipeLocker = new object();
 
-         private RecipeEngineState _state = RecipeEngineState.ExecStep;
 
-         private RecipeEngineState _pausedState = RecipeEngineState.ExecStep;
 
-         private DeviceTimer _estimatedTimeCalcTimer = new DeviceTimer();//用于定时计算工艺程序估计的结束时间
 
-         public DateTime RecipeStartTime { get; private set; }
 
-         public int RecipeChangeNo { get; private set; }
 
-         public string CurrentRecipeBaseName { get; private set; }
 
-         public string CurrentRecipeRunningName { get; private set; }
 
-         public string CurrentRecipeContent { get; private set; }
 
-         public string CurrentLotName { get; set; }
 
-         public string CurrentRecipeGuid { get; set; }
 
-         private List<RecipeStep> _recipeStepList = new List<RecipeStep>();
 
-         public List<RecipeStep> CurrentRecipeStepList
 
-         {
 
-             get
 
-             {
 
-                 return _recipeStepList;
 
-             }
 
-             set
 
-             {
 
-                 _recipeStepList = value;
 
-             }
 
-         }
 
-         public RecipeHead CurrentRecipeHead { get; set; }
 
-         public int CurStepNum { get; private set; }
 
-         public int CurStepTotalLoopCount { get; private set; }
 
-         public double CurStepTotalTime
 
-         {
 
-             get
 
-             {
 
-                 if (_recipeStepList == null || _recipeStepList.Count == 0 || _state == RecipeEngineState.RecipeCompleted || _state == RecipeEngineState.Error)
 
-                     return 0;
 
-                 return _recipeStepList[CurStepNum].StepTime * 1000;
 
-             }
 
-         }
 
-         public int CurrentLoopCount
 
-         {
 
-             get;
 
-             private set;
 
-         }
 
-         private DeviceTimer StepTimer = new DeviceTimer();
 
-         public bool IsPaused
 
-         {
 
-             private set;
 
-             get;
 
-         }
 
-         public string CurStepComment
 
-         {
 
-             get
 
-             {
 
-                 if (_recipeStepList == null || _recipeStepList.Count == 0)
 
-                     return string.Empty;
 
-                 return _recipeStepList[CurStepNum].StepName;
 
-             }
 
-         }
 
-         public double CurStepLeftTime
 
-         {
 
-             get
 
-             {
 
-                 if (IsPaused)
 
-                     return StepTimer.GetTotalTime() - StepTimer.GetElapseTime() + _beginPauseTimer.GetElapseTime();
 
-                 //return Math.Max(0,StepTimer.GetTotalTime() - StepTimer.GetElapseTime());
 
-                 return StepTimer.GetTotalTime() - StepTimer.GetElapseTime();
 
-             }
 
-         }
 
-         public double CurStepElpasedTime
 
-         {
 
-             get
 
-             {
 
-                 if (_recipeStepList == null || _recipeStepList.Count == 0 || _state == RecipeEngineState.RecipeCompleted || _state == RecipeEngineState.Error)
 
-                     return 0;
 
-                 return StepTimer.GetElapseTime();
 
-             }
 
-         }
 
-         public double CurStepTotalRfTime
 
-         {
 
-             get
 
-             {
 
-                 if (_recipeStepList == null || _recipeStepList.Count == 0 || _state == RecipeEngineState.RecipeCompleted || _state == RecipeEngineState.Error)
 
-                     return 0;
 
-                 if (_recipeStepList[CurStepNum].RecipeCommands.ContainsKey("Rf.SetPower") &&
 
-                     !string.IsNullOrEmpty(_recipeStepList[CurStepNum].RecipeCommands["Rf.SetPower"]) &&
 
-                     Convert.ToDouble(_recipeStepList[CurStepNum].RecipeCommands["Rf.SetPower"]) > 0.1)
 
-                     return CurStepTotalTime;
 
-                 return 0;
 
-             }
 
-         }
 
-         public int TotalCycle
 
-         {
 
-             get
 
-             {
 
-                 if (string.IsNullOrEmpty(DateTimeRecipeBaseName))
 
-                     return 0;
 
-                 lock (_lockerTotalCycle)
 
-                 {
 
-                     if (_recipeTotalCycle.ContainsKey(DateTimeRecipeBaseName))
 
-                         return _recipeTotalCycle[DateTimeRecipeBaseName];
 
-                 }
 
-                 return 0;
 
-             }
 
-         }
 
-         public string DateTimeRecipeBaseName
 
-         {
 
-             get
 
-             {
 
-                 if (string.IsNullOrEmpty(CurrentRecipeBaseName))
 
-                     return "";
 
-                 return DateTime.Now.ToString("yyyyMMdd") + CurrentRecipeBaseName;
 
-             }
 
-         }
 
-         public double PausedTime
 
-         {
 
-             get
 
-             {
 
-                 return IsPaused ? _beginPauseTimer.GetElapseTime() : 0;
 
-             }
 
-         }
 
-         public double EstimatedTotalLeftTime
 
-         {
 
-             get;
 
-             private set;
 
-         }
 
-         public int RecipeTotalStepNum
 
-         {
 
-             get
 
-             {
 
-                 return _recipeStepList.Count;
 
-             }
 
-         }
 
-         protected PMEntity _chamberEntity;
 
-         private RecipeFACallback _faCallback;
 
-         private RecipeDBCallback _dbCallback;
 
-         private Fdc _fdc;
 
-         public ProcessRoutine(JetPM chamber, PMEntity entity) : base(chamber)
 
-         {
 
-             Name = "ProcessRoutine";
 
-             RecipeStartTime = new DateTime(0);
 
-             EstimatedTotalLeftTime = 0;
 
-             CalcEstimatedRecipeEndTime();
 
-             _chamberEntity = entity;
 
-             _faCallback = new RecipeFACallback();
 
-             _dbCallback = new RecipeDBCallback();
 
-             _fdc = new Fdc(Module);
 
-         }
 
-         public Result Start(params object[] param)
 
-         {
 
-             RecipeStartTime = DateTime.Now;
 
-             CurrentRecipeBaseName = (string)param[0];
 
-             CurrentRecipeRunningName = (string)param[1];
 
-             RecipeChangeNo = (int)param[2];
 
-             CurrentLotName = (string)param[3];
 
-             CurrentRecipeContent = (string)param[4];
 
-             CurrentRecipeHead = (RecipeHead)param[5];
 
-             CurrentRecipeStepList = (List<RecipeStep>)param[6];
 
-             if (!_chamber.IsRFGInterlockOn)
 
-             {
 
-                 EV.PostAlarmLog(Module, "射频电源 Interlock条件不满足");
 
-                 return Result.VERIFYFAIL;
 
-             }
 
-             lock (_lockerTotalCycle)
 
-             {
 
-                 if (_recipeTotalCycle.ContainsKey(DateTimeRecipeBaseName))
 
-                     _recipeTotalCycle[DateTimeRecipeBaseName] += 1;
 
-                 else
 
-                 {
 
-                     _recipeTotalCycle[DateTimeRecipeBaseName] = 1;
 
-                 }
 
-                 List<string> keys = new List<string>();
 
-                 foreach (KeyValuePair<string, int> item in _recipeTotalCycle)
 
-                 {
 
-                     if (!item.Key.StartsWith(DateTime.Now.ToString("yyyyMMdd")))
 
-                         keys.Add(item.Key);
 
-                 }
 
-                 foreach (string key in keys)
 
-                 {
 
-                     _recipeTotalCycle.Remove(key);
 
-                 }
 
-             }
 
-             _chamber.SetValveOnOff(ValveType.PROCESS, true);
 
-             CurStepNum = CurStepTotalLoopCount = 0;
 
-             _estimatedTimeCalcTimer.Start(1000);
 
-             EV.PostInfoLog(Module, $"工艺程序 {CurrentRecipeRunningName} 开始运行");
 
-             _chamberEntity.RecipeRunningInfo.InnerId = Guid.NewGuid();
 
-             _chamberEntity.RecipeRunningInfo.BeginTime = DateTime.Now;
 
-             _chamberEntity.RecipeRunningInfo.RecipeName = CurrentRecipeBaseName;
 
-             _chamberEntity.RecipeRunningInfo.RecipeStepList = CurrentRecipeStepList;
 
-             //ProcessDataRecorder.UpdateStatus(RecipeRunGuid.ToString(), SusceptorStatus.InProcessing.ToString(), Module);
 
-             _state = RecipeEngineState.ExecStep;
 
-             double totalTime = 0;
 
-             foreach (var step in CurrentRecipeStepList)
 
-             {
 
-                 totalTime += step.StepTime;
 
-             }
 
-             _dbCallback.RecipeStart(_chamber.Module.ToString(), 0, _chamberEntity.RecipeRunningInfo.InnerId.ToString(), _chamberEntity.RecipeRunningInfo.RecipeName);
 
-             _dbCallback.RecipeUpdateStatus(_chamberEntity.RecipeRunningInfo.InnerId.ToString(), "InProcess", (float)totalTime);
 
-             _faCallback.RecipeStart(_chamber.Module.ToString(), CurrentRecipeBaseName);
 
-             _fdc.Reset();
 
-             _chamberEntity.EndPointRecipeStart(CurrentRecipeBaseName);
 
-             return Result.RUN;
 
-         }
 
-         /// <summary>
 
-         /// quiting current state
 
-         /// </summary>
 
-         /// <param name="nextState"></param>
 
-         public void Exit()
 
-         {
 
-             _chamber.IsPressureToleranceEnabled = false;
 
-             var ts = DateTime.Now - RecipeStartTime;
 
-             var totalTime = $"{Convert.ToInt32(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}";
 
-             bool isProcessCompleted = _state == RecipeEngineState.RecipeCompleted;
 
-             if (isProcessCompleted)
 
-             {
 
-                 EV.PostInfoLog(Module, $"工艺程序 {CurrentRecipeRunningName} 正常运行完毕");
 
-                 _faCallback.RecipeComplete(_chamber.Module.ToString(), CurrentRecipeBaseName);
 
-                 _dbCallback.RecipeComplete(_chamberEntity.RecipeRunningInfo.InnerId.ToString());
 
-                 _fdc.Stop();
 
-             }
 
-             else
 
-             {
 
-                 _faCallback.RecipeFailed(_chamber.Module.ToString(), CurrentRecipeBaseName);
 
-                 _dbCallback.RecipeFailed(_chamberEntity.RecipeRunningInfo.InnerId.ToString());
 
-                 _chamberEntity.StopEndPoint();
 
-                 string info = string.Format("Recipe:{0}\r\nStart time:{1:yyyy/MM/dd HH:mm:ss}\r\nEnd time:{2:yyyy/MM/dd HH:mm:ss}\r\nTotal time:{3}",
 
-                     CurrentRecipeRunningName, RecipeStartTime, DateTime.Now, totalTime);
 
-                 EV.PostWarningLog(Module, info);
 
-                 EV.PostPopDialogMessage(EventLevel.Warning, $"{Module} recipe was aborted", info);
 
-             }
 
-             _chamberEntity.EndPointRecipeStop();
 
-             //重置工艺程序名
 
-             CurrentRecipeRunningName = string.Empty;
 
-             CurrentLotName = string.Empty;
 
-             var tolerance = _chamberEntity.RecipeRunningInfo.RecipeStepList[0].ToleranceCommands;
 
-             foreach (var cmd in tolerance)
 
-             {
 
-                 OP.DoOperation($"{Module}.{cmd.Key}", out string reason1, 0,  new object[]{"0", "0" , "0" });
 
-             }
 
-         }
 
-         public Result Monitor()
 
-         {
 
-             string reason = string.Empty;
 
-             CalcEstimatedRecipeEndTime();
 
-             //工艺程序运行监控,自动打开阀门如果对应的MFC设定设置大于0
 
-             _chamber.Monitor();
 
-             if (_chamber.IsError)
 
-                 return Result.FAIL;
 
-             //工艺程序运行引擎
 
-             lock (_recipeLocker)
 
-             {
 
-                 try
 
-                 {
 
-                     switch (_state)
 
-                     {
 
-                         case RecipeEngineState.ExecStep:
 
-                             {
 
-                                 //工艺程序循环设置
 
-                                 if (_recipeStepList[CurStepNum].IsLoopStartStep)
 
-                                 {
 
-                                     CurStepTotalLoopCount = _recipeStepList[CurStepNum].LoopCount;
 
-                                     if (CurStepTotalLoopCount == 0)
 
-                                     {
 
-                                         CurrentLoopCount = 0;
 
-                                     }
 
-                                     else
 
-                                     {
 
-                                         CurrentLoopCount++;
 
-                                     }
 
-                                 }
 
-                                 //当前工艺程序步的定时器设定
 
-                                 StepTimer.Start(_recipeStepList[CurStepNum].StepTime * 1000);
 
-                                 //发送信息到用户界面
 
-                                 EV.PostInfoLog(Module, $"工艺程序 {CurrentRecipeRunningName} 第{CurStepNum + 1} 步开始:{_recipeStepList[CurStepNum].StepName}");
 
-                                 //执行工艺程序命令
 
-                                 foreach (var cmdkey in _recipeStepList[CurStepNum].RecipeCommands.Keys)
 
-                                 {
 
-                                     string recipeCmd = cmdkey;
 
-                                     string param = _recipeStepList[CurStepNum].RecipeCommands[recipeCmd];
 
-                                     if (string.IsNullOrWhiteSpace(param)) continue;
 
-                                     if (recipeCmd == "EPD.SetConfig" && !SC.GetValue<bool>($"{Module}.EPD.IsEnabled"))
 
-                                         continue;
 
-                                         
 
-                                     if (!OP.CanDoOperation($"{Module}." + recipeCmd, out reason, param))
 
-                                     {
 
-                                         EV.PostAlarmLog(Module, $"不能执行 {recipeCmd}, {reason}");
 
-                                         return Result.FAIL;
 
-                                     }
 
-                                     else
 
-                                     {
 
-                                         var rampTime_ms = (int)(_recipeStepList[CurStepNum].StepTime * 1000);
 
-                                         if (_recipeStepList[CurStepNum].IsJumpStep)
 
-                                             rampTime_ms = 0;
 
-                                         if (recipeCmd == "EPD.SetConfig")
 
-                                         {
 
-                                             if(SC.GetValue<bool>($"{Module}.EPD.IsEnabled"))
 
-                                                 OP.DoOperation($"{Module}." + recipeCmd, out string reason1, rampTime_ms, CurStepNum, _recipeStepList[CurStepNum].RecipeCommands[recipeCmd]);
 
-                                         }
 
-                                         else
 
-                                         {
 
-                                             OP.DoOperation($"{Module}." + recipeCmd, out string reason1, rampTime_ms, param);
 
-                                         }
 
-                                     }
 
-                                 }
 
-                                 foreach (var toleranceCommand in _recipeStepList[CurStepNum].ToleranceCommands)
 
-                                 {
 
-                                     OP.DoOperation($"{Module}." + toleranceCommand.Key, out string reason1, 0, toleranceCommand.Value);
 
-                                 }
 
-                                 string endby = _recipeStepList[CurStepNum].EndBy;
 
-                                 if (!string.IsNullOrEmpty(endby) && endby == "EndByEndPoint")
 
-                                 {
 
-                                     _state = RecipeEngineState.EndPointWait;
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     _state = RecipeEngineState.TimeWait;
 
-                                 }
 
-                                 _faCallback.RecipeStepStart(_chamber.Module.ToString(), CurrentRecipeBaseName, CurStepNum);
 
-                                 _dbCallback.RecipeStepStart(_chamberEntity.RecipeRunningInfo.InnerId.ToString(), CurStepNum, _chamberEntity.RecipeRunningInfo.RecipeStepList[CurStepNum].StepName, (float)_chamberEntity.RecipeRunningInfo.RecipeStepList[CurStepNum].StepTime);
 
-                                 _fdc.Start(_chamberEntity.RecipeRunningInfo.RecipeStepList[CurStepNum].RecipeCommands);
 
-                             }
 
-                             break;
 
-                         case RecipeEngineState.TimeWait:
 
-                             _chamber.CheckPressureStability();
 
-                             if (StepTimer.IsTimeout())
 
-                             {
 
-                                 _state = RecipeEngineState.StepCompleted;
 
-                             }
 
-                             break;
 
-                         case RecipeEngineState.EndPointWait:
 
-                             {
 
-                                 if (_chamberEntity.CheckEndPoint())
 
-                                 {
 
-                                     _state = RecipeEngineState.StepCompleted;
 
-                                 }
 
-                                 if (StepTimer.IsTimeout())
 
-                                 {
 
-                                     if (_recipeStepList[CurStepNum].FaultIfNoEPDTrigger)
 
-                                     {
 
-                                         EV.PostAlarmLog(Module, $"{_chamberEntity.Module} EPD step not triggered, timeout");
 
-                                         return Result.FAIL;
 
-                                     }
 
-                                     else
 
-                                     {
 
-                                         EV.PostWarningLog(Module, $"{_chamberEntity.Module} EPD step not triggered, skipped");
 
-                                     }
 
-                                     _state = RecipeEngineState.StepCompleted;
 
-                                 }
 
-                             }
 
-                             break;
 
-                         case RecipeEngineState.Paused:
 
-                             break;
 
-                         case RecipeEngineState.StepCompleted:
 
-                             {
 
-                                 EV.PostInfoLog(Module, $"工艺程序 {CurrentRecipeRunningName} 第{CurStepNum + 1}步结束");
 
-                                 _chamberEntity.StopEndPoint();
 
-                                 _faCallback.RecipeStepEnd(_chamber.Module.ToString(), CurrentRecipeBaseName, CurStepNum, _fdc.DataList);
 
-                                 _dbCallback.RecipeStepEnd(_chamberEntity.RecipeRunningInfo.InnerId.ToString(), CurStepNum, _fdc.DataList);
 
-                                 _fdc.Stop();
 
-                                 //判断是否当前步循环终止
 
-                                 if (_recipeStepList[CurStepNum].IsLoopEndStep)
 
-                                 {
 
-                                     //重新读取循环的设定次数
 
-                                     for (int nn = CurStepNum; nn >= 0; nn--)
 
-                                     {
 
-                                         if (_recipeStepList[nn].IsLoopStartStep)
 
-                                         {
 
-                                             CurStepTotalLoopCount = _recipeStepList[nn].LoopCount;
 
-                                             break;
 
-                                         }
 
-                                     }
 
-                                     if (CurrentLoopCount >= CurStepTotalLoopCount)
 
-                                     {
 
-                                         CurrentLoopCount = CurStepTotalLoopCount = 0;
 
-                                         CurStepNum++;
 
-                                     }
 
-                                     else
 
-                                     {
 
-                                         int n = CurStepNum - 1;
 
-                                         int next = -1;
 
-                                         while (n >= 0)
 
-                                         {
 
-                                             if (_recipeStepList[n].IsLoopStartStep)
 
-                                             {
 
-                                                 next = n;
 
-                                                 break;
 
-                                             }
 
-                                             n--;
 
-                                         }
 
-                                         if (next == -1)
 
-                                             throw new Exception("Loop End control error");
 
-                                         CurStepNum = next;
 
-                                     }
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     if (CurStepNum < _recipeStepList.Count - 1)
 
-                                     {
 
-                                         CurStepNum++;
 
-                                         _state = RecipeEngineState.ExecStep;
 
-                                     }
 
-                                     else
 
-                                     {
 
-                                         EV.PostInfoLog(Module, $"工艺 {CurrentRecipeRunningName} 完毕");
 
-                                         CurStepNum = _recipeStepList.Count - 1;
 
-                                         _state = RecipeEngineState.RecipeCompleted;
 
-                                         return Result.DONE;
 
-                                     }
 
-                                 }
 
-                             }
 
-                             break;
 
-                         case RecipeEngineState.RecipeCompleted:
 
-                             return Result.DONE;
 
-                         case RecipeEngineState.Error:
 
-                             return Result.FAIL;
 
-                         default:
 
-                             break;
 
-                     }
 
-                 }
 
-                 catch (Exception ex)
 
-                 {
 
-                     EV.PostAlarmLog(Module, $"{CurStepNum + 1}, 语法错误, {ex.Message}");
 
-                     return Result.FAIL;
 
-                 }
 
-             }
 
-             return Result.RUN;
 
-         }
 
-         /// <summary>
 
-         /// 暂停工艺程序运行
 
-         /// </summary>
 
-         public void PauseRecipe()
 
-         {
 
-             if (_state != RecipeEngineState.TimeWait && _state != RecipeEngineState.EndPointWait)
 
-                 return;
 
-             if (!IsPaused)
 
-             {
 
-                 string reason = string.Empty;
 
-                 IsPaused = true;
 
-                 _pausedState = _state;
 
-                 _state = RecipeEngineState.Paused;
 
-                 _beginPauseTimer.Start(0);
 
-                 EV.PostInfoLog(Module, $"工艺程序'{CurrentRecipeRunningName}'第{CurStepNum + 1}步暂停");
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 恢复工艺程序运行
 
-         /// </summary>
 
-         public void ResumeRecipe()
 
-         {
 
-             if (IsPaused)
 
-             {
 
-                 //update current recipe step time
 
-                 string recipeXml = CurrentRecipeContent;
 
-                 int currentStepNo = CurStepNum;
 
-                 XmlDocument xmlDoc = new XmlDocument();
 
-                 xmlDoc.LoadXml(recipeXml);
 
-                 var stepNodes = xmlDoc.SelectNodes("/TableRecipeData/Step");
 
-                 if (currentStepNo >= 0 && currentStepNo < stepNodes.Count)
 
-                 {
 
-                     var curStepNode = stepNodes[currentStepNo] as XmlElement;
 
-                     var curStepNewTime = CurStepTotalTime + PausedTime;
 
-                     if (curStepNewTime < 0)
 
-                         curStepNewTime = 0;
 
-                     TimeSpan tspan = new TimeSpan(0, 0, 0, 0, (int)curStepNewTime);
 
-                     var timeString =
 
-                         $"{((int)tspan.TotalHours).ToString("00")}:{tspan.Minutes.ToString("00")}:{tspan.Seconds.ToString("00")}";
 
-                     curStepNode.SetAttribute("Time", timeString);
 
-                     LOG.Write($"执行Resume命令,将当前第{currentStepNo}步时间修改为{timeString}");
 
-                     UpdateRecipe(xmlDoc.OuterXml);
 
-                 }
 
-                 //Resume recipe
 
-                 IsPaused = false;
 
-                 _state = _pausedState;
 
-                 EV.PostInfoLog(Module, $"工艺程序'{CurrentRecipeRunningName}'第{CurStepNum + 1}步继续");
 
-                 //resume recipe
 
-                 double stepElapsedTime = StepTimer.GetElapseTime() - _beginPauseTimer.GetElapseTime();
 
-                 double stepLeftTime = StepTimer.GetTotalTime() - stepElapsedTime;
 
-                 if (stepLeftTime < 0)
 
-                     stepLeftTime = 0;
 
-                 //更新当前步的定时器时间
 
-                 StepTimer.Restart(StepTimer.GetTotalTime() + _beginPauseTimer.GetElapseTime());
 
-                 //重新执行当前工艺程序步
 
-                 foreach (var recipeCmd in _recipeStepList[CurStepNum].RecipeCommands.Keys)
 
-                 {
 
-                     if (!DEVICE.CanDo(recipeCmd))
 
-                     {
 
-                         EV.PostInfoLog(Module, $"不可识别的工艺程序控制命令{recipeCmd}");
 
-                     }
 
-                     else
 
-                     {
 
-                         var rampTime_ms = (int)(_recipeStepList[CurStepNum].StepTime * 1000);
 
-                         if (_recipeStepList[CurStepNum].IsJumpStep)
 
-                             rampTime_ms = 0;
 
-                         DEVICE.Do(recipeCmd, rampTime_ms, false, _recipeStepList[CurStepNum].RecipeCommands[recipeCmd]);
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         /// <summary>
 
-         /// 终止工艺程序运行
 
-         /// </summary>
 
-         public void AbortRecipe()
 
-         {
 
-             ResumeRecipe();
 
-             _chamberEntity.StopEndPoint();
 
-             _state = RecipeEngineState.Error;
 
-             CalcEstimatedRecipeEndTime();
 
-             _faCallback.RecipeFailed(_chamber.Module.ToString(), CurrentRecipeBaseName);
 
-             _dbCallback.RecipeFailed(_chamberEntity.RecipeRunningInfo.InnerId.ToString());
 
-             _fdc.Stop();
 
-             EV.PostInfoLog(Module, "工艺程序被终止运行");
 
-         }
 
-         /// <summary>
 
-         /// 跳至工艺程序下一步
 
-         /// </summary>
 
-         public void SkipCurrentRecipeStep()
 
-         {
 
-             if (_state == RecipeEngineState.Paused)
 
-             {
 
-                 EV.PostInfoLog(Module, "在 Pause Recipe 状态下不能执行 Skip to next step 命令");
 
-                 return;
 
-             }
 
-             try
 
-             {
 
-                 //update current recipe step time
 
-                 string recipeXml = CurrentRecipeContent;
 
-                 int currentStepNo = CurStepNum;
 
-                 XmlDocument xmlDoc = new XmlDocument();
 
-                 xmlDoc.LoadXml(recipeXml);
 
-                 var stepNodes = xmlDoc.SelectNodes("/TableRecipeData/Step");
 
-                 if (currentStepNo >= 0 && currentStepNo < stepNodes.Count)
 
-                 {
 
-                     var curStepNode = stepNodes[currentStepNo] as XmlElement;
 
-                     var curStepElapsedTime = CurStepTotalTime - CurStepLeftTime;//ms
 
-                     if (curStepElapsedTime < 0)
 
-                         curStepElapsedTime = 0;
 
-                     //TimeSpan tspan = new TimeSpan(0, 0, 0, 0, (int)curStepElapsedTime);
 
-                     //var timeString =
 
-                     //    $"{((int)tspan.TotalHours).ToString("00")}:{tspan.Minutes.ToString("00")}:{tspan.Seconds.ToString("00")}";
 
-                     string timeString = ((int)(curStepElapsedTime / 1000)).ToString();
 
-                     curStepNode.SetAttribute("Time", timeString);
 
-                     LOG.Write($"step skipped,step {currentStepNo} time changed to {timeString}");
 
-                     //recipe update command
 
-                     UpdateRecipe(xmlDoc.OuterXml);
 
-                 }
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 LOG.Write(ex);
 
-             }
 
-             if (_state == RecipeEngineState.EndPointWait || _state == RecipeEngineState.TimeWait)
 
-             {
 
-                 _state = RecipeEngineState.StepCompleted;
 
-                 //send informational event
 
-                 EV.PostMessage(Module, EventEnum.GeneralInfo, Module, CurrentRecipeRunningName, CurStepNum + 1);
 
-             }
 
-         }
 
-         public bool UpdateRecipe(string newRecipeContent)
 
-         {
 
-             lock (_recipeLocker)
 
-             {
 
-                 RecipeHead head = null;
 
-                 List<RecipeStep> newRecipeData = null;
 
-                 if (!Recipe.Parse(Module, newRecipeContent, out head, out newRecipeData))
 
-                 {
 
-                     EV.PostMessage(Module, EventEnum.DefaultAlarm, Module, CurrentRecipeRunningName);
 
-                     return false;
 
-                 }
 
-                 else
 
-                 {
 
-                     string oldRecipeName = CurrentRecipeRunningName;
 
-                     CurrentRecipeRunningName =
 
-                         $"{DateTime.Now:yyyyMMddHHmmss}-{CurrentRecipeBaseName}-({RecipeChangeNo++})";
 
-                     //update local recipe data
 
-                     _recipeStepList = newRecipeData;
 
-                     CurrentRecipeContent = newRecipeContent;
 
-                     //send informational event
 
-                     EV.PostInfoLog(Module, $"运行工艺程序'{oldRecipeName}'第{CurStepNum + 1}步时更新工艺程序为'{CurrentRecipeRunningName}");
 
-                     RecipeFileManager.Instance.SaveRecipeHistory(ModuleName.System.ToString(), CurrentRecipeRunningName, CurrentRecipeContent);
 
-                 }
 
-             }
 
-             return true;
 
-         }
 
-         public override void Abort()
 
-         {
 
-             _dbCallback.RecipeFailed(_chamberEntity.RecipeRunningInfo.InnerId.ToString() );
 
-             base.Abort();
 
-         }
 
-         public override string ToString()
 
-         {
 
-             return "recipe running";
 
-         }
 
-         /// <summary>
 
-         /// 工艺程序估计结束时间计算
 
-         /// </summary>
 
-         protected void CalcEstimatedRecipeEndTime()
 
-         {
 
-             try
 
-             {
 
-                 //(*计算当前工艺程序预计所需的总时间,从当前步开始计算剩余步的估算时间+已经既成事实的时间 => 总的估计时间,采用该种方式进行总工艺时间理论上最为精确*)
 
-                 if (!_estimatedTimeCalcTimer.IsTimeout())
 
-                     return;
 
-                 _estimatedTimeCalcTimer.Start(1000);
 
-                 EstimatedTotalLeftTime = 0;
 
-                 if (_state == RecipeEngineState.RecipeCompleted)
 
-                     return;
 
-                 if (!(CurStepNum >= 0 && CurStepNum <= _recipeStepList.Count - 1))
 
-                     return;
 
-                 if (CurStepLeftTime > 0)
 
-                 {
 
-                     EstimatedTotalLeftTime = CurStepLeftTime;
 
-                 }
 
-                 int nextBegin = CurStepNum;
 
-                 //(*判断当前是否处于循环之中*)
 
-                 bool IsInLoop = false;
 
-                 int iNum1 = 0;
 
-                 int iNum2 = 0;
 
-                 //int j=i;
 
-                 for (int j = CurStepNum; j < _recipeStepList.Count; j++)
 
-                 {
 
-                     if (_recipeStepList[j].IsLoopEndStep)
 
-                     {
 
-                         iNum2 = j;
 
-                         IsInLoop = true;
 
-                         break;
 
-                     }
 
-                     else if (j > CurStepNum && _recipeStepList[j].IsLoopStartStep)
 
-                     {
 
-                         IsInLoop = false;
 
-                         break;
 
-                     }
 
-                 }
 
-                 if (IsInLoop)
 
-                 {
 
-                     //(*当前步处于循环中*)
 
-                     iNum1 = CurStepNum;
 
-                     for (int j = CurStepNum; j >= 0; j--)
 
-                     {
 
-                         if (_recipeStepList[j].IsLoopStartStep)
 
-                         {
 
-                             iNum1 = j;
 
-                             break;
 
-                         }
 
-                     }
 
-                     for (int j = CurStepNum + 1; j <= iNum2; j++)
 
-                     {
 
-                         EstimatedTotalLeftTime += _recipeStepList[j].StepTime * 1000 * (_recipeStepList[iNum1].LoopCount - CurrentLoopCount + 1);
 
-                     }
 
-                     for (int j = iNum1; j <= CurStepNum; j++)
 
-                     {
 
-                         EstimatedTotalLeftTime += _recipeStepList[j].StepTime * 1000 * (_recipeStepList[iNum1].LoopCount - CurrentLoopCount);
 
-                     }
 
-                     nextBegin = iNum2 + 1;
 
-                 }
 
-                 else
 
-                 {
 
-                     nextBegin++;
 
-                 }
 
-                 //(*当前步处于循环外*)
 
-                 for (int j = nextBegin; j < _recipeStepList.Count; j++)
 
-                 {
 
-                     if (_recipeStepList[j].IsLoopStartStep)
 
-                     {
 
-                         //j=i;
 
-                         iNum1 = j;
 
-                         iNum2 = j + 1;
 
-                         double lr1 = 0;
 
-                         for (int m = j; m < _recipeStepList.Count; m++)
 
-                         {
 
-                             lr1 += _recipeStepList[m].StepTime * 1000;
 
-                             if (_recipeStepList[m].IsLoopEndStep)
 
-                             {
 
-                                 iNum2 = m;
 
-                                 break;
 
-                             }
 
-                         }
 
-                         EstimatedTotalLeftTime = EstimatedTotalLeftTime + lr1 * _recipeStepList[iNum1].LoopCount;
 
-                         j = iNum2;
 
-                     }
 
-                     else
 
-                     {
 
-                         EstimatedTotalLeftTime += _recipeStepList[j].StepTime * 1000;
 
-                     }
 
-                     //END_WHILE
 
-                 }
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 LOG.Write(ex);
 
-             }
 
-         }
 
-         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; }
 
-         }
 
-     }
 
- }
 
 
  |