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
}
}
}
}