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.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Tolerance; using Aitex.Core.Util; using Aitex.Core.Utilities; 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 Aitex.Core.RT.Device.Unit { public class IoMfm : BaseDevice, IDevice { public string Unit { get; set; } public double Scale { get { if (_scN2Scale == null) return 0; return _scN2Scale.DoubleValue; } } public double FeedBack { get { if (_aiFlow != null) { //double aiValue = _maxScale != 0 ? (_aiFlow.Value * Scale / _maxScale) : _aiFlow.Value; return _aiFlow == null ? 0 : Converter.Phy2Logic(_aiFlow.Value, 0, Scale, _phyScaleMin, _phyScale); ; } return 0; } } public bool EnableAlarm { get { if (_scEnableAlarm != null) return _scEnableAlarm.BoolValue; return false; } } private AITWaterFlowMeterData DeviceData { get { AITWaterFlowMeterData data = new AITWaterFlowMeterData() { DeviceName = Name, DeviceSchematicId = DeviceID, DisplayName = DisplayName, FeedBack = FeedBack < 0 ? 0 : FeedBack, AlarmWatchTable = AlarmWatchTable, Unit = Unit, }; return data; } } public string DisplayName { get { if (_scGasName != null) return _scGasName.StringValue; return Display; } } public string AlarmWatchTable { get; set; } private float _setpoint; private double _phyScaleMin; private double _phyScale; private ToleranceChecker _toleranceCheckerWarning = new ToleranceChecker(); private ToleranceChecker _toleranceCheckerAlarm = new ToleranceChecker(); private AIAccessor _aiFlow; protected SCConfigItem _scGasName; private SCConfigItem _scN2Scale; private SCConfigItem _scEnableAlarm; //tolerance check private float _alarmJudgmentRange; private float _warningJudgmentRange; private float _alarmJudgmentTime; private float _warningJudgmentTime; private float _toleranceJudgmentDelayTime; private DeviceTimer _toleranceJudgmentDelayTimer = new DeviceTimer(); private int _toleranceAlarmEventId; private int _toleranceWarningEventId; public AlarmEventItem AlarmToleranceWarning { get; set; } public AlarmEventItem AlarmToleranceAlarm { get; set; } public IoMfm(string module, XmlElement node, string ioModule = "") { Unit = node.GetAttribute("unit"); base.Module = string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module"); base.Name = node.GetAttribute("id"); base.Display = node.GetAttribute("display"); base.DeviceID = node.GetAttribute("schematicId"); int.TryParse(node.GetAttribute("toleranceAlarmEventId"), out _toleranceAlarmEventId); int.TryParse(node.GetAttribute("toleranceWarningEventId"), out _toleranceWarningEventId); _aiFlow = ParseAiNode("aiFlow", node, ioModule); string scBasePath = node.GetAttribute("scBasePath"); if (string.IsNullOrEmpty(scBasePath)) scBasePath = $"{Module}.{Name}"; else { scBasePath = scBasePath.Replace("{module}", Module); } _scGasName = SC.GetConfigItem($"{scBasePath}.{Name}.Name"); _scN2Scale = ParseScNode("scN2Scale", node, ioModule, $"{scBasePath}.{Name}.N2Scale"); _scEnableAlarm = ParseScNode("scEnableAlarm", node, ioModule, $"{scBasePath}.{Name}.EnableAlarm"); if (SC.ContainsItem($"{scBasePath}.{Name}.FlowUnit")) Unit = SC.GetStringValue($"{scBasePath}.{Name}.FlowUnit"); } public bool Initialize() { DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData); DATA.Subscribe($"{Module}.{Name}.Feedback", () => FeedBack); DATA.Subscribe($"{Module}.{Name}.SetPoint", () => _setpoint); OP.Subscribe($"{Module}.{Name}.SetParameters", SetParameters); OP.Subscribe($"{Module}.{Name}.SetMfmValue", SetMfmValue); _phyScale = SC.GetValue($"{Module}.MFM.{Name}.PhyScale"); _phyScaleMin = SC.GetValue($"{Module}.MFM.{Name}.PhyScaleMin"); //AlarmToleranceWarning = SubscribeAlarm($"{Module}.{Name}.ToleranceWarning", "", ResetWarningChecker, EventLevel.Warning); //AlarmToleranceAlarm = SubscribeAlarm($"{Module}.{Name}.ToleranceAlarm", "", ResetAlarmChecker); //AlarmToleranceWarning.Id = _toleranceWarningEventId; //AlarmToleranceAlarm.Id = _toleranceAlarmEventId; return true; } public void Monitor() { MonitorTolerance(); } public bool ResetWarningChecker() { _toleranceCheckerWarning.Reset(_warningJudgmentTime); return true; } public bool ResetAlarmChecker() { _toleranceCheckerAlarm.Reset(_alarmJudgmentTime); return true; } public void Reset() { AlarmToleranceWarning.Reset(); AlarmToleranceAlarm.Reset(); } public void Terminate() { } private bool SetParameters(out string reason, int time, object[] param) { reason = string.Empty; var paras = param[0].ToString().Split(';');//flow;alarmTable if (System.Text.RegularExpressions.Regex.Match(paras[0].ToString(), @"[a-zA-Z]").Success) { var table = paras[0].ToString().Split(':')[0]; if (SC.ContainsItem($"{Module}.RecipeEditParameter.FlowSetting.{Name}.{table}")) _setpoint = (float)SC.GetValue($"{Module}.RecipeEditParameter.FlowSetting.{Name}.{table}"); } else { float.TryParse(param[0].ToString(), out _setpoint); _setpoint = (float)Converter.Logic2Phy(_setpoint, 0, Scale, 0, _phyScale); } if (paras.Length >= 2) { var alarmWatchTable = paras[1].ToString(); if (SC.ContainsItem($"{Module}.RecipeEditParameter.AlarmWatchTable.FlowAlarmWatch.Table{alarmWatchTable}.DelayTime")) { var scPath = $"{Module}.RecipeEditParameter.AlarmWatchTable.PressureAlarmWatch.Table{alarmWatchTable}"; _toleranceJudgmentDelayTime = (float)SC.GetValue($"{scPath}.DelayTime"); _alarmJudgmentRange = (float)SC.GetValue($"{scPath}.AlarmJudgment"); _warningJudgmentRange = (float)SC.GetValue($"{scPath}.WarningJudgment"); _alarmJudgmentTime = (float)SC.GetValue($"{scPath}.AlarmJudgmentTime"); _warningJudgmentTime = (float)SC.GetValue($"{scPath}.WarningJudgmentTime"); _toleranceJudgmentDelayTimer.Start(0); } else { _toleranceJudgmentDelayTime = 0; _alarmJudgmentRange = 0; _warningJudgmentRange = 0; _alarmJudgmentTime = 0; _warningJudgmentTime = 0; _toleranceJudgmentDelayTimer.Stop(); } ResetWarningChecker(); ResetAlarmChecker(); } return true; } private bool SetMfmValue(out string reason, int time, object[] param) { reason = string.Empty; var paras = param[0].ToString().Split(';'); // setpoint;alarmWatchTable float.TryParse(paras[0].ToString(), out _setpoint); _setpoint = (float)Converter.Logic2Phy(_setpoint, 0, Scale, 0, _phyScale); if (paras.Length > 1) { AlarmWatchTable = paras[1]; if (SC.ContainsItem($"{Module}.RecipeEditParameter.AlarmWatchTable.FlowAlarmWatch.Table{AlarmWatchTable}.DelayTime")) { var scPath = $"{Module}.RecipeEditParameter.AlarmWatchTable.PressureAlarmWatch.Table{AlarmWatchTable}"; _toleranceJudgmentDelayTime = (float)SC.GetValue($"{scPath}.DelayTime"); _alarmJudgmentRange = (float)SC.GetValue($"{scPath}.AlarmJudgment"); _warningJudgmentRange = (float)SC.GetValue($"{scPath}.WarningJudgment"); _alarmJudgmentTime = (float)SC.GetValue($"{scPath}.AlarmJudgmentTime"); _warningJudgmentTime = (float)SC.GetValue($"{scPath}.WarningJudgmentTime"); } else { _toleranceJudgmentDelayTime = 0; _alarmJudgmentRange = 0; _warningJudgmentRange = 0; _alarmJudgmentTime = 0; _warningJudgmentTime = 0; } } return true; } private void MonitorTolerance() { if (!EnableAlarm || _setpoint < 0.01 || _toleranceJudgmentDelayTimer.IsIdle() || _toleranceJudgmentDelayTimer.GetElapseTime() < _toleranceJudgmentDelayTime * 1000) { _toleranceCheckerWarning.RST = true; _toleranceCheckerAlarm.RST = true; return; } if (_warningJudgmentRange != 0 && _warningJudgmentTime > 0) { _toleranceCheckerWarning.Monitor(FeedBack, (_setpoint - Math.Abs(_warningJudgmentRange)), (_setpoint + Math.Abs(_warningJudgmentRange)), _warningJudgmentTime); if (_toleranceCheckerWarning.Trig) { //AlarmToleranceWarning.Description = $"{Display} flow out of range {_warningJudgmentRange} {Unit} in {_warningJudgmentTime:F0} seconds"; AlarmToleranceWarning.Set($"{Display} flow out of range {_warningJudgmentRange} {Unit} in {_warningJudgmentTime:F0} seconds"); } } if (_alarmJudgmentRange != 0 && _alarmJudgmentTime > 0) { _toleranceCheckerAlarm.Monitor(FeedBack, (_setpoint - Math.Abs(_alarmJudgmentRange)), (_setpoint + Math.Abs(_alarmJudgmentRange)), _alarmJudgmentTime); if (_toleranceCheckerAlarm.Trig) { //AlarmToleranceAlarm.Description = $"{Display} flow out of range {_alarmJudgmentRange} {Unit} in {_alarmJudgmentTime:F0} seconds"; AlarmToleranceAlarm.Set($"{Display} flow out of range {_alarmJudgmentRange} {Unit} in {_alarmJudgmentTime:F0} seconds"); } } } } }