ibms-dome/FrontendWorkerService/Quartz/Jobs/OntimeAlarmDeviceSubscriptionJob.cs
2022-10-14 16:08:54 +08:00

339 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FrontendWorkerService.Models;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.FrontendRepository.Interface;
using Repository.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace FrontendWorkerService.Quartz.Jobs
{
/// <summary>
/// 透過obix API向Niagara 訂閱告警設備
/// </summary>
[DisallowConcurrentExecution]
class OntimeAlarmDeviceSubscriptionJob : IJob
{
private readonly ILogger<OntimeAlarmDeviceSubscriptionJob> logger;
private readonly IFrontendRepository frontendRepository;
public OntimeAlarmDeviceSubscriptionJob(
ILogger<OntimeAlarmDeviceSubscriptionJob> logger,
IFrontendRepository frontendRepository)
{
this.logger = logger;
this.frontendRepository = frontendRepository;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
string watch_id = string.Empty; //紀錄watch id的編號
XmlDocument xmlDocument = new XmlDocument();
logger.LogInformation("【OntimeAlarmDeviceSubscriptionJob】【任務開始】");
EDFunction ed = new EDFunction();
var obixApiConfig = new ObixApiConfig();
var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'";
var variable = await frontendRepository.GetAllAsync<KeyValue>(sqlObix);
obixApiConfig.ApiBase = variable.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
obixApiConfig.UserName = ed.AESDecrypt(variable.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault());
obixApiConfig.Password = ed.AESDecrypt(variable.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault());
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
ObixAlarmConfig obixAlarmConfig = new ObixAlarmConfig();
obixAlarmConfig.Alarm_watch_id = variable.Where(x => x.Name == "alarm_watch_id").Select(x => x.Value).FirstOrDefault();
#region step 1 watch id是否存活
HttpWebRequest watchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/");
watchServiceRequest.Method = "GET";
watchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
watchServiceRequest.PreAuthenticate = true;
HttpWebResponse watchServiceResponse = (HttpWebResponse)watchServiceRequest.GetResponse();
var watchServiceResponseContent = new StreamReader(watchServiceResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(watchServiceResponseContent);
string watchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject watchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(watchServiceJson);
if (watchServiceJsonResult.ContainsKey("err")) //抓取錯誤
{
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【檢查watch service失敗】");
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【檢查watch service失敗】[錯誤內容]{0}", watchServiceJson);
return;
}
if (watchServiceJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
if (watchServiceJsonResult["obj"]["ref"] != null && watchServiceJsonResult["obj"]["ref"].HasValues)
{
var watchServices = watchServiceJsonResult["obj"]["ref"];
var temp_name_count = 0; //用來計算總共有幾個name
foreach (var watchService in watchServices.Children())
{
var tempKeyValue = watchService.ToString();
if (tempKeyValue.Contains("@name"))
{
temp_name_count++;
}
}
if (temp_name_count > 1)
{ //有多個watch
foreach (var watchService in watchServices.Children())
{
var tempKeyValue = watchService.ToString();
if (tempKeyValue.Contains("@name"))
{
var name = watchService["@name"].ToString();
watch_id = name.Replace("watch", "");
if (watch_id == obixAlarmConfig.Alarm_watch_id)
{ //表示有找到id
break;
}
watch_id = string.Empty;
}
}
}
else
{ //單一個watch
var tempKeyValue = watchServices.ToString();
if (tempKeyValue.Contains("@name"))
{
var name = watchServices["@name"].ToString();
watch_id = name.Replace("watch", "");
if (watch_id != obixAlarmConfig.Alarm_watch_id)
{
watch_id = string.Empty;
}
}
}
}
}
if (string.IsNullOrEmpty(watch_id))
{ //建立watch service
HttpWebRequest makeWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/make/");
makeWatchServiceRequest.Method = "POST";
makeWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
makeWatchServiceRequest.PreAuthenticate = true;
HttpWebResponse makeWatchServiceResponse = (HttpWebResponse)makeWatchServiceRequest.GetResponse();
var makeWatchServiceResponseContent = new StreamReader(makeWatchServiceResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(makeWatchServiceResponseContent);
string makeWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject makeWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(makeWatchServiceJson);
if (makeWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
{
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【重新建立watch service失敗】");
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【重新建立watch service失敗】[錯誤內容]{0}", makeWatchServiceJson);
return;
}
if (makeWatchServiceJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var makeSplit = makeWatchServiceJsonResult["obj"]["@href"].ToString().Split("/");
watch_id = makeSplit[makeSplit.Length - 2].Replace("watch", "");
}
if (!string.IsNullOrEmpty(watch_id))
{
//儲存至variable
Dictionary<string, object> updateWatchId = new Dictionary<string, object>()
{
{ "@system_value", watch_id}
};
await frontendRepository.UpdateOneByCustomTable(updateWatchId, "variable", "system_type = 'obixConfig' AND system_key = 'alarm_watch_id'");
//修改watch service 存活時間
HttpWebRequest changeWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/watch{watch_id}/lease/");
changeWatchServiceRequest.Method = "PUT";
changeWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
changeWatchServiceRequest.PreAuthenticate = true;
var realTime = $@"<reltime val='PT24H0S' />";
byte[] realTimeByteArray = Encoding.UTF8.GetBytes(realTime);
using (Stream reqStream = changeWatchServiceRequest.GetRequestStream())
{
reqStream.Write(realTimeByteArray, 0, realTimeByteArray.Length);
}
HttpWebResponse changeWatchServiceResponse = (HttpWebResponse)changeWatchServiceRequest.GetResponse();
var changeWatchServiceResponseContent = new StreamReader(changeWatchServiceResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(changeWatchServiceResponseContent);
string changeWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject changeWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(changeWatchServiceJson);
if (changeWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
{
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【修改watch service存活時間失敗】");
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【修改watch service存活時間失敗】[錯誤內容]{0}", changeWatchServiceJsonResult);
return;
}
}
}
#endregion step 1 watch id是否存活
#region step 2 alarm feed
HttpWebRequest addWatchServiceRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/watchService/watch{watch_id}/add/");
addWatchServiceRequest.Method = "POST";
addWatchServiceRequest.Headers.Add("Authorization", "Basic " + encoded);
addWatchServiceRequest.PreAuthenticate = true;
var subscripFullString = $@"<obj is='obix: WatchIn'>
<list names = 'hrefs'>
<uri val = '{obixApiConfig.ApiBase}obix/config/Services/OrionAlarmService/~alarmFeed/'/>
</list>
</obj>";
byte[] byteArray = Encoding.UTF8.GetBytes(subscripFullString);
using (Stream reqStream = addWatchServiceRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse addWatchServiceResponse = (HttpWebResponse)addWatchServiceRequest.GetResponse();
var addWatchServiceResponseContent = new StreamReader(addWatchServiceResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(addWatchServiceResponseContent);
string addWatchServiceJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject addWatchServiceJsonResult = (JObject)JsonConvert.DeserializeObject(addWatchServiceJson);
if (addWatchServiceJsonResult.ContainsKey("err")) //抓取錯誤
{
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【告警設備訂閱失敗】");
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【告警設備訂閱失敗】[錯誤內容]{0}", addWatchServiceJsonResult);
return;
}
if (addWatchServiceJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
List<Dictionary<string, object>> ontimeAlarmRawDatas = new List<Dictionary<string, object>>();
List<string> tempDeviceNumbers = new List<string>(); //用來找出設備的區域、系統大小類GUID
List<OntimeAlarmRawDataPreprocess> alarmRawDataPreprocesses = new List<OntimeAlarmRawDataPreprocess>();
var alarmList = addWatchServiceJsonResult["obj"]["list"]["feed"];
if (alarmList["obj"] != null && alarmList["obj"].HasValues)
{
//讀取資料
foreach (var obj in alarmList["obj"])
{
var sourceState = string.Empty;
var sourceName = string.Empty;
//找出
foreach (var str in obj["str"])
{
var tempName = str["@name"].ToString();
if(tempName == "toState")
{
sourceState = str["@val"].ToString();
}
if (tempName == "sourceName")
{
sourceName = str["@val"].ToString();
}
}
if (!string.IsNullOrEmpty(sourceName))
{
var sourceNameSplit = sourceName.Split("_");
var device_number = string.Join("_", sourceNameSplit, 0, sourceNameSplit.Length - 1); //找出設備編號
var name = sourceNameSplit[sourceNameSplit.Length - 1];//找出點位
tempDeviceNumbers.Add(device_number);
OntimeAlarmRawDataPreprocess alarmRawDataPreprocess = new OntimeAlarmRawDataPreprocess()
{
DeviceNumber = device_number,
Name = name,
SourceStatus = sourceState
};
alarmRawDataPreprocesses.Add(alarmRawDataPreprocess);
}
}
}
if(alarmRawDataPreprocesses.Count() > 0)
{
//找出設備的區域、系統大小類GUID
var sql = $@"SELECT * FROM device d WHERE d.deleted = 0 AND d.device_number IN @DeviceNumbers";
var deviceInfos = await frontendRepository.GetAllAsync<DeviceInfo>(sql, new { DeviceNumbers = tempDeviceNumbers });
foreach(var alarmRawDataPreprocess in alarmRawDataPreprocesses)
{
var selectedDeviceInfo = deviceInfos.Where(x => x.device_number == alarmRawDataPreprocess.DeviceNumber).FirstOrDefault();
if(selectedDeviceInfo != null)
{
Dictionary<string, object> ontimeAlarmRawData = new Dictionary<string, object>()
{
{ "@building_guid", selectedDeviceInfo.building_guid },
{ "@main_system_guid", selectedDeviceInfo.main_system_guid },
{ "@sub_system_guid", selectedDeviceInfo.sub_system_guid },
{ "@floor_guid", selectedDeviceInfo.floor_guid },
{ "@device_number", alarmRawDataPreprocess.DeviceNumber},
{ "@name", alarmRawDataPreprocess.Name},
{ "@source_state", alarmRawDataPreprocess.SourceStatus},
};
ontimeAlarmRawDatas.Add(ontimeAlarmRawData);
}
}
}
if (ontimeAlarmRawDatas.Count() > 0)
{
try
{
var insert_update_sql = $@"INSERT INTO ontime_alarm_device_rawdata (building_guid, main_system_guid, sub_system_guid, device_number, name, source_state) VALUES(@building_guid, @main_system_guid, @sub_system_guid, @device_number, @name, @source_state)
ON DUPLICATE KEY UPDATE source_state=@source_state";
await frontendRepository.ExecuteSql(insert_update_sql, ontimeAlarmRawDatas);
}
catch (Exception exception)
{
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【新增設備點位原始資料失敗】");
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【新增設備點位原始資料失敗】[Exception]{0}", exception.ToString());
}
}
}
#endregion step 2 alarm feed
logger.LogInformation("【OntimeAlarmDeviceSubscriptionJob】【任務完成】");
}
catch (Exception exception)
{
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【任務失敗】");
logger.LogError("【OntimeAlarmDeviceSubscriptionJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
}
}