using System; using System.Collections.Generic; using System.Diagnostics; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Devices; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using SicModules.PMs.RecipeExecutions; using SicModules.PMs.Routines.Base; namespace SicModules.PMs.Routines.EditableRoutine { public enum RoutineType { AtmRoutine, VacRoutine, ProcessIdleRoutine, PumpRoutine, VentRoutine, PurgeRoutine, CleanRoutine, ExchangeMORoutine, IsolationRoutine, LeakCheckRoutine, AbortRoutine } public partial class EditableRoutine : PMBaseRoutine { enum RecipeRunningState { Error, RecipeCompleted, ExecStep, TimeWait, ConditionWait, StepCompleted, } //当前步 private int _curStepNumber; //当前循环开始步 public int CurStartLoopStep; //当前循坏步已循坏次数 public int CurStepLoopNumber; //当前循坏步总数 public int CurStepLoopTotalCount; private Stopwatch _swTimer = new Stopwatch(); private DeviceTimer _stepTimer = new DeviceTimer(); private string _recipeName; private IoInterLock _pmInterLock; private RoutineType _routineType; private RecipeRunningInfo _recipeRunningInfo = new RecipeRunningInfo(); private RecipeRunningState _state = RecipeRunningState.ExecStep; private bool _isPSUHeaterJumpMode; private bool _isSCRHeaterJumpMode; private bool _isMFCJumpMode; public EditableRoutine(ModuleName module, PMModule pm) : base(module, pm) { Module = module.ToString(); Name = "EditableRoutine"; _pmInterLock = DEVICE.GetDevice($"{Module}.PMInterLock"); } public void Init(string recipeName, RoutineType routineType) { _recipeName = recipeName; _routineType = routineType; } public bool SetRoutineRunning(bool eValue,out string reason) { reason = string.Empty; if(_routineType == RoutineType.ProcessIdleRoutine) { if (!_pmInterLock.SetPMProcessIdleRunning(eValue, out reason)) { return false; } } else if (_routineType == RoutineType.CleanRoutine) { if (!_pmInterLock.SetPMCleanRoutineRunning(eValue, out reason)) { return false; } } else if (_routineType == RoutineType.PurgeRoutine) { if (!_pmInterLock.SetPMPurgeRoutineRunning(eValue, out reason)) { return false; } } else if (_routineType == RoutineType.PumpRoutine) { if (!_pmInterLock.SetPMPumpRoutineRunning(eValue, out reason)) { return false; } } else if (_routineType == RoutineType.VentRoutine) { if (!_pmInterLock.SetPMVentRoutineRunning(eValue, out reason)) { return false; } } else if (_routineType == RoutineType.ExchangeMORoutine) { if (!_pmInterLock.SetPMExchangeMoRoutineRunning(eValue, out reason)) { return false; } } return true; } public override Result Start(params object[] param) { Reset(); //解析Recipe if (!EditableRoutineParser.Parse(_recipeName, Module, out var recipeHead, out var recipeSteps, out string reason)) { Stop($"Load Routine {_recipeName} failed, {reason}"); return Result.FAIL; } if(!SetRoutineRunning(true,out reason)) { EV.PostAlarmLog(Module, $"can not run Routine, {reason}"); return Result.FAIL; } if (_routineType == RoutineType.PurgeRoutine) { _pmInterLock.DoLidCloseRoutineSucceed = false; } else if (_routineType == RoutineType.CleanRoutine) { _pmInterLock.DoLidOpenRoutineSucceed = false; } //设置当前Step _curStepNumber = 0; CurStartLoopStep = 0; CurStepLoopNumber = 0; CurStepLoopTotalCount = 0; _recipeRunningInfo.RecipeName = _recipeName; _recipeRunningInfo.Head = recipeHead; _recipeRunningInfo.RecipeStepList = recipeSteps; _state = RecipeRunningState.ExecStep; _swTimer.Restart(); Notify($"Start"); return Result.RUN; } public override Result Monitor() { string reason; try { switch (_state) { case RecipeRunningState.ExecStep: { Notify($"Running step {_curStepNumber + 1} : {_recipeRunningInfo.RecipeStepList[_curStepNumber].StepName}"); if (_recipeRunningInfo.RecipeStepList[_curStepNumber].EndBy == EnumEndByCondition.ByTime) { //开启Step计时器 _stepTimer.Start(_recipeRunningInfo.RecipeStepList[_curStepNumber].StepTime * 1000); _state = RecipeRunningState.TimeWait; } else { _state = RecipeRunningState.ConditionWait; } //执行工艺程序命令 foreach (var recipeCmd in _recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands.Keys) { if (recipeCmd == "SusHeaterSetMode") { if (_recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands[recipeCmd] == "Jump") { _isPSUHeaterJumpMode = true; } else { _isPSUHeaterJumpMode = false; } continue; } if (recipeCmd == "WWHeaterSetMode") { if (_recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands[recipeCmd] == "Jump") { _isSCRHeaterJumpMode = true; } else { _isSCRHeaterJumpMode = false; } continue; } if (recipeCmd == "FlowSetMode") { if (_recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands[recipeCmd] == "Jump") { _isMFCJumpMode = true; } else { _isMFCJumpMode = false; } continue; } // 不是注册的方法,需要跳过 if (IsCmdSkip(recipeCmd)) { continue; } if (!OP.CanDoOperation($"{Module}.{recipeCmd}", out reason, _recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands[recipeCmd])) { EV.PostAlarmLog(Module, $"Can not execute {recipeCmd}, {reason}"); return Result.FAIL; } else { int time = (int)_recipeRunningInfo.RecipeStepList[_curStepNumber].StepTime * 1000; if (recipeCmd.StartsWith("TC1") && _isPSUHeaterJumpMode) { time = 1; } if (recipeCmd.StartsWith("TC2") && _isSCRHeaterJumpMode) { time = 1; } if (recipeCmd.StartsWith("Mfc") && recipeCmd.EndsWith(".Ramp") && _isMFCJumpMode) { time = 1; } if (recipeCmd == "TV.SetPressure" || recipeCmd == "PMServo.SetActualSpeed" || recipeCmd.StartsWith("Pressure") && recipeCmd.EndsWith(".Ramp") || recipeCmd.StartsWith("Mfc") && recipeCmd.EndsWith(".Ramp")) { if (_curStepNumber >= 1) { int previousStepNumber = _curStepNumber - 1; if (_recipeRunningInfo.RecipeStepList[previousStepNumber].RecipeCommands.ContainsKey(recipeCmd)) { string previousValue = _recipeRunningInfo.RecipeStepList[previousStepNumber].RecipeCommands[recipeCmd]; string currentValue = _recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands[recipeCmd]; if (previousValue == currentValue) { time = 1; } } } } if (recipeCmd.EndsWith(AITValveOperation.GVTurnValve)) // 阀门 { OP.DoOperation($"{Module}.{recipeCmd}", _recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands[recipeCmd]); } else { OP.DoOperation($"{Module}.{recipeCmd}", out _, time, _recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands[recipeCmd]); } } } if (CurStepLoopNumber == 0) { if (_recipeRunningInfo.RecipeStepList[_curStepNumber].IsLoopStartStep) { CurStartLoopStep = _curStepNumber; CurStepLoopNumber = 0; CurStepLoopTotalCount = _recipeRunningInfo.RecipeStepList[_curStepNumber].LoopCount; } } } break; case RecipeRunningState.TimeWait: { if (_stepTimer.IsTimeout()) { _state = RecipeRunningState.StepCompleted; } } break; case RecipeRunningState.ConditionWait: { //设置的压力 double.TryParse(_recipeRunningInfo.RecipeStepList[_curStepNumber].RecipeCommands["TV.SetPressure"], out double setPressure); //实时反馈的压力 double feedBackPressure = DEVICE.GetDevice($"{Module}.TV").PressureFeedback; double _pmPressureMaxDiff = SC.GetValue($"PM.{Module}.ThrottlePressureMaxDiff"); if (Math.Abs(setPressure - feedBackPressure) <= _pmPressureMaxDiff) { _state = RecipeRunningState.StepCompleted; } } break; case RecipeRunningState.StepCompleted: { if (_recipeRunningInfo.RecipeStepList[_curStepNumber].IsLoopEndStep) { CurStepLoopNumber++; if (CurStepLoopNumber >= CurStepLoopTotalCount) { CurStartLoopStep = 0; CurStepLoopNumber = 0; CurStepLoopTotalCount = 0; _curStepNumber++; } else { _curStepNumber = CurStartLoopStep; } } else { _curStepNumber++; } //判断最后一步是否执行完 if (_curStepNumber >= _recipeRunningInfo.RecipeStepList.Count) { _state = RecipeRunningState.RecipeCompleted; } else { _state = RecipeRunningState.ExecStep; } } break; case RecipeRunningState.RecipeCompleted: { if (!SetRoutineRunning(false, out reason)) { EV.PostAlarmLog(Module, $"can not run Routine, {reason}"); return Result.FAIL; } //设置Succeed状态 if (_routineType == RoutineType.PurgeRoutine) { _pmInterLock.SetLidOpenRoutineSucceed(true, out reason); } else if (_routineType == RoutineType.CleanRoutine) { _pmInterLock.SetLidClosedRoutineSucceed(true, out reason); } _curStepNumber = 0; CurStartLoopStep = 0; CurStepLoopNumber = 0; CurStepLoopTotalCount = 0; Notify("Finished"); return Result.DONE; } case RecipeRunningState.Error: { if (!SetRoutineRunning(false, out reason)) { EV.PostAlarmLog(Module, $"can not run Routine, {reason}"); return Result.FAIL; } return Result.DONE; } default: break; } } catch (Exception ex) { PmDevice.SetHeaterStopRamp(); PmDevice.SetMfcStopRamp(PmDevice.GetMfcListByGroupName(MfcGroupName.All)); PmDevice.SetRotationStopRamp(); if (!SetRoutineRunning(false, out reason)) { EV.PostAlarmLog(Module, $"can not run Process, {reason}"); return Result.FAIL; } LOG.Write(ex); return Result.FAIL; } return Result.RUN; } public override void Abort() { if (!SetRoutineRunning(false, out string reason)) { EV.PostAlarmLog(Module, $"can not run Process, {reason}"); } //根据Routine类型执行Abort SetRoutineAbort(); base.Abort(); } private List _lstGroup1 = new List() { "V46", "V46s", "V73" }; private List _lstGroup2 = new List() { "V46", "V46s" }; private List _lstGroup3 = new List() { "V43", "V43s", "V45" }; //默认为TMA换源参数 private int mfc7Or10 = 7; private int mfc8Or12 = 8; private int mfc11 = 11; private int pc2Or3 = 2; public void SetRoutineAbort() { if (_routineType == RoutineType.ProcessIdleRoutine) { PmDevice._ioThrottleValve.StopRamp(); PmDevice.SetMfcStopRamp(PmDevice.GetMfcListByGroupName(MfcGroupName.All)); PmDevice.SetHeaterStopRamp(); PmDevice.SetRotationStopRamp(); PmDevice.SetRotationServo(0, 0); } else if (_routineType == RoutineType.CleanRoutine) { PmDevice._ioThrottleValve.StopRamp(); PmDevice.SetMfcStopRamp(PmDevice.GetMfcListByGroupName(MfcGroupName.All)); PmDevice.SetRotationServo(0, 0); } else if (_routineType == RoutineType.PurgeRoutine) { PmDevice._ioThrottleValve.StopRamp(); PmDevice.SetMfcStopRamp(PmDevice.GetMfcListByGroupName(MfcGroupName.All)); PmDevice.SetRotationServo(0, 0); } else if (_routineType == RoutineType.PumpRoutine) { PmDevice.SetRotationServo(0, 0); } else if (_routineType == RoutineType.VentRoutine) { PmDevice._ioThrottleValve.StopRamp(); PmDevice.SetMfcStopRamp(PmDevice.GetMfcListByGroupName(MfcGroupName.All)); PmDevice.SetRotationServo(0, 0); } else if (_routineType == RoutineType.ExchangeMORoutine) { PmDevice.SetIoValue(_lstGroup1, false); PmDevice.SetIoValue(_lstGroup2, false); PmDevice.SetMfcValueToDefault(new List { mfc7Or10 }); PmDevice.SetMfcValueToDefault(new List { mfc8Or12 }); PmDevice.SetMfcValueToDefault(new List { mfc11 }); PmDevice.SetPCValueToDefault(new List { pc2Or3 }); PmDevice.SetRotationServo(0, 0); } else if (_routineType == RoutineType.VacRoutine) { PmDevice.SetRotationServo(0, 0); } } } }