太陽能排程

This commit is contained in:
dev02 2025-01-16 15:06:18 +08:00
parent b86a6ff42f
commit 595526ab15
18 changed files with 1840 additions and 472 deletions

View File

@ -266,9 +266,78 @@ namespace Backend.Models
#endregion
#region weather api
public class Root3
{
public string Success { get; set; }
public Records3 Records { get; set; }
}
public class Records3
{
public string DatasetDescription { get; set; }
public string LocationsName { get; set; }
public string Dataid { get; set; }
public List<Locations3> Locations { get; set; }
}
public class Locations3
{
public List<Location3> Location { get; set; }
}
public class Location3
{
public string LocationName { get; set; }
public string Geocode { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public List<WeatherElement3> WeatherElement { get; set; }
}
public class WeatherElement3
{
public string ElementName { get; set; }
public List<Time> Time { get; set; }
}
public class Time
{
public string DataTime { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public List<ElementValue> ElementValue { get; set; }
}
public class ElementValue
{
public string Temperature { get; set; }
public string DewPoint { get; set; }
public string RelativeHumidity { get; set; }
public string ApparentTemperature { get; set; }
public string ComfortIndex { get; set; }
public string ComfortIndexDescription { get; set; }
public string WindSpeed { get; set; }
public string BeaufortScale { get; set; }
public string WindDirection { get; set; }
public string ProbabilityOfPrecipitation { get; set; }
public string Weather { get; set; }
public string WeatherCode { get; set; }
public string WeatherDescription { get; set; }
}
public enum ElementName
{
,
,
,
,
,
,
,
,
,
}
#endregion
}

View File

@ -10,6 +10,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.19" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="3.1.19" />
<PackageReference Include="ncrontab" Version="3.3.1" />
<PackageReference Include="Npgsql" Version="7.0.9" />
<PackageReference Include="Quartz" Version="3.3.3" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
</ItemGroup>

View File

@ -0,0 +1,59 @@
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Bcpg;
using QuickType;
using System;
using System.Collections.Generic;
using System.Text;
using static NPOI.HSSF.Util.HSSFColor;
namespace BackendWorkerService.Models
{
public class device
{
public string site_id { get; set; }
public string site_name { get; set; }
public string device_sys_tag { get; set; }
public DateTime archive_lastDate { get; set; }
public DateTime archive_lastActionDate { get; set; }
public string path_n4 { get; set; }
public string device_id { get; set; }
public DateTime created_at { get; set; }
public byte is_link { get; set; }
public bool isSuccess { get; set; } = true;
}
public class device_point
{
public string device_sys_tag { get; set; }
public string point { get; set; }
public string unit { get; set; }
public string site_id { get; set; }
public string device_id { get; set; }
public string history_path { get; set; }
public byte is_link { get; set; }
}
public class data_value
{
public string device_sys_tag { get; set; }
public string point { get; set; }
public string site_id { get; set; }
public string device_id { get; set; }
public string value_unit { get; set; }
}
public class site
{
public string site_id { get; set; }
public string site_name { get; set; }
}
public class data
{
public string site_id { get; set; }
public string device_id { get; set; }
public string timestamp { get; set; }
public string device_sys_tag { get; set; }
public List<Dictionary<string, decimal>> value { get; set; }
}
}

View File

@ -84,6 +84,7 @@ namespace BackendWorkerService
services.AddTransient<IBackendRepository, BackendRepository>();
services.AddTransient<IBackgroundServiceRepository, BackgroundServiceRepository>();
services.AddTransient<IBackgroundServiceMsSqlRepository, BackgroundServiceMsSqlRepository>();
services.AddTransient<IBackgroundServicePostgresqlRepository, BackgroundServicePostgresqlRepository>();
services.AddTransient<IFrontendRepository, FrontendRepository>();
services.AddTransient<IBaseRepository, BaseRepository>();
#endregion Repository ª`¤J
@ -135,20 +136,33 @@ namespace BackendWorkerService
//);
//#endregion
#region ( )
services.AddSingleton<ArchiveElectricMeterDayJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(ArchiveElectricMeterDayJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:ArchiveElectricMeterDayJob"))
);
#endregion
//#region 電錶歸檔(設定每 天 執行一次)
//services.AddSingleton<ArchiveElectricMeterDayJob>();
//services.AddSingleton(
//new JobSchedule(jobType: typeof(ArchiveElectricMeterDayJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:ArchiveElectricMeterDayJob"))
//);
//#endregion
//#region 定時取得氣象API
#region API
//services.AddSingleton<Quartz.Jobs.WeatherAPIJob>();
//services.AddSingleton(
//new JobSchedule(jobType: typeof(Quartz.Jobs.WeatherAPIJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:WeatherAPIJob"))
//);
//#endregion
#endregion
#region ( )
//services.AddSingleton<ArchiveSolarHourJob>();
//services.AddSingleton(
//new JobSchedule(jobType: typeof(ArchiveSolarHourJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:ArchiveSolarHourJob"))
//);
#endregion
#region ( )
services.AddSingleton<ArchiveSolarDayJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(ArchiveSolarDayJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:ArchiveSolarDayJob"))
);
#endregion
}).ConfigureLogging((hostContext, logFactory) => {
IConfiguration configuration = hostContext.Configuration;

View File

@ -8,6 +8,7 @@ using System.Text;
using System.Threading.Tasks;
using NCrontab;
using static NCrontab.CrontabSchedule;
using Org.BouncyCastle.Utilities;
namespace BackendWorkerService.Quartz
{
@ -72,15 +73,40 @@ namespace BackendWorkerService.Quartz
var sql = $@" select b.system_value from task_detail a
join variable b on a.variable_id = b.id
where a.task = '{task}' and a.task_item = '{task_item}'";
Times = await backendRepository.GetOneAsync<string>(sql);
#region when dont have data
if (string.IsNullOrWhiteSpace(Times))
{
Times = task_item.ToLower() == "hour" ? "0 0 0/1 * * *"
: task_item.ToLower() == "day" ? "0 0 0 1/1 * *"
: task_item.ToLower() == "month" ? "0 0 0 1 1/1 *"
: task_item.ToLower() == "year" ? "0 0 0 1 1 1/1"
: task.ToLower() == "weatherapi" ? "0 0/10 * * * *"
: "* * * * * *";
sql = @$"insert into variable (deleted, system_type, system_key, system_value, system_remark, system_priority, system_parent_id)
values (0, 'taskTime', '{task}_{task_item}', '{Times}', '', 0, 0);";
await backendRepository.ExecuteSql(sql);
sql = $@"select id from variable where system_type = 'taskTime' and system_key = '{task}_{task_item}'";
var id = await backendRepository.GetOneAsync<string>(sql);
sql = $"update task_detail set variable_id = {id} where task = '{task}' and task_item = '{task_item}'";
await backendRepository.ExecuteSql(sql);
}
catch(Exception exception)
#endregion
}
catch (Exception exception)
{
logger.LogError("【Task_Detail】【任務時間獲取失敗】");
logger.LogError("【Task_Detail】【任務時間獲取失敗】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(),task,task_item);
}
return Times;
}
/// <summary>
/// 是否執行任務
/// </summary>
@ -100,6 +126,12 @@ namespace BackendWorkerService.Quartz
string ss = "";
}
if (lastworkTime == null)
{
sql = $"insert into task_detail (task, task_item, lastwork_time, created_at) values ('{task}', '{task_item}', now(), now());";
await backendRepository.ExecuteSql(sql, null);
}
DateTime dateTime = lastworkTime != null ? Convert.ToDateTime(lastworkTime) : Convert.ToDateTime("1970-01-01 00:00:01");
//取得 variable 中的 crob 時間設定 ex: 0 0/1 * * * *
@ -128,10 +160,11 @@ namespace BackendWorkerService.Quartz
{
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@lastwork_time", DateTime.Now},
{ "@lastwork_time", DateTime.Now.ToUniversalTime()},
{ "@success", 2},
{ "@updated_at", DateTime.Now},
{ "@updated_at", DateTime.Now.ToUniversalTime()},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
if(LoggerWord == null)
@ -158,8 +191,8 @@ namespace BackendWorkerService.Quartz
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@success", 0},
{ "@lastwork_end_time", DateTime.Now},
{ "@updated_at", DateTime.Now},
{ "@lastwork_end_time", DateTime.Now.ToUniversalTime()},
{ "@updated_at", DateTime.Now.ToUniversalTime()},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
if (LoggerWord == null)
@ -186,7 +219,7 @@ namespace BackendWorkerService.Quartz
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@success", 1},
{ "@updated_at", DateTime.Now},
{ "@updated_at", DateTime.Now.ToUniversalTime()},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
logger.LogError("【Task_Detail】【任務執行失敗】[Exception]{0},Task:{1},task_item:{2}", reason, task, task_item);

View File

@ -0,0 +1,183 @@
using Backend.Models;
using BackendWorkerService.Models;
using BackendWorkerService.Services.Implement;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace BackendWorkerService.Quartz.Jobs
{
/// <summary>
/// 電錶歸檔,每小時執行,只執行小時歸檔
/// </summary>
[DisallowConcurrentExecution]
class ArchiveSolarDayJob : IJob
{
private readonly ILogger<ArchiveSolarDayJob> logger;
private readonly IBackgroundServicePostgresqlRepository backgroundServiceRepository;
private readonly ILogger<Task_Detail> loggers;
public ArchiveSolarDayJob(
ILogger<ArchiveSolarDayJob> logger,
IBackgroundServicePostgresqlRepository backgroundServiceRepository, ILogger<Task_Detail> loggers)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
this.loggers = loggers;
}
public async Task Execute(IJobExecutionContext context)
{
Task_Detail task_Detail = new Task_Detail(loggers, backgroundServiceRepository);
try
{
if (await task_Detail.GetNeedWorkTask("ArchiveSolarDayJob", "Day"))
{
await task_Detail.InsertWorkTime("ArchiveSolarDayJob", "Day", "太陽能日任務開始");
EDFunction ed = new EDFunction();
XmlDocument xmlDocument = new XmlDocument();
var solarService = new SolarService();
var deviceSyncData = new List<device>();
var devicePointSyncData = new List<device_point>();
var sites = new List<site>();
string bql = string.Empty;
string sql = string.Empty;
#region obix
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 variableObix = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlObix);
obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
obixApiConfig.UserName = ed.AESDecrypt(variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault());
obixApiConfig.Password = ed.AESDecrypt(variableObix.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));
#endregion obix
#region sync solar data
await solarService.SyncSiteInfo(logger, sites, obixApiConfig);
bql = "neql:solar:archive|bql:select slotPath, name,displayName";
await solarService.SyncDevice(logger, deviceSyncData, obixApiConfig, bql, sites);
await solarService.ImportDevice(logger, backgroundServiceRepository, deviceSyncData);
bql = "neql:solar:archive and n:history|bql:select displayName, slotPath";
await solarService.SyncDevicePoint(logger, backgroundServiceRepository, devicePointSyncData, obixApiConfig, bql);
await solarService.ImportDevicePoint(logger, backgroundServiceRepository, devicePointSyncData);
#endregion
#region solar設備
sql = "select * from device where is_link = '1'";
var deviceData = await backgroundServiceRepository.GetAllAsync<device>(sql);
#endregion solar設備
#region solar系統的點位
sql = "select * from device_point where is_link = '1'";
var devicePointData = await backgroundServiceRepository.GetAllAsync<device_point>(sql);
#endregion solar系統的點位
if (deviceData.Any() && devicePointData.Any())
{
var now = DateTime.Now;
var preHour = now.AddDays(-1); //取得前一天
var startTimestamp = $"{preHour.ToString("yyyy-MM-dd")}T23:55:00.000+08:00";
var endTimestamp = $"{now.ToString("yyyy-MM-dd")}T00:00:00.000+08:00";
string intervalValue = "PT5M";
var data_value = new List<data_value>();
await solarService.SyncDataValue(logger, data_value, obixApiConfig);
await solarService.CheckLastData(logger, backgroundServiceRepository, obixApiConfig, deviceData, devicePointData, startTimestamp, endTimestamp, intervalValue, data_value);
startTimestamp = $"{preHour.ToString("yyyy-MM-dd")}T00:00:00.000+08:00";
endTimestamp = $"{now.ToString("yyyy-MM-dd")}T00:00:00.000+08:00";
intervalValue = "PT1H";
if (deviceData.Any())
{
await solarService.SyncData(logger, backgroundServiceRepository, obixApiConfig, deviceData, devicePointData, startTimestamp, endTimestamp, intervalValue, data_value, true);
}
}
await task_Detail.InsertWorkTime_End("ArchiveSolarDayJob", "Day", "太陽能日任務完成");
}
if (await task_Detail.GetNeedWorkTask("ArchiveSolarDayJob", "Month"))
{
await task_Detail.InsertWorkTime("ArchiveSolarDayJob", "Month", "太陽能月任務開始");
EDFunction ed = new EDFunction();
XmlDocument xmlDocument = new XmlDocument();
var solarService = new SolarService();
var deviceSyncData = new List<device>();
var devicePointSyncData = new List<device_point>();
var sites = new List<site>();
string bql = string.Empty;
string sql = string.Empty;
#region obix
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 variableObix = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlObix);
obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
obixApiConfig.UserName = ed.AESDecrypt(variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault());
obixApiConfig.Password = ed.AESDecrypt(variableObix.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));
#endregion obix
#region sync solar data
await solarService.SyncSiteInfo(logger, sites, obixApiConfig);
bql = "neql:solar:archive|bql:select slotPath, name,displayName";
await solarService.SyncDevice(logger, deviceSyncData, obixApiConfig, bql, sites);
await solarService.ImportDevice(logger, backgroundServiceRepository, deviceSyncData);
bql = "neql:solar:archive and n:history|bql:select displayName, slotPath";
await solarService.SyncDevicePoint(logger, backgroundServiceRepository, devicePointSyncData, obixApiConfig, bql);
await solarService.ImportDevicePoint(logger, backgroundServiceRepository, devicePointSyncData);
#endregion
#region solar設備
sql = "select * from device where is_link = '1'";
var deviceData = await backgroundServiceRepository.GetAllAsync<device>(sql);
#endregion solar設備
#region solar系統的點位
sql = "select * from device_point where is_link = '1'";
var devicePointData = await backgroundServiceRepository.GetAllAsync<device_point>(sql);
#endregion solar系統的點位
if (deviceData.Any() && devicePointData.Any())
{
var now = DateTime.Now;
var preHour = now.AddMonths(-1); //取得前一月
var startTimestamp = $"{preHour.ToString("yyyy-MM-dd")}T00:00:00.000+08:00";
var endTimestamp = $"{now.ToString("yyyy-MM-dd")}T00:00:00.000+08:00";
string intervalValue = "PT1H";
var data_value = new List<data_value>();
await solarService.SyncDataValue(logger, data_value, obixApiConfig);
await solarService.SyncData(logger, backgroundServiceRepository, obixApiConfig, deviceData, devicePointData, startTimestamp, endTimestamp, intervalValue, data_value, false);
}
await task_Detail.InsertWorkTime_End("ArchiveSolarDayJob", "Month", "太陽能月任務完成");
}
}
catch (Exception exception)
{
await task_Detail.WorkFail("ArchiveSolarDayJob", "Day", exception.ToString());
logger.LogError("【ArchiveSolarDayJob】【任務失敗】");
logger.LogError("【ArchiveSolarDayJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
}
}

