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.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; #endregion #region 属性 /// /// 检验阳极是否highlevel /// public bool IsANHighLevel { get { return _reservoirData.AnTowerHigh; } } /// /// 检验阳极是否lowlevel /// public bool IsANLowLevel { get { return _reservoirData.AnTowerLow; } } #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) { } /// /// 订阅变量 /// protected override void SubscribeValueAction() { base.SubscribeValueAction(); IoSubscribeUpdateVariable(AN_DI_REPLEN); IoSubscribeUpdateVariable(AN_FLOW); IoSubscribeUpdateVariable(AN_PUMP_ENABLE); IoSubscribeUpdateVariable(AN_PUMP_SPEED); IoSubscribeUpdateVariable(DEGAS_ENABLE); } /// /// 订阅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}.ANIsolationOn", (cmd, para) => { return ANIsolationOn(); }); OP.Subscribe($"{Module}.ANIsolationOff", (cmd, para) => { return ANIsolationOff(); }); } #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); } /// /// ANIsolationOn /// /// public bool ANIsolationOn() { return WriteVariableValue(AN_ISOLATION, true); } /// /// ANIsolationOff /// /// public bool ANIsolationOff() { return WriteVariableValue(AN_ISOLATION, false); } #endregion /// /// 水位监控 /// 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"); //若recipe允许补水且res auto ,需要启动阳极自动补水 } 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(); } /// /// 阳极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()); } } }