Sic.Framework/MECF.Framework.RT.Equipment.../Devices/IoSCR.cs

242 lines
7.4 KiB
C#

using Aitex.Core.Common.DeviceData.IoDevice;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using System;
using System.Xml;
namespace Aitex.Core.RT.Device.Devices
{
public class IoSCR : BaseDevice, IDevice
{
#region Variables
private float _resLimitMax;
private readonly bool _isFloatAioType = true;
private readonly AIAccessor _aiVoltage;
private readonly AIAccessor _aiArms;
private readonly AIAccessor _aiPower;
private readonly DIAccessor _diStatus;
private DIAccessor _diAlarm;
private readonly DOAccessor _doStatus;
private readonly DOAccessor _doReset;
private readonly DeviceTimer _timResetPulse = new();
private readonly R_TRIG _trigResOutOfRange = new();
private readonly DeviceTimer _timResOutOfRange = new();
private readonly IoPsuData _deviceData = new();
#endregion
#region Constructors
public IoSCR(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
_aiVoltage = ParseAiNode("aiVoltage", node, ioModule);
_aiArms = ParseAiNode("aiArms", node, ioModule);
_aiPower = ParseAiNode("aiPower", node, ioModule);
_diStatus = ParseDiNode("diStatus", node, ioModule);
_doReset = ParseDoNode("doReset", node, ioModule);
_doStatus = ParseDoNode("doStatus", node, ioModule);
_diAlarm = ParseDiNode("diAlarm", node, ioModule);
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
}
#endregion
#region Properties
public float VoltageFeedBack => _aiVoltage == null ? 0 : (_isFloatAioType ? _aiVoltage.FloatValue : _aiVoltage.Value);
public float ArmsFeedBack => _aiArms == null ? 0 : (_isFloatAioType ? _aiArms.FloatValue : _aiArms.Value);
public float ResistanceLimitMax => _resLimitMax;
public float Resistance => ArmsFeedBack == 0 ? 0 : VoltageFeedBack / ArmsFeedBack;
public bool IsResistanceOutOfRange => IsResistanceTooHigh;
public bool IsResistanceTooHigh { get; private set; }
public float PowerFeedBack => _aiPower == null ? 0 : (_isFloatAioType ? _aiPower.FloatValue : _aiPower.Value);
public bool StatusFeedBack => _diStatus == null ? false : _diStatus.Value;
private IoPsuData DeviceData
{
get
{
_deviceData.IsAlarm = false;
_deviceData.OutputStatusFeedBack = StatusFeedBack;
_deviceData.OutputArmsFeedBack = ArmsFeedBack;
_deviceData.OutputPowerFeedBack = PowerFeedBack;
_deviceData.OutputVoltageFeedback = VoltageFeedBack;
_deviceData.ResistanceLimitMax = ResistanceLimitMax;
_deviceData.Resistance = Resistance;
_deviceData.IsResistanceOutOfRange = IsResistanceOutOfRange;
_deviceData.IsResistanceTooHigh = IsResistanceTooHigh;
return _deviceData;
}
}
#endregion
#region Methods
public bool Initialize()
{
DATA.Subscribe($"{Module}.{Name}.VoltageFeedBack", () => VoltageFeedBack);
DATA.Subscribe($"{Module}.{Name}.ArmsFeedBack", () => ArmsFeedBack);
DATA.Subscribe($"{Module}.{Name}.Resistance", () => Resistance);
DATA.Subscribe($"{Module}.{Name}.PowerFeedBack", () => PowerFeedBack);
DATA.Subscribe($"{Module}.{Name}.StatusFeedBack", () => StatusFeedBack);
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
OP.Subscribe($"{Module}.{Name}.SetEnable", (function, args) =>
{
var isTrue = Convert.ToBoolean(args[0]);
SetEnable(isTrue, out _);
return true;
});
OP.Subscribe($"{Module}.{Name}.SetReset", (function, args) =>
{
var isTrue = Convert.ToBoolean(args[0]);
SetReset(isTrue, out _);
return true;
});
return true;
}
public bool SetEnable(bool setValue, out string reason)
{
if (!_doStatus.Check(setValue, out reason))
return false;
if (!_doStatus.SetValue(setValue, out reason))
{
return false;
}
return true;
}
public bool SetReset(bool setValue, out string reason)
{
if (!_doReset.Check(setValue, out reason))
return false;
if (!_doReset.SetValue(setValue, out reason))
{
return false;
}
_timResetPulse.Start(1000);
return true;
}
public bool CheckSCREnable()
{
return _doStatus.Value;
}
public void Terminate()
{
}
protected override void HandleMonitor()
{
try
{
MonitorAlarm();
if (_timResetPulse.IsTimeout())
{
_timResetPulse.Stop();
if (_doReset.Value)
_doReset.Value = false;
ResetResistanceMonitorResult();
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public void Reset()
{
ResetResistanceMonitorResult();
}
/// <summary>
/// 复位加热器电阻监测结果。
/// </summary>
private void ResetResistanceMonitorResult()
{
IsResistanceTooHigh = false;
_trigResOutOfRange.RST = true;
_timResOutOfRange.Stop();
}
private void MonitorAlarm()
{
//检查电阻值是否在合理范围
_resLimitMax = (float)SC.GetValue<double>($"PM.{Module}.Heater.{Name}ResistanceMax");
var timeOut = SC.GetValue<int>($"PM.{Module}.Heater.ResistanceMonitorHysteresis");
if (Resistance > _resLimitMax && _timResOutOfRange.IsIdle())
{
_timResOutOfRange.Start(timeOut * 1000);
}
if (Resistance <= _resLimitMax)
{
IsResistanceTooHigh = false;
_timResOutOfRange.Stop();
}
_trigResOutOfRange.CLK = _timResOutOfRange.IsTimeout();
if (_trigResOutOfRange.Q)
{
IsResistanceTooHigh = true;
EV.PostWarningLog(Module, $"{Name} Current resistance {Resistance}ohm exceeds the high limit {_resLimitMax}ohm.");
}
}
public double AETemp
{
get
{
var temp = new object();
if (SC.GetConfigItem("AETemp.EnableDevice").BoolValue)
{
temp = DATA.Poll($"{Module}.AETemp.Middle");
}
if (SC.GetConfigItem("AKunTemp.EnableDevice").BoolValue)
{
temp = DATA.Poll($"{Module}.AKunTemp.Middle");
}
return temp == null ? 0 : (double)temp;
}
}
#endregion
}
}