using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.CommonData.Prewet; using MECF.Framework.Common.CommonData.Vpw; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using PunkHPX8_Core; using PunkHPX8_RT.Devices.LinMot; using PunkHPX8_RT.Devices.VpwCell; using PunkHPX8_RT.Modules.VpwMain; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Modules.VpwCell { public class VpwCycleManualProcessRecipeRoutine : RoutineBase, IRoutine { private const int LOTTRACK_TIME = 1000; private enum CycleManualRunRecipeStep { LoopStart, LoopRunProcess, LoopWaitRunProcess, LoopDelay, LoopEnd, End } #region 内部变量 private VpwManualRecipeRoutine _processRecipeRoutine; private int _cycle = 0; private int _achievedCycle; private object[] param; /// /// Vpw recipe /// private VpwRecipe _recipe; /// /// lock track time /// private DateTime _lotTackTime = DateTime.Now; /// /// LotTrack数据 /// private List _datas = new List(); /// /// LotTrack文件头数据 /// private LotTrackFileHeaderCommonData _header = new LotTrackFileHeaderCommonData(); /// /// 设备对象 /// private VpwCellDevice _vpwCellDevice; #endregion #region 属性 /// /// 当前执行到循环哪一步 /// public string CurrentStatus { get { return Runner.CurrentStep.ToString(); } } /// /// 当前执行到循环哪一步内的哪个动作 /// public string CurrentStateMachine { get { return _processRecipeRoutine.CurrentStep; } } /// /// LotTrack数据 /// public List VpwLotTrackDatas { get { return _datas; } } /// /// LotTrack文件头数据 /// public LotTrackFileHeaderCommonData VpwLotTrackHeaderDatas { get { return _header; } } #endregion /// /// 构造函数 /// /// public VpwCycleManualProcessRecipeRoutine(string module) : base(module) { _processRecipeRoutine = new VpwManualRecipeRoutine(module); } /// /// Abort /// public void Abort() { _processRecipeRoutine.Abort(); Runner.Stop("Vpw Cycle ManualRunRecipe Abort"); } public RState Start(params object[] objs) { _cycle = (int)objs[1]; _achievedCycle = 0; param = objs; _vpwCellDevice = DEVICE.GetDevice(Module); _datas.Clear(); _recipe = objs[0] as VpwRecipe; if (_recipe == null) { LOG.WriteLog(eEvent.ERR_VPW, Module, "recipe is null"); return RState.Failed; } if (SC.ContainsItem("System.ToolID")) _header.ToolID = SC.GetStringValue("System.ToolID"); _header.SoftWareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); _header.Recipe = $"{_recipe.Ppid}.vpw.rcp"; //lotTract记录SequenceRecipe //VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(Module); //if (vpwCellEntity.WaferHolderInfo != null && vpwCellEntity.WaferHolderInfo.SequenceRecipe != null && !string.IsNullOrEmpty(vpwCellEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString())) //{ // _header.SequenceRecipe = vpwCellEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString(); // _header.ProcessTransferList = new List(); // _header.ProcessTransferList.AddRange(vpwCellEntity.WaferHolderInfo.SchedulerModules); // vpwCellEntity.WaferHolderInfo.SchedulerModules.Clear(); //} _lotTackTime = DateTime.Now; return Runner.Start(Module, "Start Vpw Cycle ManualRunRecipe"); } public RState Monitor() { LottrackRecord(); Runner.LoopStart(CycleManualRunRecipeStep.LoopStart, "Loop Start ManualRunRecipe", _cycle, NullFun, _delay_1ms) .LoopRun(CycleManualRunRecipeStep.LoopRunProcess, () => _processRecipeRoutine.Start(param) == RState.Running, _delay_1ms) .LoopRunWithStopStatus(CycleManualRunRecipeStep.LoopWaitRunProcess, () => CheckRoutineEndStatus(_processRecipeRoutine), () => CheckRoutineStopStatus(_processRecipeRoutine)) .LoopDelay(CycleManualRunRecipeStep.LoopDelay, _delay_1s) .LoopEnd(CycleManualRunRecipeStep.LoopEnd, AchievedCycleCount, _delay_1ms) .End(CycleManualRunRecipeStep.End, NullFun, _delay_1ms); return Runner.Status; } private bool CheckRoutineEndStatus(IRoutine routine) { bool result = routine.Monitor() == RState.End; return result; } private bool CheckRoutineStopStatus(IRoutine routine) { RState state = routine.Monitor(); if (state == RState.Failed || state == RState.Timeout) { AddLotTrackData(); return true; } return false; } /// /// 统计完成的Cycle次数 /// /// private bool AchievedCycleCount() { _achievedCycle += 1; return true; } /// /// 获取已经完成的Cycle次数 /// /// public int GetAchievedCycle() { return _achievedCycle; } /// /// 记录Lottrack /// private void LottrackRecord() { //记录Lottrack if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME) { AddLotTrackData(); _lotTackTime = DateTime.Now; } } /// /// 获取Lot Track数据 /// /// private void AddLotTrackData() { VpwLotTrackData data = new VpwLotTrackData(); data.TimeStamp = DateTime.Now; data.StateMachine = CurrentStateMachine; data.VacuumPressure = _vpwCellDevice.CommonData.VacuumPressure; data.CellFlow = _vpwCellDevice.CommonData.DiwFlow; data.DiwLoopDo = _vpwCellDevice.LoopDOValue; data.WaterPressure = _vpwCellDevice.MainCommonData.DiwPressure; data.DripValve = _vpwCellDevice.CommonData.FlowDrip; data.SmallValve = _vpwCellDevice.CommonData.FlowSmall; data.LargeValve = _vpwCellDevice.CommonData.FlowLarge; data.ChamberClosed = _vpwCellDevice.MainCommonData.ChamberClosed; _datas.Add(data); } } }