Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../Devices/IoPSU.cs

414 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Aitex.Core.RT.DataCenter;
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;
using Aitex.Core.Common.DeviceData.IoDevice;
using MECF.Framework.Common.Aitex.Core.Common.DeviceData.IoDevice;
namespace Aitex.Core.RT.Device.Devices
{
public class IoPSU : BaseDevice, IDevice
{
#region Variables
private readonly string _scResLimitMax;
private float _resLimitMax;
private readonly bool _isFloatAioType;
private readonly AIAccessor _aiOutputVoltage;
private readonly AIAccessor _aiOutputArms;
private readonly AIAccessor _aiOutputPower;
private readonly AIAccessor _aiSimVoltage;
private readonly AIAccessor _aiSimArms;
//private AOAccessor _aoEnable = null;
//private AOAccessor _aoReset = null;
private readonly AOAccessor _aoConstant;
private readonly DIAccessor _diStatus;
private readonly DIAccessor _diAlarm;
private readonly DIAccessor _diHeatEnable;
private DIAccessor _diCommunicationError;
private readonly DOAccessor _doReset;
private readonly DOAccessor _doStatus;
private readonly DOAccessor _doHeatEnable;
private readonly DOAccessor _doRelatedEnable; //每个Enable同时关联的InnerMiddleOut Enable
private string _infoText = "";
private string _commInfoText = "";
private readonly R_TRIG _alarmTrig = new();
private readonly R_TRIG _commAlarmTrig = new();
private readonly R_TRIG _enableTrig = new();
private readonly R_TRIG _enableTrig2 = new();
private readonly R_TRIG _trigVoltage = new();
private readonly R_TRIG _trigCurrent = new();
private readonly R_TRIG _trigResistance = new();
private readonly DeviceTimer _timer = new();
private readonly DeviceTimer _timerResistance = new();
private readonly IoPsuData _deviceData = new();
#endregion
#region Constructors
public IoPSU(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
_aiOutputVoltage = ParseAiNode("aiOutputVoltage", node, ioModule);
_aiOutputArms = ParseAiNode("aiOutputArms", node, ioModule);
_aiOutputPower = ParseAiNode("aiOutputPower", node, ioModule);
_aiSimVoltage = ParseAiNode("aiSimVoltage", node, ioModule);
_aiSimArms = ParseAiNode("aiSimArms", node, ioModule);
_aoConstant = ParseAoNode("aoConstant", node, ioModule);
_doReset = ParseDoNode("doReset", node, ioModule);
_doStatus = ParseDoNode("doStatus", node, ioModule);
_diStatus = ParseDiNode("diStatus", node, ioModule);
_diAlarm = ParseDiNode("diAlarm", node, ioModule);
_doHeatEnable = ParseDoNode("doHeatEnable", node, ioModule);
_diHeatEnable = ParseDiNode("diHeatEnable", node, ioModule);
_doRelatedEnable = ParseDoNode("doRelatedEnable", node, ioModule);
_diCommunicationError = ParseDiNode("diCommunicationError", node, ioModule);
_infoText = node.GetAttribute("AlarmText");
_commInfoText = node.GetAttribute("commAlarmText");
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
// 读取电阻上限设定值
_scResLimitMax = node.GetAttribute("scResLimitMax");
LoadConfig();
}
#endregion
#region Properties
public float OutputVoltageFeedBack => _aiOutputVoltage == null ? 0 : (_isFloatAioType ? _aiOutputVoltage.FloatValue : _aiOutputVoltage.Value);
public float OutputArmsFeedBack => _aiOutputArms == null ? 0 : (_isFloatAioType ? _aiOutputArms.FloatValue : _aiOutputArms.Value);
public float ResistanceLimitMax => _resLimitMax;
public float Resistance => OutputArmsFeedBack == 0 ? 0 : OutputVoltageFeedBack / OutputArmsFeedBack;
public bool IsResistanceOutOfRange => IsResistanceTooHigh;
public bool IsResistanceTooHigh => Resistance > ResistanceLimitMax;
public float OutputPowerFeedBack => _aiOutputPower == null ? 0 : (_isFloatAioType ? _aiOutputPower.FloatValue : _aiOutputPower.Value);
public bool StatusFeedBack => _diStatus?.Value ?? false;
public float SimVoltageFeedBack => _aiSimVoltage == null ? 0 : (_isFloatAioType ? _aiSimVoltage.FloatValue : _aiSimVoltage.Value);
public float SimArmsFeedBack => _aiSimArms == null ? 0 : (_isFloatAioType ? _aiSimArms.FloatValue : _aiSimArms.Value);
public bool AlarmFeedBack => _diAlarm?.Value ?? false;
public float ConstantSetPoint
{
get => _aoConstant == null ? 0 : (_isFloatAioType ? _aoConstant.FloatValue : _aoConstant.Value);
set
{
if (_isFloatAioType)
{
_aoConstant.FloatValue = value;
}
else
{
_aoConstant.Value = (short)value;
}
}
}
public bool AllHeatEnable => _diHeatEnable?.Value ?? false;
private IoPsuData DeviceData
{
get
{
_deviceData.IsAlarm = AlarmFeedBack;
_deviceData.OutputStatusFeedBack = StatusFeedBack;
_deviceData.AllHeatEnable = AllHeatEnable;
_deviceData.ConstantSetPoint = ConstantSetPoint;
_deviceData.OutputArmsFeedBack = OutputArmsFeedBack;
_deviceData.OutputPowerFeedBack = OutputPowerFeedBack;
_deviceData.OutputVoltageFeedback = OutputVoltageFeedBack;
_deviceData.ResistanceLimitMax = ResistanceLimitMax;
_deviceData.Resistance = Resistance;
_deviceData.IsResistanceOutOfRange = IsResistanceOutOfRange;
_deviceData.IsResistanceTooHigh = IsResistanceTooHigh;
return _deviceData;
}
}
public Func<bool, bool> FuncCheckInterLock { get; set; }
#endregion
#region Methods
/// <summary>
/// 加载必要的配置。
/// </summary>
private void LoadConfig()
{
// 读取系统配置中电阻最大值定义;
// 如果DeviceModel配置中指定的系统配置节点找不到则用默认的路径找配置
// 如果还找不到则默认为3欧姆。
var scResLimitMax = $"{ScBasePath}.{_scResLimitMax}";
var sc = SC.GetConfigItem(scResLimitMax);
if (sc != null)
_resLimitMax = (float)sc.Value;
else
{
scResLimitMax = $"PM.{Module}.Heater.{Name}ResistanceLimitMax";
sc = SC.GetConfigItem(scResLimitMax);
if (sc != null)
_resLimitMax = (float)sc.Value;
else
{
_resLimitMax = 3;
EV.PostWarningLog(Module,
$"Unable to find {Name} ResistanceMax config, set to {_resLimitMax} as the default value");
}
}
// 监测系统配置变化。
SC.RegisterValueChangedCallback(scResLimitMax, v =>
{
_resLimitMax = (float)v;
});
}
public bool Initialize()
{
DATA.Subscribe($"{Module}.{Name}.OutputVoltageFeedBack", () => OutputVoltageFeedBack);
DATA.Subscribe($"{Module}.{Name}.OutputArmsFeedBack", () => OutputArmsFeedBack);
DATA.Subscribe($"{Module}.{Name}.ResistanceLimitMax", () => ResistanceLimitMax);
DATA.Subscribe($"{Module}.{Name}.Resistance", () => Resistance);
DATA.Subscribe($"{Module}.{Name}.IsResistanceOutOfRange", () => IsResistanceOutOfRange);
DATA.Subscribe($"{Module}.{Name}.IsResistanceTooHigh", () => IsResistanceTooHigh);
DATA.Subscribe($"{Module}.{Name}.OutputPowerFeedBack", () => OutputPowerFeedBack);
DATA.Subscribe($"{Module}.{Name}.StatusFeedBack", () => StatusFeedBack);
DATA.Subscribe($"{Module}.{Name}.SimVoltageFeedBack", () => SimVoltageFeedBack);
DATA.Subscribe($"{Module}.{Name}.SimArmsFeedBack", () => SimArmsFeedBack);
DATA.Subscribe($"{Module}.{Name}.ConstantSetPoint", () => ConstantSetPoint);
DATA.Subscribe($"{Module}.{Name}.AlarmFeedBack", () => AlarmFeedBack);
DATA.Subscribe($"{Module}.{Name}.AllHeatEnable", () => AllHeatEnable);
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
OP.Subscribe($"{Module}.{Name}.SetHeadHeaterEnable", (function, args) =>
{
var isTrue = Convert.ToBoolean(args[0]);
SetHeadHeaterEnable(isTrue, out _);
return true;
});
OP.Subscribe($"{Module}.{Name}.SetPSUEnable", (function, args) =>
{
var isTrue = Convert.ToBoolean(args[0]);
SetPSUEnable(isTrue, out _);
return true;
});
OP.Subscribe($"{Module}.{Name}.SetPSUReset", (function, args) =>
{
var isTrue = Convert.ToBoolean(args[0]);
SetPSUReset(isTrue, out _);
return true;
});
return true;
}
public bool SetPSUEnable(bool setValue, out string reason)
{
if (!_doStatus.Check(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
if (!_doRelatedEnable.Check(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
if (!_doStatus.SetValue(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
if (!_doRelatedEnable.SetValue(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
return true;
}
public bool SetHeadHeaterEnable(bool setValue, out string reason)
{
reason = "";
if (FuncCheckInterLock != null)
{
if (!FuncCheckInterLock(setValue))
{
EV.PostInfoLog(Module, $"Set PSU Enable fialed for Interlock!");
return false;
}
}
if (!_doHeatEnable.Check(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
if (!_doHeatEnable.SetValue(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
return true;
}
public bool SetPSUReset(bool setValue, out string reason)
{
if (!_doReset.Check(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
if (!_doReset.SetValue(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
return false;
}
_timer.Start(1000);
return true;
}
public bool CheckPSUEnable()
{
return _doStatus.Value;
}
public void Terminate()
{
}
protected override void HandleMonitor()
{
try
{
MonitorEnableTimer();
MonitorAlarm();
if (_timer.IsTimeout())
{
_timer.Stop();
}
else if (_timer.IsIdle())
{
if (_doReset.Value)
{
_doReset.Value = false;
}
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public void Reset()
{
_alarmTrig.RST = true;
_commAlarmTrig.RST = true;
_trigVoltage.RST = true;
_trigCurrent.RST = true;
}
private void MonitorAlarm()
{
//检查电阻值是否在合理范围
var dbResistorMax = SC.GetValue<double>($"PM.{Module}.Heater.{Name}ResistanceMax");
var timeOut = SC.GetValue<int>($"PM.{Module}.Heater.ResistanceCheckTimeOut");
if (Resistance > dbResistorMax && _timerResistance.IsIdle())
{
_timerResistance.Start(timeOut);
}
if (Resistance <= dbResistorMax)
{
_timerResistance.Stop();
}
_trigResistance.CLK = _timerResistance.IsTimeout();
if (_trigResistance.Q)
{
EV.PostWarningLog(Module, $"{Name} Resistance is out of range.Current Resistance is {Resistance}");
}
}
private void MonitorEnableTimer()
{
if (Name == "PSU2")
{
_enableTrig.CLK = !_diHeatEnable.Value;
if (_enableTrig.Q)
{
SC.SetItemValue($"PM.{Module}.OpenLidCountDownTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
}
_enableTrig2.CLK = _diHeatEnable.Value;
if (_enableTrig2.Q)
{
SC.SetItemValue($"PM.{Module}.OpenLidCountDownTime", "");
}
}
}
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
}
}