using Aitex.Core.RT.Device; using Aitex.Core.RT.Routine; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using CyberX8_Core; using CyberX8_RT.Devices.Rinse; using System; using System.Collections.Generic; using MECF.Framework.Common.Utilities; using Aitex.Core.RT.Log; using MECF.Framework.Common.CommonData.Rinse; using CyberX8_RT.Devices.Resistivity; using MECF.Framework.Common.CommonData; using Aitex.Core.Util; using CyberX8_RT.Devices.Facilities; using Aitex.Core.RT.SCCore; namespace CyberX8_RT.Modules.Rinse { sealed class RinseCycleManualProcessRecipeRoutine : RoutineBase,IRoutine { private const int LOTTRACK_TIME = 1000; private const string DI_WATER_PRESSURE_VALUE = "DiWaterPressure"; private enum CycleManualRunRecipeStep { LoopStart, LoopRunFirstStep, LoopWaitRunFirstStepProcess, LoopFirstStepDelay, LoopRunSecondStep, LoopWaitRunSecondStepProcess, LoopSecondStepDelay, LoopRunThirdStep, LoopWaitRunThirdStepProcess, LoopThirdStepDelay, LoopEnd, ProcessComplete } #region 内部变量 private RinseFirstStepRoutine _rinseFirstStepRoutine; private RinseSecondStepRoutine _rinseSecondStepRoutine; private RinseThirdStepRoutine _rinseThirdStepRoutine; private int _cycle = 0; private int _achievedCycle; private object[] param; /// /// 设备对象 /// private RinseDevice _device; /// /// Recipe /// private QdrRecipe _recipe; /// /// 当前执行到哪一步的显示 /// private string _currentStateMachine; /// /// lock track time /// private DateTime _lotTackTime = DateTime.Now; /// /// LotTrack数据 /// private List _datas = new List(); /// /// LotTrack文件头数据 /// private LotTrackFileHeaderCommonData _header = new LotTrackFileHeaderCommonData(); /// /// Facilities /// private SystemFacilities _facilities; #endregion #region 属性 /// /// LotTrack数据 /// public List RinseLotTrackDatas { get { return _datas; } } /// /// LotTrack文件头数据 /// public LotTrackFileHeaderCommonData RinseLotTrackHeaderDatas { get { return _header; } } #endregion /// /// 构造函数 /// /// public RinseCycleManualProcessRecipeRoutine(string module) : base(module) { _rinseFirstStepRoutine = new RinseFirstStepRoutine(module); _rinseSecondStepRoutine = new RinseSecondStepRoutine(module); _rinseThirdStepRoutine = new RinseThirdStepRoutine(module); } /// /// Start 参数包括cycle和recipe /// public RState Start(params object[] objs) { //清除lotTrack数据 _datas.Clear(); _device = DEVICE.GetDevice(Module); _recipe = objs[0] as QdrRecipe; if (_recipe == null) { NotifyError(eEvent.ERR_RINSE, "recipe is null",-1); return RState.Failed; } _cycle = (int)objs[1]; _achievedCycle = 0; param = objs; if (SC.ContainsItem("System.ToolID")) _header.ToolID = SC.GetStringValue("System.ToolID"); _header.SoftWareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); _header.Recipe = $"{_recipe.Ppid}.qdr.rcp"; //lotTract记录SequenceRecipe RinseEntity rinseEntity = Singleton.Instance.GetModule(Module); if (rinseEntity.WaferHolderInfo != null && rinseEntity.WaferHolderInfo.SequenceRecipe != null && !String.IsNullOrEmpty(rinseEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString())) { _header.SequenceRecipe = rinseEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString(); _header.ProcessTransferList = new List(); _header.ProcessTransferList.AddRange(rinseEntity.WaferHolderInfo.SchedulerModules); rinseEntity.WaferHolderInfo.SchedulerModules.Clear(); } _facilities = DEVICE.GetDevice("System.Facilities"); if(_facilities == null) { LOG.WriteLog(eEvent.ERR_RINSE, Module, "Facility is null"); return RState.Failed; } _lotTackTime = DateTime.Now; return Runner.Start(Module, "Start cycle ManualRunRecipe"); } /// /// Monitor /// /// public RState Monitor() { _currentStateMachine = Runner.CurrentStep.ToString(); _device.UpdateStatus(_currentStateMachine); LottrackRecord(); Runner.LoopStart(CycleManualRunRecipeStep.LoopStart, "Loop Start ManualRunRecipe", _cycle, NullFun, _delay_1ms) .LoopRun(CycleManualRunRecipeStep.LoopRunFirstStep, () => _rinseFirstStepRoutine.Start(param) == RState.Running, _delay_1ms) .LoopRunWithStopStatus(CycleManualRunRecipeStep.LoopWaitRunFirstStepProcess, () => CommonFunction.CheckRoutineEndState(_rinseFirstStepRoutine), () => { return CheckRoutineStopStatus(_rinseFirstStepRoutine, _rinseFirstStepRoutine.ErrorMsg, 0); }) .LoopDelay(CycleManualRunRecipeStep.LoopFirstStepDelay, _delay_1ms) .LoopRun(CycleManualRunRecipeStep.LoopRunSecondStep, () => _rinseSecondStepRoutine.Start(param) == RState.Running, _delay_1ms) .LoopRunWithStopStatus(CycleManualRunRecipeStep.LoopWaitRunSecondStepProcess, () => CommonFunction.CheckRoutineEndState(_rinseSecondStepRoutine), () => { return CheckRoutineStopStatus(_rinseSecondStepRoutine, _rinseSecondStepRoutine.ErrorMsg, 0); }) .LoopDelay(CycleManualRunRecipeStep.LoopSecondStepDelay, _delay_1ms) .LoopRunIf(CycleManualRunRecipeStep.LoopRunThirdStep, _recipe.FinalRinseDry == true, () => _rinseThirdStepRoutine.Start(param) == RState.Running, _delay_1ms) .LoopRunIfWithStopStatus(CycleManualRunRecipeStep.LoopWaitRunThirdStepProcess, _recipe.FinalRinseDry == true, () => CommonFunction.CheckRoutineEndState(_rinseThirdStepRoutine), () => { return CheckRoutineStopStatus(_rinseThirdStepRoutine, _rinseThirdStepRoutine.ErrorMsg, 0); }) .LoopRunIf(CycleManualRunRecipeStep.LoopThirdStepDelay, _recipe.FinalRinseDry == true, NullFun, _delay_1ms) .LoopEnd(CycleManualRunRecipeStep.LoopEnd, AchievedCycleCount, _delay_1ms) .End(CycleManualRunRecipeStep.ProcessComplete, NullFun, _delay_1ms); return Runner.Status; } /// /// 检验Routine停止状态 /// /// /// /// /// private bool CheckRoutineStopStatus(IRoutine routine,string error,int index) { bool result=CommonFunction.CheckRoutineStopState(routine); if (result) { AddLotTrackData(); NotifyError(eEvent.ERR_RINSE, error, 0); } return result; } /// /// 记录Lottrack /// private void LottrackRecord() { //记录Lottrack if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME) { AddLotTrackData(); _lotTackTime = DateTime.Now; } } /// /// 获取Lot Track数据 /// /// private void AddLotTrackData() { RinseLotTrackData data = new RinseLotTrackData(); data.TimeStamp = DateTime.Now; data.StateMachine = _device.CurrentStateMachine; data.WaterLevel = _device.RinseData.WaterLevel; data.DIFillEnabled = _device.RinseData.FillValve; data.DumpEnabled = _device.RinseData.DrainValve; data.WaterPressure = _facilities.GetCommonLimitDataByName(DI_WATER_PRESSURE_VALUE).Value; ResistivityController resistivityController = DEVICE.GetDevice(_device.RinseItem.ResistivityID); if (resistivityController != null) { try { data.Resistivity = double.Parse(resistivityController.ResisitivityValue.Trim()); } catch { data.Resistivity = 0; } } _datas.Add(data); } /// /// 统计完成的Cycle次数 /// /// private bool AchievedCycleCount() { _achievedCycle += 1; return true; } /// /// 释放定时器 /// /// private bool DisposeTimer() { return true; } /// /// 获取已经完成的Cycle次数 /// /// public int GetAchievedCycle() { return _achievedCycle; } /// /// Abort /// public void Abort() { if (_device != null) { _device.N2ValveOff(); _device.FillValveOff(); } Runner.Stop("Cycle ManualRunRecipe Abort"); } /// /// 重试 /// /// public RState Retry(int step) { if (_recipe == null) { NotifyError(eEvent.ERR_RINSE, "recipe is null",-1); return RState.Failed; } List preStepIds = new List(); return Runner.Retry(CycleManualRunRecipeStep.LoopStart, preStepIds, Module, "Runrecipe Retry"); } } }