View File

@ -0,0 +1,113 @@
using Backend.Models;
using BackendWorkerService.Models;
using BackendWorkerService.Services.Implement;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace BackendWorkerService.Quartz.Jobs
{
/// <summary>
/// 電錶歸檔,每小時執行,只執行小時歸檔
/// </summary>
[DisallowConcurrentExecution]
class ArchiveSolarHourJob : IJob
{
private readonly ILogger<ArchiveSolarHourJob> logger;
private readonly IBackgroundServicePostgresqlRepository backgroundServiceRepository;
private readonly ILogger<Task_Detail> loggers;
public ArchiveSolarHourJob(
ILogger<ArchiveSolarHourJob> logger,
IBackgroundServicePostgresqlRepository backgroundServiceRepository, ILogger<Task_Detail> loggers)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
this.loggers = loggers;
}
public async Task Execute(IJobExecutionContext context)
{
Task_Detail task_Detail = new Task_Detail(loggers, backgroundServiceRepository);
try
{
if (await task_Detail.GetNeedWorkTask("ArchiveSolarHourJob", "Hour"))
{
await task_Detail.InsertWorkTime("ArchiveSolarHourJob", "Hour", "太陽能時任務開始");
EDFunction ed = new EDFunction();
XmlDocument xmlDocument = new XmlDocument();
var solarService = new SolarService();
var deviceSyncData = new List<device>();
var devicePointSyncData = new List<device_point>();
var sites = new List<site>();
string bql = string.Empty;
string sql = string.Empty;
#region obix
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 variableObix = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlObix);
obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
obixApiConfig.UserName = ed.AESDecrypt(variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault());
obixApiConfig.Password = ed.AESDecrypt(variableObix.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));
#endregion obix
#region sync solar data
await solarService.SyncSiteInfo(logger, sites, obixApiConfig);
bql = "neql:solar:archive|bql:select slotPath, name,displayName";
await solarService.SyncDevice(logger, deviceSyncData, obixApiConfig, bql, sites);
await solarService.ImportDevice(logger, backgroundServiceRepository, deviceSyncData);
bql = "neql:solar:archive and n:history|bql:select displayName, slotPath";
await solarService.SyncDevicePoint(logger, backgroundServiceRepository, devicePointSyncData, obixApiConfig, bql);
await solarService.ImportDevicePoint(logger, backgroundServiceRepository, devicePointSyncData);
#endregion
#region solar設備
sql = "select * from device where is_link = '1'";
var deviceData = await backgroundServiceRepository.GetAllAsync<device>(sql);
#endregion solar設備
#region solar系統的點位
sql = "select * from device_point where is_link = '1'";
var devicePointData = await backgroundServiceRepository.GetAllAsync<device_point>(sql);
#endregion solar系統的點位
if (deviceData.Any() && devicePointData.Any())
{
var now = DateTime.Now;
var preHour = now.AddHours(-1); //取得前一小時
var startTimestamp = $"{preHour.ToString("yyyy-MM-dd")}T{preHour.ToString("HH")}:00:00.000+08:00";
var endTimestamp = $"{now.ToString("yyyy-MM-dd")}T{now.ToString("HH")}:00:00.000+08:00";
string intervalValue = "PT1H";
var data_value = new List<data_value>();
await solarService.SyncDataValue(logger, data_value, obixApiConfig);
await solarService.SyncData(logger, backgroundServiceRepository, obixApiConfig, deviceData, devicePointData, startTimestamp, endTimestamp, intervalValue, data_value, false);
}
await task_Detail.InsertWorkTime_End("ArchiveSolarHourJob", "Hour", "太陽能時任務完成");
}
}
catch (Exception exception)
{
await task_Detail.WorkFail("ArchiveSolarHourJob", "Hour", exception.ToString());
logger.LogError("【ArchiveSolarHourJob】【任務失敗】");
logger.LogError("【ArchiveSolarHourJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
}
}

