using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.VpwCell;
using PunkHPX8_RT.Devices.VpwMain;
using PunkHPX8_RT.Modules.VpwCell;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Modules.VpwMain
{
public class VpwPurgeRoutine : RoutineBase, IRoutine
{
private enum PurgeStep
{
ChameberUp,
SetRotationSpeed,
StartRotation,
CheckRotationRunning,
CloseDiwDegas,
N2PurgeDelay,
CloseN2Purge,
OpenDiwDegas,
FlowDelay,
CheckFlow,
CheckCellFlow,
StopRotation,
CheckStopStatus,
LastHomeRotation,
CheckLastHomeRotation,
CheckFlowOk,
ChamberDown,
LastCheckStatus,
End
}
#region 常量
///
/// 增加额外一分钟
///
private const int PLUS_TIME = 60000;
#endregion
#region 内部变量
///
/// Cell device集合
///
private List _vpwCellDevices = new List();
///
/// Main Device
///
private VpwMainDevice _mainDevice;
///
/// cell集合
///
private List _cellLst = new List();
///
/// N2 Purge时长
///
private int _n2PurgeTime = 15000;
///
/// Flow holder off time
///
private int _flowFaultHolderoffTime = 15000;
///
/// Degas delay时间
///
private int _degasEnableDelayTime = 2000;
///
/// 旋转速度
///
private int _rotationSpeed = 0;
///
/// 总流量起始流量数值
///
private double _totalFlowStartLimit = 2.0;
///
/// Cell起始流量数值
///
private double _cellFlowStartLimit = 2.0;
///
/// total flow合格
///
private bool _totalFlowOk = false;
///
/// cell flow合格集合
///
private Dictionary _cellFlowOk = new Dictionary();
///
/// 检验流量是否ok
///
private bool _checkFlowOk = false;
///
/// 总流量
///
private double _totalFlow = 0;
///
/// Cell注意集合
///
private Dictionary _cellFlows = new Dictionary();
#endregion
///
/// 构造函数
///
///
///
public VpwPurgeRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
Runner.Stop("Purge abort");
}
///
/// 监控
///
///
public RState Monitor()
{
Runner.Run(PurgeStep.ChameberUp, _mainDevice.ChamberUp, CheckChamberClosed, _delay_1s)
.Run(PurgeStep.SetRotationSpeed, SetRotationSpeed, _delay_1s)
.Run(PurgeStep.StartRotation, StartRotation, _delay_1ms)
.Wait(PurgeStep.CheckRotationRunning, CheckRotationRunningStatus, 500)
.Run(PurgeStep.CloseDiwDegas, CloseDiwDegas)
.Delay(PurgeStep.N2PurgeDelay, _n2PurgeTime)
.Run(PurgeStep.CloseN2Purge, _mainDevice.N2PurgeValveOff, _delay_1ms)
.Run(PurgeStep.OpenDiwDegas, OpenDiwDegas, _delay_1ms)
.Delay(PurgeStep.FlowDelay, _flowFaultHolderoffTime)
.Run(PurgeStep.CheckFlow, CheckTotalFlow, _delay_1ms)
.Run(PurgeStep.CheckCellFlow, CheckCellFlow, _delay_1ms)
.Run(PurgeStep.StopRotation, StopRotationAxis, _delay_1ms)
.WaitWithStopCondition(PurgeStep.CheckStopStatus, CheckStopPostionEndStatus, CheckStopPostionStopStatus)
.Run(PurgeStep.LastHomeRotation, HomeAllRotation, _delay_1ms)
.WaitWithStopCondition(PurgeStep.CheckLastHomeRotation, CheckAllRotationHomeStatus, CheckAllRotationHomeStopStatus)
.Run(PurgeStep.CheckFlowOk, CheckFlowOk, _delay_1ms)
.RunIf(PurgeStep.ChamberDown, _checkFlowOk, () => { return _mainDevice.ChamberDown(); },
() => { return !_mainDevice.CommonData.ChamberClosed && _mainDevice.CommonData.ChamberOpened; })
.Run(PurgeStep.LastCheckStatus, LastCheckResult, _delay_1ms)
.End(PurgeStep.End, NullFun, _delay_1ms);
return Runner.Status;
}
///
/// 检验Chamber关闭
///
///
private bool CheckChamberClosed()
{
return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;
}
private bool SetRotationSpeed()
{
bool result = true;
foreach (var item in _cellLst)
{
result &= item.SetRotationSpeed(_rotationSpeed);
}
return result;
}
///
/// 打开所有cell valve
///
///
private bool OpenCellDrainValve()
{
foreach (var device in _cellLst)
{
bool result = device.DrainValveOn();
if (!result)
{
LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{device.Module} open drain valve failed");
CloseCellDrainValve();
return false;
}
}
return true;
}
///
/// 检验Cell Drain状态
///
///
private bool CheckCellDrainValveStatus()
{
foreach (var item in _cellLst)
{
bool result = item.CommonData.DrainValve;
if (!result)
{
LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{item.Module} drain valve is not opened");
CloseCellDrainValve();
return false;
}
}
return true;
}
///
/// 关闭所有cell的Drain valve
///
private void CloseCellDrainValve()
{
foreach (var item in _cellLst)
{
item.DrainValveOff();
}
}
///
/// Home All Rotation
///
///
private bool HomeAllRotation()
{
foreach (var item in _cellLst)
{
bool result = item.HomeRotation();
if (!result)
{
CloseCellDrainValve();
return false;
}
}
return true;
}
///
/// 检验所有Rotation Home成功
///
///
private bool CheckAllRotationHomeStatus()
{
int count = 0;
foreach (var item in _cellLst)
{
bool result = item.CheckHomeEndStatus();
if (result)
{
count++;
}
}
bool success = count == _cellLst.Count;
if (success)
{
foreach (var item in _cellLst)
{
item.SetRotationSpeed(_rotationSpeed);
}
}
return success;
}
///
/// rotation电机 home是否停止
///
///
private bool CheckAllRotationHomeStopStatus()
{
foreach (var item in _cellLst)
{
bool result = item.CheckRotationStopStatus();
if (result)
{
return true;
}
}
return false;
}
///
/// 启动rotation
///
///
private bool StartRotation()
{
int totalTime = (_n2PurgeTime + _flowFaultHolderoffTime+ PLUS_TIME) / 1000;
int targetPsition = _rotationSpeed * totalTime;
foreach (var item in _cellLst)
{
bool result = item.RotationProfilePosition(targetPsition);
if (!result)
{
StopAllRotation();
return false;
}
}
return true;
}
///
/// 检验Rotation是否运动
///
///
private bool CheckRotationRunningStatus()
{
foreach (var item in _cellLst)
{
bool result = item.CheckRotationRunning();
if (!result)
{
StopAllRotation();
return false;
}
}
return true;
}
///
/// 停止所有rotation电机
///
private void StopAllRotation()
{
foreach (var item in _cellLst)
{
item.StopProfilePosition();
}
}
///
/// 关闭DiwDegas等
///
///
private bool CloseDiwDegas()
{
int count = 0;
count += _mainDevice.DiwDegasValveOff() ? 1 : 0;
count += _mainDevice.N2PurgeValveOn() ? 1 : 0;
foreach (var item in _cellLst)
{
count += item.FlowDripOn() ? 1 : 0;
count += item.FlowSmallOn() ? 1 : 0;
count += item.FlowLargeOn() ? 1 : 0;
}
return count == _cellLst.Count * 3 + 2;
}
///
/// 打开DiwDegas
///
///
private bool OpenDiwDegas()
{
return _mainDevice.DiwDegasValveOff();
}
///
/// 检验流量
///
///
private bool CheckTotalFlow()
{
double totalFlow = _mainDevice.CommonData.DiwTotalFlow;
if (totalFlow < _totalFlowStartLimit)
{
_totalFlowOk = false;
}
else
{
_totalFlowOk = true;
}
_totalFlow = totalFlow;
return true;
}
///
/// 检验CellFlow
///
///
private bool CheckCellFlow()
{
foreach (var item in _cellLst)
{
double cellFlow = item.CommonData.DiwFlow;
if (cellFlow < _cellFlowStartLimit)
{
_cellFlowOk[item.Module] = false;
}
else
{
_cellFlowOk[item.Module] = true;
item.FlowSmallOff();
item.FlowLargeOff();
}
_cellFlows[item.Module] = cellFlow;
}
return true;
}
///
/// 停止rotation
///
///
public bool StopRotationAxis()
{
foreach (var item in _cellLst)
{
bool result = item.StopProfilePosition();
if (!result)
{
return false;
}
}
return true;
}
///
/// 检验停止是否完成
///
///
public bool CheckStopPostionEndStatus()
{
foreach (var item in _cellLst)
{
bool result = item.CheckRotationEndStatus();
if (!result)
{
return false;
}
}
return true;
}
///
/// 检验停止失败状态
///
///
public bool CheckStopPostionStopStatus()
{
foreach (var item in _cellLst)
{
bool result = item.CheckRotationStopStatus();
if (result)
{
return true;
}
}
return false;
}
///
/// 检验流量是否ok
///
///
private bool CheckFlowOk()
{
if (!_totalFlowOk)
{
_checkFlowOk = false;
return true;
}
foreach (var item in _cellLst)
{
if (!_cellFlowOk[item.Module])
{
_checkFlowOk = false;
return true;
}
}
_checkFlowOk = true;
return true;
}
///
/// 最后确认结果
///
///
private bool LastCheckResult()
{
AllCellPostMsg();
if (_totalFlowOk)
{
return true;
}
else
{
LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"total flow {_totalFlow} is less than {_totalFlowStartLimit}");
return false;
}
}
///
/// 所有cell推送消息
///
private void AllCellPostMsg()
{
foreach (var item in _cellLst)
{
VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(item.Module);
if (!_cellFlowOk[item.Module])
{
vpwCellEntity.PostMsg((int)VpwCellMsg.Error);
LOG.WriteLog(eEvent.ERR_VPW, item.Module, $"cell flow {_cellFlows[item.Module]} is less than {_cellFlowStartLimit}");
}
}
}
///
/// 检验Rotation电机是否上电
///
///
///
private bool CheckRotationSwitchOn(VpwCellDevice device)
{
if (!device.CheckRotationSwitchOn())
{
LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{device.Module} rotation is not switch on");
return false;
}
return true;
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
List lstDevice = (List)objs[0];
_vpwCellDevices.Clear();
_cellFlows.Clear();
_cellLst.Clear();
_cellFlowOk.Clear();
_totalFlowOk = false;
_checkFlowOk = false;
_totalFlow = 0;
for (int i = 0; i < lstDevice.Count; i++)
{
_vpwCellDevices.Add(lstDevice[i]);
VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(lstDevice[i].Module);
if (vpwCellEntity.IsAuto || vpwCellEntity.IsManual)
{
_cellLst.Add(lstDevice[i]);
if (!CheckRotationSwitchOn(lstDevice[i]))
{
return RState.Failed;
}
_cellFlowOk[lstDevice[i].Module] = false;
}
}
_mainDevice = DEVICE.GetDevice(Module.ToString());
_n2PurgeTime = SC.GetValue("VPWMain.Plumbing.N2PurgeTime");
_flowFaultHolderoffTime = SC.GetValue("VPWMain.Plumbing.FlowFaultHoldoffTime");
double purgeMotorSpeed = SC.GetValue("VPWMain.Plumbing.PurgeMotorSpeed");
_rotationSpeed = (int)(Math.Round(purgeMotorSpeed * 360 / 60, 0));
_totalFlowStartLimit = SC.GetValue("VPWMain.Plumbing.TotalFlowStartLowLimit");
_cellFlowStartLimit = SC.GetValue("VPWMain.Plumbing.CellFlowStartLowLimit");
_degasEnableDelayTime = SC.GetValue("VPWMain.Plumbing.DegasEnableDelayTime");
return Runner.Start(Module, "VPW Purge");
}
}
}