298 lines
9.0 KiB
C#
298 lines
9.0 KiB
C#
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;
|
||
|
||
namespace Aitex.Core.RT.Device.Devices
|
||
{
|
||
public class IoPressure : ErrorDetectableBaseDevice, IPressureMeter
|
||
{
|
||
public double FeedBack => _isFloatAioType ? _aiValue.FloatValue : _aiValue.Value;
|
||
|
||
public double SetPoint
|
||
{
|
||
get
|
||
{
|
||
if (_aoValue != null)
|
||
return _isFloatAioType ? _aoValue.FloatValue : _aoValue.Value;
|
||
else
|
||
return 0;
|
||
}
|
||
set
|
||
{
|
||
if (_aoValue != null)
|
||
{
|
||
if (_isFloatAioType)
|
||
_aoValue.FloatValue = (float)value;
|
||
else
|
||
_aoValue.Value = (short)value;
|
||
}
|
||
}
|
||
}
|
||
|
||
public double OpenDegree
|
||
{
|
||
get
|
||
{
|
||
if (_aiOpenDegree != null)
|
||
{
|
||
return _aiOpenDegree.FloatValue;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
public double ActMode
|
||
{
|
||
get
|
||
{
|
||
if (_aiActMode != null)
|
||
{
|
||
return _aiActMode.FloatValue;
|
||
}
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
public double SetMode
|
||
{
|
||
get
|
||
{
|
||
if (_aoSetMode != null)
|
||
{
|
||
return _aoSetMode.FloatValue;
|
||
}
|
||
return 0;
|
||
}
|
||
set
|
||
{
|
||
if (_aoSetMode != null)
|
||
{
|
||
if (_isFloatAioType)
|
||
_aoSetMode.FloatValue = (float)value;
|
||
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;
|
||
|
||
public bool IsError
|
||
{
|
||
get
|
||
{
|
||
return ErrAlarmChecker.Result;
|
||
}
|
||
}
|
||
|
||
public double MaxPressure => _scMaxValue?.DoubleValue ?? 100;
|
||
|
||
public bool IsOutOfRange => (FeedBack > MaxPressure);
|
||
|
||
private readonly AIAccessor _aiValue = null;
|
||
private readonly AOAccessor _aoValue = null;
|
||
private readonly AIAccessor _aiActMode;
|
||
private readonly AOAccessor _aoSetMode;
|
||
private readonly AIAccessor _aiOpenDegree;
|
||
|
||
private readonly string _formatString = "0.0";
|
||
|
||
private SCConfigItem _scUnitValue;
|
||
private readonly SCConfigItem _scMaxValue;
|
||
private readonly SCConfigItem _scDefaultSetPoint;
|
||
|
||
private readonly bool _isFloatAioType = false;
|
||
|
||
private readonly DeviceTimer _rampTimer = new DeviceTimer();
|
||
private double _rampTarget;
|
||
private double _rampInitValue;
|
||
private int _rampTime;
|
||
private string _infoText = "";
|
||
|
||
public IoPressure(string module, XmlElement node, string ioModule = ""): base(module, node, ioModule)
|
||
{
|
||
_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);
|
||
|
||
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");
|
||
}
|
||
|
||
public override bool Initialize()
|
||
{
|
||
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.FloatValue = (float)target;
|
||
}
|
||
|
||
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()
|
||
{
|
||
_aoValue.FloatValue = (float)DefaultValue;
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
public override void Monitor()
|
||
{
|
||
MonitorRamping();
|
||
// 当SetPoint大于0.01,并且没有Ramp时,允许检测误差。
|
||
MonitorSpFbError(SetPoint >= 0.01 && _rampTimer.IsIdle(), SetPoint, FeedBack);
|
||
}
|
||
}
|
||
}
|