using AlarmMonitorWorkerService.Models; using Microsoft.Extensions.Logging; using Quartz; using Repository.FrontendRepository.Interface; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Data.Xml.Dom; using Windows.UI.Notifications; using System.IO; namespace AlarmMonitorWorkerService.Quartz.Jobs { /// /// 監控緊急應變畫面是否有開啟 /// [DisallowConcurrentExecution] class AlarmMonitorJob : IJob { private const string APP_ID = "WPF ToastNotificaiton Test"; private readonly ILogger logger; private readonly IFrontendRepository frontendRepository; public AlarmMonitorJob( ILogger logger, IFrontendRepository frontendRepository) { this.logger = logger; this.frontendRepository = frontendRepository; } public async Task Execute(IJobExecutionContext context) { try { logger.LogInformation("【AlarmMonitorJob】【任務開始】"); //找出當前緊急應變的PID var sqlWatchDog = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'watchDogCongfig'"; var variable = await frontendRepository.GetAllAsync(sqlWatchDog); var alarmPID = variable.Where(x => x.Name == "AlarmPID").Select(x => x.Value).FirstOrDefault(); var category = new PerformanceCounterCategory("Process"); var instances = category.GetInstanceNames(); var hasFound = false; foreach (var instance in instances) { try { using (var counter = new PerformanceCounter(category.CategoryName, "ID Process", instance, true)) { int val = (int)counter.RawValue; if (val == Convert.ToInt32(alarmPID)) { hasFound = true; break; } } } catch (Exception exception) { } } var header = string.Empty; if (!hasFound) { header = "請開啟監控頁面"; } //找出異常的設備 string sql = $@"SELECT amc.id, sl.source source_path, from_unixtime(amc.timestamp/1000,'%Y-%m-%d %H:%i:%s') alarm_timestamp , temp_source.source_name, temp_msg.source_msg FROM alarmorion_orionalarmrecord amc JOIN ( SELECT MAX(amc.alarm) ad, m.source FROM alarmorion_orionalarmsourceorder amc JOIN ( SELECT * FROM alarmorion_orionalarmsource a WHERE substring(a.source,23,5) ='Arena' ) m ON amc.alarmSource = m.id GROUP BY m.source ) sl ON amc.id = sl.ad JOIN( SELECT val.alarm , val.value AS source_name FROM alarmorion_orionalarmfacetvalue val JOIN alarmorion_orionalarmfacetname nam ON val.facetName = nam.id AND nam.facetName = 'sourceName' ) temp_source ON amc.id = temp_source.alarm JOIN( SELECT val.alarm, val.value AS source_msg FROM alarmorion_orionalarmfacetvalue val JOIN alarmorion_orionalarmfacetname nam ON val.facetName = nam.id AND nam.facetName = 'msgText' ) temp_msg ON amc.id = temp_msg.alarm WHERE amc.sourceState = 1"; var alarms = await frontendRepository.GetAllAsync(sql); //組出device_number List tempDeviceNumbers = new List(); foreach (var alarm in alarms) { var alarmSplit = alarm.source_path.Split("|"); var deviceSplit = alarmSplit[alarmSplit.Length - 1].Split("/"); var device_number = deviceSplit[deviceSplit.Length - 3]; var point = deviceSplit[deviceSplit.Length - 2]; alarm.device_number = device_number.Replace("$3", ""); alarm.point = point; tempDeviceNumbers.Add(device_number); } //找出所有設備相關資訊 var sql_device = $@"SELECT d.device_number, d.full_name AS device_name, b.full_name AS building_name, f.full_name AS floor_name, (SELECT v.system_key FROM device_disaster dd JOIN variable v ON v.deleted = 0 AND v.system_type = 'disaster' AND v.system_value = dd.device_system_value WHERE dd.device_guid = d.device_guid ) AS Device_disaster_type_text FROM device d JOIN building b ON b.deleted = 0 AND d.building_guid = b.building_guid JOIN floor f ON f.deleted = 0 AND d.floor_guid = f.floor_guid WHERE d.deleted = 0 AND d.device_number IN @device_numbers"; var deviceInfos = await frontendRepository.GetAllAsync(sql_device, new { device_numbers = tempDeviceNumbers.Distinct().ToList() }); var alarmFormat = @"{0}:{1} {2} {3} {4} {5}觸發"; List alarmMsg = new List(); foreach (var alarm in alarms) { var selected_deviceinfo = deviceInfos.Where(x => x.device_number == alarm.device_number).FirstOrDefault(); if (selected_deviceinfo != null) { alarmMsg.Add(string.Format(alarmFormat, selected_deviceinfo.device_disaster_type_text, alarm.alarm_timestamp, selected_deviceinfo.building_name, selected_deviceinfo.floor_name, selected_deviceinfo.device_name, alarm.point)); } } GenerateToast("IBMS緊急應變通知", null, header, "", string.Join("\n", alarmMsg)); logger.LogInformation("【AlarmMonitorJob】【任務完成】"); } catch (Exception exception) { logger.LogError("【AlarmMonitorJob】【任務失敗】"); logger.LogError("【AlarmMonitorJob】【任務失敗】[Exception]:{0}", exception.ToString()); } } public void GenerateToast(string appid, string imageFullPath, string h1, string h2, string p1) { try { var template = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04); var textNodes = template.GetElementsByTagName("text"); textNodes[0].AppendChild(template.CreateTextNode(h1)); textNodes[1].AppendChild(template.CreateTextNode(h2)); textNodes[2].AppendChild(template.CreateTextNode(p1)); //if (File.Exists(imageFullPath)) //{ // XmlNodeList toastImageElements = template.GetElementsByTagName("image"); // ((XmlElement)toastImageElements[0]).SetAttribute("src", imageFullPath); //} IXmlNode toastNode = template.SelectSingleNode("/toast"); ((XmlElement)toastNode).SetAttribute("duration", "long"); var notifier = ToastNotificationManager.CreateToastNotifier(appid); var notification = new ToastNotification(template); notifier.Show(notification); } catch (Exception) { // Ignore } } } }