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");
}
}
}