View File

@ -24,67 +24,23 @@ namespace BackendWorkerService.Quartz.Jobs
class WeatherAPIJob : IJob
{
private readonly ILogger<WeatherAPIJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly IBackendRepository backendRepository;
private readonly IBackgroundServicePostgresqlRepository backgroundServiceRepository;
private readonly ILogger<Task_Detail> loggers;
public WeatherAPIJob(ILogger<WeatherAPIJob> logger,
IBackgroundServiceRepository backgroundServiceRepository, IBackendRepository backendRepository, ILogger<Task_Detail> loggers)
public WeatherAPIJob(ILogger<WeatherAPIJob> logger, IBackgroundServicePostgresqlRepository backgroundServiceRepository, 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
{
string username = "stanGG";
string password = "St12345678";
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);
Task_Detail task_Detail = new Task_Detail(loggers, backgroundServiceRepository);
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'";
@ -95,7 +51,8 @@ namespace BackendWorkerService.Quartz.Jobs
encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
#endregion obix
//取得氣象預報
#region
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_weateher"))
{
try
@ -103,11 +60,11 @@ namespace BackendWorkerService.Quartz.Jobs
await task_Detail.InsertWorkTime("WeatherAPI", "api_weateher");
var client = new HttpClient();
var DataNO = "F-D0047-061";
var UVUri = "https://opendata.cwb.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";
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<Root>(jsonUVs);
var observation = JsonConvert.DeserializeObject<Root3>(jsonUVs);
logger.LogInformation("【WeatherAPIJob】【取得成功氣象預報】");
if (observation.Success != "true")
@ -119,67 +76,200 @@ namespace BackendWorkerService.Quartz.Jobs
logger.LogInformation("【WeatherAPIJob】【開始存入氣象預報到資料庫】");
List<Dictionary<string, object>> WeatherAPIdbS = new List<Dictionary<string, object>>();
var Type_ALL = observation.Records.Locations[0].Location[0].WeatherElement;
string sql = "";
if (Type_ALL.Any())
{
foreach (var a in Type_ALL)
{
if (a.ElementName.Contains(ElementName..ToString()))
{
foreach (var b in a.Time)
{
if (a.ElementName == "PoP12h" || a.ElementName == "Wx")
foreach (var c in b.ElementValue)
{
if (Convert.ToDateTime(b.StartTime) > DateTime.Now.AddDays(1))
{
break;
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.DewPoint}'
WHERE start_time = '{b.DataTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.DataTime}', null, now(), '{a.ElementName}', '{DataNO}', '{c.DewPoint}', null
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
else
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
if (Convert.ToDateTime(b.DataTime) > DateTime.Now.AddDays(1))
foreach (var b in a.Time)
{
break;
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.ApparentTemperature}'
WHERE start_time = '{b.DataTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.DataTime}', null, now(), '{a.ElementName}', '{DataNO}', '{c.ApparentTemperature}', null
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
Dictionary<string, object> WeatherAPIdb = new Dictionary<string, object>()
{
{ "@weather_type", a.ElementName},
{ "@data_no", DataNO},
{ "@get_value", b.ElementValue[0].Value},
{ "@measures", b.ElementValue[0].Measures},
{ "@created_by", "system"},
{ "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
if (a.ElementName == "PoP12h" || a.ElementName == "Wx")
{
WeatherAPIdb.Add("@start_time", b.StartTime);
WeatherAPIdb.Add("@end_time", b.EndTime);
}
else
else if (a.ElementName.Contains(ElementName..ToString()))
{
WeatherAPIdb.Add("@start_time", b.DataTime);
WeatherAPIdb.Add("@end_time", null);
foreach (var b in a.Time)
{
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.Temperature}'
WHERE start_time = '{b.DataTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.DataTime}', null, now(), '{a.ElementName}', '{DataNO}', '{c.Temperature}', null
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
WeatherAPIdbS.Add(WeatherAPIdb);
if (a.ElementName == "Wx")
}
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
Dictionary<string, object> TWeatherAPIdb = new Dictionary<string, object>()
foreach (var b in a.Time)
{
{ "@weather_type", "WxV"},
{ "@data_no", DataNO},
{ "@get_value", b.ElementValue[1].Value},
{ "@measures", b.ElementValue[1].Measures},
{ "@start_time", b.StartTime},
{ "@end_time", b.EndTime},
{ "@created_by", "system"},
{ "@created_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
WeatherAPIdbS.Add(TWeatherAPIdb);
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.RelativeHumidity}'
WHERE start_time = '{b.DataTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.DataTime}', null, now(), '{a.ElementName}', '{DataNO}', '{c.RelativeHumidity}', null
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
foreach (var b in a.Time)
{
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.ComfortIndex}', get_value2 = '{c.ComfortIndexDescription}'
WHERE start_time = '{b.DataTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.DataTime}', null, now(), '{a.ElementName}', '{DataNO}', '{c.ComfortIndex}', '{c.ComfortIndexDescription}'
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
foreach (var b in a.Time)
{
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.WindSpeed}', get_value2 = '{c.BeaufortScale}'
WHERE start_time = '{b.DataTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.DataTime}', null, now(), '{a.ElementName}', '{DataNO}', '{c.WindSpeed}', '{c.BeaufortScale}'
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
foreach (var b in a.Time)
{
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.WindDirection}'
WHERE start_time = '{b.DataTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.DataTime}', null, now(), '{a.ElementName}', '{DataNO}', '{c.WindDirection}', null
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
foreach (var b in a.Time)
{
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.ProbabilityOfPrecipitation}'
WHERE start_time = '{b.StartTime}' and end_time = '{b.EndTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.StartTime}', '{b.EndTime}', now(), '{a.ElementName}', '{DataNO}', '{c.ProbabilityOfPrecipitation}', null
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
foreach (var b in a.Time)
{
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.Weather}', get_value2 = '{c.WeatherCode}'
WHERE start_time = '{b.StartTime}' and end_time = '{b.EndTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.StartTime}', '{b.EndTime}', now(), '{a.ElementName}', '{DataNO}', '{c.Weather}', '{c.WeatherCode}'
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
}
else if (a.ElementName.Contains(ElementName..ToString()))
{
foreach (var b in a.Time)
{
foreach (var c in b.ElementValue)
{
sql += $@"WITH updated_rows AS (
UPDATE weather_forecast
SET get_value = '{c.WeatherDescription}'
WHERE start_time = '{b.StartTime}' and end_time = '{b.EndTime}' and weather_type = '{a.ElementName}'
RETURNING *
)
insert into weather_forecast (start_time, end_time, created_at, weather_type, data_no, get_value, get_value2)
select '{b.StartTime}', '{b.EndTime}', now(), '{a.ElementName}', '{DataNO}', '{c.WeatherDescription}', null
WHERE NOT EXISTS (SELECT 1 FROM updated_rows);";
}
}
}
}
}
if (!string.IsNullOrWhiteSpace(sql))
{
await backgroundServiceRepository.ExecuteSql(sql, null);
}
}
await backendRepository.AddMutiByCustomTable(WeatherAPIdbS, "api_weateher");
}
await task_Detail.InsertWorkTime_End("WeatherAPI", "api_weateher");
}
@ -188,313 +278,7 @@ namespace BackendWorkerService.Quartz.Jobs
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");
WebClient mywebClient = new WebClient();
mywebClient.DownloadFile("https://opendata.cwb.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 haveinfo = json.Split("info");
//if (haveinfo.Length > 2)
//{
// var observation = RainApi.Welcome.FromJson(json);
// var area = observation.Alert.Info[0].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[0].Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info[0].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[0].Headline},
// { "@areaDesc", area},
// { "@onset", observation.Alert.Info[0].Onset},
// { "@expires", observation.Alert.Info[0].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[0].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);
// }
// }
// FolderFunction folderFunction = new FolderFunction();
// folderFunction.DeleteFile("root/PowerfulRain.xml");
// await task_Detail.InsertWorkTime_End("WeatherAPI", "api_rain");
//}
//else
//{
// var observation = RainApi.Welcome.FromJson(json);
// var area = observation.Alert.Info[0].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[0].Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info[0].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[0].Headline},
// { "@areaDesc", area},
// { "@onset", observation.Alert.Info[0].Onset.ToString("yyyy-MM-dd HH:mm:ss")},
// { "@expires", observation.Alert.Info[0].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[0].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);
// }
// }
// 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());
}
}
if (await task_Detail.GetNeedWorkTask("WeatherAPI", "api_typhoon"))
{
try
{
await task_Detail.InsertWorkTime("WeatherAPI", "api_typhoon");
WebClient mywebClient = new WebClient();
mywebClient.DownloadFile("https://opendata.cwb.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 haveinfo = json.Split("info");
//if (haveinfo.Length > 2)
//{
// var observation = TyphoonApi.Welcome.FromJson(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[0].Onset.ToString("yyyy-MM-dd HH:mm:ss")}' and expires = '{observation.Alert.Info[0].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[0].Headline},
// { "@areaDesc", area},
// { "@urgency",observation.Alert.Info[0].Urgency},
// { "@severity",observation.Alert.Info[0].Severity},
// { "@onset", observation.Alert.Info[0].Onset},
// { "@expires", observation.Alert.Info[0].Expires},
// { "@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[0].Urgency != null && observation.Alert.Info[0].Urgency != "Expected")
// {
// var ReStr = Fetch_PostWithJSONFormat($@"{obixApiConfig.ApiBase}obix/config/Arena/D2/CWB/L110/CAP/D2_CWB_L110_CAP_MET2/SeverityLEVL_Typhoon/set", observation.Alert.Info[0].Urgency);
// UpdatedNiagara("api_typhoon", ReStr, id);
// }
// }
// FolderFunction folderFunction = new FolderFunction();
// folderFunction.DeleteFile("root/Typhoon.xml");
// await task_Detail.InsertWorkTime_End("WeatherAPI", "api_typhoon");
//}
//else
//{
// var observation = TyphoonApi.Welcome.FromJson(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/SeverityLEVL_Typhoon/set", observation.Alert.Info.Urgency);
// UpdatedNiagara("api_typhoon", ReStr, id);
// }
// }
// 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");
var client = new HttpClient();
var UVUri = "https://opendata.cwb.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 observation = QuickType.Welcome.FromJson(jsonUVs);
if (!observation.Success)
{
logger.LogInformation("【WeatherAPIJob】【取得地震觀測資料不正確】");
}
else
{
logger.LogInformation("【WeatherAPIJob】【開始存入地震觀測到資料庫】");
List<Dictionary<string, object>> EarthquakeAPIdbS = new List<Dictionary<string, object>>();
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.Length > 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/SeverityLEVL_LMI/set", a.Intensity.ShakingArea[0].AreaIntensity.ToString());
if (Nag.Contains("err"))
{
EarthquakeAPIdb.Add("@niagara", Nag);
}
else
{
EarthquakeAPIdb.Add("@niagara", "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/SeverityLEVL_LMI/set", "NULL");
if (Nag.Contains("err"))
{
EarthquakeAPIdb.Add("@niagara", Nag);
}
else
{
EarthquakeAPIdb.Add("@niagara", "success");
}
EarthquakeAPIdbS.Add(EarthquakeAPIdb);
}
}
}
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());
}
}
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");
}
catch (Exception ex)
{
await task_Detail.WorkFail("WeatherAPI", "set_weather", ex.Message.ToString());
}
}
#endregion
}
catch (Exception exception)
{
@ -502,58 +286,5 @@ namespace BackendWorkerService.Quartz.Jobs
logger.LogError("【WeatherAPIJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
public int RainValue(string Ty, string Headline)
{
var rint = 5;
if (Ty == "")
{
return 0;
}
else
{
if (Headline.Contains("大雨"))
{
rint = 1;
}
else if (Headline.Contains("豪雨"))
{
rint = 2;
}
else if (Headline.Contains("大豪雨"))
{
rint = 3;
}
else if (Headline.Contains("超大豪雨"))
{
rint = 4;
}
}
return rint;
}
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;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,8 @@
"ParkingJob": "0 0 2 * * ?",
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
"ArchiveElectricMeterDayJob": "0/2 * * * * ?", // 5
"WeatherAPIJob": "0 0 2 * * ?"
"WeatherAPIJob": "0/5 * * * * ?",
"ArchiveSolarHourJob": "0/5 * * * * ?"
},
"DBConfig": {
"MySqlDBConfig": {
@ -38,6 +39,13 @@
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
},
"PostgresqlDBConfig": {
"Server": "7PXnRw6HjsbvZCGMnaCUFw==",
"Port": "fn9N5byn3or3CINTF2jlDA==",
"Database": "d39gVx6T7y1+TrDZJVLmlg==",
"Root": "j7Lj7ZBR/oMrsAj7YontpQ==",
"Password": "aQ/1DotdsX8Zm471HESQDg=="
}
},
"SMTPConfig": {

View File

@ -15,7 +15,9 @@
"ParkingJob": "0 0 2 * * ?",
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
"WeatherAPIJob": "0 0 2 * * ?"
"WeatherAPIJob": "0 0 2 * * ?",
"ArchiveSolarHourJob": "0/5 * * * * ?",
"ArchiveSolarDayJob": "0/5 * * * * ?"
},
"DBConfig": {
"MySqlDBConfig": {
@ -35,6 +37,13 @@
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
},
"PostgresqlDBConfig": {
"Server": "7PXnRw6HjsbvZCGMnaCUFw==",
"Port": "fn9N5byn3or3CINTF2jlDA==",
"Database": "j7Lj7ZBRd39gVx6T7y1+TrDZJVLmlg==",
"Root": "j7Lj7ZBR/oMrsAj7YontpQ==",
"Password": "aQ/1DotdsX8Zm471HESQDg=="
}
},
"SMTPConfig": {

View File

@ -0,0 +1,17 @@
using Repository.BackendRepository.Interface;
using Repository.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Repository.BackendRepository.Implement
{
public class BackgroundServicePostgresqlRepository : BackendRepository, IBackgroundServicePostgresqlRepository
{
public BackgroundServicePostgresqlRepository(IDatabaseHelper databaseHelper) : base(databaseHelper)
{
UseDB = "POSTGRESQL";
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Repository.BackendRepository.Interface
{
public interface IBackgroundServicePostgresqlRepository : IBackendRepository
{
}
}

View File

@ -12,6 +12,8 @@ using System.Text;
using System.Data.SqlClient;
using MySql.Data.MySqlClient;
using Repository.Services.Implement;
using Npgsql;
using System.Data.Common;
namespace Repository.BaseRepository.Implement
{
@ -58,6 +60,10 @@ namespace Repository.BaseRepository.Implement
{
conn = new SqlConnection(this._databaseHelper.GetMSSqlConnectionString());
}
else if (UseDB == "POSTGRESQL")
{
conn = new NpgsqlConnection(this._databaseHelper.GetPostgresqlConnectionString());
}
else
{
conn = new MySqlConnection(this._databaseHelper.GetMySqlConnectionString());
@ -86,6 +92,7 @@ namespace Repository.BaseRepository.Implement
return insertQuery.ToString();
}
public string UpdateGenerateString(List<string> properties, string table_name, string sWhere)
{
var updateQuery = new StringBuilder($"UPDATE {table_name} SET ");

View File

@ -22,17 +22,20 @@ namespace Repository.Helper
/// <returns></returns>
string GetMSSqlConnectionString();
string GetMySqlConnectionString();
string GetPostgresqlConnectionString();
}
public class DatabaseHelper : IDatabaseHelper
{
private MySqlDBConfig _mySqlDBConfig;
private MSSqlDBConfig _msSqlDBConfig;
private PostgresqlDBConfig _postgresqlDBConfig;
public DatabaseHelper(IOptions<DBConfig> dbConfig)
{
_mySqlDBConfig = dbConfig.Value.MySqlDBConfig;
_msSqlDBConfig = dbConfig.Value.MSSqlDBConfig;
_postgresqlDBConfig = dbConfig.Value.PostgresqlDBConfig;
}
public string GetMSSqlConnectionString()
@ -70,5 +73,20 @@ namespace Repository.Helper
//var conn = new MySqlConnection(connStr);
return connStr;
}
public string GetPostgresqlConnectionString()
{
EDFunction ed = new EDFunction();
var serverStr = ed.AESDecrypt(_postgresqlDBConfig.Server);
var portStr = ed.AESDecrypt(_postgresqlDBConfig.Port);
var databaseStr = ed.AESDecrypt(_postgresqlDBConfig.Database);
var rootStr = ed.AESDecrypt(_postgresqlDBConfig.Root);
var passwordStr = ed.AESDecrypt(_postgresqlDBConfig.Password);
var connStr = $"Host={serverStr};Port={portStr};Database={databaseStr};Username={rootStr};Password={passwordStr};Pooling=true;";
//Host={serverStr};Port={portStr};Database={databaseStr};Username={rootStr};Password={passwordStr};Pooling=true;SSL Mode=Disable;Timeout=15;
return connStr;
}
}
}

View File

@ -9,6 +9,7 @@ namespace Repository.Models
{
public MySqlDBConfig MySqlDBConfig { get; set; }
public MSSqlDBConfig MSSqlDBConfig { get; set; }
public PostgresqlDBConfig PostgresqlDBConfig { get; set; }
}
public class MySqlDBConfig
@ -29,4 +30,12 @@ namespace Repository.Models
public string Password { get; set; }
}
public class PostgresqlDBConfig
{
public string Server { get; set; }
public string Port { get; set; }
public string Database { get; set; }
public string Root { get; set; }
public string Password { get; set; }
}
}

View File

@ -34,6 +34,9 @@ namespace Repository.Models
[JsonProperty("str")]
public List<Str> Str { get; set; }
[JsonProperty("ref")]
public List<Ref> Ref { get; set; }
}
public partial class Str
@ -57,6 +60,27 @@ namespace Repository.Models
public string Encoding { get; set; }
}
public partial class Ref
{
[JsonProperty("@name")]
public string Name { get; set; }
[JsonProperty("@href")]
public string Href { get; set; }
[JsonProperty("@is")]
public string Is { get; set; }
[JsonProperty("@display")]
public string display { get; set; }
[JsonProperty("@displayName")]
public string displayName { get; set; }
[JsonProperty("@icon")]
public string icon { get; set; }
}
public partial class Welcome
{
public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, Models.Converter.Settings);

View File

@ -12,6 +12,7 @@
<PackageReference Include="Dapper" Version="2.0.90" />
<PackageReference Include="MySql.Data" Version="8.0.29" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Npgsql" Version="7.0.9" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
</ItemGroup>