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

299 lines
9.0 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 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.Value : _aiValue.Value;
public double SetPoint
{
get
{
if (_aoValue != null)
return _isFloatAioType ? _aoValue.Value : _aoValue.Value;
else
return 0;
}
set
{
if (_aoValue != null)
{
if (_isFloatAioType)
_aoValue.Value = (float)value;
else
_aoValue.Value = (short)value;
}
}
}
public double OpenDegree
{
get
{
if (_aiOpenDegree != null)
{
return _aiOpenDegree.Value;
}
return 0;
}
}
public double ActMode
{
get
{
if (_aiActMode != null)
{
return _aiActMode.Value;
}
return 0;
}
}
public double SetMode
{
get
{
if (_aoSetMode != null)
{
return _aoSetMode.Value;
}
return 0;
}
set
{
if (_aoSetMode != null)
{
if (_isFloatAioType)
_aoSetMode.Value = (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.Value = (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.Value = (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;
}
}
}
protected override void HandleMonitor()
{
MonitorRamping();
// 当SetPoint大于0.01并且没有Ramp时允许检测误差。
MonitorSpFbError(SetPoint >= 0.01 && _rampTimer.IsIdle(), SetPoint, FeedBack);
}
}
}