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

299 lines
9.0 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System;
using System.Xml;
using Aitex.Core.Common.DeviceData;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device.Unit;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Aitex.Core.RT.Device;
2023-04-13 11:51:03 +08:00
namespace Aitex.Core.RT.Device.Devices
{
public class IoPressure : ErrorDetectableBaseDevice, IPressureMeter
2023-04-13 11:51:03 +08:00
{
public double FeedBack => _isFloatAioType ? _aiValue.Value : _aiValue.Value;
2023-04-13 11:51:03 +08:00
public double SetPoint
{
get
{
if (_aoValue != null)
return _isFloatAioType ? _aoValue.Value : _aoValue.Value;
2023-04-13 11:51:03 +08:00
else
return 0;
}
set
{
if (_aoValue != null)
{
if (_isFloatAioType)
_aoValue.Value = (float)value;
2023-04-13 11:51:03 +08:00
else
_aoValue.Value = (short)value;
}
}
}
public double OpenDegree
{
get
{
if (_aiOpenDegree != null)
{
return _aiOpenDegree.Value;
2023-04-13 11:51:03 +08:00
}
return 0;
}
}
public double ActMode
{
get
{
if (_aiActMode != null)
{
return _aiActMode.Value;
2023-04-13 11:51:03 +08:00
}
return 0;
}
}
public double SetMode
{
get
{
if (_aoSetMode != null)
{
return _aoSetMode.Value;
2023-04-13 11:51:03 +08:00
}
return 0;
}
set
{
if (_aoSetMode != null)
{
if (_isFloatAioType)
_aoSetMode.Value = (float)value;
2023-04-13 11:51:03 +08:00
else
_aoSetMode.Value = (short)value;
}
}
}
public double DefaultValue
{
get
{
return _scDefaultSetPoint == null ? 1000 : _scDefaultSetPoint.DoubleValue;
}
}
private AITPressureMeterData DeviceData
{
get
{
AITPressureMeterData data = new AITPressureMeterData()
{
Module =Module,
DeviceName = Name,
DeviceSchematicId = DeviceID,
DisplayName = Display,
SetPoint = SetPoint,
FeedBack = FeedBack,
Unit = Unit,
FormatString = _formatString,
DisplayWithUnit = true,
IsError = IsError,
IsWarning = IsWarning,
//Precision = Precision,
Scale = MaxPressure,
ActMode = ActMode,
SetMode = SetMode,
OpenDegree = OpenDegree,
DefaultValue = DefaultValue
};
return data;
}
}
public bool IsWarning => ErrWarningChecker.Result;
2023-04-13 11:51:03 +08:00
public bool IsError
{
get
{
return ErrAlarmChecker.Result;
2023-04-13 11:51:03 +08:00
}
}
public double MaxPressure => _scMaxValue?.DoubleValue ?? 100;
2023-04-13 11:51:03 +08:00
public bool IsOutOfRange => (FeedBack > MaxPressure);
2023-04-13 11:51:03 +08:00
private readonly AIAccessor _aiValue = null;
private readonly AOAccessor _aoValue = null;
private readonly AIAccessor _aiActMode;
private readonly AOAccessor _aoSetMode;
private readonly AIAccessor _aiOpenDegree;
2023-04-13 11:51:03 +08:00
private readonly string _formatString = "0.0";
2023-04-13 11:51:03 +08:00
private SCConfigItem _scUnitValue;
private readonly SCConfigItem _scMaxValue;
private readonly SCConfigItem _scDefaultSetPoint;
private readonly bool _isFloatAioType = false;
2023-04-13 11:51:03 +08:00
private readonly DeviceTimer _rampTimer = new DeviceTimer();
2023-04-13 11:51:03 +08:00
private double _rampTarget;
private double _rampInitValue;
private int _rampTime;
private string _infoText = "";
public IoPressure(string module, XmlElement node, string ioModule = ""): base(module, node, ioModule)
2023-04-13 11:51:03 +08:00
{
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
_aiValue = ParseAiNode("aiValue", node, ioModule);
_aoValue = ParseAoNode("aoValue", node, ioModule);
_aiActMode = ParseAiNode("aiActMode", node, ioModule);
_aoSetMode = ParseAoNode("aoSetMode", node, ioModule);
_aiOpenDegree = ParseAiNode("aiOpenDegree", node, ioModule);
2023-04-13 11:51:03 +08:00
if (node.HasAttribute("formatString"))
_formatString = string.IsNullOrEmpty(node.GetAttribute("formatString")) ? "F5" : node.GetAttribute("formatString");
_scMaxValue = ParseScNode("", node, "", $"{ScBasePath}.{Display}.Scale");
_scDefaultSetPoint = ParseScNode("scDefaultSetPoint", node, ioModule, $"{ScBasePath}.{Display}.DefaultSetPoint");
2023-04-13 11:51:03 +08:00
}
public override bool Initialize()
2023-04-13 11:51:03 +08:00
{
DATA.Subscribe($"{Module}.{Name}.SetPoint", () => SetPoint);
DATA.Subscribe($"{Module}.{Name}.FeedBack", () => FeedBack);
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
DATA.Subscribe($"{Module}.{Name}.SetMode", () => SetMode);
OP.Subscribe($"{Module}.{Name}.Ramp", (out string reason, int time, object[] param) =>
{
reason = "";
double target = Convert.ToDouble(param[0].ToString());
if (target < 0 || target > MaxPressure)
{
reason = $"set {Display} value {target} out of range [0, {MaxPressure}] {Unit}";
return false;
}
Ramp(target, time);
if (time > 0)
{
reason = $"{Display} ramp to {target} {Unit} in {time} seconds";
}
else
{
reason = $"{Display} ramp to {target} {Unit}";
}
return true;
});
OP.Subscribe($"{Module}.{Name}.SetMode", SetContrlMode);
return true;
}
private bool SetContrlMode(out string reason, int time, object[] param)
{
return SetPcMode((PcCtrlMode)Enum.Parse(typeof(PcCtrlMode), (string)param[0], true),
out reason);
}
public bool SetPcMode(PcCtrlMode mode, out string reason)
{
switch (mode)
{
case PcCtrlMode.Normal:
SetMode = (double)PcCtrlMode.Normal;
break;
case PcCtrlMode.Close:
SetMode = (double)PcCtrlMode.Close;
break;
case PcCtrlMode.Open:
SetMode = (double)PcCtrlMode.Open;
break;
case PcCtrlMode.Hold:
SetMode = (double)PcCtrlMode.Hold;
break;
default:
break;
}
reason = $"{Display} set to {mode}";
return true;
}
public void Ramp(double target)
{
_aoValue.Value = (float)target;
2023-04-13 11:51:03 +08:00
}
public void Ramp(double target, int time)
{
_rampTimer.Stop();
target = Math.Max(0, target);
target = Math.Min(MaxPressure, target);
_rampInitValue = SetPoint; //ramp 初始值取当前设定值,而非实际读取值.零漂问题
_rampTime = time;
_rampTarget = target;
_rampTimer.Start(_rampTime);
}
public override void Terminate()
2023-04-13 11:51:03 +08:00
{
_aoValue.Value = (float)DefaultValue;
2023-04-13 11:51:03 +08:00
}
public void StopRamp()
{
if (!_rampTimer.IsIdle())
{
if (_rampTime != 0)
{
Ramp(SetPoint, 0);
}
}
}
private void MonitorRamping()
{
if (!_rampTimer.IsIdle())
{
if (_rampTimer.IsTimeout() || _rampTime == 0)
{
_rampTimer.Stop();
SetPoint = _rampTarget;
}
else
{
SetPoint = _rampInitValue + (_rampTarget - _rampInitValue) * _rampTimer.GetElapseTime() / _rampTime;
}
}
}
protected override void HandleMonitor()
2023-04-13 11:51:03 +08:00
{
MonitorRamping();
// 当SetPoint大于0.01并且没有Ramp时允许检测误差。
MonitorSpFbError(SetPoint >= 0.01 && _rampTimer.IsIdle(), SetPoint, FeedBack);
2023-04-13 11:51:03 +08:00
}
}
}