using Aitex.Core.RT.IOCore; using Aitex.Core.RT.SCCore; using System.Xml; using Aitex.Core.RT.Event; using Aitex.Core.Util; namespace Aitex.Core.RT.Device.Devices { public class PSUPowerDetection : BaseDevice, IDevice { private readonly AIAccessor _aiPower; private readonly string _scMaxPower; /// /// 硬件最大物理功率 /// private double _maxPower; private readonly string _scMaxHighPowerPercent; /// /// SC中配置的功率上限百分比 /// private double _maxHighPowerPercent; private readonly R_TRIG _trigMaxPower = new(); private readonly DeviceTimer _timer = new(); public PSUPowerDetection(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule) { _aiPower = ParseAiNode("aiPower", node, ioModule); _scMaxPower = $"{ScBasePath}.{Name}.MaxPower"; _scMaxHighPowerPercent = $"{ScBasePath}.{Name}.MaxHighPowerPercent"; } protected override void HandleMonitor() { PowerOutput(_aiPower); } /// /// 连续2秒都超过最大功率 /// /// private void PowerOutput(AIAccessor power) { if (_maxHighPowerPercent == 0) return; var v = power.Value / _maxPower; // 计算百分比 var percentage = v * 100.0; if (percentage > _maxHighPowerPercent) { if (_timer.IsIdle()) _timer.Start(2000); if (percentage <= _maxHighPowerPercent)//功率掉下来了,计时器停掉 { _timer.Stop(); return; } if (_timer.IsTimeout()) { PostWarning(power); } } else { _trigMaxPower.RST = true; _timer.Stop(); } } private void PostWarning(AIAccessor power) { _trigMaxPower.CLK = true; if (_trigMaxPower.Q) { EV.PostWarningLog(Module, $"{Display} {power.Name} {power.Value} over maxPower {_maxPower}"); } } public bool Initialize() { _maxPower = SC.SafeGetValue(_scMaxPower, double.PositiveInfinity); SC.RegisterValueChangedCallback(_scMaxPower, v => _maxPower = (double)v); _maxHighPowerPercent = SC.SafeGetValue(_scMaxHighPowerPercent, 100.0); SC.RegisterValueChangedCallback(_scMaxHighPowerPercent, v => _maxHighPowerPercent = (double)v); return true; } public void Terminate() { } public void Reset() { _trigMaxPower.RST = true; _timer.Stop(); } } }