using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.Persistent.Reservoirs; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using CyberX8_Core; using CyberX8_RT.Devices.Facilities; using CyberX8_RT.Devices.Metal; using CyberX8_RT.Devices.PowerSupplier; using CyberX8_RT.Devices.Reservoir; using CyberX8_RT.Devices.Temperature; using System; using System.Collections.Generic; namespace CyberX8_RT.Modules.Reservoir { public class StandardHotReservoirInitializeRoutine : RoutineBase, IRoutine { private enum InitializeStep { AutoDiReplen, CellPump, WaitCellPump, CheckHedFlow, ManualCellByPass, AutoCellManual, AutoEnableCMM, AutoEnableCMMWait, AutoCMMFlowDelay, AutoCMMFlowCheck, AutoPHDetect, AutoCellAutoFlow, AutoCellAutoFlowDelay, AutoCellAutoFlowCheck, AutoCellAutoEnableHED, AutoCellAutoEnableHEDDelay, AutoCellAutoEnableHEDCheck, AutoCellAutoCheckPowerSupplier, AutoCellAutoLinmotReset, AutoCellAutoLinmotResetCheck, CellWSUnclamp, End } #region 常量 private const string AUTO = "Auto"; private const string MANUAL = "Manual"; private const int ENABLE = 5; #endregion #region 内部变量 List _metalDevices = new List(); private double _hedFlowLowLimit; private StandardHotReservoirDevice _reservoirDevice; private ResRecipe _recipe; private CellPowerSupplier _cellPowerSupplier; private TemperatureController _temperatureController; private int _autoHedDelay = 0; /// /// CMM Check Flow延时 /// private int _cmmFlowCheckDelay = 6; /// /// CMM Flow High Fault /// private double _cmmFlowHighFault; /// /// CMM Flow High Warning /// private double _cmmFlowHighWarning; /// /// CMM Flow High Warning /// private double _cmmFlowLowFault; /// /// CMM Flow High Warning /// private double _cmmFlowLowWarning; /// /// Reservoir Persistent /// private ReservoirsPersistentValue _persistentValue; #endregion /// /// 构造函数 /// /// public StandardHotReservoirInitializeRoutine(string module) : base(module) { } /// /// 中止 /// public void Abort() { Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { //Cell Pump Runner.RunIf(InitializeStep.AutoDiReplen, _recipe.DIReplenEnable, CheckFacilitiesDiReplenStatus, _delay_1ms) .Run(InitializeStep.CellPump, CellsPumpOn, _delay_1ms) .WaitWithStopCondition(InitializeStep.WaitCellPump, CheckPumpOnEndStatus, CheckPumpOnStopStatus) .Run(InitializeStep.CheckHedFlow, CheckHedFlow, _delay_1ms) //Manual cell Bypass同时disable HED .RunIf(InitializeStep.ManualCellByPass, _reservoirDevice.OperationMode == MANUAL, CellsByPassEnableHed, _delay_1ms) //Auto 所有metal 处于Manual, cell Bypass,Enable HED,设置温度 .RunIf(InitializeStep.AutoCellManual, CheckAutoAndAllMetalManual(), AutoCellManualByPassEnableHed, CheckCellManualByPassAndTemperature, _delay_2s) //Auto 同时recipe enable cmm,并检测CMM Flow .RunIf(InitializeStep.AutoEnableCMM, CheckAutoEnableCMM(), AutoEnableCMM, _delay_1ms) .WaitWithStopConditionIf(InitializeStep.AutoEnableCMMWait, CheckAutoEnableCMM(), () => { return _cellPowerSupplier.Status == RState.End; } , () => { return _cellPowerSupplier.Status == RState.Failed; }, _delay_5s) .DelayIf(InitializeStep.AutoCMMFlowDelay, CheckAutoEnableCMM(), _cmmFlowCheckDelay * 1000) .RunIf(InitializeStep.AutoCMMFlowCheck, CheckAutoEnableCMM(), CheckCMMTargetFlow, _delay_1ms) //Auto 启动PH检测 .RunIf(InitializeStep.AutoPHDetect,_reservoirDevice.OperationMode==AUTO,StartAutoPHDetect,_delay_1ms) //Auto Cell Flow .Run(InitializeStep.AutoCellAutoFlow,AllMetalSwitchFlow,_delay_1ms) .Delay(InitializeStep.AutoCellAutoFlowDelay, 500) .Run(InitializeStep.AutoCellAutoFlowCheck, AllMetalCheckFlow,_delay_1ms) //Auto HED .Run(InitializeStep.AutoCellAutoEnableHED, AutoHedOn, _delay_1ms) .Delay(InitializeStep.AutoCellAutoEnableHEDDelay,_autoHedDelay) .Run(InitializeStep.AutoCellAutoEnableHEDCheck, AutoHedSuccess, _delay_1ms) //检验PowerSupplier通信 .Run(InitializeStep.AutoCellAutoCheckPowerSupplier, AutoMetalsPowerSupplierCommuncationStatus, _delay_1ms) //Cell Linmot Reset .RunIf(InitializeStep.AutoCellAutoLinmotReset,_reservoirDevice.OperationMode==AUTO,AutoMetalResetLinmot,_delay_1ms) .WaitWithStopCondition(InitializeStep.AutoCellAutoLinmotResetCheck, CheckAutoMetalResetStatus, CheckAutoMetalResetStopStatus) //Cell Unclamp .Run(InitializeStep.CellWSUnclamp,MetalsWHUnclampOn,_delay_1ms) .End(InitializeStep.End, NullFun, _delay_1ms); return Runner.Status; } /// /// 检验总Di有没有开 /// /// private bool CheckFacilitiesDiReplenStatus() { SystemFacilities systemFacilities = DEVICE.GetDevice("System.Facilities"); if (systemFacilities != null) { bool result = systemFacilities.DIReplenEnable; if (!result) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Facilities DiReplen is disable"); } return result; } return false; } /// /// Metals Pump On /// /// private bool CellsPumpOn() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; hotMetalDevice.PumpOnOperation("", null); } return true; } /// /// Cell ByPass /// /// private bool CellsByPassEnableHed() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; hotMetalDevice.SwitchToBypass("", null); } _temperatureController.EnableOperation("", null); return true; } /// /// 检验metal Pump /// /// private bool CheckPumpOnEndStatus() { int totalCount = 0; for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice.Status == RState.End) { totalCount++; } } if (totalCount >= _metalDevices.Count) { return true; } else { return false; } } /// /// 检验metal Pump停止状态 /// /// private bool CheckPumpOnStopStatus() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice.Status == RState.Failed) { PumpOffMetals(); return true; } } return false; } /// /// Pump Off All Metals /// private void PumpOffMetals() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; hotMetalDevice.PumpOff(); } } /// /// 检验HED Flow /// /// private bool CheckHedFlow() { double hedFlow = _reservoirDevice.ReservoirData.HedFlow; bool result = hedFlow > _hedFlowLowLimit; if (!result) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"HED Flow {hedFlow} is less than {_hedFlowLowLimit}"); PumpOffMetals(); } return result; } /// /// 检验所有Metal处于Manual /// /// private bool CheckAutoAndAllMetalManual() { if (_reservoirDevice.OperationMode != AUTO) { return false; } for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice.OperationMode != MANUAL) { return false; } } return true; } /// /// Auto 同时Metal均为Manual,Bypass metal,enable HED,设置温度 /// /// private bool AutoCellManualByPassEnableHed() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; hotMetalDevice.SwitchToBypass("", null); } _temperatureController.EnableOperation("", null); _temperatureController.SetTargetTemperatureOperation("", new object[] { _recipe.TemperatureSetPoint }); return true; } /// /// 检验cell By Pass和温度 /// /// private bool CheckCellManualByPassAndTemperature() { for (int i = 0; i<_metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if(hotMetalDevice.MetalDeviceData.Circulation) { return false; } } if(_temperatureController.TemperatureData.ControlOperationModel==0) { return false; } if(Math.Abs(_recipe.TemperatureSetPoint-_temperatureController.TemperatureData.TargetTemperature)>=0.1*_recipe.TemperatureSetPoint) { return false; } return true; } /// /// 检验 Auto ,同时Enable CMM /// /// private bool CheckAutoEnableCMM() { if(_reservoirDevice.OperationMode!=AUTO) { return false; } return _recipe.CMMEnable; } /// /// 自动Enable CMM /// /// private bool AutoEnableCMM() { return _cellPowerSupplier.SetCurrentAndOutput(_recipe.CMMCurrentSetPoint); } /// /// 检验目标Flow是否到达设定值 /// /// private bool CheckCMMTargetFlow() { double flow = _reservoirDevice.ReservoirData.Flow; if(flow < _cmmFlowLowFault) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} CMM flow:{flow} is less than config item CMMFlowLowFault:{_cmmFlowLowFault}"); if (_cellPowerSupplier.PowerSupplierData.Enabled) _cellPowerSupplier.DisableOperation("", null); return false; } else if (flow < _cmmFlowLowWarning) { LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} CMM flow:{flow} is less than config item CMMFlowLowWarning:{_cmmFlowLowWarning}"); } else if (flow > _cmmFlowHighFault) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} CMM flow:{flow} is over config item CMMFlowHighFault:{_cmmFlowLowFault}"); if(_cellPowerSupplier.PowerSupplierData.Enabled) _cellPowerSupplier.DisableOperation("", null); return false; } else if (flow > _cmmFlowHighWarning) { LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} CMM flow:{flow} is over config item CMMFlowHighWarning:{_cmmFlowLowWarning}"); } return true; } /// /// 启动自动检测 /// /// private bool StartAutoPHDetect() { return _reservoirDevice.StartDetectPHValve(); } /// /// 检验所有Metal处于Manual /// /// private bool CheckAutoAndAllMetalAuto() { if (_reservoirDevice.OperationMode != AUTO) { return false; } for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice.OperationMode != AUTO) { return false; } } return true; } /// /// 所有Metal切换Flow /// /// private bool AllMetalSwitchFlow() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice != null && !hotMetalDevice.IsDisable&&hotMetalDevice.IsAuto) { bool result = hotMetalDevice.SwitchToFlow("", null); if (!result) { return false; } } } return true; } /// /// 检验所有Metal Flow检验 /// /// private bool AllMetalCheckFlow() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice != null && !hotMetalDevice.IsDisable && hotMetalDevice.IsAuto) { double cellFlow = hotMetalDevice.MetalDeviceData.CellFlow; if (cellFlow <= _recipe.CAFlowRateErrorLow) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"cell {hotMetalDevice.Name} flow {cellFlow} is less than {_recipe.CAFlowRateErrorLow}"); return false; } else if (cellFlow <= _recipe.CAFlowRateWarningLow) { LOG.WriteLog(eEvent.WARN_METAL, Module, $"cell {hotMetalDevice.Name} flow {cellFlow} is less than {_recipe.CAFlowRateWarningLow}"); } } } return true; } /// /// 自动HED On /// /// private bool AutoHedOn() { double hedFlow = _reservoirDevice.ReservoirData.HedFlow; bool result = hedFlow > _hedFlowLowLimit; if (!result) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"HED Flow {hedFlow} is less than {_hedFlowLowLimit}"); return false; } _autoHedDelay = _delay_2s; _temperatureController.EnableOperation("", null); _temperatureController.SetTargetTemperatureOperation("", new object[] { _recipe.TemperatureSetPoint }); return true; } /// /// 检验Hed是否成功 /// /// private bool AutoHedSuccess() { if (_temperatureController.TemperatureData.ControlOperationModel == 0) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature control is disable"); return false; } if (Math.Abs(_recipe.TemperatureSetPoint - _temperatureController.TemperatureData.TargetTemperature) >= 0.1 * _recipe.TemperatureSetPoint) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"recipe temperature {_recipe.TemperatureSetPoint} is not match temperature target point {_temperatureController.TemperatureData.TargetTemperature}"); return false; } return true; } /// /// 检验Metal A/B PowerSupplier通信状态 /// /// private bool AutoMetalsPowerSupplierCommuncationStatus() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (!hotMetalDevice.IsDisable && hotMetalDevice.IsAuto) { if (hotMetalDevice.SideAPowerSupplier == null) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side A PowerSupplier is null"); return false; } if (hotMetalDevice.SideBPowerSupplier == null) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Side B PowerSupplier is null"); return false; } if (!hotMetalDevice.SideAPowerSupplier.IsConnected) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side A PowerSupplier {hotMetalDevice.SideAPowerSupplier.Name} is not connected"); return false; } if (!hotMetalDevice.SideBPowerSupplier.IsConnected) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Side B PowerSupplier {hotMetalDevice.SideBPowerSupplier.Name} is not connected"); return false; } } } return true; } /// /// Auto Metal reset linmot /// /// private bool AutoMetalResetLinmot() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if(hotMetalDevice.OperationMode==AUTO) { bool result= hotMetalDevice.ResetLinmot(); if(!result) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Reset linmot error"); return false; } } } return true; } /// /// Auto Metal reset linmot /// /// private bool CheckAutoMetalResetStatus() { if(_reservoirDevice.OperationMode == MANUAL) { return true; } for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice.OperationMode == AUTO) { bool result = hotMetalDevice.CheckLinmotRoutineEnd(); if (!result) { return false; } } } return true; } /// /// Auto Metal reset linmot /// /// private bool CheckAutoMetalResetStopStatus() { if (_reservoirDevice.OperationMode == MANUAL) { return false; } for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice.OperationMode == AUTO) { bool result = hotMetalDevice.CheckLinmotRoutineError(); if (result) { return true; } } } return false; } /// Metal WS Unclamp /// /// private bool MetalsWHUnclampOn() { for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; bool result = hotMetalDevice.WaferHolderClampOff("", null); if (!result) { return false; } } return true; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { List lstDevice = (List)objs[0]; _metalDevices.Clear(); for(int i=0;i(Module.ToString()); _recipe=_reservoirDevice.Recipe; if (!(objs[1] is null)) { _cellPowerSupplier = (CellPowerSupplier)objs[1]; } _temperatureController=(TemperatureController)objs[2]; _hedFlowLowLimit = SC.GetValue($"Reservoir.{Module}.HEDFlowLowLimit"); if (!CheckPreCondition()) { return RState.Failed; } _cmmFlowHighFault = SC.GetValue($"Reservoir.CMM.CMMFlowHighFault"); _cmmFlowHighWarning = SC.GetValue($"Reservoir.CMM.CMMFlowHighWarning"); _cmmFlowLowFault = SC.GetValue($"Reservoir.CMM.CMMFlowLowFault"); _cmmFlowLowWarning = SC.GetValue($"Reservoir.CMM.CMMFlowLowWarning"); _cmmFlowCheckDelay = SC.GetValue($"Reservoir.CMM.CMMFlowCheckDelaySeconds"); if (_recipe.CMMEnable) { _persistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(Module); } return Runner.Start(Module, "Start Initialize"); } /// /// 检验前置条件 /// /// private bool CheckPreCondition() { if(_recipe==null) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "recipe is null"); return false; } if(_recipe.CMMEnable&&!_cellPowerSupplier.IsConnected) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "PowerSupplier is not connected"); return false; } if (!_temperatureController.IsConnected) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Temperature is not connected"); return false; } return true; } } }