using Prism.Events; using Prism.Mvvm; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Media; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Input; using System.Windows.Threading; using Txgy.EWS.Client.Common.MessageEvents; using Txgy.EWS.Client.Common; using Txgy.EWS.Client.IBLL; using Txgy.EWS.Client.ILog; using Txgy.EWS.Client.Models; using Txgy.EWS.Client.PageModule.Models; using Unity; using static Txgy.EWS.Client.Common.GlobalConfig; using Txgy.EWS.Client.Entity; using Newtonsoft.Json; using System.IO; using System.ComponentModel; using Txgy.Microseismic.BaseLib.Models; using SharpDX.Direct2D1.Effects; using System.Windows.Media.Media3D; using System.Windows.Media; using Txgy.EWS.Client.PageModule.Common; namespace Txgy.EWS.Client.PageModule.ViewModels { public class TitleViewModel : BindableBase { private readonly IEventAggregator _ea; private readonly ISearchMsEventBLL searchMsEventBLL; private readonly ILogHelper _logHelper; Dispatcher _dispatcher; private bool isCanRun = true; SoundPlayer alarmPlayer = new SoundPlayer(); public DateTime SystemRunTime { get; set; } /// /// 报警等级列表 /// public List ListAlarmLevel; public List ListAlramMusic { get; set; } private bool canPlayAlarmSound = true; public bool CanPlayAlarmSound { get { return canPlayAlarmSound; } set { SetProperty(ref canPlayAlarmSound, value); } } public bool IsCanRun { get { return isCanRun; } set { SetProperty(ref isCanRun, value); } } /// /// 刷新间隔(s) /// private int refreshInterval = 3; public int RefreshInterval { get { return refreshInterval; } set { SetProperty(ref refreshInterval, value); } } private string curAlarmMusic; public string CurAlarmMusic { get { return curAlarmMusic; } set { SetProperty(ref curAlarmMusic, value); alarmPlayer.SoundLocation = AppDomain.CurrentDomain.BaseDirectory + "audio\\" + curAlarmMusic; alarmPlayer.LoadAsync(); } } private string runSpan = "0"; public string RunSpan { get { return runSpan; } set { SetProperty(ref runSpan, value); } } private int _receivedEventCount; /// /// 接收到的事件数量 /// public int ReceivedEventCount { get { return _receivedEventCount; } set { SetProperty(ref _receivedEventCount, value); } } private int _alarmedEventCount = 0; /// /// 已报警事件数量 /// public int AlarmedEventCount { get { return _alarmedEventCount; } set { SetProperty(ref _alarmedEventCount, value); } } private AlarmSetting _alarmSetting; /// /// 报警参数 /// public AlarmSetting AlarmSetting { get { return _alarmSetting; } set { SetProperty(ref _alarmSetting, value); } } DateTime alarmEndTime = DateTime.Now; //private double alarmThreshold = 1; ///// ///// 报警阈值:J ///// //public double AlarmThreshold //{ // get { return alarmThreshold; } // set // { // SetProperty(ref alarmThreshold, value); // } //} private AlarmLevelModel curAlarmLevel; /// /// 当前预警等级 /// public AlarmLevelModel CurAlarmLevel { get { return curAlarmLevel; } set { SetProperty(ref curAlarmLevel, value); } } public ICommand ChangeMusicCommand { get => new Prism.Commands.DelegateCommand(() => { LogObject.Log(MethodBase.GetCurrentMethod().Name).Info("===========End==============>>>"); }); } public ICommand StartMonitoringCommand { //2023-02-21 get => new Prism.Commands.DelegateCommand(StartMonitorning); } public TitleViewModel(IUnityContainer unityContainer, IEventAggregator ea, ISearchMsEventBLL searchMsEventBLL, ILogHelper logHelper) { _dispatcher = unityContainer.Resolve(); this._ea = ea; this._logHelper = logHelper; this.searchMsEventBLL = searchMsEventBLL; //AlarmThreshold = 1000; using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + System.Configuration.ConfigurationManager.AppSettings["AlarmSetting"].ToString())) { AlarmSetting = JsonConvert.DeserializeObject(sr.ReadToEnd()); } //AlarmThreshold = AlarmSettingConfig.AlarmThreshold; //RefreshInterval = AlarmSetting.RefreshInterval; RefreshInterval = int.Parse(System.Configuration.ConfigurationManager.AppSettings["RefreshInterval"].ToString()); CurAlarmMusic = AlarmSetting.AlarmSound; ListAlarmLevel = new List(); using (System.IO.StreamReader sr = new System.IO.StreamReader(AppDomain.CurrentDomain.BaseDirectory + System.Configuration.ConfigurationManager.AppSettings["AlarmLevelConfig"].ToString())) { ListAlarmLevel = JsonConvert.DeserializeObject>(sr.ReadToEnd()); } CurAlarmLevel = ListAlarmLevel.First(la => la.Level == 1); _dispatcher.Invoke(new System.Action(() => { GlobalData.CurAlarmLevelValue = CurAlarmLevel.Level; GlobalData.CurAlarmLevelColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString(CurAlarmLevel.ColorStr)); })); ListAlramMusic = new List(); string[] alarmTmpArray = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "audio", "*.wav"); for (int i = 0; i < alarmTmpArray.Length; i++) { ListAlramMusic.Add(Path.GetFileName(alarmTmpArray[i])); } GlobalConfig.IsInitializing = true; //初始化检索数据库数据 Task.Run(async () => { string dataFilePath = GlobalConfig.ProjectConfig.MseedFilePath + "\\"; GlobalData.ListAlarmEventId = new List(); GlobalData.AlarmEvents = new List(); GlobalData.ReceivedEvents = new List(); GlobalData.LastEvent = new GridItemEventResult(); GlobalData.LastEvent.EventID = 0; //预警平面参数 GlobalData.AlarmPlanList = new List(); GlobalData.MidEventList = new List(); DateTime timeNow = DateTime.Now; var events = searchMsEventBLL.GetGridEvents(timeNow.AddMinutes(-GlobalConfig.LoadDataTimeLenMins), timeNow, -3, 0); for (int i = 0; i < events.Count; i++) { await searchMsEventBLL.DownloadJsonDataAsync(events[i], dataFilePath, NotifyView); GlobalConfig.InitializingCounter = ((i+1.0)/(double)events.Count)*100.0; //await Console.Out.WriteLineAsync(GlobalConfig.InitializingCounter.ToString()); } }).ContinueWith(t => { GlobalConfig.IsInitializing = false; }); // } void StartMonitorning() { if (!GlobalData.IsRunning) { this._logHelper.Debug(this, "===========End==============>>>"); //LogObject.Log(MethodBase.GetCurrentMethod().Name).Info("===========End==============>>>"); Task.WaitAll(GlobalData.TaskList.ToArray()); Task.Delay(2000); } else { this._logHelper.Debug(this, "===========Startup==============>>>"); //LogObject.Log(MethodBase.GetCurrentMethod().Name).Info("===========Startup==============>>>"); string dataFilePath = GlobalConfig.ProjectConfig.MseedFilePath + "\\"; AlarmedEventCount = 0; SystemRunTime = DateTime.Now; //DateTime alarmTime = DateTime.Now; DateTime eventFreqTime = DateTime.Now; #region 预警平面参数 //GlobalData.AlarmPlanList = new List(); //GlobalData.MidEventList = new List(); #endregion //2023-03-15新事件查询,每10秒查询一次,如果有新事件,需要下载二进制数据,数据大小:5m左右,因为是远程数据库,下载需要5秒左右。 //2023-04-25已修正 var taskAlarm = Task.Factory.StartNew(new System.Action(async () => { if (GlobalConfig.IsDesign) { alarmEndTime = new DateTime(2023, 4, 1); RefreshInterval = GlobalConfig.DRefreshInterval; // await Task.Delay(3000); int qid = 54171; while (GlobalData.IsRunning) { try { await Task.Delay(500).ContinueWith(async t => { //Console.WriteLine($"查询开始时间:{DateTime.Now.ToString("HH:mm:ss.FFF")}"); //var events = searchMsEventBLL.GetLastEvents(qid); var events = searchMsEventBLL.GetGridEvents(alarmEndTime, alarmEndTime.AddSeconds(3600), -3, 0); foreach (var item in events) { await searchMsEventBLL.DownloadJsonDataAsync(item, dataFilePath, NotifyView); //Console.WriteLine(item.EventID); } //Console.WriteLine($"查询开始时间:{DateTime.Now.ToString("HH:mm:ss.FFF")}"); //alarmEndTime = alarmEndTime.AddMinutes(10); //await searchMsEventBLL.QueryAndDownloadDataAsync(qid, alarmEndTime, dataFilePath, NotifyView); alarmEndTime = alarmEndTime.AddMinutes(60); qid++; //alarmEndTime = DateTime.Parse(GlobalData.LastEvent.EventTime); //alarmEndTime =GlobalData.LastEvent.OTime; }); } catch (Exception ex) { string strLog = String.Format("查询线程,{0}", ex.StackTrace); this._logHelper.Error(this, strLog); throw; } } } else { //获取最后一个事件 GridItemEventResult lastEvent = searchMsEventBLL.GetLastTopEvents(1)[0]; GlobalData.ListAlarmEventId.Add(lastEvent.EventID); GlobalData.LastEvent = new GridItemEventResult(); GlobalData.LastEvent.EventID = lastEvent.EventID; GlobalData.LastEvent.EventTime = lastEvent.EventTime; GlobalData.LastEvent.OTime = DateTime.Parse(lastEvent.EventTime); while (GlobalData.IsRunning) { try { await Task.Delay(RefreshInterval * 1000).ContinueWith(async t => { //2023-04-25 //await searchMsEventBLL.QueryAndDownloadDataAsync(GlobalData.LastEvent.EventID, dataFilePath, NotifyView); //_logHelper.Debug($"{DateTime.Now.ToString("G")}:事件查询完成", ""); //2023-04-26 var events = searchMsEventBLL.GetLastEvents(GlobalData.LastEvent.EventID); foreach (var item in events) { await searchMsEventBLL.DownloadJsonDataAsync(item, dataFilePath, NotifyView); //Console.WriteLine(item.EventID); } }); } catch (Exception ex) { string strLog = String.Format("查询线程,{0}", ex.StackTrace); this._logHelper.Error(this, strLog); //string strInfoLog = String.Format("事件查询异常结束,系统运行时长:{0}", (DateTime.Now - SystemRunTime).TotalSeconds); //this._logHelper.Error(this, strInfoLog); //LogObject.Log(MethodBase.GetCurrentMethod().Name).Error(ex.Message); //throw; } } } })); //事件数量统计查询,每60秒查询一次,大多数情况运行正常,如果遇到网络不好的情况或者新事件查询功能在下载数据,数据库连接会出问题。 var taskEventFreq = Task.Factory.StartNew(new System.Action(async () => { if (GlobalConfig.IsDesign) { eventFreqTime = GlobalConfig.DStartTime; while (GlobalData.IsRunning) { try { await Task.Delay(10000).ContinueWith(async t => { DateTime st = eventFreqTime.AddSeconds(-3600); DateTime et = eventFreqTime; int StatCount = await searchMsEventBLL.StatEventCountAsync(st, et); //通知更新一小时前事件数量 this._ea.GetEvent().Publish(StatCount); eventFreqTime = eventFreqTime.AddSeconds(3600); }); } catch (Exception ex) { string strLog = String.Format("统计线程,{0}", ex.StackTrace); Console.WriteLine(strLog); this._logHelper.Error(this, strLog); //throw; } } } else { while (GlobalData.IsRunning) { try { await Task.Delay(60000).ContinueWith(async t => { DateTime st = eventFreqTime.AddSeconds(-3600); DateTime et = eventFreqTime; int StatCount = await searchMsEventBLL.StatEventCountAsync(st, et); //通知更新一小时前事件数量 this._ea.GetEvent().Publish(StatCount); eventFreqTime = DateTime.Now; }); } catch (Exception ex) { string strLog = String.Format("统计线程,{0}", ex.StackTrace); //Console.WriteLine(strLog); this._logHelper.Error(this, strLog); //throw; } } } })); //更新监控时长 var taskRunTime = Task.Factory.StartNew(new System.Action(async () => { while (GlobalData.IsRunning) { TimeSpan ts = DateTime.Now - SystemRunTime; RunSpan = ts.Days.ToString() + "天" + ts.Hours.ToString() + "小时" + ts.Minutes.ToString() + "分" + ts.Seconds.ToString() + "秒"; await Task.Delay(1000); } })); GlobalData.TaskList.Add(taskAlarm); GlobalData.TaskList.Add(taskEventFreq); GlobalData.TaskList.Add(taskRunTime); } } void NotifyView(GridItemEventResult gier) { _logHelper.Debug($"{DateTime.Now.ToString("G")}:回调执行", "回调执行完成"); //Console.WriteLine($"事件ID:{gier.EventID}下载回调成功,下载结束时间:{DateTime.Now.ToString("HH:mm:ss.FFF")}!"); if (GlobalData.ListAlarmEventId.Contains(gier.EventID)) { // Console.WriteLine($"事件ID:{gier.EventID}已存在,返回!"); _logHelper.Debug($"{DateTime.Now.ToString("G")}:回调执行", $"事件ID:{gier.EventID}已存在,返回"); return; } GlobalData.ListAlarmEventId.Add(gier.EventID); if (gier.EventID > GlobalData.LastEvent.EventID) { gier.DominantFreq = GlobalData.GetDominFreq(gier.EventTime); GlobalData.LastEvent = new GridItemEventResult(); GlobalData.LastEvent.EventID = gier.EventID; GlobalData.LastEvent.EventTime = gier.EventTime; GlobalData.LastEvent.OTime = gier.OTime; _logHelper.Debug($"{DateTime.Now.ToString("G")}:回调执行", $"事件ID:{gier.EventID}LastEvent事件更新。"); //通知主频更新 this._ea.GetEvent().Publish(gier.DominantFreq); _logHelper.Debug($"{DateTime.Now.ToString("G")}:回调执行", $"事件ID:{gier.EventID}LastEvent页面更新。"); } #region 通知页面更新 //通知预警页面图表变化 this._ea.GetEvent().Publish(gier); //计算震源机制 EventFunc.ComputeFM(gier); //计算主频 gier.DominantFreq = GlobalData.GetDominFreq(gier.EventTime); //从接收事件列表中删除超过指定时间范围的数据 var timeoutReceivedEvents = GlobalData.ReceivedEvents.FindAll(re => (DateTime.Now - DateTime.Parse(re.EventTime)).TotalSeconds >= GlobalData.EventShowTimeout).ToArray(); if (timeoutReceivedEvents.Length > 0) { for (int i = timeoutReceivedEvents.Length - 1; i >= 0; i--) { GlobalData.ReceivedEvents.Remove(timeoutReceivedEvents[i]); } } if (gier.ML >= GlobalConfig.MidML) { GlobalData.MidEventList.Add(gier); GlobalData.MidEventCount = GlobalData.MidEventList.Count; SearchPlane(gier); } //添加到已接收事件列表 if (!GlobalData.ReceivedEvents.Contains(gier)) { GlobalData.ReceivedEvents.Add(gier); GlobalData.PlanesAddEvent(gier); this._ea.GetEvent().Publish(gier); } ReceivedEventCount = GlobalData.ReceivedEvents.Count(); //检查预警平面是否失效 if (GlobalConfig.IsDesign) { foreach (var plane in GlobalData.AlarmPlanList) { if (plane.Valid) { //Debug.WriteLine((moniCurTime - plane.Event1.OTime).TotalSeconds); bool ec1 = (alarmEndTime - DateTime.Parse(plane.Event1.EventTime)).TotalSeconds > GlobalData.ValidSecend; if (ec1) { //Debug.WriteLine($"ec1:{(moniCurTime - plane.Event1.OTime).TotalSeconds}"); plane.Valid = false; continue; } bool ec2 = (alarmEndTime - DateTime.Parse(plane.Event2.EventTime)).TotalSeconds > GlobalData.ValidSecend; if (ec2) { //Debug.WriteLine($"ec2:{(moniCurTime - plane.Event2.OTime).TotalSeconds}"); plane.Valid = false; continue; } bool ec3 = (alarmEndTime - DateTime.Parse(plane.Event3.EventTime)).TotalSeconds > GlobalData.ValidSecend; if (ec3) { //Debug.WriteLine($"ec3:{(moniCurTime - plane.Event3.OTime).TotalSeconds}"); plane.Valid = false; //continue; } } } } else { foreach (var plane in GlobalData.AlarmPlanList) { if (plane.Valid) { //Debug.WriteLine((moniCurTime - plane.Event1.OTime).TotalSeconds); bool ec1 = (DateTime.Now - DateTime.Parse(plane.Event1.EventTime)).TotalSeconds > GlobalData.ValidSecend; if (ec1) { //Debug.WriteLine($"ec1:{(moniCurTime - plane.Event1.OTime).TotalSeconds}"); plane.Valid = false; continue; } bool ec2 = (DateTime.Now - DateTime.Parse(plane.Event2.EventTime)).TotalSeconds > GlobalData.ValidSecend; if (ec2) { //Debug.WriteLine($"ec2:{(moniCurTime - plane.Event2.OTime).TotalSeconds}"); plane.Valid = false; continue; } bool ec3 = (DateTime.Now - DateTime.Parse(plane.Event3.EventTime)).TotalSeconds > GlobalData.ValidSecend; if (ec3) { //Debug.WriteLine($"ec3:{(moniCurTime - plane.Event3.OTime).TotalSeconds}"); plane.Valid = false; //continue; } } } } //Console.WriteLine($"删除前平面数量:{GlobalData.AlarmPlanList.Count}"); //删除以失效的平面 GlobalData.AlarmPlanList.RemoveAll(x => x.Valid == false); GlobalData.AlarmPlanCount = GlobalData.AlarmPlanList.Count(); //Console.WriteLine($"删除后平面数量:{GlobalData.AlarmPlanList.Count}"); //统计预警平面的事件每小时频度 int maxFrequency = 0; foreach (var plane in GlobalData.AlarmPlanList) { if (plane.Valid) { var hourlyFrequency = plane.InRangeEventList .GroupBy(e => new DateTime(e.OTime.Year, e.OTime.Month, e.OTime.Day, e.OTime.Hour, 0, 0)) .Select(g => new { Hour = g.Key, Frequency = g.Count() }) .ToList(); if (hourlyFrequency != null) { if (hourlyFrequency.Count > 0) { if (hourlyFrequency[hourlyFrequency.Count - 1].Frequency > maxFrequency) { maxFrequency = hourlyFrequency[hourlyFrequency.Count - 1].Frequency; } } } plane.EventFrequencyList = new List(); //Debug.WriteLine($"平面ID:{plane.ID}\t当前时间:{moniCurTime.ToString("G")}\t最大连续:{plane.MaxUnbrokenSameFocalCount}"); if (!GlobalData.unbrokenSameFocalList.Contains(plane.MaxUnbrokenSameFocalCount)) { GlobalData.unbrokenSameFocalList.Add(plane.MaxUnbrokenSameFocalCount); } if (plane.MaxUnbrokenSameFocalCount < GlobalData.maxUnbrokenFocal) { GlobalData.maxUnbrokenFocal = plane.MaxUnbrokenSameFocalCount; } foreach (var item in hourlyFrequency) { plane.EventFrequencyList.Add(new EventFrequency { StartTime = item.Hour, Frequency = item.Frequency }); if (item.Frequency > GlobalData.maxFrequency) { GlobalData.maxFrequency = item.Frequency; } if (!GlobalData.frequencyList.Contains(item.Frequency)) { GlobalData.frequencyList.Add(item.Frequency); } //Debug.WriteLine($"小时:{item.Hour}\t频度:{item.Frequency}"); } //Debug.WriteLine("---------------------------------------------"); } } if (maxFrequency > 40) { CurAlarmLevel = ListAlarmLevel.First(la => la.Level == 4); } else if (maxFrequency > 30) { CurAlarmLevel = ListAlarmLevel.First(la => la.Level == 3); } else if (maxFrequency > 20) { CurAlarmLevel = ListAlarmLevel.First(la => la.Level == 2); } else if (maxFrequency > 10) { CurAlarmLevel = ListAlarmLevel.First(la => la.Level == 1); } _dispatcher.Invoke(new System.Action(() => { GlobalData.CurAlarmLevelValue = CurAlarmLevel.Level; GlobalData.CurAlarmLevelColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString(CurAlarmLevel.ColorStr)); })); //Console.WriteLine($"maxFre:{maxFrequency}\tLevel:{GlobalData.CurAlarmLevelValue}\tColor:{CurAlarmLevel.ColorStr}"); //如果能量大于设定值,通知报警 if (gier.Energy >= AlarmSetting.AlarmThreshold) { //添加到报警事件列表 if (!GlobalData.AlarmEvents.Contains(gier)) { //通知报警事件更新 this._ea.GetEvent().Publish(gier); //CurAlarmLevel = ListAlarmLevel.First(lal => lal.MaxEnergy >= gier.Energy && lal.MinEnergy <= gier.Energy); //声音报警 if (canPlayAlarmSound) { alarmPlayer.PlaySync(); } if (!GlobalConfig.IsDesign) { //从预警事件列表中删除超过指定时间范围的数据 var timeoutAlarmEvents = GlobalData.AlarmEvents.FindAll(re => (DateTime.Now - DateTime.Parse(re.EventTime)).TotalSeconds >= GlobalData.EventShowTimeout).ToArray(); if (timeoutAlarmEvents.Length > 0) { for (int i = timeoutAlarmEvents.Length - 1; i >= 0; i--) { GlobalData.AlarmEvents.Remove(timeoutAlarmEvents[i]); } } } //报警数量 AlarmedEventCount = GlobalData.AlarmEvents.Count; } //AlarmRecordEntity arent = new AlarmRecordEntity(); //arent.EventId = gier.EventID; //arent.AlarmTime = gier.OriginTime; //arent.AlarmLevel = CurAlarmLevel.Level; //arent.Energy = gier.Energy; //写入报警记录 //var haveAre = fsqlSqLite.Select().Where(are => are.EventId == arent.EventId).ToOne(); //if (haveAre == null) //{ // fsqlSqLite.Insert(arent).ExecuteIdentityAsync(); //} #endregion } } public void SearchPlane(GridItemEventResult newEvent) { if (GlobalData.MidEventList != null) { if (GlobalData.MidEventList.Count > 2) { for (int i = 0; i < GlobalData.MidEventList.Count - 1; i++) { for (int j = i + 1; j < GlobalData.MidEventList.Count; j++) { if (GlobalData.MidEventList[i].EventID != GlobalData.MidEventList[j].EventID && GlobalData.MidEventList[i].EventID != newEvent.EventID && GlobalData.MidEventList[j].EventID != newEvent.EventID) { Plane sf = CreatePlane(GlobalData.AlarmPlanList.Count + 1, GlobalData.MidEventList[i], GlobalData.MidEventList[j], newEvent); GlobalData.AlarmPlanList.Add(sf); } } } } } } public Plane CreatePlane(int id, GridItemEventResult pe1, GridItemEventResult pe2, GridItemEventResult pe3) { Plane sur = new Plane(); sur.ID = id; sur.Event1 = pe1; sur.Pos1 = AbsoluteCoord2RelativeCoord(pe1); sur.Event2 = pe2; sur.Pos2 = AbsoluteCoord2RelativeCoord(pe2); sur.Event3 = pe3; sur.Pos3 = AbsoluteCoord2RelativeCoord(pe3); sur.focal = new Random().Next(3); sur.SetMNPPara(); return sur; } } }