Sic01/Modules/SicPM/Devices/IoPressure.cs

305 lines
9.5 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;
namespace SicPM.Devices
{
public class IoPressure : ErrorDetectableIoDeviceBase, IPressureMeter
{
//public double Value
//{
// get
// {
// return _isFloatAioType ? _aiValue.FloatValue : _aiValue.Value;
// }
//}
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 => _scDefaultSetPoint?.DoubleValue ?? 1000;
public bool IsOutOfRange => (FeedBack > MaxPressure);
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 = ErrAlarmChecker.Result,
IsWarning = ErrWarningChecker.Result,
//Precision = Precision,
Scale = MaxPressure,
ActMode = ActMode,
SetMode = SetMode,
OpenDegree = OpenDegree,
DefaultValue = DefaultValue
};
return data;
}
}
public double MaxPressure => _scMaxValue?.DoubleValue ?? 100;
public bool bIsGreen => !DiAlarm?.Value ?? true;
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 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;
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");
var scBasePath = node.GetAttribute("scBasePath");
if (string.IsNullOrEmpty(scBasePath))
scBasePath = $"{Module}.{Name}";
else
{
scBasePath = scBasePath.Replace("{module}", Module);
}
_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);
DATA.Subscribe($"{Module}.{Name}.bIsGreen", () => bIsGreen);
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);
/*AlarmToleranceWarning = SubscribeAlarm($"{Module}.{Name}.OutOfToleranceWarning", "", ResetWarningChecker, EventLevel.Warning);
AlarmToleranceError = SubscribeAlarm($"{Module}.{Name}.OutOfToleranceError", "", ResetErrorChecker);*/
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);
}
}
}