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 MECF.Framework.Common.ToolLayout; using PunkHPX8_Core; using PunkHPX8_RT.Devices.AXIS; using PunkHPX8_RT.Devices.PlatingCell; using PunkHPX8_RT.Devices.Reservoir; using System; using System.Collections.Generic; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media.Imaging; namespace PunkHPX8_RT.Modules.PlatingCell { public class PlatingCellInitializeRoutine : RoutineBase, IRoutine { private enum InitializeStep { CheckPowerSupplierConnected, CheckClamShellClosed, VerticalGotoLoad, VerticalGotoLoadCheck, RotationHome, RotationHomeCheck, AngleEntryTilt, AngleEntryVertical, CheckClamShellOpen, OpenCAAndANIsoltaionValve, CheckCellFlowWait, CheckCellFlow, OpenCCRAndRinseValve, RinseDripIdleDelay, CloseCCRAndRinseValve, End } #region 内部变量 /// /// 持久化对象 /// private PlatingCellPersistentValue _persistentValue; /// /// 设备对象 /// private PlatingCellDevice _platingCellDevice; /// /// 槽体对象 /// private ReservoirDevice _reservoirDevice; /// /// Reservoir Recipe /// private ResRecipe _resRecipe; /// /// vertical axis /// private JetAxisBase _verticalAxis; /// /// Rotation axis /// private JetAxisBase _rotationAxis; /// /// _flowFaultHoldOffTime 单位ms /// private int _flowFaultHoldOffTime = 1000; /// /// Cell Flow Start Low Limit /// private double _cellFlowStartLowLimit = 3.0; /// /// Anode flow start low limit /// private double _anFlowStartLowLimit = 0.5; /// /// Rinse Drip Idle Period /// private int _rinseDripIdlePeriod = 1000; #endregion /// /// 构造函数 /// /// public PlatingCellInitializeRoutine(string module) : base(module) { } /// /// 中止 /// public void Abort() { Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.Run(InitializeStep.CheckPowerSupplierConnected, CheckPowerSupplierStatus, _delay_1ms) .Run(InitializeStep.CheckClamShellClosed, () => _platingCellDevice.ClamShellClose(), CheckClamShellClosed, _delay_1ms) .Run(InitializeStep.VerticalGotoLoad, VerticalGotoLoad, NullFun, 100) .WaitWithStopCondition(InitializeStep.VerticalGotoLoadCheck, CheckVerticalPositionStatus, CheckVerticalPositionRunStop) .Run(InitializeStep.RotationHome, RotationGotoHome, NullFun, 100) .WaitWithStopCondition(InitializeStep.RotationHomeCheck, CheckRotationPositionStatus, CheckRotationPositionRunStop) .Run(InitializeStep.AngleEntryTilt, () => _platingCellDevice.HeadtTiltAction(), CheckAngleTilt, _delay_1ms) .Run(InitializeStep.AngleEntryVertical, () => _platingCellDevice.HeadtVerticalAction(), CheckAngleVertical, _delay_1ms) .Run(InitializeStep.CheckClamShellClosed, () => _platingCellDevice.ClamShellOpen(), CheckClamShellOpen, _delay_1ms) .Run(InitializeStep.OpenCAAndANIsoltaionValve, OpenReservoirIsolationValve,_delay_1ms) .Delay(InitializeStep.CheckCellFlowWait, _flowFaultHoldOffTime) .Run(InitializeStep.CheckCellFlow, CheckCellFlow, _delay_1ms) .Run(InitializeStep.OpenCCRAndRinseValve, OpenCCRAndRinseValve, _delay_1ms) .Delay(InitializeStep.RinseDripIdleDelay, _rinseDripIdlePeriod) .Run(InitializeStep.CloseCCRAndRinseValve, CloseCCRAndRinseValve, _delay_1ms) .End(InitializeStep.End, NullFun, _delay_1ms); return Runner.Status; } /// /// 检查cell flow /// /// private bool CheckCellFlow() { if ("Manual".Equals(_persistentValue.OperatingMode)) { if(_reservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"CA flow{_reservoirDevice.ReservoirData.CaFlow} is lower than cellFlowStartLowLimit{_cellFlowStartLowLimit}"); _reservoirDevice.CAIsolationOff(); return false; } if (_reservoirDevice.ReservoirData.AnFlow < _anFlowStartLowLimit) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"AN flow{_reservoirDevice.ReservoirData.AnFlow} is lower than cellFlowStartLowLimit{_anFlowStartLowLimit}"); _reservoirDevice.ANIsolationOff(); return false; } } else { if (_reservoirDevice.ReservoirData.CaFlow < _resRecipe.CAFlowRateErrorLow) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"CA flow{_reservoirDevice.ReservoirData.CaFlow} is lower than resRecipe CAFlowRateErrorLow{_resRecipe.CAFlowRateErrorLow}"); return false; } if (_reservoirDevice.ReservoirData.AnFlow < _resRecipe.ANFlowRateErrorLow) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"AN flow{_reservoirDevice.ReservoirData.AnFlow} is lower than resRecipe ANFlowRateErrorLow{_resRecipe.ANFlowRateErrorLow}"); return false; } } return true; } /// /// 打开reservoir Isolation valve /// /// private bool OpenReservoirIsolationValve() { return _reservoirDevice.ANIsolationOn() && _reservoirDevice.ANIsolationOn(); } /// /// 打开CCR/Rinse valve /// /// private bool OpenCCRAndRinseValve() { return _platingCellDevice.CCREnableAction() && _platingCellDevice.RinseEnableAction(); } /// /// 关闭CCR/Rinse valve /// /// private bool CloseCCRAndRinseValve() { return _platingCellDevice.CCRDisableAction() && _platingCellDevice.RinseDisableAction(); } /// /// vertical 运动到Load位置 /// /// private bool VerticalGotoLoad() { if(_verticalAxis != null ) { if (!_verticalAxis.IsSwitchOn) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical is not Power On"); return false; } else if (!_verticalAxis.IsHomed) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical is not Home,Home vertical first"); return false; } return _verticalAxis.PositionStation("Load", true); } else { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "vertical axis is null"); return false; } } /// /// vertical 运动到Load位置 /// /// private bool RotationGotoHome() { if (_rotationAxis != null) { if (!_rotationAxis.IsSwitchOn) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Roation is not Power On"); return false; } else if (!_rotationAxis.IsHomed) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Rotation is not Home,Home Rotation first"); return false; } return _rotationAxis.PositionStation("Home", true); } else { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Rotation axis is null"); return false; } } /// /// 检查ClamShell是否closed /// /// private bool CheckClamShellClosed() { return _platingCellDevice.PlatingCellDeviceData.ClamShellClose; } /// /// 检查ClamShell是否Open /// /// private bool CheckClamShellOpen() { return !_platingCellDevice.PlatingCellDeviceData.ClamShellClose; } /// /// 检查Angle是否Tilt /// /// private bool CheckAngleTilt() { return _platingCellDevice.PlatingCellDeviceData.HeadTilt; } /// /// 检查Angle是否Vertical /// /// private bool CheckAngleVertical() { return !_platingCellDevice.PlatingCellDeviceData.HeadTilt; } /// /// 检验Metal A/B 面PowerSupplier通讯状况 /// /// private bool CheckPowerSupplierStatus() { if (!_platingCellDevice.PowerSupplier.IsConnected) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "power is not connected"); return false; } return true; } /// /// 检验Vertical移动状态 /// /// private bool CheckVerticalPositionStatus() { return _verticalAxis.Status == RState.End; } /// /// 检验Vertical是否还在运动 /// /// private bool CheckVerticalPositionRunStop() { return _verticalAxis.Status == RState.Failed; } /// /// 检验Rotation移动状态 /// /// private bool CheckRotationPositionStatus() { return _rotationAxis.Status == RState.End; } /// /// 检验Rotaion是否还在运动 /// /// private bool CheckRotationPositionRunStop() { return _rotationAxis.Status == RState.Failed; } /// /// 获取Reservoir设备 /// /// private ReservoirDevice GetReservoirDevice() { string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString()); return DEVICE.GetDevice(reservoir); } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _persistentValue = (PlatingCellPersistentValue)objs[0]; _platingCellDevice = DEVICE.GetDevice(Module); _reservoirDevice = GetReservoirDevice(); _flowFaultHoldOffTime = SC.GetValue("PlatingCell.FlowFaultHoldOffTime"); _rinseDripIdlePeriod = SC.GetValue("PlatingCell.RinseDripIdlePeriod"); _cellFlowStartLowLimit = SC.GetValue("PlatingCell.CellFlowStartLowLimit"); _anFlowStartLowLimit = SC.GetValue("PlatingCell.ANFlowStartLowLimit"); if("PlatingCell1".Equals(Module) || "PlatingCell2".Equals(Module)) { _verticalAxis = DEVICE.GetDevice("PlatingCell1_2.Vertical"); } else { _verticalAxis = DEVICE.GetDevice("PlatingCell3_4.Vertical"); } _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString()); ReservoirDevice reservoirDevice = DEVICE.GetDevice(reservoir); if (reservoirDevice == null) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{reservoir} device is null"); return RState.Failed; } if (reservoirDevice.Recipe == null) { LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{reservoir} current recipe is null"); return RState.Failed; } _resRecipe = reservoirDevice.Recipe; return Runner.Start(Module, "Start Reservoir Initialize"); } } }