using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using MECF.Framework.Common.Beckhoff.AxisProvider; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.ToolLayout; using MECF.Framework.Common.Utilities; using PunkHPX8_Core; using PunkHPX8_RT.Devices.AXIS; using PunkHPX8_RT.Devices.Facilities; using PunkHPX8_RT.Devices.PlatingCell; using PunkHPX8_RT.Modules.Reservoir; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Modules.PlatingCell { public class PlatingCellRunRecipeRoutine : RoutineBase, IRoutine { private enum RunRecipeStep { Delay, InterRinse, CheckInterRinse, Vertical, CheckVertical, End } #region 常量 private const int ALL_DAY_MILLOSECONDS = 24 * 60 * 60 * 1000; #endregion #region 内部变量 /// /// recipe /// private DepRecipe _recipe; /// /// Platingcell device /// private PlatingCellDevice _device; /// /// Rotation axis /// private JetAxisBase _rotationAxis; /// ///rotation Provider对象 /// private BeckhoffProviderAxis _rotationProviderAxis; /// cycle次数 /// private int _cycle; /// /// 当前完成的Cycle次数 /// private int _currentCycle; /// /// platingcell entity /// private PlatingCellEntity _platingCellEntity; /// /// 对应reservoir entity /// private ReservoirEntity _reservoirEntity; /// /// interbal rinse routien /// private PlatingCellInterRinseRoutine _interRinseRoutine; /// /// vertical axis entity /// private PlatingCellVerticalEntity _verticalEntity; #endregion /// /// 构造函数 /// /// public PlatingCellRunRecipeRoutine(string module) : base(module) { _interRinseRoutine = new PlatingCellInterRinseRoutine(module); } /// /// 中止 /// public void Abort() { Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.Delay(RunRecipeStep.Delay, 5000) .RunIf(RunRecipeStep.InterRinse, _recipe.RinseBeforeEntryEnable,() => { return _interRinseRoutine.Start(_recipe,_rotationAxis, _device, _rotationProviderAxis) == RState.Running; }) .WaitWithStopConditionIf(RunRecipeStep.CheckInterRinse, _recipe.RinseBeforeEntryEnable,CheckInterRinseEndStatus, () => CommonFunction.CheckRoutineStopState(_interRinseRoutine)) .Run(RunRecipeStep.Vertical, StartVertical) .WaitWithStopCondition(RunRecipeStep.CheckVertical, CheckVerticalEnd, CheckVerticalError) .End(RunRecipeStep.End, NullFun); return Runner.Status; } private bool CheckInterRinseEndStatus() { bool result = CommonFunction.CheckRoutineEndState(_interRinseRoutine); SubRoutineStep = _interRinseRoutine.CurrentStep; return result; } /// /// 垂直电机运行(仅示例只做参考) /// /// private bool StartVertical() { double position = 101; return _verticalEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL, Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, position); } /// /// 检验垂直电机是否运动完成 /// /// private bool CheckVerticalEnd() { return _verticalEntity.IsIdle; } /// /// 检验垂直是否出现错误 /// /// private bool CheckVerticalError() { return _verticalEntity.IsError; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _recipe = objs[0] as DepRecipe; if (_recipe == null) { LOG.WriteLog(eEvent.ERR_METAL, Module, "recipe is null"); return RState.Failed; } if (objs.Length > 1) { _cycle = (int)objs[1]; } _device = DEVICE.GetDevice(Module); _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); _rotationProviderAxis = BeckhoffAxisProviderManager.Instance.GetAxisProvider($"{Module}.Rotation"); if (_rotationProviderAxis == null) { NotifyError(eEvent.ERR_PLATINGCELL, $"{Module}.Rotation Provider is not exist", 0); return RState.Failed; } //获取vertical entity string vertical = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module); _verticalEntity = Singleton.Instance.GetModule(vertical); //获取platingcell eneity _platingCellEntity = Singleton.Instance.GetModule(Module); //获取对应reservoir eneity string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module); _reservoirEntity = Singleton.Instance.GetModule(reservoir); if (!CheckPreCondition()) { return RState.Failed; } _currentCycle = 0; return Runner.Start(Module, "Run Recipe"); } /// /// 检验前置条件 /// /// private bool CheckPreCondition() { if (_recipe == null) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Recipe is null"); return false; } //if (_recipe.DepSteps.Count == 0) //{ // LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Recipe DepSteps count is 0"); // return false; //} CheckAxisHome(); CheckFacility(); CheckModuleAndReservoir(); return true; } private bool CheckModuleAndReservoir() { if (!_platingCellEntity.IsIdle) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{Module} is not initialized"); return false; } if (!_reservoirEntity.IsIdle) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"Releated reseroivr is not initialized"); return false; } if (!_reservoirEntity.TemperatureReached) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"Releated reseroivr temperature is not reached"); return false; } if ("Manual".Equals(_reservoirEntity.PersistentValue.OperatingMode) && !WaferManager.Instance.CheckHasWafer(Module, 0)) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"Run recipe in manual must has wafer!"); return false; } return true; } /// /// 检查马达是否上电且home /// /// private bool CheckAxisHome() { if (!_rotationAxis.IsSwitchOn) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Rotation Axis is off"); return false; } if (!_rotationAxis.IsHomed) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Rotation Axis is not home"); return false; } if (!_verticalEntity.IsIdle) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical Axis is not home"); return false; } return true; } /// /// 检查facility /// /// private bool CheckFacility() { SystemFacilities systemFacilities = DEVICE.GetDevice("System.Facilities"); if (systemFacilities == null) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Facility is null"); return false; } if (!systemFacilities.CDAEnable) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Facility CDA is off"); return false; } if (!systemFacilities.N2Enable) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Facility N2 is off"); return false; } if (!systemFacilities.DIFillEnable) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Facility DIW is off"); return false; } if (systemFacilities.FacilitiesDataDic["CDA1Pressure"].IsError || systemFacilities.FacilitiesDataDic["CDA2Pressure"].IsError) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Facility CDA Data is in errro range"); return false; } if (systemFacilities.FacilitiesDataDic["Nitrogen1APressure"].IsError || systemFacilities.FacilitiesDataDic["Nitrogen1BPressure"].IsError || systemFacilities.FacilitiesDataDic["Nitrogen2APressure"].IsError || systemFacilities.FacilitiesDataDic["Nitrogen2BPressure"].IsError) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Facility N2 Data is in errro range"); return false; } if (systemFacilities.FacilitiesDataDic["DiWaterPressure"].IsError) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Facility Diw Pressure value is in errro range"); return false; } return true; } } }