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 System; using System.Collections.Generic; using MECF.Framework.Common.Alarm; 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 MECF.Framework.Common.ToolLayout; using Aitex.Core.Util; namespace CyberX8_RT.Modules.Reservoir { public class StandardHotReservoirInitializeRoutine : RoutineBase, IRoutine { private enum InitializeStep { AutoDiReplen, CellPump, WaitCellPump, WaitRegulatePumpOn, CheckCellFlow, 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 _cellFlowLowLimit; private StandardHotReservoirDevice _reservoirDevice; private ResRecipe _recipe; private CellPowerSupplier _cellPowerSupplier; private TemperatureController _temperatureController; private int _autoHedDelay = 0; private bool _isRegulatePump; private int _cellFlowFaultHoldOffTime = 5000; /// /// 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) .RunIf(InitializeStep.CellPump, !_isRegulatePump,CellsPumpOn, _delay_1ms) .WaitWithStopConditionIf(InitializeStep.WaitCellPump, !_isRegulatePump, CheckPumpOnEndStatus, CheckPumpOnStopStatus) .RunIf(InitializeStep.CellPump, _isRegulatePump, ReservoirPumpOn, _delay_1ms) .WaitIf(InitializeStep.WaitCellPump, _isRegulatePump, CheckRegulatePumpOn,_delay_3m) .DelayIf(InitializeStep.WaitRegulatePumpOn,_isRegulatePump, _cellFlowFaultHoldOffTime) .Run(InitializeStep.CheckCellFlow, CheckCellFlow, _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 && ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).PHProbeType == "Standard", 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, ClearAlarmDataError, _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.OpenPump("", null); } return true; } /// /// Reservoir Pump On /// /// private bool ReservoirPumpOn() { return _reservoirDevice.RegulatePumpOn("",null); } /// /// 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; } } private bool CheckRegulatePumpOn() { bool result = _reservoirDevice.ReservoirData.RegulatePumpSignalIn; return result; } /// /// 检验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.ClosePump("",null); } } /// /// 检验Cell Flow /// /// private bool CheckCellFlow() { double toatalCellFlow = 0; for (int i = 0; i < _metalDevices.Count; i++) { StandardHotMetalDevice hotMetalDevice = _metalDevices[i]; if (hotMetalDevice!=null && hotMetalDevice.MetalDeviceData!=null) { toatalCellFlow += hotMetalDevice.MetalDeviceData.CellFlow; } } if (toatalCellFlow < _cellFlowLowLimit) { LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Cell flow:{toatalCellFlow} is less than config item CellFlowLowLimit:{_cellFlowLowLimit}"); return false; } return true; } /// /// 检验所有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 || ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).CMMType != "Standard") { 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; } /// /// 清除alarm界面相关的dataerror /// private bool ClearAlarmDataError() { AlarmListManager.Instance.RemoveDataError(Module); _reservoirDevice.ClearErrorLogSet(Module); //清除device里面的ErrorLogSet return true; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { List lstDevice = (List)objs[0]; _metalDevices.Clear(); for (int i = 0; i < lstDevice.Count; i++) { _metalDevices.Add((StandardHotMetalDevice)lstDevice[i]); } if (ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).PumpType == "Regulate") { _isRegulatePump = true; } _reservoirDevice = DEVICE.GetDevice(Module.ToString()); _recipe = _reservoirDevice.Recipe; if (!(objs[1] is null)) { _cellPowerSupplier = (CellPowerSupplier)objs[1]; } _temperatureController = (TemperatureController)objs[2]; _cellFlowLowLimit = SC.GetValue($"Reservoir.{Module}.CellFlowLowLimit"); if (!CheckPreCondition()) { return RState.Failed; } if (ReservoirItemManager.Instance.GetReservoirItem(Module.ToString()).CMMType == "Standard") { _cmmFlowHighFault = SC.GetValue($"Reservoir.{Module}.CMMFlowHighFault"); _cmmFlowHighWarning = SC.GetValue($"Reservoir.{Module}.CMMFlowHighWarning"); _cmmFlowLowFault = SC.GetValue($"Reservoir.{Module}.CMMFlowLowFault"); _cmmFlowLowWarning = SC.GetValue($"Reservoir.{Module}.CMMFlowLowWarning"); _cmmFlowCheckDelay = SC.GetValue($"Reservoir.{Module}.CMMFlowCheckDelaySeconds"); } if (_recipe.CMMEnable) { _persistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(Module); } _cellFlowFaultHoldOffTime = SC.GetValue("Metal.CellFlowFaultHoldOffTime"); 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 != null && !_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; } WaterLevelMonitor(); return true; } /// /// WaterLevelMonitor /// private bool WaterLevelMonitor() { ReservoirEntity reservoirEntity = Singleton.Instance.GetModule(Module); //触发水位过高或者过低将reservoir切成error if (_reservoirDevice.ReservoirData.WaterLevel < SC.GetValue($"Reservoir.{Module}.LowLevel")) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"WaterLevel low is Activate"); return false; } else if (_reservoirDevice.ReservoirData.WaterLevel > SC.GetValue($"Reservoir.{Module}.HighLevel")) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"WaterLevel:{_reservoirDevice.ReservoirData.WaterLevel} is larger than HighLevel Config:{SC.GetValue($"Reservoir.{Module}.HighLevel")}"); return false; } //水位触发reservoir里面的high/low将对应的reservoir切成error if (_reservoirDevice.ReservoirData.Level < _recipe.CALevelErrorLow) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Current level:{_reservoirDevice.ReservoirData.Level} is lower than recipe's CA Errorlow paramater:{_recipe.CALevelErrorLow}"); return false; } else if (_reservoirDevice.ReservoirData.Level > _recipe.CALevelErrorHigh) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"Current level:{_reservoirDevice.ReservoirData.Level} is larger than recipe's CA ErrorHigh paramater:{_recipe.CALevelErrorHigh}"); return false ; } return true; } } }