using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Event; using System; using System.Diagnostics; using System.Xml; namespace Aitex.Core.RT.Device.Unit { /// /// DO reset /// DI alarm signal /// public class IoAlarmSignal : BaseDevice, IDevice { private bool SignalFeedback { get { if (_diSignal != null) return _diSignal.Value; if(_aiSignal != null && !string.IsNullOrEmpty(_condition)) { if (_condition == "H") return _aiSignal.FloatValue > _limitValue; if (_condition == "L") return _aiSignal.FloatValue < _limitValue; } return false; } set { } } private bool SignalSetPoint { get { if (_doReset != null) return _doReset.Value; return false; } set { if (_doReset != null) _doReset.Value = value; } } private AIAccessor _aiSignal = null; private DIAccessor _diSignal = null; private DOAccessor _doReset = null; private Stopwatch _resetTimer = new Stopwatch(); public AlarmEventItem AlarmTriggered { get; set; } public AlarmEventItem AlarmRecovery { get; set; } private RD_TRIG _trigSignalOn = new RD_TRIG(); public RD_TRIG RrigSignalOn => _trigSignalOn; private bool _alarmTrigValue; public bool AlarmTrigValue => _alarmTrigValue; private DeviceTimer _alarmMonitorTimer = new DeviceTimer(); public bool IsAlarmAutoRecovery => _isAlarmAutoRecovery; public bool _isAlarmAutoRecovery; public string Level { get; set; } private float _delayTime;//大于0时,此时间段内一直满足条件才报警 private Stopwatch _delayTimer = new Stopwatch(); private float _limitValue;//大于0时,此时间段内一直满足条件才报警 private string _condition; public AITSensorData DeviceData { get { AITSensorData data = new AITSensorData() { DeviceName = Name, DeviceSchematicId = DeviceID, DisplayName = Display, Value = SignalFeedback, }; return data; } } public bool Value => SignalFeedback; public IoAlarmSignal(string module,string name,DIAccessor diSignal,bool alarmTrigValue=true,bool isAlarmAutoRecovery=false) { base.Module = module; base.Name = name; _diSignal = diSignal; _alarmTrigValue = alarmTrigValue; _isAlarmAutoRecovery = isAlarmAutoRecovery; Initialize(); } public IoAlarmSignal(string module, XmlElement node, string ioModule = "") { 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"); Level = node.GetAttribute("level"); _doReset = ParseDoNode("doReset", node, ioModule); _diSignal = ParseDiNode("diSignal", node, ioModule); _aiSignal = ParseAiNode("aiSignal", node, ioModule); if (_diSignal == null) _diSignal = ParseDiNode("di", node, ioModule); _alarmTrigValue = Convert.ToBoolean(string.IsNullOrEmpty(node.GetAttribute("alarmTrigValue")) ? "true" : node.GetAttribute("alarmTrigValue")); _isAlarmAutoRecovery = Convert.ToBoolean(string.IsNullOrEmpty(node.GetAttribute("alarmAutoRecovery")) ? "false" : node.GetAttribute("alarmAutoRecovery")); _delayTime = Convert.ToSingle(string.IsNullOrEmpty(node.GetAttribute("delay")) ? "0" : node.GetAttribute("delay")); _limitValue = Convert.ToSingle(string.IsNullOrEmpty(node.GetAttribute("limitValue")) ? "0" : node.GetAttribute("limitValue")); _condition = node.GetAttribute("condition"); } public bool Initialize() { //AlarmTriggered = SubscribeAlarm($"{Module}.{Name}.AlarmTriggered", $"{Name} alarm triggered", ResetAlarmChecker); DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData); DATA.Subscribe($"{Module}.{Name}.Value", () => SignalFeedback); _alarmMonitorTimer.Start(2000); return true; } private bool ResetAlarmChecker() { if (SignalFeedback) { if (!SignalSetPoint) { _resetTimer.Restart(); SignalSetPoint = true; } } return !SignalFeedback; } public void Terminate() { } public void Monitor() { if (SC.ContainsItem("System.BypassInterlock") && SC.GetValue("System.BypassInterlock")) return; //两秒后才检测,防止有报警是false值的时候,PLC还没读取数值就报警 if (!_alarmMonitorTimer.IsTimeout()) return; if (AlarmTriggered != null) { if(_delayTime > 0) { if(_alarmTrigValue == SignalFeedback) { if(!_delayTimer.IsRunning) _delayTimer.Restart(); if (_delayTimer.ElapsedMilliseconds > _delayTime * 1000) _trigSignalOn.CLK = true; else _trigSignalOn.CLK = false; } else { _trigSignalOn.CLK = false; _delayTimer.Stop(); } } else { _trigSignalOn.CLK = _alarmTrigValue ? SignalFeedback : !SignalFeedback; } if (_trigSignalOn.R) { AlarmTriggered?.Set(); } if (_trigSignalOn.T) { AlarmTriggered?.Set(); EV.ClearAlarmEvent(AlarmTriggered.EventEnum); LOG.Write($"{AlarmTriggered.EventEnum} is auto recovered"); } if (SignalSetPoint) { if (!SignalFeedback) { AlarmTriggered.Reset(); SignalSetPoint = false; _resetTimer.Stop(); } if (SignalFeedback && _resetTimer.IsRunning && _resetTimer.ElapsedMilliseconds > 5 * 1000) { _resetTimer.Stop(); EV.PostWarningLog(Module, $"Can not reset {Display} in 5 seconds"); SignalSetPoint = false; } } } } public void Reset() { _trigSignalOn.RST = true; if (AlarmTriggered != null) AlarmTriggered.IsAcknowledged = true; } public void SetIgnoreError(bool ignore) { AlarmTriggered.SetIgnoreError(ignore); } } }