using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.CommonData.Reservoir;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.Persistent.Temperature;
using MECF.Framework.Common.TwinCat;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace PunkHPX8_RT.Devices.Reservoir
{
public class DMReservoirDevice : ReservoirDevice
{
#region 常量
private const string AN_PUMP = "ANPump";
#endregion
#region 内部变量
///
/// 默认泵速
///
private double _anPumpSpeed = 5000;
///
/// an泵速Helper
///
private ReservoirANPumpSpeedHelper _anPumpSpeedHelper;
#endregion
#region 属性
///
/// 检验阳极是否highlevel
///
public bool IsANHighLevel { get { return _reservoirData.AnTowerHigh; } }
///
/// 检验阳极是否lowlevel
///
public bool IsANLowLevel { get { return _reservoirData.AnTowerLow; } }
///
/// 阳极是否需要补水
///
public bool AnNeedDireplen { get { return CheckANNeedDiReplen(); } }
#endregion
#region Trigger
///
/// low WaterLevel trigger
///
private R_TRIG _anWaterLevelLowerTrigger = new R_TRIG();
///
/// low WaterLevel trigger
///
private R_TRIG _anWaterLevelHighTrigger = new R_TRIG();
#endregion
///
/// 构造函数
///
///
public DMReservoirDevice(string moduleName) : base(moduleName)
{
_anPumpSpeedHelper = new ReservoirANPumpSpeedHelper(Module, this);
}
///
/// 订阅变量
///
protected override void SubscribeValueAction()
{
base.SubscribeValueAction();
IoSubscribeUpdateVariable(AN_DI_REPLEN);
IoSubscribeUpdateVariable(AN_FLOW);
IoSubscribeUpdateVariable(AN_PUMP_ENABLE);
IoSubscribeUpdateVariable(AN_PUMP_SPEED);
IoSubscribeUpdateVariable(DEGAS_ENABLE);
}
///
/// 订阅Data
///
protected override void SubscribeData()
{
base.SubscribeData();
DATA.Subscribe($"{Module}.IsManualANReplen", () => { return _currentDireplenOperation == DiReplenOperation.ManualANDiReplen; }, SubscriptionAttribute.FLAG.IgnoreSaveDB);
}
///
/// 订阅Operation
///
protected override void InitializeOperation()
{
base.InitializeOperation();
OP.Subscribe($"{Module}.ANPumpEnable", AnPumpOnOperation);
OP.Subscribe($"{Module}.ANPumpSpeed", ANPumpSpeedOperation);
OP.Subscribe($"{Module}.ANPumpDisable", AnPumpOffOperation);
OP.Subscribe($"{Module}.ANDiReplenOn", ANDiReplenOnOperation);
OP.Subscribe($"{Module}.ANDiReplenOff", ANDiReplenOff);
OP.Subscribe($"{Module}.ManualANDiReplen", ManualANDiReplen);
}
#region AnPump
///
/// AN Pump调速
///
///
///
///
private bool ANPumpSpeedOperation(string cmd, object[] args)
{
double anMaxPumpSpeed = 0;
if (SC.ContainsItem("Reservoir.ANMaxPumpSpeed"))
{
anMaxPumpSpeed = SC.GetValue("Reservoir.ANMaxPumpSpeed");
}
if (double.TryParse(args[0].ToString(), out double speed))
{
_anPumpSpeed = speed;
if (_anPumpSpeed > anMaxPumpSpeed)
{
LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"AN pump speed:{_anPumpSpeed} is over AN max pump speed {anMaxPumpSpeed}!");
return false;
}
return AnPumpSpeed(_anPumpSpeed);
}
else
{
LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{args[0]} is nor invalid speed");
return false;
}
}
///
/// 设置AN泵速
///
///
///
public bool AnPumpSpeed(double anPumpSpeed)
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_PUMP_SPEED}");
return BeckhoffIOManager.Instance.WriteIoValue(ioName, anPumpSpeed);
}
///
/// 阳极Pump On
///
///
///
///
public bool AnPumpOnOperation(string cmd, object[] args)
{
double caPumpSpeed = SC.GetValue("Reservoir.ANDefaultPumpSpeed");
bool result = AnPumpSpeed(caPumpSpeed);
if (result)
{
string enableIOName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_PUMP_ENABLE}");
return BeckhoffIOManager.Instance.WriteIoValue(enableIOName, true);
}
else
{
return false;
}
}
///
/// 阳极Pump Off
///
///
///
///
private bool AnPumpOffOperation(string cmd, object[] args)
{
return AnPumpOff();
}
///
/// 关闭阳极Pump
///
///
public bool AnPumpOff()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_PUMP_ENABLE}");
return BeckhoffIOManager.Instance.WriteIoValue(ioName, false);
}
#endregion
protected override void AutoMonitor()
{
base.AutoMonitor();
if (_persistentValue.OperatingMode == AUTO)
{
_anPumpSpeedHelper.Monitor(_resRecipe);
}
}
///
/// 水位监控
///
protected override void WaterLevelMonitor()
{
base.WaterLevelMonitor();
//增加AN tower监控逻辑
_anWaterLevelLowerTrigger.CLK = _reservoirData.AnTowerLow;
_anWaterLevelHighTrigger.CLK = _reservoirData.AnTowerHigh;
if (_anWaterLevelLowerTrigger.Q && !Recipe.ANDIReplenEnable)
{
LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"AN tower low is activate and recipe ANDIReplenEnable is false");
}
if (_anWaterLevelHighTrigger.Q && !Recipe.ANDIReplenEnable)
{
LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"AN tower high is activate and recipe ANDIReplenEnable is false");
}
}
///
/// 补水监控,用于关闭自动补水
///
protected override void AutoDireplenMonitor()
{
base.AutoDireplenMonitor();
if (_currentDireplenOperation == DiReplenOperation.ManualANDiReplen)
{
bool result = _direplenHelper.MonitorManualDiReplenComplete(_manualReplenSecond, ANDiReplenOff, ref _isDIReplenMaxTimeOut);
if (result)
{
_currentDireplenOperation = DiReplenOperation.None;
}
}
if (_currentDireplenOperation == DiReplenOperation.AutoANDiReplen)
{
AutoANDiReplenMonitor(ANDiReplenOff, _resRecipe.ANDIReplenEnable, _resRecipe.ANDIReplenTimeRate, _resRecipe.ANDIReplenCurrentRate);
}
}
///
/// 阳极DI Replen On
///
///
///
///
private bool ANDiReplenOnOperation(string cmd, object[] args)
{
return ANDiReplenOn();
}
///
/// 阳极DI Replen On
///
///
///
private bool ANDiReplenOn()
{
bool preCondition = CheckPreDiReplenCondition();
if (!preCondition)
{
return false;
}
if (IsANHighLevel)
{
LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"ANHighLevel is activate,Can't do AN_DIReple");
return false;
}
if (IsANLowLevel)
{
LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"ANLowLevel is activate,Can't do AN_DIReple");
return false;
}
if (ReservoirData.CaDiReplen)
{
LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "CADiReplen is on");
return false;
}
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_DI_REPLEN}");
return BeckhoffIOManager.Instance.WriteIoValue(ioName, true);
}
///
/// 阳极DI Replen Off
///
///
///
///
private bool ANDiReplenOff(string cmd, object[] args)
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{AN_DI_REPLEN}");
bool result = BeckhoffIOManager.Instance.WriteIoValue(ioName, false);
if (result)
{
_persistentValue.IsDiReplenOn = false;
if (_currentDireplenOperation == DiReplenOperation.ManualANDiReplen || _currentDireplenOperation == DiReplenOperation.AutoANDiReplen)
{
_currentDireplenOperation = DiReplenOperation.None;
_persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
ReservoirsPersistentManager.Instance.UpdatePersistentValue(Module);
}
}
return result;
}
///
/// 手动阳极注水
///
///
///
///
private bool ManualANDiReplen(string cmd, object[] args)
{
return ManualDiReplen(ANDiReplenOnOperation, DiReplenOperation.ManualANDiReplen, args[0].ToString());
}
///
/// 检验阳极是否需要补水
///
///
private bool CheckANNeedDiReplen()
{
if (IsAuto && _resRecipe != null)
{
if (_resRecipe.ANDIReplenEnable && _resRecipe.ANDIReplenCurrentRate == 0 && _resRecipe.ANDIReplenTimeRate == 0)
{
return _reservoirData.AnTowerLow;
}
return false;
}
else
{
return false;
}
}
///
/// 阳极自动注水
///
///
public bool AutoANDiReplen()
{
return AutoDireplen(ANDiReplenOn, DiReplenOperation.AutoANDiReplen);
}
///
/// 阳极自动注水监控
///
///
///
///
private void AutoANDiReplenMonitor(Func direplenOff, bool replenEnable, int direplenTimeRate, int direplenCurrentRate)
{
//判断是否注水超时(包括单次和累计)
bool result = _direplenHelper.AutoDiReplenMonitorTimeOut(direplenOff, ref _isDIReplenMaxTimeOut, ref _isDIReplenPerfillTimeOut);
if (result)
{
_currentDireplenOperation = DiReplenOperation.None;
}
else
{
//按液位补水
result = AutoANDiReplenMonitorComplete(replenEnable, direplenTimeRate, direplenCurrentRate, direplenOff);
if (result)
{
_currentDireplenOperation = DiReplenOperation.None;
}
}
}
///
/// 阳极自动注水是否结束
///
///
///
///
///
///
private bool AutoANDiReplenMonitorComplete(bool replenEnable, int direplenTimeRate, int direplenCurrentRate, Func direplenOffAction)
{
if (replenEnable && direplenTimeRate == 0 && direplenCurrentRate == 0 && ReservoirData.AnTowerHigh)
{
LOG.WriteLog(eEvent.INFO_RESERVOIR, Module, "Auto AN DiReplen complete");
bool result = direplenOffAction("", null);
if (result)
{
_persistentValue.LastTotalReplen = _persistentValue.TotalReplen;
_persistentValue.IsDiReplenOn = false;
ReservoirsPersistentManager.Instance.UpdatePersistentValue(Module);
return result;
}
}
return false;
}
}
}