using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Tolerance; using Aitex.Core.Util; using MECF.Framework.Common.Event; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; namespace FurnaceRT.Devices { public class IoPressureMeter : BaseDevice, IDevice { public double Value { get { return FeedBack; } } public double FeedBack { get { if (_aiValue != null) { double _feedback = _isFloatAioType ? _aiValue.FloatValue : _aiValue.Value; return _unSigned ? Math.Max(0, _feedback) : _feedback; } return 0; } } public double Precision { get { return _scPrecision == null ? 1000 : _scPrecision.DoubleValue; } } private AITWaterFlowMeterData DeviceData { get { AITWaterFlowMeterData data = new AITWaterFlowMeterData() { DeviceName = Name, DeviceSchematicId = DeviceID, DisplayName = Display, FeedBack = FeedBack, Unit = Unit }; return data; } } public bool IsWarning { get { return _checkWarning.Result; } } public bool IsError { get { return _checkAlarm.Result; } } public double MinPressure { get { return _scMinValue == null ? 0 : _scMinValue.DoubleValue; } } public double MaxPressure { get { return _scMaxValue == null ? 0 : _scMaxValue.DoubleValue; } } public int WarningTime { get { return _scWarningTime == null ? 0 : _scWarningTime.IntValue; } } public int AlarmTime { get { return _scAlarmTime == null ? 0 : _scAlarmTime.IntValue; } } public bool EnableAlarm { get { return _scEnableAlarm == null ? true : _scEnableAlarm.BoolValue; } } public bool IsOutOfRange { get { if (MinPressure < 0.01 && MaxPressure < 0.01) return false; return (Value < MinPressure) || (Value > MaxPressure); } } public string Unit { get; set; } private AIAccessor _aiValue = null; private string _formatString = "F5"; //是否为无符号数(只显示大于等于0) private bool _unSigned = false; private SCConfigItem _scMinValue; private SCConfigItem _scMaxValue; private SCConfigItem _scEnableAlarm; private SCConfigItem _scWarningTime; private SCConfigItem _scAlarmTime; private SCConfigItem _scPrecision; private ToleranceChecker _checkWarning = new ToleranceChecker(); private ToleranceChecker _checkAlarm = new ToleranceChecker(); public AlarmEventItem AlarmToleranceWarning { get; set; } public AlarmEventItem AlarmToleranceAlarm { get; set; } private bool _isFloatAioType = false; private float _tuningPercent; private double _rangeMin = Int16.MinValue * 0.1; private double _rangeMax = Int16.MaxValue * 0.9; private double _min = Int16.MinValue * 0.1; private double _max = Int16.MaxValue * 0.9; public IoPressureMeter(string module, XmlElement node, string ioModule = "") { var attrModule = node.GetAttribute("module"); base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule; Name = node.GetAttribute("id"); Display = node.GetAttribute("display"); DeviceID = node.GetAttribute("schematicId"); Unit = node.GetAttribute("unit"); _isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType").ToLower() == "float"); _aiValue = ParseAiNode("aiFeedback", node, ioModule); string[] range = node.GetAttribute("scale").Split(','); double.TryParse(range[0], out _rangeMin); double.TryParse(range[1], out _rangeMax); string[] physical = node.GetAttribute("physical").Split(','); double.TryParse(physical[0], out _min); double.TryParse(physical[1], out _max); if (node.HasAttribute("formatString")) _formatString = string.IsNullOrEmpty(node.GetAttribute("formatString")) ? "F5" : node.GetAttribute("formatString"); string scBasePath = node.GetAttribute("scBasePath"); if (string.IsNullOrEmpty(scBasePath)) scBasePath = $"{Module}.{Name}"; else { scBasePath = scBasePath.Replace("{module}", Module); } if (node.HasAttribute("unSigned")) { string unSignedStr = node.GetAttribute("unSigned"); if (!string.IsNullOrEmpty(unSignedStr)) { bool.TryParse(unSignedStr, out _unSigned); } } //_scale = SC.GetValue($"{scBasePath}.PressureScale"); //_phyScale = SC.GetValue($"{scBasePath}.PhyScale"); _scMinValue = ParseScNode("", node, "", $"{scBasePath}.{Name}.MinValue"); _scMaxValue = ParseScNode("", node, "", $"{scBasePath}.{Name}.MaxValue"); _scEnableAlarm = ParseScNode("", node, "", $"{scBasePath}.{Name}.EnableAlarm"); _scWarningTime = ParseScNode("", node, "", $"{scBasePath}.{Name}.WarningTime"); _scAlarmTime = ParseScNode("", node, "", $"{scBasePath}.{Name}.AlarmTime"); _scPrecision = ParseScNode("", node, "", $"{scBasePath}.{Name}.Precision"); } public bool Initialize() { DATA.Subscribe($"{Module}.{Name}.Value", () => Value); DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData); //AlarmToleranceWarning = SubscribeAlarm($"{Module}.{Name}.OutOfToleranceWarning", "", ResetWarningChecker, EventLevel.Warning); //AlarmToleranceError = SubscribeAlarm($"{Module}.{Name}.OutOfToleranceError", "", ResetErrorChecker); AlarmToleranceWarning = SubscribeAlarm(new AlarmEventItem() { EventEnum = $"{Module}.{Name}ToleranceWarning", Description = $"{Name} tolerance warning ", Solution = "No information available. Press[Clear] to delete alarm message.", Explaination = "No information available.", AutoRecovery = false, Level = EventLevel.Warning, Action = EventAction.Clear, Category = "TubeAlarm", }, () => { Reset(); return true; }); AlarmToleranceAlarm = SubscribeAlarm(new AlarmEventItem() { EventEnum = $"{Module}.{Name}ToleranceAlarm", Description = $"{Name} tolerance alarm ", Solution = "No information available. Press[Clear] to delete alarm message.", Explaination = "No information available.", AutoRecovery = false, Level = EventLevel.Alarm, Action = EventAction.Clear, Category = "TubeAlarm", }, () => { Reset(); return true; }); return true; } public void Terminate() { } public void SetTuning(float percent) { if (percent > 0 && percent <= 100) _tuningPercent = percent; } public void UnsetTuning() { _tuningPercent = 0; } public void Monitor() { if (EnableAlarm && (WarningTime > 0)) { _checkWarning.Monitor(Value, MinPressure, MaxPressure, WarningTime); if (_checkWarning.Trig) { AlarmToleranceWarning.Description = $"{Display} out of range [{MinPressure},{MaxPressure}]{Unit} for {WarningTime} seconds"; AlarmToleranceWarning.Set(); } if (!_checkWarning.Result) { AlarmToleranceWarning.Reset(); } } else { AlarmToleranceWarning.Reset(); } if (EnableAlarm && (AlarmTime > 0)) { _checkAlarm.Monitor(Value, MinPressure, MaxPressure, AlarmTime); if (_checkAlarm.Trig) { AlarmToleranceAlarm.Description = $"{Display} out of range [{MinPressure},{MaxPressure}]{Unit} for {AlarmTime} seconds"; AlarmToleranceAlarm.Set(); } if (!_checkAlarm.Result) { AlarmToleranceAlarm.Reset(); } } else { AlarmToleranceAlarm.Reset(); } } public bool ResetWarningChecker() { _checkWarning.RST = true; return true; } public bool ResetErrorChecker() { _checkAlarm.RST = true; return true; } public void Reset() { _checkWarning.RST = true; _checkAlarm.RST = true; AlarmToleranceWarning.Reset(); AlarmToleranceAlarm.Reset(); } private double GetAIScale() { return Converter.Phy2Logic(_isFloatAioType ? _aiValue.FloatValue : _aiValue.Value, _rangeMin, _rangeMax, _min, _max); } } }