ibms-dome/BackendWorkerService/Quartz/Jobs/WeatherAPIJob.cs

965 lines
56 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 Backend.Models;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.BackendRepository.Implement;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using System.Linq;
using NCrontab;
using BackendWorkerService.Services.Implement;
using RainApi;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace BackendWorkerService.Quartz.Jobs
{
[DisallowConcurrentExecution]
class WeatherAPIJob : IJob
{
private readonly ILogger<WeatherAPIJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly IBackendRepository backendRepository;
private readonly ILogger<Task_Detail> loggers;
public WeatherAPIJob(ILogger<WeatherAPIJob> logger,
IBackgroundServiceRepository backgroundServiceRepository, IBackendRepository backendRepository, ILogger<Task_Detail> loggers)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
this.backendRepository = backendRepository;
this.loggers = loggers;
}
public string Fetch_PostWithJSONFormat(string url, string paramter)
{
try
{
var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'";
var variableObix = backgroundServiceRepository.GetAllAsync<KeyValue>(sqlObix).Result;
string username = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault();
string password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
string encoded = Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
HttpWebRequest Postrequest = (HttpWebRequest)WebRequest.Create(url);
Postrequest.Method = "POST";
Postrequest.Headers.Add("Authorization", "Basic " + encoded);
Postrequest.PreAuthenticate = true;
using (var streamWriter = new StreamWriter(Postrequest.GetRequestStream()))
{
if (paramter != "NULL")
{
string json = "<real val=\"" + paramter + "\"/>";
streamWriter.Write(json);
}
else
{
string json = "<real val= NULL />";
streamWriter.Write(json);
}
}
HttpWebResponse response = (HttpWebResponse)Postrequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(responseString);
string jsonText = JsonConvert.SerializeXmlNode(xmlDoc);
//JObject resultVal = (JObject)JsonConvert.DeserializeObject(jsonText);
return jsonText;
}
catch (Exception ex)
{
logger.LogError("【WeatherAPIJob】" + "Fetch_PostWithJSONFormat:" + ex.ToString());
throw ex;
}
}
public async Task Execute(IJobExecutionContext context)
{
Task_Detail task_Detail = new Task_Detail(loggers, backendRepository);
try
{
var obixApiConfig = new ObixApiConfig();
string encoded = string.Empty;
#region obix
var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'";
var variableObix = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlObix);
obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
obixApiConfig.UserName = variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault();
obixApiConfig.Password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
#endregion obix
//取得氣象預報
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "ClearWeatherData"))
{
try
{
await task_Detail.InsertWorkTime("WeatherAPI", "ClearWeatherData", null, new DateTime(DateTime.Now.AddDays(1).Year, DateTime.Now.AddDays(1).Month, DateTime.Now.AddDays(1).Day, 0, 0, 0));
await ClearData("api_weateher", 1);
await task_Detail.InsertWorkTime_End("WeatherAPI", "ClearWeatherData");
}
catch (Exception ex)
{
await task_Detail.WorkFail("WeatherAPI", "ClearWeatherData", ex.Message.ToString());
logger.LogError($"ClearWeatherData error: {ex}, {ex.InnerException}, {ex.Message}");
}
}
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_weateher"))
{
try
{
await task_Detail.InsertWorkTime("WeatherAPI", "api_weateher");
var client = new HttpClient();
var DataNO = "F-D0047-061";
var UVUri = "https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-D0047-061?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&format=JSON&locationName=%E4%BF%A1%E7%BE%A9%E5%8D%80&elementName=Wx,PoP12h,T,RH";
HttpResponseMessage response = client.GetAsync(UVUri).Result;
String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
var observation = JsonConvert.DeserializeObject<Root3>(jsonUVs); // Use Root3 here
logger.LogInformation("【WeatherAPIJob】【取得成功氣象預報】");
if (observation.Success != "true")
{
logger.LogInformation("【WeatherAPIJob】【取得氣象預報資料不正確】");
}
else
{
logger.LogInformation("【WeatherAPIJob】【開始存入氣象預報到資料庫】");
List<Dictionary<string, object>> WeatherAPIdbS = new List<Dictionary<string, object>>();
var Type_ALL = observation.Records.Locations[0].Location[1].WeatherElement; // Location[1]是信義區
foreach (var a in Type_ALL)
{
foreach (var b in a.Time)
{
Dictionary<string, object> WeatherAPIdb = new Dictionary<string, object>()
{
{ "@weather_type", a.ElementName},
{ "@data_no", DataNO},
{ "@created_by", "system"},
{ "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}
};
ProcessElementValue(a, b, WeatherAPIdb, WeatherAPIdbS);
}
}
string sql = @"
INSERT INTO api_weateher (weather_type, data_no, get_value, get_value2, created_by, created_at, start_time, end_time)
VALUES (@weather_type, @data_no, @get_value, @get_value2, @created_by, @created_at, @start_time, @end_time)
ON DUPLICATE KEY UPDATE
get_value = VALUES(get_value),
get_value2 = VALUES(get_value2);";
foreach (var item in WeatherAPIdbS)
{
await backendRepository.ExecuteSql(sql, item);
}
}
await task_Detail.InsertWorkTime_End("WeatherAPI", "api_weateher");
}
catch (Exception ex)
{
await task_Detail.WorkFail("WeatherAPI", "api_weateher", ex.Message.ToString());
}
}
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_rain"))
{
try
{
//await task_Detail.InsertWorkTime("WeatherAPI", "api_rain", null, new DateTime(DateTime.Now.AddDays(1).Year, DateTime.Now.AddDays(1).Month, DateTime.Now.AddDays(1).Day, 0, 25, 0));
await task_Detail.InsertWorkTime("WeatherAPI", "api_rain");
await ClearData("api_rain", 3);
WebClient mywebClient = new WebClient();
mywebClient.DownloadFile("https://opendata.cwa.gov.tw/fileapi/v1/opendataapi/W-C0033-003?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&downloadType=WEB&format=CAP", @"root/PowerfulRain.xml");
XmlDocument doc = new XmlDocument();
doc.Load("root/PowerfulRain.xml");
var json = JsonConvert.SerializeXmlNode(doc);
var observation = JsonConvert.DeserializeObject<RainApi.Welcome>(json);
var taipeiInfo = observation.Alert.Info
.Where(info => info.Area
.Any(area => area.AreaDesc == "臺北市" || area.AreaDesc == "臺北市信義區"))
//.Any(area => area.Geocode.Value == "63" || area.Geocode.Value == "6300200"))
.FirstOrDefault();
var result = "";
if (taipeiInfo != null)
{
var sql = $"select id from api_rain where msgType = '{observation.Alert.MsgType}' and onset = '{taipeiInfo.Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{taipeiInfo.Expires.ToString("yyyy-MM-dd HH:mm:ss")}'";
var NeedCallApi = await backendRepository.GetOneAsync<int>(sql);
if (NeedCallApi == 0)
{
var area = taipeiInfo.Area.Where(a => a.AreaDesc == "臺北市" || a.AreaDesc == "臺北市信義區").Select(x => x.AreaDesc).FirstOrDefault();
var severity_level = taipeiInfo.Parameter
.Where(x => x.ValueName == "severity_level")
.Select(x => x.Value)
.FirstOrDefault();
Dictionary<string, object> RainAPIdb = new Dictionary<string, object>()
{
{ "@msgType", observation.Alert.MsgType},
{ "@headline", taipeiInfo.Headline},
{ "@severity_level", severity_level },
{ "@areaDesc", area},
{ "@onset", taipeiInfo.Onset.ToString("yyyy-MM-dd HH:mm:ss")},
{ "@expires", taipeiInfo.Expires.ToString("yyyy-MM-dd HH:mm:ss")},
{ "@created_by", "system"},
{ "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
var id = await backendRepository.AddOneByCustomTableReturnId(RainAPIdb, "api_rain");
var val = RainValue(severity_level, taipeiInfo.Headline);
if (val < 5)
{
var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/ALMLEVL_RAIN/set", val.ToString());
UpdatedNiagara("api_rain", ReStr, id);
result = ReStr.Contains("err") ? "fail" : "success";
logger.LogInformation($"set niagara rain value {result}");
}
}
}
else
{
// 目前看起來只有全縣市都無警報才會有解除警報的資訊故若警報中途更新後沒臺北了則應視為解除table裡的紀錄只留發生跟解除的紀錄
var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/ALMLEVL_RAIN/set", "0");
result = ReStr.Contains("err") ? "fail" : "success";
logger.LogInformation($"set niagara rain value {result}");
}
FolderFunction folderFunction = new FolderFunction();
folderFunction.DeleteFile(@"root/PowerfulRain.xml");
await task_Detail.InsertWorkTime_End("WeatherAPI", "api_rain");
//var haveinfo = json.Split("info");
//var sql = $"select id from api_rain where msgType = '{observation.Alert.MsgType}' and onset = '{observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")}'";
//if (haveinfo.Length > 2)
//{
// var observation = JsonConvert.DeserializeObject<RainApi.Welcome>(json);
// var area = observation.Alert.Info.Area.Where(a => a.Geocode.Value == "63").Select(a => a.AreaDesc).FirstOrDefault();
// var sql = $"select id from api_rain where msgType = '{observation.Alert.MsgType}' and onset = '{observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")}'";
// var NeedCallApi = await backendRepository.GetOneAsync<int>(sql);
// Dictionary<string, object> RainAPIdb = new Dictionary<string, object>()
// {
// { "@msgType", observation.Alert.MsgType},
// { "@headline", observation.Alert.Info.Headline},
// { "@areaDesc", area},
// { "@onset", observation.Alert.Info.Onset},
// { "@expires", observation.Alert.Info.Expires},
// { "@created_by", "system"},
// { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
// };
// var id = await backendRepository.AddOneByCustomTableReturnId(RainAPIdb, "api_rain");
// if (NeedCallApi != 0)
// {
// var val = RainValue(observation.Alert.MsgType, observation.Alert.Info.Headline);
// if (val < 5)
// {
// var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString());
// UpdatedNiagara("api_rain", ReStr, id);
// logger.LogInformation($"set niagara rain value success");
// }
// }
// FolderFunction folderFunction = new FolderFunction();
// folderFunction.DeleteFile("root/PowerfulRain.xml");
// await task_Detail.InsertWorkTime_End("WeatherAPI", "api_rain");
//}
//else
//{
// var observation = JsonConvert.DeserializeObject<RainApi.Welcome>(json);
// var area = observation.Alert.Info.Area.Where(a => a.Geocode.Value == "63").Select(a => a.AreaDesc).FirstOrDefault();
// var sql = $"select id from api_rain where msgType = '{observation.Alert.MsgType}' and onset = '{observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")}'";
// var NeedCallApi = await backendRepository.GetOneAsync<int>(sql);
// Dictionary<string, object> RainAPIdb = new Dictionary<string, object>()
// {
// { "@msgType", observation.Alert.MsgType},
// { "@headline", observation.Alert.Info.Headline},
// { "@areaDesc", area},
// { "@onset", observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")},
// { "@expires", observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")},
// { "@created_by", "system"},
// { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
// };
// var id = await backendRepository.AddOneByCustomTableReturnId(RainAPIdb, "api_rain");
// if (NeedCallApi != 0)
// {
// var val = RainValue(observation.Alert.MsgType, observation.Alert.Info.Headline);
// if (val < 5)
// {
// var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET1/SeverityLEVL_RAIN/set", val.ToString());
// UpdatedNiagara("api_rain", ReStr, id);
// logger.LogInformation($"set niagara rain value success");
// }
// }
// FolderFunction folderFunction = new FolderFunction();
// folderFunction.DeleteFile("root/PowerfulRain.xml");
// await task_Detail.InsertWorkTime_End("WeatherAPI", "api_rain");
//}
}
catch (Exception ex)
{
await task_Detail.WorkFail("WeatherAPI", "api_rain", ex.Message.ToString());
logger.LogError($"apirain error: {ex}, {ex.InnerException}, {ex.Message}");
}
}
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_typhoon"))
{
try
{
//await task_Detail.InsertWorkTime("WeatherAPI", "api_typhoon", null, new DateTime(DateTime.Now.AddDays(1).Year, DateTime.Now.AddDays(1).Month, DateTime.Now.AddDays(1).Day, 0, 25, 0));
await task_Detail.InsertWorkTime("WeatherAPI", "api_typhoon");
await ClearData("api_typhoon", 3);
WebClient mywebClient = new WebClient();
mywebClient.DownloadFile("https://opendata.cwa.gov.tw/fileapi/v1/opendataapi/W-C0034-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&downloadType=WEB&format=CAP", @"root/Typhoon.xml");
XmlDocument doc = new XmlDocument();
doc.Load(@"root/Typhoon.xml");
var json = JsonConvert.SerializeXmlNode(doc);
var observation = JsonConvert.DeserializeObject<TyphoonApi.Welcome>(json);
var taipeiInfo = observation.Alert.Info
.Where(info => info.Area
.Any(area => area.AreaDesc == "臺北市"))
.FirstOrDefault();
var result = "";
if (taipeiInfo != null)
{
var sql = $"select id from api_typhoon where msgType = '{observation.Alert.MsgType}' and onset = '{taipeiInfo.Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{taipeiInfo.Expires.ToString("yyyy-MM-dd HH:mm:ss")}'";
var NeedCallApi = await backendRepository.GetOneAsync<int>(sql);
if (NeedCallApi == 0)
{
var area = taipeiInfo.Area.Where(a => a.AreaDesc == "臺北市").Select(x => x.AreaDesc).FirstOrDefault();
Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
{
{ "@msgType", observation.Alert.MsgType},
{ "@headline", taipeiInfo.Headline},
{ "@areaDesc", area},
{ "@urgency",taipeiInfo.Urgency},
{ "@severity",taipeiInfo.Severity},
{ "@onset", taipeiInfo.Onset.ToString("yyyy-MM-dd HH:mm:ss")},
{ "@expires", taipeiInfo.Expires.ToString("yyyy-MM-dd HH:mm:ss")},
{ "@created_by", "system"},
{ "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
var id = await backendRepository.AddOneByCustomTableReturnId(EarthquakeAPIdb, "api_typhoon");
if (taipeiInfo.Urgency != null && taipeiInfo.Urgency != "Expected")
{
var val = taipeiInfo.Urgency;
var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/ALMLEVL_Typhoon/set", val);
UpdatedNiagara("api_typhoon", ReStr, id);
result = ReStr.Contains("err") ? "fail" : "success";
logger.LogInformation($"set niagara typhoon value {result}");
}
}
}
else
{
// 目前看起來只有全縣市都無警報才會有解除警報的資訊故若警報中途更新後沒臺北了則應視為解除table裡的紀錄只留發生跟解除的紀錄
var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/ALMLEVL_Typhoon/set", "Past");
result = ReStr.Contains("err") ? "fail" : "success";
logger.LogInformation($"set niagara typhoon value {result}");
}
FolderFunction folderFunction = new FolderFunction();
folderFunction.DeleteFile(@"root/Typhoon.xml");
await task_Detail.InsertWorkTime_End("WeatherAPI", "api_typhoon");
//var haveinfo = json.Split("info");
//if (haveinfo.Length > 2)
//{
// var observation = JsonConvert.DeserializeObject<TyphoonApi.Welcome>(json);
// var area = observation.Alert.Info.Area.Where(a => a.Geocode.Value == "63").Select(a => a.AreaDesc).FirstOrDefault();
// var sql = $"select id from api_typhoon where msgType = '{observation.Alert.MsgType}' and onset = '{observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")}'";
// var NeedCallApi = await backendRepository.GetOneAsync<int>(sql);
// Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
// {
// { "@msgType", observation.Alert.MsgType},
// { "@headline", observation.Alert.Info.Headline},
// { "@areaDesc", area},
// { "@urgency",observation.Alert.Info.Urgency},
// { "@severity",observation.Alert.Info.Severity},
// { "@onset", observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")},
// { "@expires", observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")},
// { "@created_by", "system"},
// { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
// };
// var id = await backendRepository.AddOneByCustomTableReturnId(EarthquakeAPIdb, "api_typhoon");
// if (NeedCallApi != 0)
// {
// if (observation.Alert.Info.Urgency != null && observation.Alert.Info.Urgency != "Expected")
// {
// var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/ALMLEVL_Typhoon/set", observation.Alert.Info.Urgency);
// UpdatedNiagara("api_typhoon", ReStr, id);
// logger.LogInformation($"set niagara typhoon value success");
// }
// }
// FolderFunction folderFunction = new FolderFunction();
// folderFunction.DeleteFile("root/Typhoon.xml");
// await task_Detail.InsertWorkTime_End("WeatherAPI", "api_typhoon");
//}
//else
//{
// var observation = JsonConvert.DeserializeObject<TyphoonApi.Welcome>(json);
// var area = observation.Alert.Info.Area.Where(a => a.Geocode.Value == "63").Select(a => a.AreaDesc).FirstOrDefault();
// var sql = $"select id from api_typhoon where msgType = '{observation.Alert.MsgType}' and onset = '{observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")}'";
// var NeedCallApi = await backendRepository.GetOneAsync<int>(sql);
// Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
// {
// { "@msgType", observation.Alert.MsgType},
// { "@headline", observation.Alert.Info.Headline},
// { "@areaDesc", area},
// { "@urgency",observation.Alert.Info.Urgency},
// { "@severity",observation.Alert.Info.Severity},
// { "@onset", observation.Alert.Info.Onset.ToString("yyyy-MM-dd HH:mm:ss")},
// { "@expires", observation.Alert.Info.Expires.ToString("yyyy-MM-dd HH:mm:ss")},
// { "@created_by", "system"},
// { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
// };
// var id = await backendRepository.AddOneByCustomTableReturnId(EarthquakeAPIdb, "api_typhoon");
// if (NeedCallApi != 0)
// {
// if (observation.Alert.Info.Urgency != null && observation.Alert.Info.Urgency != "Expected")
// {
// var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/ALMLEVL_Typhoon/set", observation.Alert.Info.Urgency);
// UpdatedNiagara("api_typhoon", ReStr, id);
// logger.LogInformation($"set niagara typhoon value success");
// }
// }
// FolderFunction folderFunction = new FolderFunction();
// folderFunction.DeleteFile("root/Typhoon.xml");
// await task_Detail.InsertWorkTime_End("WeatherAPI", "api_typhoon");
//}
}
catch (Exception ex)
{
await task_Detail.WorkFail("WeatherAPI", "api_typhoon", ex.Message.ToString());
}
}
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_earthquake"))
{
try
{
await task_Detail.InsertWorkTime("WeatherAPI", "api_earthquake");
await ClearData("api_earthquake", 3);
var client = new HttpClient();
var UVUri = "https://opendata.cwa.gov.tw/api/v1/rest/datastore/E-A0015-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&format=JSON&areaName=%E8%87%BA%E5%8C%97%E5%B8%82";
HttpResponseMessage response = client.GetAsync(UVUri).Result;
String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
var j = JsonConvert.DeserializeObject(jsonUVs);
var result = "";
var observation = JsonConvert.DeserializeObject<QuickType.Welcome>(jsonUVs);
if (!observation.Success)
{
logger.LogInformation("【WeatherAPIJob】【取得地震觀測資料不正確】");
}
else
{
logger.LogInformation("【WeatherAPIJob】【開始存入地震觀測到資料庫】");
List<Dictionary<string, object>> EarthquakeAPIdbS = new List<Dictionary<string, object>>();
var maxEarthquakeNo = observation.Records.Earthquake.Max(eq => eq.EarthquakeNo);
var eq = observation.Records.Earthquake.Where(eq => eq.EarthquakeNo == maxEarthquakeNo).FirstOrDefault();
var exist = eq.Intensity.ShakingArea.Where(area => area.CountyName == "臺北市").FirstOrDefault();
if (exist != null)
{
var sql = $"select id from api_earthquake where earthquakeNo = {eq.EarthquakeNo}";
var NeedCallApi = await backendRepository.GetOneAsync<int>(sql);
if (NeedCallApi == 0)
{
Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
{
{ "@earthquakeNo", eq.EarthquakeNo},
{ "@newEarthquake", 1},
{ "@originTime", DateTime.Parse(eq.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)},
{ "@magnitudeValue", eq.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue},
{ "@areaName", exist.CountyName},
{ "@areaIntensity", exist.AreaIntensity},
{ "@created_by", "system"},
{ "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/ALMLEVL_LMI/set", Regex.Match(exist.AreaIntensity, @"\d+").ToString());
if (Nag.Contains("err"))
{
EarthquakeAPIdb.Add("@niagara", Nag);
logger.LogInformation($"set niagara earthquake value fail: {Nag}");
}
else
{
EarthquakeAPIdb.Add("@niagara", "success");
logger.LogInformation($"set niagara earthquake value success");
}
EarthquakeAPIdbS.Add(EarthquakeAPIdb);
}
}
else
{
var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/ALMLEVL_LMI/set", "0");
result = Nag.Contains("err") ? "fail" : "success";
logger.LogInformation($"set niagara earthquake value {result}");
}
//var nowNo = await backendRepository.GetOneAsync<int>("select if( Max(earthquakeNo) is null ,0,Max(earthquakeNo)) earthquakeNo from api_earthquake where newEarthquake = 1");
//foreach (var a in observation.Records.Earthquake)
//{
// if (a.EarthquakeNo <= nowNo)
// {
// Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
// {
// { "@earthquakeNo", a.EarthquakeNo},
// { "@newEarthquake", 0},
// { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)},
// { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue},
// { "@areaName", null},
// { "@areaIntensity", null},
// { "@created_by", "system"},
// { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
// };
// EarthquakeAPIdbS.Add(EarthquakeAPIdb);
// break;
// }
// else
// {
// if (a.Intensity.ShakingArea.Count > 0)
// {
// Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
// {
// { "@earthquakeNo", a.EarthquakeNo},
// { "@newEarthquake", 1},
// { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)},
// { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue},
// { "@areaName", a.Intensity.ShakingArea[0].CountyName},
// { "@areaIntensity", a.Intensity.ShakingArea[0].AreaIntensity},
// { "@created_by", "system"},
// { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
// };
// var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/ALMLEVL_LMI/set", a.Intensity.ShakingArea[0].AreaIntensity.ToString());
// if (Nag.Contains("err"))
// {
// EarthquakeAPIdb.Add("@niagara", Nag);
// logger.LogInformation($"set niagara earthquake value fail: {Nag}");
// }
// else
// {
// EarthquakeAPIdb.Add("@niagara", "success");
// logger.LogInformation($"set niagara earthquake value success");
// }
// EarthquakeAPIdbS.Add(EarthquakeAPIdb);
// }
// else
// {
// Dictionary<string, object> EarthquakeAPIdb = new Dictionary<string, object>()
// {
// { "@earthquakeNo", a.EarthquakeNo},
// { "@newEarthquake", 1},
// { "@originTime", DateTime.Parse(a.EarthquakeInfo.OriginTime.ToString(), System.Globalization.CultureInfo.CurrentCulture)},
// { "@magnitudeValue", a.EarthquakeInfo.EarthquakeMagnitude.MagnitudeValue},
// { "@areaName", null},
// { "@areaIntensity", null},
// { "@created_by", "system"},
// { "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
// };
// var Nag = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_GEO/ALMLEVL_LMI/set", "NULL");
// if (Nag.Contains("err"))
// {
// EarthquakeAPIdb.Add("@niagara", Nag);
// logger.LogInformation($"set niagara earthquake value fail: {Nag}");
// }
// else
// {
// EarthquakeAPIdb.Add("@niagara", "success");
// logger.LogInformation($"set niagara earthquake value success");
// }
// EarthquakeAPIdbS.Add(EarthquakeAPIdb);
// }
// }
//}
EarthquakeAPIdbS.Reverse();
if (EarthquakeAPIdbS.Count != 0)
{
await backendRepository.AddMutiByCustomTable(EarthquakeAPIdbS, "api_earthquake");
}
}
await task_Detail.InsertWorkTime_End("WeatherAPI", "api_earthquake");
}
catch (Exception ex)
{
await task_Detail.WorkFail("WeatherAPI", "api_earthquake", ex.Message.ToString());
}
}
// Niagara批次寫法
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "set_weather"))
{
try
{
await task_Detail.InsertWorkTime("WeatherAPI", "set_weather");
var sql = @$"SELECT
id,
weather_type,
get_value
FROM api_weateher
WHERE id IN (
SELECT MAX(id)
FROM api_weateher
WHERE start_time < NOW()
GROUP BY weather_type
)
ORDER BY start_time DESC";
var types = await backendRepository.GetAllAsync<ShowWeather>(sql);
var urlMapping = new Dictionary<string, string>
{
{ "溫度", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set" },
{ "相對濕度", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set" },
{ "3小時降雨機率", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set" },
{ "天氣現象", "obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set" }
};
// 建立批次請求
var batchRequests = types
.Where(t => urlMapping.ContainsKey(t.weather_type))
.Select(t => (
url: obixApiConfig.ApiBase + urlMapping[t.weather_type],
value: t.get_value
))
.ToList();
// 呼叫批次請求
var batchResponse = await ProcessBatchRequestAsync(obixApiConfig, batchRequests);
// 解析回應 XML
var batchResponseXml = XDocument.Parse(batchResponse);
var listElement = batchResponseXml.Descendants().FirstOrDefault(e => e.Name.LocalName == "list");
if (listElement == null)
{
throw new Exception("Batch response XML does not contain a 'list' element.");
}
var childElements = listElement.Elements().ToList();
// 使用 urlMapping 的值反向找對應的 weather_type
for (int i = 0; i < childElements.Count; i++)
{
var tag = childElements[i].Name.LocalName;
var responseStr = childElements[i].ToString();
var currentRequest = batchRequests[i];
// 找到當前 URL 在 urlMapping 中的 key (weather_type)
var weatherTypeKey = urlMapping.FirstOrDefault(x => currentRequest.url.Contains(x.Value)).Key;
if (weatherTypeKey != null)
{
var weatherType = types.FirstOrDefault(t => t.weather_type == weatherTypeKey);
if (weatherType != null)
{
if (tag == "err")
{
UpdatedNiagara("api_weateher", responseStr, weatherType.id);
}
else
{
UpdatedNiagara("api_weateher", "success", weatherType.id);
}
}
else
{
logger.LogWarning($"No matching weather type found for key: {weatherTypeKey}");
}
}
else
{
logger.LogWarning($"No matching URL found for request: {currentRequest.url}");
}
}
await task_Detail.InsertWorkTime_End("WeatherAPI", "set_weather");
logger.LogInformation($"Set Niagara weather value success");
}
catch (Exception ex)
{
logger.LogError($"Set Niagara weather value fail: {ex.Message}");
await task_Detail.WorkFail("WeatherAPI", "set_weather", ex.Message);
}
}
// Niagara單次寫法
//if (await task_Detail.GetNeedWorkTask("WeatherAPI", "set_weather"))
//{
// try
// {
// await task_Detail.InsertWorkTime("WeatherAPI", "set_weather");
// var sql = @$"SELECT
// id,
// weather_type,
// get_value
// FROM api_weateher
// where id in (select MAX(id) from api_weateher where start_time < NOW() group by weather_type)
// order by start_time desc";
// var types = await backendRepository.GetAllAsync<ShowWeather>(sql);
// var T = types.Where(a => a.weather_type == "T").FirstOrDefault();
// var RbT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/T/set", T.get_value);
// UpdatedNiagara("api_weateher", RbT, T.id);
// var RH = types.Where(a => a.weather_type == "RH").FirstOrDefault();
// var RHT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/RH/set", RH.get_value);
// UpdatedNiagara("api_weateher", RHT, RH.id);
// var PoP12h = types.Where(a => a.weather_type == "PoP12h").FirstOrDefault();
// var PoP12hT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/PoP6h/set", PoP12h.get_value);
// UpdatedNiagara("api_weateher", PoP12hT, PoP12h.id);
// var Wx = types.Where(a => a.weather_type == "Wx").FirstOrDefault();
// var WxT = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/OPD/D2_CWB_L110_OPD_element/Wx/set", Wx.get_value);
// UpdatedNiagara("api_weateher", WxT, Wx.id);
// await task_Detail.InsertWorkTime_End("WeatherAPI", "set_weather");
// logger.LogInformation($"set niagara weather value success");
// }
// catch (Exception ex)
// {
// logger.LogInformation($"set niagara weather value fail");
// await task_Detail.WorkFail("WeatherAPI", "set_weather", ex.Message.ToString());
// }
//}
}
catch (Exception exception)
{
logger.LogError("【WeatherAPIJob】【任務失敗】");
logger.LogError("【WeatherAPIJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
public int RainValue(string severity_level, string Headline)
{
var rint = 5;
if (severity_level == null)
{
return 0;
}
else
{
if (Headline.Contains("解除"))
rint = 0;
else if (severity_level.Contains("大雨"))
{
rint = 1;
}
else if (severity_level.Contains("豪雨"))
{
rint = 2;
}
else if (severity_level.Contains("大豪雨"))
{
rint = 3;
}
else if (severity_level.Contains("超大豪雨"))
{
rint = 4;
}
}
return rint;
}
public async Task<string> ProcessBatchRequestAsync(ObixApiConfig obixApiConfig, List<(string url, string value)> batchRequests)
{
try
{
var batchRequestData = new StringBuilder();
string authInfo = Convert.ToBase64String(Encoding.Default.GetBytes($"{obixApiConfig.UserName}:{obixApiConfig.Password}"));
// 組合批次請求的資料
foreach (var request in batchRequests)
{
var jsonData = $"<real name='in' val=\"{request.value}\" />";
batchRequestData.AppendLine($"<uri is='obix:Invoke' val='{request.url}'>" + jsonData + "</uri>");
}
// 最終的批次請求資料
var batchRequestXml = $@"<list is='obix:BatchIn'>{batchRequestData}</list>";
// 建立 HTTP 請求
var requestBacth = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/batch");
requestBacth.Method = "POST";
requestBacth.Headers.Add("Authorization", "Basic " + authInfo);
// 寫入請求資料
using (var streamWriter = new StreamWriter(requestBacth.GetRequestStream()))
{
streamWriter.Write(batchRequestXml);
}
// 獲取回應
using (var response = (HttpWebResponse)await requestBacth.GetResponseAsync())
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
return await streamReader.ReadToEndAsync();
}
}
catch (Exception)
{
return "BatchRequestg失敗";
}
}
//Helper Method to process Element Values
private void ProcessElementValue(WeatherElement3 a, Time b, Dictionary<string, object> WeatherAPIdb, List<Dictionary<string, object>> WeatherAPIdbS)
{
//Common parameters for element value
if (a.ElementName.Contains(ElementName..ToString()) || a.ElementName.Contains(ElementName..ToString()) || a.ElementName.Contains(ElementName..ToString()))
{
if (Convert.ToDateTime(b.StartTime) > DateTime.Now.AddDays(1))
{
return; // Skip to next element
}
WeatherAPIdb.Add("@start_time", Convert.ToDateTime(b.StartTime).ToString("yyyy-MM-dd HH:mm:ss"));
WeatherAPIdb.Add("@end_time", Convert.ToDateTime(b.EndTime).ToString("yyyy-MM-dd HH:mm:ss"));
}
else
{
if (Convert.ToDateTime(b.DataTime) > DateTime.Now.AddDays(1))
{
return; // Skip to next element
}
WeatherAPIdb.Add("@start_time", Convert.ToDateTime(b.DataTime).ToString("yyyy-MM-dd HH:mm:ss"));
WeatherAPIdb.Add("@end_time", null);
}
//Switch statement to handle different element names and their values
switch (a.ElementName)
{
case "溫度":
WeatherAPIdb.Add("@get_value", b.ElementValue[0].Temperature);
WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
break;
//case "露點溫度":
// WeatherAPIdb.Add("@get_value", b.ElementValue[0].DewPoint);
// WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
// break;
case "相對濕度":
WeatherAPIdb.Add("@get_value", b.ElementValue[0].RelativeHumidity);
WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
break;
//case "體感溫度":
// WeatherAPIdb.Add("@get_value", b.ElementValue[0].ApparentTemperature);
// WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
// break;
//case "舒適度指數":
// WeatherAPIdb.Add("@get_value", b.ElementValue[0].ComfortIndex);
// WeatherAPIdb.Add("@get_value2", b.ElementValue[0].ComfortIndexDescription);
// WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
// break;
//case "風速":
// WeatherAPIdb.Add("@get_value", b.ElementValue[0].WindSpeed);
// WeatherAPIdb.Add("@get_value2", b.ElementValue[0].BeaufortScale);
// WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
// break;
//case "風向":
// WeatherAPIdb.Add("@get_value", b.ElementValue[0].WindDirection);
// WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
// break;
case "3小時降雨機率":
WeatherAPIdb.Add("@get_value", b.ElementValue[0].ProbabilityOfPrecipitation);
WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
break;
case "天氣現象":
WeatherAPIdb.Add("@get_value", b.ElementValue[0].Weather);
WeatherAPIdb.Add("@get_value2", b.ElementValue[0].WeatherCode);
WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
break;
//case "天氣預報綜合描述":
// WeatherAPIdb.Add("@get_value", b.ElementValue[0].WeatherDescription);
// WeatherAPIdbS.Add(new Dictionary<string, object>(WeatherAPIdb));
// break;
}
}
public async void UpdatedNiagara(string DBTableName, string ResponseStr, int CheckNumId)
{
try
{
var Su = "success";
if (ResponseStr.Contains("err"))
{
Su = ResponseStr;
}
Dictionary<string, object> RainAPIdb = new Dictionary<string, object>()
{
{ "@niagara", Su}
};
await backendRepository.UpdateOneByCustomTable(RainAPIdb, DBTableName, " id = " + CheckNumId);
}
catch (Exception ex)
{
logger.LogError("【WeatherAPIJob】" + "UpdatedNiagara:" + ex.ToString());
throw ex;
}
}
public async Task ClearData(string tableName, int monthNumber)
{
try
{
string sql = $@"delete from {tableName} WHERE created_at < DATE_SUB(NOW(), INTERVAL {monthNumber} MONTH)";
await backgroundServiceRepository.ExecuteSql(sql);
}
catch (Exception e)
{
logger.LogError($"[ClearData] clear {tableName} data error");
throw e;
}
}
}
}