212 lines
9.3 KiB
C#
212 lines
9.3 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 監控緊急應變畫面是否有開啟
|
||
/// </summary>
|
||
[DisallowConcurrentExecution]
|
||
class AlarmMonitorJob : IJob
|
||
{
|
||
private const string APP_ID = "WPF ToastNotificaiton Test";
|
||
private readonly ILogger<AlarmMonitorJob> logger;
|
||
private readonly IFrontendRepository frontendRepository;
|
||
|
||
public AlarmMonitorJob(
|
||
ILogger<AlarmMonitorJob> 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<KeyValue>(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<AlarmorionString>(sql);
|
||
|
||
//組出device_number
|
||
List<string> tempDeviceNumbers = new List<string>();
|
||
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<DeviceInfo>(sql_device, new { device_numbers = tempDeviceNumbers.Distinct().ToList() });
|
||
|
||
var alarmFormat = @"{0}:{1} {2} {3} {4} {5}觸發";
|
||
|
||
List<string> alarmMsg = new List<string>();
|
||
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
|
||
}
|
||
}
|
||
}
|
||
}
|