|
@@ -6,7 +6,9 @@ using Aitex.Core.RT.RecipeCenter;
|
|
|
using Aitex.Core.RT.SCCore;
|
|
|
using Aitex.Core.Util;
|
|
|
using MECF.Framework.Common.Alarm;
|
|
|
+using MECF.Framework.Common.Algorithm;
|
|
|
using MECF.Framework.Common.Beckhoff.ModuleIO;
|
|
|
+using MECF.Framework.Common.CommonData.Prewet;
|
|
|
using MECF.Framework.Common.CommonData.Reservoir;
|
|
|
using MECF.Framework.Common.IOCore;
|
|
|
using MECF.Framework.Common.Persistent.Reservoirs;
|
|
@@ -121,7 +123,27 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
/// 注水Helper
|
|
|
/// </summary>
|
|
|
private ReservoirDiReplenHelper _direplenHelper;
|
|
|
-
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 上一时刻platingcell的overflow level
|
|
|
+ /// </summary>
|
|
|
+ private double _lastOverFlow;
|
|
|
+ /// <summary>
|
|
|
+ /// platingcell的overflow status
|
|
|
+ /// </summary>
|
|
|
+ private string _overFlowStatus = "Empty";
|
|
|
+ /// <summary>
|
|
|
+ /// 当前调节return valve的时间
|
|
|
+ /// </summary>
|
|
|
+ private DateTime _adjustReturnvalveStartTime = DateTime.Now;
|
|
|
+ /// <summary>
|
|
|
+ /// 首次发现ca flow 满足条件的时间,用于自动打开degas valve
|
|
|
+ /// </summary>
|
|
|
+ private DateTime _caFlowOKTime = DateTime.Now;
|
|
|
+ /// <summary>
|
|
|
+ /// ca flow 是否首次达到条件
|
|
|
+ /// </summary>
|
|
|
+ private bool _isFirstCaFlowOK = false;
|
|
|
#endregion
|
|
|
|
|
|
#region Trigger
|
|
@@ -198,6 +220,10 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
/// 累计补水是否超时
|
|
|
/// </summary>
|
|
|
public bool IsDIReplenMaxTimeOut { get { return _isDIReplenMaxTimeOut; } }
|
|
|
+ /// <summary>
|
|
|
+ /// 是否启动retrun valve自动调节开闭
|
|
|
+ /// </summary>
|
|
|
+ public bool IsStartAutoReturnValve { get; set; }
|
|
|
#endregion
|
|
|
/// <summary>
|
|
|
/// 构造函数
|
|
@@ -257,6 +283,7 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
DATA.Subscribe($"{Module}.CurrentRecipe", () => _resRecipe, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
DATA.Subscribe($"{Module}.IsCAHighLevel", () => IsCAHighLevel, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
DATA.Subscribe($"{Module}.IsCALowLevel", () => IsCALowLevel, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
+ DATA.Subscribe($"{Module}.AvgCALevel", () => _avgCALevel, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
|
|
|
DATA.Subscribe($"{Module}.DIValveMaxOnTime", () => SC.GetValue<double>($"Reservoir.{Module}.DIValveMaxOnTime") * 60, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
DATA.Subscribe($"{Module}.IsManualCAReplen", () => { return _currentDireplenOperation == DiReplenOperation.ManualCADiReplen; }, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
@@ -372,13 +399,84 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
/// <returns></returns>
|
|
|
protected virtual bool OnTimer()
|
|
|
{
|
|
|
- //CalculateCALevel();
|
|
|
+ CalculateCALevel();
|
|
|
+ AdjustPumpSpeed();
|
|
|
WaterLevelMonitor();
|
|
|
DireplenMonitor();
|
|
|
+ AutoOpenDegasValve();
|
|
|
return true;
|
|
|
}
|
|
|
#region timer
|
|
|
/// <summary>
|
|
|
+ /// safety和ca flow满足条件,自动打开degas valve
|
|
|
+ /// </summary>
|
|
|
+ public void AutoOpenDegasValve()
|
|
|
+ {
|
|
|
+ if(ReservoirData.CaFlow >= Recipe.CAFlowSetPoint) //缺了safety的条件,待补充
|
|
|
+ {
|
|
|
+ int degasValveOpenIdlePeriod = SC.GetValue<int>($"Reservoir.DegasValveOpenIdlePeriod");
|
|
|
+ if (!_isFirstCaFlowOK)
|
|
|
+ {
|
|
|
+ _isFirstCaFlowOK = true;
|
|
|
+ _caFlowOKTime = DateTime.Now;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(DateTime.Now.Subtract(_caFlowOKTime).TotalMinutes >= degasValveOpenIdlePeriod && !ReservoirData.DegasEnable)
|
|
|
+ {
|
|
|
+ DegasValveOn();
|
|
|
+ _caFlowOKTime = DateTime.Now;//开启后重置一下检测到ca flow ok的时间
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _isFirstCaFlowOK = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 自动调节retrun valve 开闭
|
|
|
+ /// </summary>
|
|
|
+ public void AdjustPumpSpeed()
|
|
|
+ {
|
|
|
+ ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(Module);
|
|
|
+ if (reservoirEntity != null)
|
|
|
+ {
|
|
|
+ //retrun valve打开
|
|
|
+ if (ReservoirData.ReturnValveEnable && (!reservoirEntity.IsInit && !reservoirEntity.IsError))
|
|
|
+ {
|
|
|
+ double overflow = new Random().NextDouble() * 6 + 10;//模拟platingcell的液位;
|
|
|
+ int _overflowLevelDelta = SC.GetValue<int>($"Reservoir.{Module}.OverflowLevelDelta");
|
|
|
+ int _overflowLevelCheckTime = SC.GetValue<int>($"Reservoir.{Module}.OverflowLevelCheckTime");
|
|
|
+ int _retrunOpenHoldStep = SC.GetValue<int>($"Reservoir.{Module}.RetrunOpenHoldStep");
|
|
|
+ int _retrunOpenRampStep = SC.GetValue<int>($"Reservoir.{Module}.RetrunOpenRampStep");
|
|
|
+ int adjustNumber = "Full".Equals(_overFlowStatus) ? _retrunOpenHoldStep : _retrunOpenRampStep;//判断当前overflow状态
|
|
|
+ if (overflow > _lastOverFlow)//液位升高的情况
|
|
|
+ {
|
|
|
+ if (overflow - _lastOverFlow > _overflowLevelDelta && DateTime.Now.Subtract(_adjustReturnvalveStartTime).TotalMilliseconds > _overflowLevelCheckTime)
|
|
|
+ {
|
|
|
+ double percent = ReservoirData.ReturnValveOpening - adjustNumber;
|
|
|
+ percent = percent >= 0 ? percent : 0;
|
|
|
+ ReturnValvePercent(percent);
|
|
|
+ _lastOverFlow = overflow;
|
|
|
+ _adjustReturnvalveStartTime = DateTime.Now;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (_lastOverFlow - overflow > _overflowLevelDelta && DateTime.Now.Subtract(_adjustReturnvalveStartTime).TotalMilliseconds > _overflowLevelCheckTime)
|
|
|
+ {
|
|
|
+ double percent = ReservoirData.ReturnValveOpening + adjustNumber;
|
|
|
+ ReturnValvePercent(percent);
|
|
|
+ _lastOverFlow = overflow;
|
|
|
+ _adjustReturnvalveStartTime = DateTime.Now;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
/// 计算CA
|
|
|
/// </summary>
|
|
|
private void CalculateCALevel()
|
|
@@ -408,7 +506,6 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
{
|
|
|
|
|
|
ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(Module);
|
|
|
-
|
|
|
string reason = $"Current CAWaterlevel:{ReservoirData.CaWaterLevel} is lower than CALowLevel Config:{SC.GetValue<double>($"Reservoir.{Module}.CALowLevel")}";
|
|
|
LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, reason);
|
|
|
CALowLevelOperation();
|
|
@@ -437,6 +534,10 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
{
|
|
|
CAPumpOff("", null);
|
|
|
}
|
|
|
+ if (_reservoirData.CaIsolation)// 不确定是否是关闭cell flow
|
|
|
+ {
|
|
|
+ CAIsolationOff();
|
|
|
+ }
|
|
|
//禁用TC
|
|
|
if (!string.IsNullOrEmpty(reservoirItem.TCID))
|
|
|
{
|
|
@@ -446,9 +547,7 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
temperatureController.DisableOperation("", null);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(Module);
|
|
|
-
|
|
|
if (!reservoirEntity.IsError) reservoirEntity.PostMsg(ReservoirMsg.Error);
|
|
|
}
|
|
|
/// <summary>
|
|
@@ -781,7 +880,7 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
/// <returns></returns>
|
|
|
private bool ReturnValveOn(string cmd, object[] args)
|
|
|
{
|
|
|
- double percent = SC.GetValue<double>("Reservoir.ReturnOpenDefaultPercentage");
|
|
|
+ double percent = SC.GetValue<int>("Reservoir.ReturnOpenDefaultPercentage");
|
|
|
bool result = ReturnValvePercent(percent);
|
|
|
if (result)
|
|
|
{
|
|
@@ -1033,6 +1132,7 @@ namespace PunkHPX8_RT.Devices.Reservoir
|
|
|
private bool ResetTotalTime(string cmd, object[] objs)
|
|
|
{
|
|
|
_isDIReplenMaxTimeOut = false;
|
|
|
+ _isDIReplenPerfillTimeOut = false;
|
|
|
_persistentValue.TotalReplen = 0;
|
|
|
_persistentValue.LastTotalReplen = 0;
|
|
|
ReservoirsPersistentManager.Instance.UpdatePersistentValue(Module);
|