using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.ServiceModel; using Aitex.Core.Account; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.Util; using Aitex.Core.WCF; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Event; using MECF.Framework.Common.FAServices; namespace Aitex.Core.RT.Event { public class EventManager : ICommonEvent { #region Variable private const string INFORMATION_EVENT = "INFORMATION_EVENT"; private const string WARNING_EVENT = "WARNING_EVENT"; private const string ALARM_EVENT = "ALARM_EVENT"; public event Action FireEvent; public event Action OnAlarmEvent; public event Action OnEvent; private FixSizeQueue _eventQueue; private FixSizeQueue _alarmQueue; private PeriodicJob _eventJob; private EventDBWriter _eventDb; private EventLogWriter _writerToLog; private EventMailWriter _writerToMail; private EventService _eventService; private ServiceHost _eventServiceHost; /// /// 系统支持的事件类型。 /// private readonly Dictionary _dictEvTypeSource = new(); private List _alarms; #endregion #region Properties public EventService Service => _eventService; public List VidEventList { get { var list = new List(); foreach (var item in _dictEvTypeSource) { list.Add(new VIDItem { DataType = "", Description = item.Value.Description, Index = 0, Name = item.Key, Unit = "" }); } return list; } } public List VidAlarmList { get { var list = new List(); foreach (var alarm in _alarms) { list.Add(new VIDItem { DataType = "", Description = alarm.Description, Index = 0, Name = alarm.EventEnum, Unit = "" }); } return list; } } #endregion #region Methods public void Initialize(string commonEventListXmlFile, bool needCreateService = true, bool needSaveDb = true, bool needMailOut = false, string localEventListXmlFile = null) { InitData(); InitOp(); if (needSaveDb) { _eventDb = new EventDBWriter(); try { _eventDb.Initialize(); } catch (Exception ex) { LOG.Write(ex); } } _writerToLog = new EventLogWriter(); if (needMailOut) { _writerToMail = new EventMailWriter(); } _eventService = new EventService(); if (needCreateService) { try { _eventServiceHost = new ServiceHost(_eventService); _eventServiceHost.Open(); } catch (Exception ex2) { throw new ApplicationException("创建Event服务失败," + ex2.Message); } } _eventQueue = new FixSizeQueue(1000); _alarmQueue = new FixSizeQueue(1000); _alarms = new List(1000); _eventJob = new PeriodicJob(100, PeriodicRun, "EventPeriodicJob", isStartNow: true); try { var eventDefine = CustomXmlSerializer.Deserialize(new FileInfo(commonEventListXmlFile)); foreach (var item in eventDefine.Types) { _dictEvTypeSource[item.EventEnum] = item; } } catch (ArgumentNullException) { throw new ApplicationException("初始化EventManager没有设置Event列表文件"); } catch (FileNotFoundException ex4) { throw new ApplicationException("没有找到Event列表文件," + ex4.Message); } catch (Exception ex5) { throw new ApplicationException("EventDefine文件格式不对," + commonEventListXmlFile + ",\r\n" + ex5.Message); } try { if (!string.IsNullOrEmpty(localEventListXmlFile)) { var eventDefine2 = CustomXmlSerializer.Deserialize(new FileInfo(localEventListXmlFile)); foreach (var item2 in eventDefine2.Types) { _dictEvTypeSource[item2.EventEnum] = item2; } } } catch (ArgumentNullException) { throw new ApplicationException("初始化EventManager没有设置Event列表文件"); } catch (FileNotFoundException ex) { throw new ApplicationException("没有找到Event列表文件," + ex.Message); } catch (Exception ex) { throw new ApplicationException("EventDefine文件格式不对," + localEventListXmlFile + ",\r\n" + ex.Message); } Subscribe(new EventItem(INFORMATION_EVENT, EventType.EventUI_Notify, EventLevel.Information)); Subscribe(new EventItem(WARNING_EVENT, EventType.EventUI_Notify, EventLevel.Warning)); Subscribe(new EventItem(ALARM_EVENT, EventType.EventUI_Notify, EventLevel.Alarm)); EV.InnerEventManager = this; } private void InitData() { DATA.Subscribe("System.LiveAlarmEvent", GetAlarmEvent); DATA.Subscribe("System.ActiveAlarm", () => _alarmQueue.ToList().FindAll(x => !x.IsAcknowledged)); DATA.Subscribe("System.HasActiveAlarm", () => _alarmQueue.ToList().Any(x => !x.IsAcknowledged)); DATA.Subscribe("System.HasActiveAlarmEvent", () => _alarmQueue.ToList().Any(x => x.Level == EventLevel.Alarm && !x.IsAcknowledged)); DATA.Subscribe("System.HasAckedAlarmEvent", () => _alarmQueue.ToList().Any(x => x.Level == EventLevel.Alarm && x.IsAcknowledged)); DATA.Subscribe("System.HasActiveWarningEvent", () => _alarmQueue.ToList().Any(x => x.Level == EventLevel.Warning && !x.IsAcknowledged)); DATA.Subscribe("System.HasAckedWarningEvent", () => _alarmQueue.ToList().Any(x => x.Level == EventLevel.Warning && x.IsAcknowledged)); } private void InitOp() { OP.Subscribe("System.AckAllAlarms", InvokeAckAllAlarms); OP.Subscribe("System.ResetAlarm", InvokeResetAlarm); #region 以下为用于测试Event的操作 OP.Subscribe("System.Diagnosis.GenWarningEvent", (s, args) => { PostWarningLog(ModuleName.System.ToString(), args[0].ToString()); return true; }); OP.Subscribe("System.Diagnosis.GenAlarmEvent", (s, args) => { PostAlarmLog(ModuleName.System.ToString(), args[0].ToString()); return true; }); OP.Subscribe("System.Diagnosis.GenPjDoneEvent", (s, args) => { //WriteEvent(ModuleName.System.ToString(), "PJ_DONE", "LoadLock", "0"); //EV.PostMessage(ModuleName.System.ToString(), EventEnum.PJ_DONE, "LoadLock", "0"); OP.DoOperation("System.AlertJobDone", ModuleName.LoadLock, 0); return true; }); #endregion } /// /// 响应所有报警事件。 /// /// private bool InvokeAckAllAlarms(string arg1, object[] arg2) { AckAlarmEvents(); return true; } /// /// 复位指定的Alarm。 /// /// 请参考UI.Client库中的ModuleAlarmViewModel对象。 ///
/// 在此视图中,可以复位单条Alarm. ///
///
/// /// /// private bool InvokeResetAlarm(string arg1, object[] arg2) { ClearAlarmEvent(); if (arg2 != null && arg2.Length >= 2) { _alarms.FirstOrDefault(x => x.Source == (string)arg2[0] && x.EventEnum == (string)arg2[1])?.Reset(); } return true; } /// /// 终止事件管理器。 /// public void Terminate() { if (_eventJob != null) { _eventJob.Stop(); _eventJob = null; } if (_eventServiceHost != null) { _eventServiceHost.Close(); _eventServiceHost = null; } } /// /// 创建指定的事件并将其写入列队。 /// /// 事件名称。 public void WriteEvent(string eventName) { if (!_dictEvTypeSource.ContainsKey(eventName)) { LOG.Write("Event name not registered, " + eventName); } else { WriteEvent(_dictEvTypeSource[eventName].Source, eventName); } } /// /// 创建指定的事件并将其写入列队。 /// /// 事件所属模组名称。 /// 事件名称。 /// 事件消息。 public void WriteEvent(string module, string eventName, string message) { if (!_dictEvTypeSource.ContainsKey(eventName)) { LOG.Write("Event name not registered, " + eventName); return; } var eventItem = _dictEvTypeSource[eventName].Clone(); eventItem.Source = module; eventItem.Description = message; eventItem.OccuringTime = DateTime.Now; _eventQueue.Enqueue(eventItem); if (eventItem.Level == EventLevel.Alarm || eventItem.Level == EventLevel.Warning) { _alarmQueue.Enqueue(eventItem); OnAlarmEvent?.Invoke(eventItem); } OnEvent?.Invoke(eventItem); _writerToLog.WriteEvent(eventItem); } /// /// 创建指定的事件并将其写入列队。 /// /// 事件名称。 /// public void WriteEvent(string eventName, SerializableDictionary dvid) { if (!_dictEvTypeSource.ContainsKey(eventName)) { LOG.Write("Event name not registered, " + eventName); } else { WriteEvent(_dictEvTypeSource[eventName].Source, eventName, dvid); } } public void WriteEvent(string eventName, SerializableDictionary dvid) { if (!_dictEvTypeSource.ContainsKey(eventName)) { LOG.Error("Event name not registered, " + eventName); return; } var eventItem = _dictEvTypeSource[eventName].Clone(dvid); eventItem.OccuringTime = DateTime.Now; ProceedReceivedEvent(eventItem); } public void WriteEvent(string module, string eventName, params object[] args) { var eventItem = _dictEvTypeSource[eventName].Clone(); eventItem.Source = module; if (_dictEvTypeSource[eventName].Description == null) { return; } eventItem.Description = string.Format(_dictEvTypeSource[eventName].Description, args); if (!string.IsNullOrEmpty(_dictEvTypeSource[eventName].GlobalDescription_en)) { eventItem.GlobalDescription_en = string.Format(_dictEvTypeSource[eventName].GlobalDescription_en, args); } if (!string.IsNullOrEmpty(_dictEvTypeSource[eventName].GlobalDescription_zh)) { eventItem.GlobalDescription_zh = string.Format(_dictEvTypeSource[eventName].GlobalDescription_zh, args); } eventItem.OccuringTime = DateTime.Now; _eventQueue.Enqueue(eventItem); if (eventItem.Level == EventLevel.Alarm || eventItem.Level == EventLevel.Warning) { _alarmQueue.Enqueue(eventItem); OnAlarmEvent?.Invoke(eventItem); } OnEvent?.Invoke(eventItem); _writerToLog.WriteEvent(eventItem); } public void WriteEvent(string module, string eventName, SerializableDictionary dvid, params object[] args) { var eventItem = _dictEvTypeSource[eventName].Clone(); eventItem.Source = module; eventItem.Description = string.Format(_dictEvTypeSource[eventName].Description, args); if (!string.IsNullOrEmpty(_dictEvTypeSource[eventName].GlobalDescription_en)) { eventItem.GlobalDescription_en = string.Format(_dictEvTypeSource[eventName].GlobalDescription_en, args); } if (!string.IsNullOrEmpty(_dictEvTypeSource[eventName].GlobalDescription_zh)) { eventItem.GlobalDescription_zh = string.Format(_dictEvTypeSource[eventName].GlobalDescription_zh, args); } eventItem.OccuringTime = DateTime.Now; eventItem.DVID = dvid; _eventQueue.Enqueue(eventItem); if (eventItem.Level == EventLevel.Alarm || eventItem.Level == EventLevel.Warning) { _alarmQueue.Enqueue(eventItem); OnAlarmEvent?.Invoke(eventItem); } OnEvent?.Invoke(eventItem); _writerToLog.WriteEvent(eventItem); } private void ProceedReceivedEvent(EventItem item) { _eventQueue.Enqueue(item); if (item.Level == EventLevel.Alarm || item.Level == EventLevel.Warning) { _alarmQueue.Enqueue(item); OnAlarmEvent?.Invoke(item); } OnEvent?.Invoke(item); _writerToLog.WriteEvent(item); } public void PostNotificationMessage(string message) { var eventItem = new EventItem { Type = EventType.UIMessage_Notify, Description = message, OccuringTime = DateTime.Now }; _eventQueue.Enqueue(eventItem); _writerToLog.WriteEvent(eventItem); } public void PostPopDialogMessage(EventLevel level, string title, string message) { var eventItem = new EventItem { Type = EventType.Dialog_Nofity, Description = title, Explaination = message, OccuringTime = DateTime.Now, Level = level }; _eventQueue.Enqueue(eventItem); _writerToLog.WriteEvent(eventItem); } public void PostKickoutMessage(string message) { var eventItem = new EventItem { Type = EventType.KickOut_Notify, Description = message, OccuringTime = DateTime.Now }; _eventQueue.Enqueue(eventItem); _writerToLog.WriteEvent(eventItem); } public void PostSoundMessage(string message) { var eventItem = new EventItem { Type = EventType.Sound_Notify, Description = message, OccuringTime = DateTime.Now }; _eventQueue.Enqueue(eventItem); _writerToLog.WriteEvent(eventItem); } private bool PeriodicRun() { while (_eventQueue.TryDequeue(out var ev)) { try { _eventDb?.WriteEvent(ev); _writerToMail?.WriteEvent(ev); _eventService?.FireEvent(ev); FireEvent?.Invoke(ev); } catch (Exception ex) { LOG.Error("Failed to post event", ex); } } return true; } /// /// 返回当前报警事件列表。 /// /// public List GetAlarmEvent() { return _alarmQueue.ToList(); } /// /// 将当前事件管理器中的所有报警事件设置为已响应。 /// public void AckAlarmEvents() { _alarmQueue.ToList().ForEach(x=> { x.IsAcknowledged = true; x.AcknowledgedTime = DateTime.Now; }); } /// /// 清楚当前报警事件列表。 /// public void ClearAlarmEvent() { _alarmQueue.Clear(); } public List QueryDBEvent(string sql) { return _eventDb.QueryDBEvent(sql); } public void Subscribe(EventItem item) { if (!_dictEvTypeSource.ContainsKey(item.EventEnum)) { _dictEvTypeSource[item.EventEnum] = item; if (item is AlarmEventItem eventItem) { _alarms.Add(eventItem); } } } public void PostInfoLog(string module, string message) { WriteEvent(module, INFORMATION_EVENT, message); } public void PostWarningLog(string module, string message) { WriteEvent(module, WARNING_EVENT, message); } public void PostAlarmLog(string module, string message) { WriteEvent(module, ALARM_EVENT, message); } #endregion } }