using FrontendWebApi.Models; using Microsoft.Extensions.Logging; using Quartz; using Repository.BackendRepository.Interface; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace BackendWorkerService.Quartz.Jobs { [DisallowConcurrentExecution] class EmergencyRecordJob : IJob { private readonly ILogger logger; private readonly IBackendRepository backendRepository; private readonly ILogger loggers; public EmergencyRecordJob(ILogger logger, IBackendRepository backendRepository, ILogger loggers) { this.logger = logger; this.backendRepository = backendRepository; this.loggers = loggers; } public async Task Execute(IJobExecutionContext context) { Task_Detail task_Detail = new Task_Detail(loggers, backendRepository); try { if (await task_Detail.GetNeedWorkTask("EmergencyRecordJob", "EmergencyRecord")) { try { await task_Detail.InsertWorkTime("EmergencyRecordJob", "EmergencyRecord"); var sqlString = $@"SELECT system_value FROM variable WHERE system_type = 'obixConfig' AND system_key = 'ApiBase' AND deleted = 0"; string baseApiUrl = await backendRepository.GetOneAsync(sqlString); sqlString = $@"SELECT system_value FROM variable WHERE system_type = 'emergencyConfig' AND system_key = 'getNiagaraAlarmMoveDayNumStart' AND deleted = 0"; int moveDayNum = int.Parse((await backendRepository.GetOneAsync(sqlString)) ?? "-1"); string apiUrl = Path.Combine(baseApiUrl, "obix/config/Services/AlarmService/~alarmQuery/"); var device_disaster = await backendRepository.GetAllAsync("device_disaster",""); using (HttpClient client = new HttpClient()) { string username = "stanGG"; string password = "St12345678"; string encoded = Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password)); client.DefaultRequestHeaders.Add("Authorization", "Basic " + encoded); // 建構 XML 數據 string xmlData = @$" "; HttpContent content = new StringContent(xmlData, Encoding.UTF8, "application/xml"); var response = await client.PostAsync(apiUrl, content); var resString = (await response.Content.ReadAsStringAsync()).ToString(); XDocument xmlDoc = XDocument.Parse(resString); var list = xmlDoc.Descendants().Where(d => d.Name?.LocalName == "list").FirstOrDefault(); var objs = list.Descendants().Where(d => d.Name?.LocalName == "obj" && (d.Attribute("is")?.Value?.Contains("obix:Alarm") ?? false)).ToList(); var dictionaryList = new List>(); List filterList = device_disaster.Select(x => x.device_number).ToList(); var filteredObjs = objs.Where(obj => { var deviceNumber = obj.Descendants().Where(d => d.Name.LocalName == "str" && d.Attribute("name").Value == "sourceName") .Select(d => d.Attribute("val").Value) .Select(d => string.Join("_", d.Split("_").Take(5))) .FirstOrDefault(); return filterList.Contains(deviceNumber); }).ToList(); foreach (var obj in filteredObjs) { var guid = obj.Descendants().Where(d => d.Name.LocalName == "str" && d.Attribute("name").Value == "niagara-uuid"). Select(x => x.Attribute("val").Value).FirstOrDefault(); var alarm_timestamp = obj.Descendants().Where(d => d.Name.LocalName == "abstime" && d.Attribute("name").Value == "timestamp") .Select(d => { DateTime valid; if (DateTime.TryParse(d.Attribute("val").Value, out valid)) { return DateTime.Parse(d.Attribute("val").Value).ToString("yyyy-MM-dd HH:mm:ss"); } else { return null; } }).FirstOrDefault(); var device_number = obj.Descendants().Where(d => d.Name.LocalName == "str" && d.Attribute("name").Value == "sourceName") .Select(d => d.Attribute("val").Value) .Select(d => string.Join("_", d.Split("_").Take(5))) .FirstOrDefault(); var filterDevice = device_disaster.Where(x => x.device_number == device_number).FirstOrDefault(); var dictionary = new Dictionary() { {"@emergency_event_guid",guid}, {"@disaster",filterDevice.device_system_value}, {"@building_tag", filterDevice.device_building_tag}, {"@device_guid",filterDevice.device_guid }, {"@type",0}, {"@alarm_time",alarm_timestamp} }; dictionaryList.Add(dictionary); } // 之前以為沒有唯一識別碼(uuid),故該table有設置一個以device_guid跟alarm_time的unique替代 var mergeSql = @" INSERT INTO emergency_event (emergency_event_guid, disaster, device_guid, building_tag, type, alarm_time) VALUES (@emergency_event_guid, @disaster, @device_guid, @building_tag, @type, @alarm_time) ON DUPLICATE KEY UPDATE disaster = VALUES(disaster), building_tag = VALUES(building_tag), type = VALUES(type)"; await backendRepository.ExecuteSql(mergeSql, dictionaryList); } await task_Detail.InsertWorkTime_End("EmergencyRecordJob", "EmergencyRecord"); } catch (Exception ex) { await task_Detail.WorkFail("EmergencyRecordJob", "EmergencyRecord", ex.Message.ToString()); } } } catch (Exception exception) { logger.LogError("【EmergencyRecordJob】【任務失敗】"); logger.LogError("【EmergencyRecordJob】【任務失敗】[Exception]:{0}", exception.ToString()); } } } }