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