using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
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 SecsGem.Core.ItemModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Modules.VpwMain
{
public class VPWHomeRoutine : RoutineBase, IRoutine
{
private enum HomeStep
{
ChameberUp,
OpenCellDrainValve,
HomeRotation,
CheckRotationStatus,
StartRotation,
CheckRotationRunning,
CloseDiwDegas,
N2PurgeDelay,
CloseN2Purge,
BoostPumpEnable,
CheckPumpEnable,
FlowDelay,
CheckFlow,
CheckCellFlow,
StopRotation,
CheckStopStatus,
LastHomeRotation,
CheckLastHomeRotation,
CheckFlowOk,
DegasDelay,
OpenDegas,
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 VPWHomeRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
Runner.Stop("Manual abort");
}
///
/// 监控
///
///
public RState Monitor()
{
Runner.Run(HomeStep.ChameberUp, _mainDevice.ChamberUp, CheckChamberClosed, _delay_1s)
.Run(HomeStep.OpenCellDrainValve, OpenCellDrainValve, CheckCellDrainValveStatus, _delay_2s)
.Run(HomeStep.HomeRotation,HomeAllRotation,_delay_1ms)
.WaitWithStopCondition(HomeStep.CheckRotationStatus,CheckAllRotationHomeStatus,CheckAllRotationHomeStopStatus)
.Run(HomeStep.StartRotation,StartRotation,_delay_1ms)
.Wait(HomeStep.CheckRotationRunning,CheckRotationRunningStatus,500)
.Run(HomeStep.CloseDiwDegas,CloseDiwDegas)
.Delay(HomeStep.N2PurgeDelay,_n2PurgeTime)
.Run(HomeStep.CloseN2Purge,_mainDevice.N2PurgeValveOff,_delay_1ms)
.Run(HomeStep.BoostPumpEnable,OpenBoostPump,_delay_1ms)
.Wait(HomeStep.CheckPumpEnable, () => { return _mainDevice.CommonData.BoosterPumpStatus; },_delay_1s)
.Delay(HomeStep.FlowDelay,_flowFaultHolderoffTime)
.Run(HomeStep.CheckFlow,CheckTotalFlow,_delay_1ms)
.Run(HomeStep.CheckCellFlow,CheckCellFlow,_delay_1ms)
.Run(HomeStep.StopRotation,StopRotationAxis,_delay_1ms)
.WaitWithStopCondition(HomeStep.CheckRotationStatus,CheckStopPostionEndStatus,CheckStopPostionStopStatus)
.Run(HomeStep.CheckFlowOk,CheckFlowOk,_delay_1ms)
.DelayIf(HomeStep.DegasDelay,_checkFlowOk,_degasEnableDelayTime)
.RunIf(HomeStep.OpenDegas,_checkFlowOk,OpenDegasPump,_delay_1ms)
.RunIf(HomeStep.ChamberDown,_checkFlowOk, () => { return _mainDevice.ChamberDown(); },
() => { return !_mainDevice.CommonData.ChamberClosed && _mainDevice.CommonData.ChamberOpened; })
.Run(HomeStep.LastCheckStatus,LastCheckResult,_delay_1ms)
.End(HomeStep.End,NullFun, _delay_1ms);
return Runner.Status;
}
///
/// 检验Chamber关闭
///
///
private bool CheckChamberClosed()
{
return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;
}
///
/// 打开所有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)
{
CloseCellDrainValve();
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();
CloseCellDrainValve();
return false;
}
}
return true;
}
///
/// 检验Rotation是否运动
///
///
private bool CheckRotationRunningStatus()
{
foreach (var item in _cellLst)
{
bool result = item.CheckRotationRunning();
if (!result)
{
StopAllRotation();
CloseCellDrainValve();
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.BoosterPumpDisable()?1:0;
count+=_mainDevice.N2PurgeValveOn()?1:0;
foreach(var item in _cellLst)
{
count += item.FlowDripOff()?1:0;
count += item.FlowSmallOff() ? 1 : 0;
count += item.FlowLargeOff() ? 1 : 0;
}
return count==_cellLst.Count*3+3;
}
///
/// 打开Boost Pump
///
///
private bool OpenBoostPump()
{
int count = 0;
count += _mainDevice.BoosterPumpEnable()?1:0;
count += _mainDevice.DiwEnable() ? 1 : 0;
count += _mainDevice.DiwProcessOn() ? 1 : 0;
count += _mainDevice.DiwDegasValveOn() ? 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+4;
}
///
/// 检验流量
///
///
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;
item.FlowSmallOff();
item.FlowLargeOff();
}
else
{
_cellFlowOk[item.Module] = true;
}
_cellFlows[item.Module] = cellFlow;
}
return true;
}
///
/// 停止rotation
///
///
public bool StopRotationAxis()
{
foreach(var item in _cellLst)
{
bool result = item.StopProfilePosition();
if (!result)
{
CloseCellDrainValve();
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;
}
///
/// 打开Degas Pump和Adjust
///
///
private bool OpenDegasPump()
{
int count = 0;
count+=_mainDevice.DegasPumpEnable()?1:0;
count+=_mainDevice.DegasAdjustOn()?1:0;
return count == 2;
}
///
/// 最后确认结果
///
///
private bool LastCheckResult()
{
//当前是Main Home
if (Module == ModuleName.VPWMain1.ToString())
{
AllCellPostMsg();
if (_totalFlowOk)
{
return true;
}
else
{
LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"total flow {_totalFlow} is less than {_totalFlowStartLimit}");
return false;
}
}
else
{
AllCellPostMsg();
VpwMainEntity vpwMainEntity = Singleton.Instance.GetModule(ModuleName.VPWMain1.ToString());
if (_totalFlowOk)
{
vpwMainEntity.CheckToPostMessage(eEvent.INFO_VPWMAIN, ModuleName.VPWMain1.ToString(), (int)VpwCellMsg.EnterIdle);
}
else
{
vpwMainEntity.PostMsg((int)VPWMainMsg.Error);
LOG.WriteLog(eEvent.ERR_VPWMAIN,ModuleName.VPWMain1.ToString(), $"total flow {_totalFlow} is less than {_totalFlowStartLimit}");
}
if (_cellFlowOk[Module])
{
return true;
}
else
{
LOG.WriteLog(eEvent.ERR_VPW, Module, $"cell flow {_cellFlows[Module]} is less than {_cellFlowStartLimit}");
return false;
}
}
}
///
/// 所有cell推送消息
///
private void AllCellPostMsg()
{
foreach (var item in _cellLst)
{
//过滤当前本身的cell
if (item.Module == Module)
{
continue;
}
//若cell流量是ok,则post msg变成idle
VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(item.Module);
if (_cellFlowOk[item.Module])
{
vpwCellEntity.CheckToPostMessage(eEvent.INFO_VPW, item.Module, (int)VpwCellMsg.EnterIdle);
}
else//则cell流量是不ok,则post error msg
{
vpwCellEntity.PostMsg((int)VpwCellMsg.Error);
LOG.WriteLog(eEvent.ERR_VPW, item.Module, $"cell flow {_cellFlows[item.Module]} is less than {_cellFlowStartLimit}");
}
}
}
///
/// 启动
///
///
///
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 Home");
}
///
/// 检验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;
}
}
}