using System; using System.Collections.Generic; using Aitex.Core.RT.Device; using Aitex.Core.RT.Routine; using MECF.Framework.Common.Routine; using CyberX8_Core; using CyberX8_RT.Devices.LinMot; using CyberX8_RT.Devices.Prewet; using MECF.Framework.Common.CommonData.Prewet; using MECF.Framework.Common.CommonData; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Core.RT.Log; using MECF.Framework.Common.RecipeCenter; namespace CyberX8_RT.Modules.Prewet { sealed class CycleManualProcessRecipeRoutine:RoutineBase, IRoutine { private const int LOTTRACK_TIME = 1000; private enum CycleManualRunRecipeStep { LoopStart, LoopRunProcess, LoopWaitRunProcess, LoopDelay, LoopEnd, End } #region 内部变量 private PrewetProcessRoutine _processRecipeRoutine; private LinMotAxis _linmotAxis; private int _cycle = 0; private int _achievedCycle; private object[] param; /// /// Prewet recipe /// private PwtRecipe _recipe; /// /// lock track time /// private DateTime _lotTackTime = DateTime.Now; /// /// LotTrack数据 /// private List _datas = new List(); /// /// LotTrack文件头数据 /// private LotTrackFileHeaderCommonData _header = new LotTrackFileHeaderCommonData(); /// /// 设备对象 /// private PrewetDevice _prewetDevice; #endregion #region 属性 /// /// 当前执行到循环哪一步 /// public string CurrentStatus { get { return Runner.CurrentStep.ToString(); ; } } /// /// 当前执行到循环哪一步内的哪个动作 /// public string CurrentStateMachine { get { return _processRecipeRoutine.CurrentStep; } } /// /// LotTrack数据 /// public List PrewetLotTrackDatas { get { return _datas; } } /// /// LotTrack文件头数据 /// public LotTrackFileHeaderCommonData PrewetLotTrackHeaderDatas { get { return _header; } } #endregion /// /// 构造函数 /// /// public CycleManualProcessRecipeRoutine(string module, LinMotAxis linMotAxis) : base(module) { _linmotAxis = linMotAxis; _processRecipeRoutine = new PrewetProcessRoutine(module, _linmotAxis); } /// /// Abort /// public void Abort() { _processRecipeRoutine.Abort(); Runner.Stop("Cycle ManualRunRecipe Abort"); } public RState Start(params object[] objs) { _cycle = (int)objs[1]; _achievedCycle = 0; param = objs; _prewetDevice = DEVICE.GetDevice(Module); _datas.Clear(); _recipe = objs[0] as PwtRecipe; if (_recipe == null) { LOG.WriteLog(eEvent.ERR_PREWET, 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}.pwt.rcp"; //lotTract记录SequenceRecipe PrewetEntity prewetEntity = Singleton.Instance.GetModule(Module); if (prewetEntity.WaferHolderInfo != null && prewetEntity.WaferHolderInfo.SequenceRecipe != null && !string.IsNullOrEmpty(prewetEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString())) { _header.SequenceRecipe = prewetEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString(); _header.ProcessTransferList = new List(); _header.ProcessTransferList.AddRange(prewetEntity.WaferHolderInfo.SchedulerModules); prewetEntity.WaferHolderInfo.SchedulerModules.Clear(); } _lotTackTime = DateTime.Now; return Runner.Start(Module, "Start 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() { PrewetLotTrackData data = new PrewetLotTrackData(); data.TimeStamp = DateTime.Now; data.StateMachine = CurrentStateMachine; data.Pressure = _prewetDevice.PrewetPumpData.PumpPressureData.Value; data.Flow = _prewetDevice.PrewetPumpData.PumpFlowData.Value; data.PumpMode = _prewetDevice.PrewetPumpData.PumpModel; data.PressureTarget = _prewetDevice.PrewetPumpData.PressureTarget; data.CurrentScan = _linmotAxis.ScanCount; data.ScanOn = _linmotAxis.IsMotorOn; data.ValveState = _prewetDevice.PrewetPumpData.PumpValve; data.PumpSpeed = _prewetDevice.LastPumpSpeed; data.PumpControlCurrent = _prewetDevice.PrewetPumpData.PumpCurrent; _datas.Add(data); } } }