[後端] 修改排程部分更改回原先專案, 使用windows service執行

[前端] 修改alert.html 建立維修單錯誤
This commit is contained in:
dev02 2023-06-06 16:43:46 +08:00
parent dd244589c5
commit 0571ebd7ac
31 changed files with 155 additions and 6394 deletions

View File

@ -1,198 +0,0 @@
using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Implement;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using NCrontab;
using static NCrontab.CrontabSchedule;
namespace Backend.Quartz
{
/// <summary>
/// Job調度中間對象
/// </summary>
public class JobSchedule
{
public JobSchedule(Type jobType, string cronExpression)
{
this.JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
CronExpression = cronExpression ?? throw new ArgumentNullException(nameof(cronExpression));
}
/// <summary>
/// Job類型
/// </summary>
public Type JobType { get; private set; }
/// <summary>
/// Cron表達式
/// </summary>
public string CronExpression { get; private set; }
/// <summary>
/// Job狀態
/// </summary>
public JobStatus JobStatu { get; set; } = JobStatus.Init;
}
/// <summary>
/// Job運行狀態
/// </summary>
public enum JobStatus : byte
{
[Description("初始化")]
Init = 0,
[Description("運行中")]
Running = 1,
[Description("調度中")]
Scheduling = 2,
[Description("已停止")]
Stopped = 3,
}
public class Task_Detail
{
private readonly IBackendRepository backendRepository;
private readonly ILogger<Task_Detail> logger;
public Task_Detail(ILogger<Task_Detail> logger, IBackendRepository backendRepository)
{
this.logger = logger;
this.backendRepository = backendRepository;
}
/// <summary>
/// 取得時間規則
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
private async Task<string> GetWorkRule(string task,string task_item)
{
string Times = null;
try
{
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);
}
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>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task<bool> GetNeedWorkTask(string task, string task_item)
{
try
{
var sql = $@"select a.lastwork_time from task_detail a
where a.task = '{task}' and a.task_item = '{task_item}'";
var lastworkTime = await backendRepository.GetOneAsync<string>(sql);
DateTime dateTime = lastworkTime != null ? Convert.ToDateTime(lastworkTime) : Convert.ToDateTime("1970-01-01 00:00:01");
var nextTime = CrontabSchedule.Parse(await GetWorkRule(task, task_item), new ParseOptions { IncludingSeconds = true } ).GetNextOccurrence(dateTime);
if (DateTime.Now >= nextTime)
{
return true;
}
}
catch(Exception exception)
{
logger.LogError("【Task_Detail】【時間解析失敗】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
return false;
}
/// <summary>
/// 紀錄任務開始執行時間
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task InsertWorkTime(string task, string task_item ,string LoggerWord = null)
{
try
{
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@lastwork_time", DateTime.Now},
{ "@success", 2},
{ "@updated_at", DateTime.Now},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
if(LoggerWord == null)
{
logger.LogInformation($"【Task_Detail】【開始{task},{task_item}任務】");
}
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
}
catch (Exception exception)
{
logger.LogError("【Task_Detail】【任務輸入開始時間】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
}
/// <summary>
/// 紀錄任務結束時間
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task InsertWorkTime_End(string task, string task_item,string LoggerWord = null)
{
try
{
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@success", 0},
{ "@lastwork_end_time", DateTime.Now},
{ "@updated_at", DateTime.Now},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
if (LoggerWord == null)
{
logger.LogInformation($"【Task_Detail】【結束{task},{task_item}任務】");
}
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
}
catch (Exception exception)
{
logger.LogError("【Task_Detail】【任務輸入結束時間】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
}
/// <summary>
/// 執行失敗紀錄
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task WorkFail(string task, string task_item,string reason = "")
{
try
{
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@success", 1},
{ "@updated_at", DateTime.Now},
};
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);
}
catch (Exception exception)
{
logger.LogError("【Task_Detail】【任務執行失敗】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,335 +0,0 @@
using Backend.Models;
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 Backend.Quartz.Jobs
{
/// <summary>
/// 電錶歸檔,每小時執行,只執行小時歸檔
/// </summary>
[DisallowConcurrentExecution]
class ArchiveElectricMeterHourJob : IJob
{
private readonly ILogger<ArchiveElectricMeterHourJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly ILogger<Task_Detail> loggers;
public ArchiveElectricMeterHourJob(
ILogger<ArchiveElectricMeterHourJob> logger,
IBackgroundServiceRepository 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("ArchiveElectricMeterHourJob", "All"))
{
await task_Detail.InsertWorkTime("ArchiveElectricMeterHourJob", "All", "任務開始");
EDFunction ed = new EDFunction();
XmlDocument xmlDocument = new XmlDocument();
var sqlArchive = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'archiveConfig'";
var variableArchive = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlArchive);
var electricMeterGuid = variableArchive.Where(x => x.Name == "ElectricMeterGuid").Select(x => x.Value).FirstOrDefault();
#region
var sWhere = "deleted = 0 AND sub_system_guid = @sub_system_guid";
var electricMeters = await backgroundServiceRepository.GetAllAsync<Device>("device", sWhere, new { sub_system_guid = electricMeterGuid });
#endregion
#region
var sPointWhere = "deleted = 0 AND sub_system_guid = @sub_system_guid";
var points = await backgroundServiceRepository.GetAllAsync<Device_item>("device_item", sPointWhere, new { sub_system_guid = electricMeterGuid });
#endregion
#region
List<DeviceNumberPoint> deviceNumberPoints = new List<DeviceNumberPoint>();
foreach (var electricMeter in electricMeters)
{
foreach (var point in points)
{
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
deviceNumberPoint.DeviceNumber = electricMeter.Device_number;
deviceNumberPoint.Point = point.points;
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", electricMeter.Device_number, point.points);
deviceNumberPoints.Add(deviceNumberPoint);
}
}
#endregion
#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
var now = DateTime.Now;
#region
try
{
var preHour = now.AddHours(-1); //取得前一小時
var tempHour = string.Empty;
if (preHour.Hour < 10)
{
tempHour = "0" + preHour.Hour.ToString();
}
else
{
tempHour = preHour.Hour.ToString();
}
var startTimestamp = string.Format("{0}T{1}:00:00.000+08:00", preHour.ToString("yyyy-MM-dd"), tempHour);
var endTimestamp = string.Format("{0}T{1}:59:59.000+08:00", preHour.ToString("yyyy-MM-dd"), tempHour);
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
<abstime name='start' val='{startTimestamp}' />
<abstime name='end' val='{endTimestamp}' />
<reltime name='interval' val = 'PT1H' />
</obj>";
//Stopwatch stopWatch = new Stopwatch();
//stopWatch.Start();
//抓取每個設備的資料
List<Dictionary<string, object>> archiveHourRawDatas = new List<Dictionary<string, object>>();
foreach (var deviceNumberPoint in deviceNumberPoints)
{
HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
//HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
archiveHourRequest.Method = "POST";
archiveHourRequest.Headers.Add("Authorization", "Basic " + encoded);
archiveHourRequest.PreAuthenticate = true;
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
using (Stream reqStream = archiveHourRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse archiveHourResponse = (HttpWebResponse)archiveHourRequest.GetResponse();
var archiveHourResponseContent = new StreamReader(archiveHourResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(archiveHourResponseContent);
string archiveHourJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject archiveHourJsonResult = (JObject)JsonConvert.DeserializeObject(archiveHourJson);
if (archiveHourJsonResult.ContainsKey("err")) //抓取錯誤
{
//logger.LogError("【ArchiveElectricMeterHourJob】【小時歸檔】【取得資料失敗】");
//logger.LogError("【ArchiveElectricMeterHourJob】【小時歸檔】【取得資料失敗】[錯誤內容]{0}", archiveHourJsonResult);
Dictionary<string, object> archiveHourRawData = new Dictionary<string, object>();
archiveHourRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
archiveHourRawData.Add("@point", deviceNumberPoint.Point);
archiveHourRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
archiveHourRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
archiveHourRawData.Add("@is_complete", 0);
archiveHourRawData.Add("@repeat_times", 0);
archiveHourRawData.Add("@fail_reason", archiveHourJson);
archiveHourRawDatas.Add(archiveHourRawData);
}
if (archiveHourJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var histories = archiveHourJsonResult["obj"]["list"];
var rawdateCount = Convert.ToInt32(archiveHourJsonResult["obj"]["int"]["@val"].ToString());
if (histories != null && histories.HasValues)
{
if (rawdateCount > 1)
{ //多筆資料
foreach (var history in histories)
{
Dictionary<string, object> archiveHourRawData = new Dictionary<string, object>();
archiveHourRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
archiveHourRawData.Add("@point", deviceNumberPoint.Point);
//時間
if (history["abstime"] != null && history["abstime"].HasValues)
{
foreach (var abstime in history["abstime"])
{
var name = abstime["@name"].ToString();
switch (name)
{
case "start":
var startTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
archiveHourRawData.Add("@start_timestamp", startTimstamp);
break;
case "end":
var endTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
archiveHourRawData.Add("@end_timestamp", endTimstamp);
break;
}
}
}
//區間內資料筆數
if (history["int"] != null && history["int"].HasValues)
{
var count = Convert.ToInt32(histories["obj"]["int"]["@val"].ToString());
archiveHourRawData.Add("@count_rawdata", count);
}
//整合數值(最大、最小、平均、總和)
if (history["real"] != null && history["real"].HasValues)
{
foreach (var real in history["real"])
{
var name = real["@name"].ToString();
switch (name)
{
case "min":
var min = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@min_rawdata", min);
break;
case "max":
var max = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@max_rawdata", max);
break;
case "avg":
var avg = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@avg_rawdata", avg);
break;
case "sum":
var sum = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@sum_rawdata", sum);
break;
}
}
}
archiveHourRawData.Add("@is_complete", 1);
archiveHourRawDatas.Add(archiveHourRawData);
}
}
else
{ //單筆資料
Dictionary<string, object> archiveHourRawData = new Dictionary<string, object>();
archiveHourRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
archiveHourRawData.Add("@point", deviceNumberPoint.Point);
//時間
if (histories["obj"]["abstime"] != null && histories["obj"]["abstime"].HasValues)
{
foreach (var abstime in histories["obj"]["abstime"])
{
var name = abstime["@name"].ToString();
switch (name)
{
case "start":
var startTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
archiveHourRawData.Add("@start_timestamp", startTimstamp);
break;
case "end":
var endTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
archiveHourRawData.Add("@end_timestamp", endTimstamp);
break;
}
}
}
//區間內資料筆數
if (histories["obj"]["int"] != null && histories["obj"]["int"].HasValues)
{
var count = Convert.ToInt32(histories["obj"]["int"]["@val"].ToString());
archiveHourRawData.Add("@count_rawdata", count);
}
//整合數值(最大、最小、平均、總和)
if (histories["obj"]["real"] != null && histories["obj"]["real"].HasValues)
{
foreach (var real in histories["obj"]["real"])
{
var name = real["@name"].ToString();
switch (name)
{
case "min":
var min = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@min_rawdata", min);
break;
case "max":
var max = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@max_rawdata", max);
break;
case "avg":
var avg = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@avg_rawdata", avg);
break;
case "sum":
var sum = Convert.ToDecimal(real["@val"].ToString());
archiveHourRawData.Add("@sum_rawdata", sum);
break;
}
}
}
archiveHourRawData.Add("@is_complete", 1);
archiveHourRawDatas.Add(archiveHourRawData);
}
}
}
}
//stopWatch.Stop();
//logger.LogInformation("【ArchiveElectricMeterHourJob】【小時歸檔】【效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);
if (archiveHourRawDatas.Count() > 0)
{
await backgroundServiceRepository.AddMutiByCustomTable(archiveHourRawDatas, "archive_electric_meter_hour");
}
await task_Detail.InsertWorkTime_End("ArchiveElectricMeterHourJob", "All", "任務完成");
}
catch (Exception exception)
{
await task_Detail.WorkFail("ArchiveElectricMeterHourJob", "All", exception.ToString());
logger.LogError("【ArchiveElectricMeterHourJob】【小時歸檔】【任務失敗】");
logger.LogError("【ArchiveElectricMeterHourJob】【小時歸檔】【任務失敗】[Exception]{0}", exception.ToString());
}
#endregion
}
}
catch (Exception exception)
{
await task_Detail.WorkFail("ArchiveElectricMeterHourJob", "All", exception.ToString());
logger.LogError("【ArchiveElectricMeterHourJob】【任務失敗】");
logger.LogError("【ArchiveElectricMeterHourJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
}
}

View File

@ -1,269 +0,0 @@
using Backend.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Backend.Quartz.Jobs
{
[DisallowConcurrentExecution]
class DataDeliveryJob : IJob
{
private readonly ILogger<DataDeliveryJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
public DataDeliveryJob(
ILogger<DataDeliveryJob> logger,
IBackgroundServiceRepository backgroundServiceRepository)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
}
public async Task Execute(IJobExecutionContext context)
{
Dictionary<string, object> insertLog = new Dictionary<string, object>()
{
{ "@task_id", 0 },
{ "@log_level", "" },
{ "@log_content", "" }
};
try
{
logger.LogInformation("【DataDeliveryJob】【任務開始】");
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"【DataDeliveryJob】任務開始";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
//找出所有要派送的資料
string sWhere = @"is_complete = 0 AND task_type = @Task_type AND repeat_times < 10";
var backgroundServiceTasks = await backgroundServiceRepository.GetAllAsync<BackgroundServiceTask>("background_service_task", sWhere, new { Task_type = BackgroundServiceTaskType.data_delivery });
if (backgroundServiceTasks.Count == 0)
{
logger.LogInformation("【DataDeliveryJob】【查無任務列表】");
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"【DataDeliveryJob】查無任務列表";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
else
{
List<Dictionary<string, object>> updateObjs = new List<Dictionary<string, object>>();
foreach (var task in backgroundServiceTasks)
{
var DateTimeNow = DateTime.Now;
Dictionary<string, object> updateObj = new Dictionary<string, object>()
{
{ "Id", task.Id },
{ "@repeat_times", 0 },
{ "@is_complete", 0 },
{ "@fail_reason", null },
{ "@complete_at", null },
{ "@updated_at", DateTimeNow }
};
insertLog["@task_id"] = task.Id;
//var parameters = JsonSerializer.Deserialize<Dictionary<string, object>>(task.Target_data);
try
{
logger.LogInformation("【DataDeliveryJob】【開始派送】[棟別IP]{0}", task.Target_ip);
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"開始派送";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
var boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
var endBoundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
HttpWebRequest Postrequest = (HttpWebRequest)WebRequest.Create($"http://{task.Target_ip}/api/ReceiveDataDelivery/GetData");
Postrequest.ContentType = "multipart/form-data; boundary=" + boundary;
Postrequest.Method = "POST";
if (!string.IsNullOrEmpty(task.Target_table))
{
using (Stream requestStream = Postrequest.GetRequestStream())
{
//Id
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string task_id = "Content-Disposition: form-data; name=\"" + "Id" + "\"\r\n\r\n" + task.Id;
byte[] task_id_bytes = System.Text.Encoding.UTF8.GetBytes(task_id);
requestStream.Write(task_id_bytes, 0, task_id_bytes.Length);
//Target Table
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string target_table = "Content-Disposition: form-data; name=\"" + "TargetTable" + "\"\r\n\r\n" + task.Target_table;
byte[] target_table_bytes = System.Text.Encoding.UTF8.GetBytes(target_table);
requestStream.Write(target_table_bytes, 0, target_table_bytes.Length);
//mode
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string target_mode = "Content-Disposition: form-data; name=\"" + "mode" + "\"\r\n\r\n" + task.Mode;
byte[] target_mode_bytes = System.Text.Encoding.UTF8.GetBytes(target_mode);
requestStream.Write(target_mode_bytes, 0, target_mode_bytes.Length);
//Target data
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string target_data = "Content-Disposition: form-data; name=\"" + "TargetData" + "\"\r\n\r\n" + task.Target_data;
byte[] target_data_bytes = System.Text.Encoding.UTF8.GetBytes(target_data);
requestStream.Write(target_data_bytes, 0, target_data_bytes.Length);
//解析Files
if (task.Target_files != null)
{
var target_files = JsonSerializer.Deserialize<List<Backend.Models.FileInfo>>(task.Target_files);
var file_index = 0;
foreach (var file in target_files)
{
//file Folder
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string file_folder = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].Folder" + "\"\r\n\r\n" + file.Folder;
byte[] file_folder_bytes = System.Text.Encoding.UTF8.GetBytes(file_folder);
requestStream.Write(file_folder_bytes, 0, file_folder_bytes.Length);
//file OriginalFileName
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string orig_file_name = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].OriginalFileName" + "\"\r\n\r\n" + file.OriginalFileName;
byte[] orig_file_name_bytes = System.Text.Encoding.UTF8.GetBytes(orig_file_name);
requestStream.Write(orig_file_name_bytes, 0, orig_file_name_bytes.Length);
//file FileName
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string file_name = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].FileName" + "\"\r\n\r\n" + file.FileName;
byte[] file_name_bytes = System.Text.Encoding.UTF8.GetBytes(file_name);
requestStream.Write(file_name_bytes, 0, file_name_bytes.Length);
//取得Content-Type
var content_type = string.Empty;
string ext = Path.GetExtension(file.File);
using (Microsoft.Win32.RegistryKey registryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext))
{
if (registryKey != null)
{
var value = registryKey.GetValue("Content Type");
if (value != null)
{
content_type = value.ToString();
}
}
}
if (file.File != null)
{
string file_header = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].File" + "\"; filename=\"" + file.FileName + "\"\r\nContent-Type: " + content_type + "\r\n\r\n";
byte[] file_header_bytes = System.Text.Encoding.UTF8.GetBytes(file_header);
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Write(file_header_bytes, 0, file_header_bytes.Length);
byte[] buffer = new byte[32768];
int bytesRead;
// upload from file
using (FileStream fileStream = File.OpenRead(file.File))
{
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
fileStream.Close();
}
}
}
}
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
requestStream.Close();
}
}
HttpWebResponse response = (HttpWebResponse)Postrequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var statusNumber = (int)response.StatusCode;
if (statusNumber != 200)
{
logger.LogError("【DataDeliveryJob】【派送失敗】[棟別IP]{0}", task.Target_ip);
logger.LogError("【DataDeliveryJob】【派送失敗】[response]{0}", responseString);
updateObj["@repeat_times"] = task.Repeat_times + 1;
updateObj["@fail_reason"] = responseString;
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"派送失敗 - [失敗原因]{responseString}";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
else
{
//解析回傳內容
var final = JObject.Parse(responseString);
var code = final["code"].ToString();
if (code == "0000")
{
logger.LogInformation("【DataDeliveryJob】【派送成功】[棟別IP]{0}", task.Target_ip);
updateObj["@repeat_times"] = task.Repeat_times;
updateObj["@is_complete"] = 1;
updateObj["@complete_at"] = DateTime.Now;
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"派送成功";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
else
{
logger.LogError("【DataDeliveryJob】【派送失敗】[棟別IP]{0}", task.Target_ip);
logger.LogError("【DataDeliveryJob】【派送失敗】[response]{0}", responseString);
updateObj["@repeat_times"] = task.Repeat_times + 1;
updateObj["@fail_reason"] = responseString;
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"派送失敗 - [失敗原因]{responseString}";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
}
}
catch (Exception exception)
{
logger.LogError("【DataDeliveryJob】【派送失敗】[棟別IP]{0}", task.Target_ip);
logger.LogError("【DataDeliveryJob】【派送失敗】[Exception]{0}", exception.ToString());
updateObj["@repeat_times"] = task.Repeat_times + 1;
updateObj["@fail_reason"] = exception.ToString();
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"派送失敗 - [失敗原因(Exception)]{exception.ToString()}";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
updateObjs.Add(updateObj);
}
await backgroundServiceRepository.UpdateListByCustomTable(updateObjs, "background_service_task", "id = @Id");
logger.LogInformation("【DataDeliveryJob】【任務完成】");
insertLog["@task_id"] = 0;
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"任務完成";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
}
catch (Exception exception)
{
logger.LogError("【DataDeliveryJob】【任務失敗】");
logger.LogError("【DataDeliveryJob】【任務失敗】[Exception]{0}", exception.ToString());
insertLog["@task_id"] = 0;
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"任務失敗";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
}
}
}

View File

@ -1,113 +0,0 @@
using Backend.Models;
using Microsoft.Extensions.Logging;
using Quartz;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Backend.Quartz.Jobs
{
[DisallowConcurrentExecution]
public class ExecutionBackgroundServicePlanJob : IJob
{
private readonly ILogger<ExecutionBackgroundServicePlanJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
public ExecutionBackgroundServicePlanJob(
ILogger<ExecutionBackgroundServicePlanJob> logger,
IBackgroundServiceRepository backgroundServiceRepository)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
logger.LogInformation("【ExecutionBackgroundServicePlanJob】【任務開始】");
// 找出當前在起始與結束時間所有計畫
var DateTimeNow = DateTime.Now;
var sPlanWhere = @"deleted = 0
AND
(
@DateTimeNow Between start_time AND end_time
OR (end_time IS NULL AND @DateTimeNow > start_time)
)
";
var backgroundServicePlans = await backgroundServiceRepository.GetAllAsync<BackgroundServicePlan>("background_service_plan", sPlanWhere, new { DateTimeNow = DateTimeNow.ToString("yyyy-MM-dd HH:mm:ss") });
foreach (var plan in backgroundServicePlans)
{
//logger.LogInformation("【ExecutionBackgroundServicePlanJob】【計畫編號{0},計畫名稱:{1}】 - 開始生成下次任務項目", plan.Id, plan.Plane_name);
#region
try
{
var lastCreateTime = Convert.ToDateTime(plan.Last_create_time);
if (lastCreateTime == default(DateTime))
{
lastCreateTime = Convert.ToDateTime(plan.Start_time);
}
DateTime nextCreateTime; //下次待生成的時間
nextCreateTime = plan.Execution_type switch
{
(byte)ExecutionTypeEnum.Min => Convert.ToDateTime(lastCreateTime).AddMinutes(plan.Execution_time),
(byte)ExecutionTypeEnum.Hour => Convert.ToDateTime(lastCreateTime).AddHours(plan.Execution_time),
(byte)ExecutionTypeEnum.Day => Convert.ToDateTime(lastCreateTime).AddDays(plan.Execution_time),
(byte)ExecutionTypeEnum.Week => Convert.ToDateTime(lastCreateTime).AddDays(plan.Execution_time * 7),
(byte)ExecutionTypeEnum.Month => Convert.ToDateTime(lastCreateTime).AddMonths(plan.Execution_time),
_ => default(DateTime)
};
if (nextCreateTime != default(DateTime) && nextCreateTime < DateTimeNow)
{
Dictionary<string, object> servicePlanDic = new Dictionary<string, object>()
{
{ "@last_create_time", nextCreateTime},
{ "@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
};
await backgroundServiceRepository.UpdateOneByCustomTable(servicePlanDic, "background_service_plan", "id=" + plan.Id + "");
#region
try
{
BackgroundServiceTask backgroundServiceTask = new BackgroundServiceTask()
{
};
}
catch(Exception exception)
{
}
#endregion
}
}
catch (Exception exception)
{
//logger.LogError("【ExecutionBackgroundServicePlanJob】【計畫編號{0},計畫名稱:{1}】 - 產生下次任務時間失敗", plan.Id, plan.Plane_name);
//logger.LogError("【ExecutionBackgroundServicePlanJob】【計畫編號{0},計畫名稱:{1}】 - 產生下次任務時間失敗[Exception]- {2}", plan.Id, plan.Plane_name, exception.Message); ;
}
#endregion
}
logger.LogInformation("【ExecutionBackgroundServicePlanJob】【任務完成】");
}
catch (Exception exception)
{
logger.LogError("【ExecutionBackgroundServicePlanJob】【任務失敗】");
logger.LogError("【ExecutionBackgroundServicePlanJob】【任務失敗】[Exception]{0}", exception.Message); ;
}
}
}
}

View File

@ -1,163 +0,0 @@
using Backend.Models;
using BackendWorkerService.Services.Interface;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Quartz;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Backend.Quartz.Jobs
{
[DisallowConcurrentExecution]
class MessageNotificationJob : IJob
{
private readonly ILogger<MessageNotificationJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly ISendEmailService sendEmailService;
private readonly ISendSMSService sendSMSService;
private readonly ISendLineNotifyService sendLineNotifyService;
public MessageNotificationJob(
ILogger<MessageNotificationJob> logger,
IBackgroundServiceRepository backgroundServiceRepository,
ISendEmailService sendEmailService,
ISendSMSService sendSMSService,
ISendLineNotifyService sendLineNotifyService)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
this.sendEmailService = sendEmailService;
this.sendSMSService = sendSMSService;
this.sendLineNotifyService = sendLineNotifyService;
}
public async Task Execute(IJobExecutionContext context)
{
Dictionary<string, object> insertLog = new Dictionary<string, object>()
{
{ "@task_id", 0 },
{ "@log_level", "" },
{ "@log_content", "" }
};
try
{
logger.LogInformation("【MessageNotificationJob】【任務開始】");
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"任務開始";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_message_notification_task_log");
//找出所有要通知的清單
string sWhere = @"is_complete = 0";
var messageNotificationTasks = await backgroundServiceRepository.GetAllAsync<BackgroundServiceMessageNotificationTask>("background_service_message_notification_task", sWhere);
if(messageNotificationTasks.Count == 0)
{
logger.LogInformation("【MessageNotificationJob】【查無任務列表】");
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"查無任務列表";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_message_notification_task_log");
}
else
{
List<Dictionary<string, object>> updateObjs = new List<Dictionary<string, object>>();
foreach (var task in messageNotificationTasks)
{
var DateTimeNow = DateTime.Now;
Dictionary<string, object> updateObj = new Dictionary<string, object>()
{
{ "Id", task.Id },
{ "@updated_at", DateTimeNow }
};
try
{
switch (task.Task_type)
{
case (byte)MessageNotificationTaskType.email:
List<string> recipientEmails = new List<string>()
{
task.Recipient_email
};
if (sendEmailService.Send(task.Id, recipientEmails, task.Email_subject, task.Message_content))
{
updateObj.Add("@is_complete", 1);
updateObj.Add("@complete_at", DateTimeNow);
}
else
{
updateObj.Add("@repeat_times", task.Repeat_times + 1);
}
updateObjs.Add(updateObj);
break;
case (byte)MessageNotificationTaskType.sms:
if (sendSMSService.Send(task.Id, task.Recipient_phone, task.Message_content))
{
updateObj.Add("@is_complete", 1);
updateObj.Add("@complete_at", DateTimeNow);
}
else
{
updateObj.Add("@repeat_times", task.Repeat_times + 1);
}
updateObjs.Add(updateObj);
break;
case (byte)MessageNotificationTaskType.line_notify:
if (sendLineNotifyService.Send(task.Id, task.Line_token, task.Message_content))
{
updateObj.Add("@is_complete", 1);
updateObj.Add("@complete_at", DateTimeNow);
}
else
{
updateObj.Add("@repeat_times", task.Repeat_times + 1);
}
updateObjs.Add(updateObj);
break;
}
}
catch(Exception exception)
{
logger.LogError("【MessageNotificationJob】【通知失敗】[任務id]{0}", task.Id);
logger.LogError("【MessageNotificationJob】【通知失敗】[Exception]{0}", exception.ToString());
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"通知失敗 - [失敗原因(Exception)]{exception.ToString()}";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_message_notification_task_log");
}
}
await backgroundServiceRepository.UpdateListByCustomTable(updateObjs, "background_service_message_notification_task", "id = @Id");
logger.LogInformation("【MessageNotificationJob】【任務完成】");
insertLog["@task_id"] = 0;
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"任務完成";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_message_notification_task_log");
}
}
catch (Exception exception)
{
logger.LogError("【MessageNotificationJob】【任務失敗】");
logger.LogError("【MessageNotificationJob】【任務失敗】[Exception]{0}", exception.ToString());
insertLog["@task_id"] = 0;
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"任務失敗";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_message_notification_task_log");
}
}
}
}

View File

@ -1,324 +0,0 @@
using Backend.Models;
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 Backend.Quartz.Jobs
{
/// <summary>
/// 停車場管理
/// </summary>
[DisallowConcurrentExecution]
class ParkingJob : IJob
{
private readonly ILogger<ParkingJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly IBackendRepository backendRepository;
private readonly ILogger<Task_Detail> loggers;
public ParkingJob(
ILogger<ParkingJob> logger,
IBackgroundServiceRepository backgroundServiceRepository, ILogger<Task_Detail> loggers, IBackendRepository backendRepository)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
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("ParkingJob", "All"))
{
await task_Detail.InsertWorkTime("ParkingJob", "All", "任務開始");
EDFunction ed = new EDFunction();
var parkingConfig = new ParkingConfig();
var sqlParking = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'parkingConfig'";
var variable = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlParking);
parkingConfig.Host = variable.Where(x => x.Name == "Host").Select(x => x.Value).FirstOrDefault();
parkingConfig.Prefix = variable.Where(x => x.Name == "Prefix").Select(x => x.Value).FirstOrDefault();
parkingConfig.ApiBase = variable.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
parkingConfig.UserName = ed.AESDecrypt(variable.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault());
parkingConfig.Password = ed.AESDecrypt(variable.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault());
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(parkingConfig.UserName + ":" + parkingConfig.Password));
#region
if (await task_Detail.GetNeedWorkTask("ParkingJob", "Parking"))
{
try
{
await task_Detail.InsertWorkTime("ParkingJob", "Parking", "開始執行停車場剩餘車位Job");
HttpWebRequest spaceRequest = (HttpWebRequest)WebRequest.Create($"{parkingConfig.Host}{parkingConfig.Prefix}/api/space/details");
spaceRequest.Method = "GET";
//request.Headers.Add("Authorization", "Basic " + encoded);
spaceRequest.PreAuthenticate = true;
//Stopwatch stopWatch = new Stopwatch();
//stopWatch.Start();
HttpWebResponse spaceResponse = (HttpWebResponse)spaceRequest.GetResponse();
var spaceResponseContent = new StreamReader(spaceResponse.GetResponseStream()).ReadToEnd();
//logger.LogInformation("【ParkingJob】【取得成功停車場車位資訊】");
//stopWatch.Stop();
//logger.LogInformation("【ParkingJob】【取得停車場車位資訊】【效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds);
var spaceResponseResult = JsonConvert.DeserializeObject<SpaceResponse>(spaceResponseContent);
//取得停車場車位對應表
var sqlSapceMapping = $@"SELECT * FROM variable WHERE deleted = 0 AND system_type = 'parkingSapceMapping'";
var parkingSapceMapping = await backgroundServiceRepository.GetAllAsync<VariableInfo>(sqlSapceMapping);
if (spaceResponseResult != null && spaceResponseResult.Code == "20000")
{
foreach (var area in spaceResponseResult.Payload.Areas)
{
//找出對定的設備代碼
var selectedMapping = parkingSapceMapping.Where(x => x.System_key == area.Name).FirstOrDefault();
if (selectedMapping != null)
{
var tagName = selectedMapping.system_value;
var apiFormat = @"{0}obix/config/Arena/{1}/{2}/{3}/{4}/{5}/CV/set";
var tagNameSplit = tagName.Split("_");
var parames = new List<object>();
parames.Add(parkingConfig.ApiBase);
for (var i = 0; i < tagNameSplit.Length; i++)
{
if (i != tagNameSplit.Length - 1)
{
parames.Add(tagNameSplit[i]);
}
else
{
parames.Add(tagName);
}
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format(apiFormat, parames.ToArray()));
request.Method = "POST";
request.Headers.Add("Authorization", "Basic " + encoded);
request.PreAuthenticate = true;
var real = $@"<real val='{area.Remain}' />";
byte[] realByteArray = Encoding.UTF8.GetBytes(real);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(realByteArray, 0, realByteArray.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(responseContent);
string json = JsonConvert.SerializeXmlNode(xmlDocument);
JObject jsonResult = (JObject)JsonConvert.DeserializeObject(json);
if (jsonResult.ContainsKey("err")) //抓取錯誤
{
logger.LogError("【ParkingJob】【停車場剩餘車位資訊】");
logger.LogError("【ParkingJob】【停車場剩餘車位資訊】[錯誤內容]{0}", json);
}
else
{
if (jsonResult.ContainsKey("real")) //表示可以讀取到內容
{
List<Dictionary<string, object>> ontimeRawDatas = new List<Dictionary<string, object>>();
var realList = jsonResult["real"];
var display = realList["@display"];
if (display != null)
{
var tempStrSplit = display.ToString().Split(" ");
if (tempStrSplit[0] != area.Remain.ToString())
{
logger.LogError("【ParkingJob】【停車場剩餘車位資訊】[修改失敗]{0}", display.ToString());
}
}
}
}
}
else
{
logger.LogWarning("【ParkingJob】【停車場剩餘車位資訊】[查無該名稱對應表]{0}", area.Name);
}
}
}
else
{
logger.LogWarning("【ParkingJob】【停車場剩餘車位資訊】 - [查無資料]");
}
await task_Detail.InsertWorkTime_End("ParkingJob", "Parking", "執行成功停車場剩餘車位Job");
//logger.LogInformation("【ParkingJob】【執行成功停車場剩餘車位Job】");
}
catch (Exception exception)
{
await task_Detail.WorkFail("ParkingJob", "Parking", exception.ToString());
logger.LogInformation("【ParkingJob】【執行失敗停車場剩餘車位Job】");
logger.LogInformation("【ParkingJob】【執行失敗停車場剩餘車位Job】[Exception]{0}", exception.ToString());
}
}
#endregion
#region
if (await task_Detail.GetNeedWorkTask("ParkingJob", "Device"))
{
try
{
await task_Detail.InsertWorkTime("ParkingJob", "Device", "開始執行設備資訊Job");
//logger.LogInformation("【ParkingJob】【開始執行設備資訊Job】");
HttpWebRequest equipmentRequest = (HttpWebRequest)WebRequest.Create($"{parkingConfig.Host}{parkingConfig.Prefix}/api/equipment/state");
equipmentRequest.Method = "GET";
//request.Headers.Add("Authorization", "Basic " + encoded);
equipmentRequest.PreAuthenticate = true;
HttpWebResponse equipmentResponse = (HttpWebResponse)equipmentRequest.GetResponse();
var equipmentResponseContent = new StreamReader(equipmentResponse.GetResponseStream()).ReadToEnd();
var equipmentResponseResult = JsonConvert.DeserializeObject<EquipmentResponse>(equipmentResponseContent);
//取得設備對應表
var sqlEquipmentMapping = $@"SELECT * FROM variable WHERE deleted = 0 AND system_type = 'parkingEquipmentMapping'";
var parkingEquipmentMapping = await backgroundServiceRepository.GetAllAsync<VariableInfo>(sqlEquipmentMapping);
//List<VariableInfo> parkingEquipmentMapping = new List<VariableInfo>();
//VariableInfo variableInfo_1 = new VariableInfo();
//variableInfo_1.System_key = "APS-000";
//variableInfo_1.system_value = "D3_P_B4F_CAPS_B413";
//parkingEquipmentMapping.Add(variableInfo_1);
//VariableInfo variableInfo_2 = new VariableInfo();
//variableInfo_2.System_key = "APS-001";
//variableInfo_2.system_value = "D3_P_B4F_CAPS_B414";
//parkingEquipmentMapping.Add(variableInfo_2);
if (equipmentResponseResult != null && equipmentResponseResult.Code == "20000")
{
foreach (var equipment in equipmentResponseResult.Payload)
{
//找出對定的設備代碼
var selectedMapping = parkingEquipmentMapping.Where(x => x.System_key == equipment.Name).FirstOrDefault();
if (selectedMapping != null)
{
var tagName = selectedMapping.system_value;
var apiFormat = @"{0}obix/config/Arena/{1}/{2}/{3}/{4}/{5}/ST/set";
var tagNameSplit = tagName.Split("_");
var parames = new List<object>();
parames.Add(parkingConfig.ApiBase);
for (var i = 0; i < tagNameSplit.Length; i++)
{
if (i != tagNameSplit.Length - 1)
{
parames.Add(tagNameSplit[i]);
}
else
{
parames.Add(tagName);
}
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format(apiFormat, parames.ToArray()));
request.Method = "POST";
request.Headers.Add("Authorization", "Basic " + encoded);
request.PreAuthenticate = true;
var real = $@"<real val='{equipment.Alive.ToString().ToLower()}' />";
byte[] realByteArray = Encoding.UTF8.GetBytes(real);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(realByteArray, 0, realByteArray.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(responseContent);
string json = JsonConvert.SerializeXmlNode(xmlDocument);
JObject jsonResult = (JObject)JsonConvert.DeserializeObject(json);
if (jsonResult.ContainsKey("err")) //抓取錯誤
{
logger.LogError("【ParkingJob】【設備資訊】");
logger.LogError("【ParkingJob】【設備資訊】[錯誤內容]{0}", json);
}
else
{
if (jsonResult.ContainsKey("bool")) //表示可以讀取到內容
{
List<Dictionary<string, object>> ontimeRawDatas = new List<Dictionary<string, object>>();
var realList = jsonResult["bool"];
var val = realList["@val"];
if (val != null)
{
var tempStrSplit = val.ToString();
if (tempStrSplit != equipment.Alive.ToString().ToLower())
{
logger.LogError("【ParkingJob】【設備資訊】[修改失敗]{0}", val.ToString());
}
}
}
}
}
else
{
logger.LogWarning("【ParkingJob】【設備資訊】[查無該名稱對應表]{0}", equipment.Name);
}
}
}
else
{
logger.LogWarning("【ParkingJob】【設備資訊】 - [查無資料]");
}
await task_Detail.InsertWorkTime_End("ParkingJob", "Device", "執行成功設備資訊Job");
//logger.LogInformation("【ParkingJob】【執行成功設備資訊Job】");
}
catch (Exception exception)
{
await task_Detail.WorkFail("ParkingJob", "Device", exception.ToString());
logger.LogInformation("【ParkingJob】【執行失敗設備資訊Job】");
logger.LogInformation("【ParkingJob】【執行失敗設備資訊Job】[Exception]{0}", exception.ToString());
}
}
#endregion
await task_Detail.InsertWorkTime_End("ParkingJob", "All", "任務完成");
}
}
catch (Exception exception)
{
await task_Detail.WorkFail("ParkingJob", "All", exception.ToString());
logger.LogError("【ParkingJob】【任務失敗】");
logger.LogError("【ParkingJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
}
}

View File

@ -1,77 +0,0 @@
using Backend.Services.Implement;
using Microsoft.Extensions.Logging;
using Quartz;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Backend.Quartz.Jobs
{
/// <summary>
/// 定時將資料表加入派送任務
/// </summary>
[DisallowConcurrentExecution]
class RegularUpdateDBTableJob: IJob
{
private readonly ILogger<RegularUpdateDBTableJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly IBackendRepository backendRepository;
public RegularUpdateDBTableJob(
ILogger<RegularUpdateDBTableJob> logger,
IBackgroundServiceRepository backgroundServiceRepository,
IBackendRepository backendRepository)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
this.backendRepository = backendRepository;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
logger.LogInformation("【RegularUpdateDBTableJob】【任務開始】");
//要派送的資料表
List<string> db_tables = new List<string>() { "variable" };
foreach (var db_table in db_tables)
{
try
{
logger.LogInformation("【RegularUpdateDBTableJob】【新增資料表 [{0}] 至派送任務】", db_table);
//取得資料表所有資料
var temp_datas = (await backgroundServiceRepository.GetAllAsync<dynamic>(db_table, ""));
List<Dictionary<string, object>> dicts = new List<Dictionary<string, object>>();
foreach (var temp_data in temp_datas)
{
var dict = new Dictionary<string, object>((IDictionary<string, object>)temp_data);
dicts.Add(dict);
}
await backendRepository.ManualInsertBackgroundServiceTask("", "", db_table, "purge_all_insert", dicts);
logger.LogError("【RegularUpdateDBTableJob】【新增成功 資料表 [{0}] 至派送任務】", db_table);
}
catch(Exception exception)
{
logger.LogError("【RegularUpdateDBTableJob】【新增失敗 資料表 [{0}] 至派送任務】", db_table);
logger.LogError("【RegularUpdateDBTableJob】【新增失敗 資料表 [{0}] 至派送任務】[Exception]{1}", db_table, exception.ToString());
}
}
}
catch (Exception exception)
{
logger.LogError("【RegularUpdateDBTableJob】【任務失敗】");
logger.LogError("【RegularUpdateDBTableJob】【任務失敗】[Exception]{0}", exception.ToString());
}
}
}
}

View File

@ -1,559 +0,0 @@
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;
namespace Backend.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
{
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);
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", "api_weateher"))
{
try
{
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";
HttpResponseMessage response = client.GetAsync(UVUri).Result;
String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
var observation = JsonConvert.DeserializeObject<Root>(jsonUVs);
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[0].WeatherElement;
foreach (var a in Type_ALL)
{
foreach (var b in a.Time)
{
if (a.ElementName == "PoP12h" || a.ElementName == "Wx")
{
if (Convert.ToDateTime(b.StartTime) > DateTime.Now.AddDays(1))
{
break;
}
}
else
{
if (Convert.ToDateTime(b.DataTime) > DateTime.Now.AddDays(1))
{
break;
}
}
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
{
WeatherAPIdb.Add("@start_time", b.DataTime);
WeatherAPIdb.Add("@end_time", null);
}
WeatherAPIdbS.Add(WeatherAPIdb);
if (a.ElementName == "Wx")
{
Dictionary<string, object> TWeatherAPIdb = new Dictionary<string, object>()
{
{ "@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);
}
}
}
await backendRepository.AddMutiByCustomTable(WeatherAPIdbS, "api_weateher");
}
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");
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.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);
}
}
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.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);
}
}
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.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},
{ "@expires", observation.Alert.Info.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.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");
}
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());
}
}
}
catch (Exception exception)
{
logger.LogError("【WeatherAPIJob】【任務失敗】");
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;
}
}
}
}

View File

@ -1,69 +0,0 @@
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Backend.Quartz
{
public class QuartzHostedService : IHostedService
{
private readonly ISchedulerFactory _schedulerFactory;
private readonly IJobFactory _jobFactory;
private readonly IEnumerable<JobSchedule> _jobSchedules;
public QuartzHostedService(ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IEnumerable<JobSchedule> jobSchedules)
{
_schedulerFactory = schedulerFactory ?? throw new ArgumentNullException(nameof(schedulerFactory));
_jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));
_jobSchedules = jobSchedules ?? throw new ArgumentNullException(nameof(jobSchedules));
}
public IScheduler Scheduler { get; set; }
public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
Scheduler.JobFactory = _jobFactory;
foreach (var jobSchedule in _jobSchedules)
{
var job = CreateJob(jobSchedule);
var trigger = CreateTrigger(jobSchedule);
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
jobSchedule.JobStatu = JobStatus.Scheduling;
}
await Scheduler.Start(cancellationToken);
foreach (var jobSchedule in _jobSchedules)
{
jobSchedule.JobStatu = JobStatus.Running;
}
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
foreach (var jobSchedule in _jobSchedules)
{
jobSchedule.JobStatu = JobStatus.Stopped;
}
}
private static IJobDetail CreateJob(JobSchedule schedule)
{
var jobType = schedule.JobType;
return JobBuilder
.Create(jobType)
.WithIdentity(jobType.FullName)
.WithDescription(jobType.Name)
.Build();
}
private static ITrigger CreateTrigger(JobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity($"{schedule.JobType.FullName}.trigger")
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.CronExpression)
.Build();
}
}
}

View File

@ -1,26 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Text;
namespace Backend.Quartz
{
public class SingletonJobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
public SingletonJobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
}
public void ReturnJob(IJob job)
{
}
}
}

View File

@ -1,935 +0,0 @@
using Backend.Models;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using Dapper;
using System.Linq;
using Newtonsoft.Json.Linq;
using System.Xml;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using Repository.Helper;
using Repository.BackendRepository.Interface;
using Repository.BackendRepository.Implement;
using System.Threading.Tasks;
namespace BackendWorkerService.Services.Implement
{
/// <summary>
/// 電錶補償歸檔
/// </summary>
public class ProcEletricMeterService
{
private readonly IBackgroundServiceRepository backgroundServiceRepository;
private readonly IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository;
public ProcEletricMeterService(IBackgroundServiceRepository backgroundServiceRepository,
IBackgroundServiceMsSqlRepository backgroundServiceMySqlRepository)
{
this.backgroundServiceRepository = backgroundServiceRepository;
this.backgroundServiceMsSqlRepository = backgroundServiceMySqlRepository;
}
public async Task<bool> ArchiveData()
{
bool result = false;
int repeatTimes = 0;
string targetTable = string.Empty;
EDFunction ed = new EDFunction();
XmlDocument xmlDocument = new XmlDocument();
var obixApiConfig = new ObixApiConfig();
string encoded = string.Empty;
try
{
//取得可錯誤次數
var sqlArchive = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'archiveConfig'";
var variableArchive = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlArchive);
repeatTimes = Convert.ToInt32(variableArchive.Where(x => x.Name == "RepeatTimes").Select(x => x.Value).FirstOrDefault());
var saveToMSDB = await backgroundServiceRepository.GetOneAsync<string>("select system_value from variable where system_type = 'save_to_ms_db' and deleted = 0");
#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
//取得錯誤的設備sql format
var sql_error_format = @"SELECT * FROM {0} WHERE is_complete = 0 AND repeat_times < @RepeatTimes";
//MY 新增/修改sql format
var MYsql_update_format = @"
UPDATE {0} SET
count_rawdata = @count_rawdata,
min_rawdata = @min_rawdata,
max_rawdata = @max_rawdata,
avg_rawdata = @avg_rawdata,
sum_rawdata = @sum_rawdata,
is_complete = @is_complete,
repeat_times = @repeat_times,
fail_reason = @fail_reason,
updated_at = @updated_at
WHERE device_number = @device_number
AND point = @point
AND start_timestamp = @start_timestamp;
INSERT INTO {0} (
device_number,
point,
start_timestamp,
end_timestamp,
count_rawdata,
min_rawdata,
max_rawdata,
avg_rawdata,
sum_rawdata,
is_complete,
repeat_times,
fail_reason)
SELECT
@device_number,
@point,
@start_timestamp,
@end_timestamp,
@count_rawdata,
@min_rawdata,
@max_rawdata,
@avg_rawdata,
@sum_rawdata,
@is_complete,
@repeat_times,
@fail_reason
WHERE ROW_COUNT() = 0;";
//新增/修改sql format
var sql_update_format = @"BEGIN TRANSACTION;
UPDATE {0} SET
count_rawdata = @count_rawdata,
min_rawdata = @min_rawdata,
max_rawdata = @max_rawdata,
avg_rawdata = @avg_rawdata,
sum_rawdata = @sum_rawdata,
is_complete = @is_complete,
repeat_times = @repeat_times,
fail_reason = @fail_reason,
updated_at = @updated_at
WHERE device_number = @device_number
AND point = @point
AND start_timestamp = @start_timestamp;
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO {0} (
device_number,
point,
start_timestamp,
end_timestamp,
count_rawdata,
min_rawdata,
max_rawdata,
avg_rawdata,
sum_rawdata,
is_complete,
repeat_times,
fail_reason)
VALUES (
@device_number,
@point,
@start_timestamp,
@end_timestamp,
@count_rawdata,
@min_rawdata,
@max_rawdata,
@avg_rawdata,
@sum_rawdata,
@is_complete,
@repeat_times,
@fail_reason)
END
COMMIT TRANSACTION;";
#region
//using (IDbConnection conn = new SqlConnection(Connection1))
//{
// //取得所有須補償的設備資訊
// targetTable = "archive_electric_meter_hour";
// var sql_error_hour = string.Format(sql_error_format, targetTable);
// var error_hours = conn.Query<ArchiveElectricMeter>(sql_error_hour, new { RepeatTimes = repeatTimes }).ToList();
// List<Dictionary<string, object>> archiveHourRawDatas = new List<Dictionary<string, object>>();
// if (error_hours.Count() > 0)
// {
// foreach (var error_hour in error_hours)
// {
// DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
// deviceNumberPoint.DeviceNumber = error_hour.Device_number;
// deviceNumberPoint.Point = error_hour.Point;
// deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", error_hour.Device_number, error_hour.Point);
// var startTimestamp = string.Format("{0}+08:00", error_hour.Start_timestamp.Replace(" ", "T"));
// var endTimestamp = string.Format("{0}+08:00", error_hour.End_timestamp.Replace(" ", "T"));
// var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
// <abstime name='start' val='{startTimestamp}' />
// <abstime name='end' val='{endTimestamp}' />
// <reltime name='interval' val = 'PT1H' />
// </obj>";
// HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
// //HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
// archiveHourRequest.Method = "POST";
// archiveHourRequest.Headers.Add("Authorization", "Basic " + encoded);
// archiveHourRequest.PreAuthenticate = true;
// byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
// using (Stream reqStream = archiveHourRequest.GetRequestStream())
// {
// reqStream.Write(byteArray, 0, byteArray.Length);
// }
// HttpWebResponse archiveHourResponse = (HttpWebResponse)archiveHourRequest.GetResponse();
// var archiveHourResponseContent = new StreamReader(archiveHourResponse.GetResponseStream()).ReadToEnd();
// xmlDocument.LoadXml(archiveHourResponseContent);
// string archiveHourJson = JsonConvert.SerializeXmlNode(xmlDocument);
// JObject archiveHourJsonResult = (JObject)JsonConvert.DeserializeObject(archiveHourJson);
// if (archiveHourJsonResult.ContainsKey("err")) //抓取錯誤
// {
// Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
// archiveDayRawData.Add("@device_number", error_hour.Device_number);
// archiveDayRawData.Add("@point", error_hour.Point);
// archiveDayRawData.Add("@start_timestamp", error_hour.Start_timestamp);
// archiveDayRawData.Add("@end_timestamp", error_hour.End_timestamp);
// archiveDayRawData.Add("@is_complete", 0);
// archiveDayRawData.Add("@repeat_times", ++error_hour.Repeat_times);
// archiveDayRawData.Add("@fail_reason", archiveHourJson);
// archiveDayRawData.Add("@count_rawdata", 0);
// archiveDayRawData.Add("@min_rawdata", 0);
// archiveDayRawData.Add("@max_rawdata", 0);
// archiveDayRawData.Add("@avg_rawdata", 0);
// archiveDayRawData.Add("@sum_rawdata", 0);
// archiveDayRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
// archiveHourRawDatas.Add(archiveDayRawData);
// }
// if (archiveHourJsonResult.ContainsKey("obj")) //表示可以讀取到內容
// {
// var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveHourJsonResult);
// if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
// {
// archiveHourRawDatas.AddRange(ArrangeRawDatas);
// }
// }
// }
// if (archiveHourRawDatas.Count() > 0)
// {
// var sql_error_update = string.Format(sql_update_format, targetTable);
// conn.Execute(sql_error_update, archiveHourRawDatas);
// }
// }
// conn.Close();
//}
#endregion
#region
//取得所有須補償的設備資訊
targetTable = "archive_electric_meter_day";
var sql_error_day = string.Format(sql_error_format, targetTable);
var electric_error_days = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_day, new { RepeatTimes = repeatTimes });
List<Dictionary<string, object>> electricArchiveDayRawDatas = new List<Dictionary<string, object>>();
if (electric_error_days.Count() > 0)
{
foreach (var error_day in electric_error_days)
{
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
deviceNumberPoint.DeviceNumber = error_day.Device_number;
deviceNumberPoint.Point = error_day.Point;
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", error_day.Device_number, error_day.Point);
var startTimestamp = string.Format("{0}+08:00", error_day.Start_timestamp.Replace(" ", "T"));
var endTimestamp = string.Format("{0}+08:00", error_day.End_timestamp.Replace(" ", "T"));
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
<abstime name='start' val='{startTimestamp}' />
<abstime name='end' val='{endTimestamp}' />
<reltime name='interval' val = 'PT1D' />
</obj>";
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
archiveDayRequest.Method = "POST";
archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
archiveDayRequest.PreAuthenticate = true;
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
using (Stream reqStream = archiveDayRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse archiveDayResponse = (HttpWebResponse)archiveDayRequest.GetResponse();
var archiveDayResponseContent = new StreamReader(archiveDayResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(archiveDayResponseContent);
string archiveDayJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject archiveDayJsonResult = (JObject)JsonConvert.DeserializeObject(archiveDayJson);
if (archiveDayJsonResult.ContainsKey("err")) //抓取錯誤
{
Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
archiveDayRawData.Add("@device_number", error_day.Device_number);
archiveDayRawData.Add("@point", error_day.Point);
archiveDayRawData.Add("@start_timestamp", DateTime.Parse(error_day.Start_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveDayRawData.Add("@end_timestamp", DateTime.Parse(error_day.End_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveDayRawData.Add("@is_complete", 0);
archiveDayRawData.Add("@repeat_times", ++error_day.Repeat_times);
archiveDayRawData.Add("@fail_reason", archiveDayJson);
archiveDayRawData.Add("@count_rawdata", 0);
archiveDayRawData.Add("@min_rawdata", 0);
archiveDayRawData.Add("@max_rawdata", 0);
archiveDayRawData.Add("@avg_rawdata", 0);
archiveDayRawData.Add("@sum_rawdata", 0);
archiveDayRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
electricArchiveDayRawDatas.Add(archiveDayRawData);
}
if (archiveDayJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveDayJsonResult);
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
{
electricArchiveDayRawDatas.AddRange(ArrangeRawDatas);
}
}
}
if (electricArchiveDayRawDatas.Count() > 0)
{
var Mysql_error_update = string.Format(MYsql_update_format, targetTable);
var sql_error_update = string.Format(sql_update_format, targetTable);
if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
{
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, electricArchiveDayRawDatas);
}
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, electricArchiveDayRawDatas);
}
}
targetTable = "archive_water_meter_day";
sql_error_day = string.Format(sql_error_format, targetTable);
var water_error_days = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_day, new { RepeatTimes = repeatTimes });
List<Dictionary<string, object>> waterArchiveDayRawDatas = new List<Dictionary<string, object>>();
if (water_error_days.Count() > 0)
{
foreach (var error_day in water_error_days)
{
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
deviceNumberPoint.DeviceNumber = error_day.Device_number;
deviceNumberPoint.Point = error_day.Point;
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", error_day.Device_number, error_day.Point);
var startTimestamp = string.Format("{0}+08:00", error_day.Start_timestamp.Replace(" ", "T"));
var endTimestamp = string.Format("{0}+08:00", error_day.End_timestamp.Replace(" ", "T"));
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
<abstime name='start' val='{startTimestamp}' />
<abstime name='end' val='{endTimestamp}' />
<reltime name='interval' val = 'PT1D' />
</obj>";
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
archiveDayRequest.Method = "POST";
archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
archiveDayRequest.PreAuthenticate = true;
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
using (Stream reqStream = archiveDayRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse archiveDayResponse = (HttpWebResponse)archiveDayRequest.GetResponse();
var archiveDayResponseContent = new StreamReader(archiveDayResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(archiveDayResponseContent);
string archiveDayJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject archiveDayJsonResult = (JObject)JsonConvert.DeserializeObject(archiveDayJson);
if (archiveDayJsonResult.ContainsKey("err")) //抓取錯誤
{
Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
archiveDayRawData.Add("@device_number", error_day.Device_number);
archiveDayRawData.Add("@point", error_day.Point);
archiveDayRawData.Add("@start_timestamp", DateTime.Parse(error_day.Start_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveDayRawData.Add("@end_timestamp", DateTime.Parse(error_day.End_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveDayRawData.Add("@is_complete", 0);
archiveDayRawData.Add("@repeat_times", ++error_day.Repeat_times);
archiveDayRawData.Add("@fail_reason", archiveDayJson);
archiveDayRawData.Add("@count_rawdata", 0);
archiveDayRawData.Add("@min_rawdata", 0);
archiveDayRawData.Add("@max_rawdata", 0);
archiveDayRawData.Add("@avg_rawdata", 0);
archiveDayRawData.Add("@sum_rawdata", 0);
archiveDayRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
waterArchiveDayRawDatas.Add(archiveDayRawData);
}
if (archiveDayJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveDayJsonResult);
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
{
waterArchiveDayRawDatas.AddRange(ArrangeRawDatas);
}
}
}
if (waterArchiveDayRawDatas.Count() > 0)
{
var Mysql_error_update = string.Format(MYsql_update_format, targetTable);
var sql_error_update = string.Format(sql_update_format, targetTable);
if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
{
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, waterArchiveDayRawDatas);
}
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, waterArchiveDayRawDatas);
}
}
#endregion
#region
//取得所有須補償的設備資訊
targetTable = "archive_electric_meter_week";
var sql_error_week = string.Format(sql_error_format, targetTable);
var eletric_error_weeks = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_week, new { RepeatTimes = repeatTimes });
List<Dictionary<string, object>> electricArchiveWeekRawDatas = new List<Dictionary<string, object>>();
if (eletric_error_weeks.Count() > 0)
{
foreach (var error_week in eletric_error_weeks)
{
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
deviceNumberPoint.DeviceNumber = error_week.Device_number;
deviceNumberPoint.Point = error_week.Point;
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", error_week.Device_number, error_week.Point);
var startTimestamp = string.Format("{0}+08:00", error_week.Start_timestamp.Replace(" ", "T"));
var endTimestamp = string.Format("{0}+08:00", error_week.End_timestamp.Replace(" ", "T"));
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
<abstime name='start' val='{startTimestamp}' />
<abstime name='end' val='{endTimestamp}' />
<reltime name='interval' val = 'PT7D' />
</obj>";
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
archiveWeekRequest.Method = "POST";
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
archiveWeekRequest.PreAuthenticate = true;
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
using (Stream reqStream = archiveWeekRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse archiveWeekResponse = (HttpWebResponse)archiveWeekRequest.GetResponse();
var archiveWeekResponseContent = new StreamReader(archiveWeekResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(archiveWeekResponseContent);
string archiveWeekJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject archiveWeekJsonResult = (JObject)JsonConvert.DeserializeObject(archiveWeekJson);
if (archiveWeekJsonResult.ContainsKey("err")) //抓取錯誤
{
Dictionary<string, object> archiveWeekRawData = new Dictionary<string, object>();
archiveWeekRawData.Add("@device_number", error_week.Device_number);
archiveWeekRawData.Add("@point", error_week.Point);
archiveWeekRawData.Add("@start_timestamp", DateTime.Parse(error_week.Start_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveWeekRawData.Add("@end_timestamp", DateTime.Parse(error_week.End_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveWeekRawData.Add("@is_complete", 0);
archiveWeekRawData.Add("@repeat_times", ++error_week.Repeat_times);
archiveWeekRawData.Add("@fail_reason", archiveWeekJson);
archiveWeekRawData.Add("@count_rawdata", 0);
archiveWeekRawData.Add("@min_rawdata", 0);
archiveWeekRawData.Add("@max_rawdata", 0);
archiveWeekRawData.Add("@avg_rawdata", 0);
archiveWeekRawData.Add("@sum_rawdata", 0);
archiveWeekRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
electricArchiveWeekRawDatas.Add(archiveWeekRawData);
}
if (archiveWeekJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveWeekJsonResult);
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
{
electricArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
}
}
}
if (electricArchiveWeekRawDatas.Count() > 0)
{
var Mysql_error_update = string.Format(MYsql_update_format, targetTable);
var sql_error_update = string.Format(sql_update_format, targetTable);
if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
{
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, electricArchiveWeekRawDatas);
}
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, electricArchiveWeekRawDatas);
}
}
targetTable = "archive_water_meter_week";
sql_error_week = string.Format(sql_error_format, targetTable);
var water_error_weeks = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_week, new { RepeatTimes = repeatTimes });
List<Dictionary<string, object>> waterArchiveWeekRawDatas = new List<Dictionary<string, object>>();
if (water_error_weeks.Count() > 0)
{
foreach (var error_week in water_error_weeks)
{
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
deviceNumberPoint.DeviceNumber = error_week.Device_number;
deviceNumberPoint.Point = error_week.Point;
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", error_week.Device_number, error_week.Point);
var startTimestamp = string.Format("{0}+08:00", error_week.Start_timestamp.Replace(" ", "T"));
var endTimestamp = string.Format("{0}+08:00", error_week.End_timestamp.Replace(" ", "T"));
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
<abstime name='start' val='{startTimestamp}' />
<abstime name='end' val='{endTimestamp}' />
<reltime name='interval' val = 'PT7D' />
</obj>";
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
archiveWeekRequest.Method = "POST";
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
archiveWeekRequest.PreAuthenticate = true;
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
using (Stream reqStream = archiveWeekRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse archiveWeekResponse = (HttpWebResponse)archiveWeekRequest.GetResponse();
var archiveWeekResponseContent = new StreamReader(archiveWeekResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(archiveWeekResponseContent);
string archiveWeekJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject archiveWeekJsonResult = (JObject)JsonConvert.DeserializeObject(archiveWeekJson);
if (archiveWeekJsonResult.ContainsKey("err")) //抓取錯誤
{
Dictionary<string, object> archiveWeekRawData = new Dictionary<string, object>();
archiveWeekRawData.Add("@device_number", error_week.Device_number);
archiveWeekRawData.Add("@point", error_week.Point);
archiveWeekRawData.Add("@start_timestamp", DateTime.Parse(error_week.Start_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveWeekRawData.Add("@end_timestamp", DateTime.Parse(error_week.End_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveWeekRawData.Add("@is_complete", 0);
archiveWeekRawData.Add("@repeat_times", ++error_week.Repeat_times);
archiveWeekRawData.Add("@fail_reason", archiveWeekJson);
archiveWeekRawData.Add("@count_rawdata", 0);
archiveWeekRawData.Add("@min_rawdata", 0);
archiveWeekRawData.Add("@max_rawdata", 0);
archiveWeekRawData.Add("@avg_rawdata", 0);
archiveWeekRawData.Add("@sum_rawdata", 0);
archiveWeekRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
waterArchiveWeekRawDatas.Add(archiveWeekRawData);
}
if (archiveWeekJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveWeekJsonResult);
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
{
waterArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
}
}
}
if (waterArchiveWeekRawDatas.Count() > 0)
{
var Mysql_error_update = string.Format(MYsql_update_format, targetTable);
var sql_error_update = string.Format(sql_update_format, targetTable);
if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
{
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, waterArchiveWeekRawDatas);
}
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, waterArchiveWeekRawDatas);
}
}
#endregion
#region
//取得所有須補償的設備資訊
targetTable = "archive_electric_meter_month";
var sql_error_month = string.Format(sql_error_format, targetTable);
var electric_error_months = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_month, new { RepeatTimes = repeatTimes });
List<Dictionary<string, object>> electricArchiveMonthRawDatas = new List<Dictionary<string, object>>();
if (electric_error_months.Count() > 0)
{
foreach (var error_month in electric_error_months)
{
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
deviceNumberPoint.DeviceNumber = error_month.Device_number;
deviceNumberPoint.Point = error_month.Point;
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", error_month.Device_number, error_month.Point);
var startTimestamp = string.Format("{0}+08:00", error_month.Start_timestamp.Replace(" ", "T"));
var endTimestamp = string.Format("{0}+08:00", error_month.End_timestamp.Replace(" ", "T"));
var startDateTime = Convert.ToDateTime(error_month.Start_timestamp);
var dayInMonth = DateTime.DaysInMonth(startDateTime.Year, startDateTime.Month);
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
<abstime name='start' val='{startTimestamp}' />
<abstime name='end' val='{endTimestamp}' />
<reltime name='interval' val = 'PT{dayInMonth}D' />
</obj>";
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
archiveMonthRequest.Method = "POST";
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
archiveMonthRequest.PreAuthenticate = true;
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
using (Stream reqStream = archiveMonthRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse archiveMonthResponse = (HttpWebResponse)archiveMonthRequest.GetResponse();
var archiveMonthResponseContent = new StreamReader(archiveMonthResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(archiveMonthResponseContent);
string archiveMonthJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject archiveMonthJsonResult = (JObject)JsonConvert.DeserializeObject(archiveMonthJson);
if (archiveMonthJsonResult.ContainsKey("err")) //抓取錯誤
{
Dictionary<string, object> archiveMonthRawData = new Dictionary<string, object>();
archiveMonthRawData.Add("@device_number", error_month.Device_number);
archiveMonthRawData.Add("@point", error_month.Point);
archiveMonthRawData.Add("@start_timestamp", DateTime.Parse(error_month.Start_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveMonthRawData.Add("@end_timestamp", DateTime.Parse(error_month.End_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveMonthRawData.Add("@is_complete", 0);
archiveMonthRawData.Add("@repeat_times", ++error_month.Repeat_times);
archiveMonthRawData.Add("@fail_reason", archiveMonthJson);
archiveMonthRawData.Add("@count_rawdata", 0);
archiveMonthRawData.Add("@min_rawdata", 0);
archiveMonthRawData.Add("@max_rawdata", 0);
archiveMonthRawData.Add("@avg_rawdata", 0);
archiveMonthRawData.Add("@sum_rawdata", 0);
archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
electricArchiveMonthRawDatas.Add(archiveMonthRawData);
}
if (archiveMonthJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveMonthJsonResult);
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
{
electricArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
}
}
}
if (electricArchiveMonthRawDatas.Count() > 0)
{
var Mysql_error_update = string.Format(MYsql_update_format, targetTable);
var sql_error_update = string.Format(sql_update_format, targetTable);
if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
{
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, electricArchiveMonthRawDatas);
}
await backgroundServiceRepository.ExecuteSql(MYsql_update_format, electricArchiveMonthRawDatas);
}
}
targetTable = "archive_electric_meter_month";
sql_error_month = string.Format(sql_error_format, targetTable);
var water_error_months = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_month, new { RepeatTimes = repeatTimes });
List<Dictionary<string, object>> waterArchiveMonthRawDatas = new List<Dictionary<string, object>>();
if (water_error_months.Count() > 0)
{
foreach (var error_month in water_error_months)
{
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
deviceNumberPoint.DeviceNumber = error_month.Device_number;
deviceNumberPoint.Point = error_month.Point;
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", error_month.Device_number, error_month.Point);
var startTimestamp = string.Format("{0}+08:00", error_month.Start_timestamp.Replace(" ", "T"));
var endTimestamp = string.Format("{0}+08:00", error_month.End_timestamp.Replace(" ", "T"));
var startDateTime = Convert.ToDateTime(error_month.Start_timestamp);
var dayInMonth = DateTime.DaysInMonth(startDateTime.Year, startDateTime.Month);
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
<abstime name='start' val='{startTimestamp}' />
<abstime name='end' val='{endTimestamp}' />
<reltime name='interval' val = 'PT{dayInMonth}D' />
</obj>";
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
archiveMonthRequest.Method = "POST";
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
archiveMonthRequest.PreAuthenticate = true;
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
using (Stream reqStream = archiveMonthRequest.GetRequestStream())
{
reqStream.Write(byteArray, 0, byteArray.Length);
}
HttpWebResponse archiveMonthResponse = (HttpWebResponse)archiveMonthRequest.GetResponse();
var archiveMonthResponseContent = new StreamReader(archiveMonthResponse.GetResponseStream()).ReadToEnd();
xmlDocument.LoadXml(archiveMonthResponseContent);
string archiveMonthJson = JsonConvert.SerializeXmlNode(xmlDocument);
JObject archiveMonthJsonResult = (JObject)JsonConvert.DeserializeObject(archiveMonthJson);
if (archiveMonthJsonResult.ContainsKey("err")) //抓取錯誤
{
Dictionary<string, object> archiveMonthRawData = new Dictionary<string, object>();
archiveMonthRawData.Add("@device_number", error_month.Device_number);
archiveMonthRawData.Add("@point", error_month.Point);
archiveMonthRawData.Add("@start_timestamp", DateTime.Parse(error_month.Start_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveMonthRawData.Add("@end_timestamp", DateTime.Parse(error_month.End_timestamp, System.Globalization.CultureInfo.CurrentCulture));
archiveMonthRawData.Add("@is_complete", 0);
archiveMonthRawData.Add("@repeat_times", ++error_month.Repeat_times);
archiveMonthRawData.Add("@fail_reason", archiveMonthJson);
archiveMonthRawData.Add("@count_rawdata", 0);
archiveMonthRawData.Add("@min_rawdata", 0);
archiveMonthRawData.Add("@max_rawdata", 0);
archiveMonthRawData.Add("@avg_rawdata", 0);
archiveMonthRawData.Add("@sum_rawdata", 0);
archiveMonthRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
waterArchiveMonthRawDatas.Add(archiveMonthRawData);
}
if (archiveMonthJsonResult.ContainsKey("obj")) //表示可以讀取到內容
{
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveMonthJsonResult);
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
{
waterArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
}
}
}
if (waterArchiveMonthRawDatas.Count() > 0)
{
var Mysql_error_update = string.Format(MYsql_update_format, targetTable);
var sql_error_update = string.Format(sql_update_format, targetTable);
if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
{
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, waterArchiveMonthRawDatas);
}
await backgroundServiceRepository.ExecuteSql(MYsql_update_format, waterArchiveMonthRawDatas);
}
}
#endregion
result = true;
}
catch (Exception exception)
{
throw exception;
}
return result;
}
private List<Dictionary<string, object>> ArrangeRawData(DeviceNumberPoint deviceNumberPoint, JObject jsonResult)
{
List<Dictionary<string, object>> arrangeRawDatas = new List<Dictionary<string, object>>();
var histories = jsonResult["obj"]["list"];
var rawdateCount = Convert.ToInt32(jsonResult["obj"]["int"]["@val"].ToString());
if (rawdateCount == 0)
{
return null;
}
if (histories != null && histories.HasValues)
{
if (rawdateCount > 1)
{ //多筆資料
foreach (var history in histories)
{
Dictionary<string, object> arrangeRawData = new Dictionary<string, object>();
arrangeRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
arrangeRawData.Add("@point", deviceNumberPoint.Point);
//時間
if (history["abstime"] != null && history["abstime"].HasValues)
{
foreach (var abstime in history["abstime"])
{
var name = abstime["@name"].ToString();
switch (name)
{
case "start":
var startTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
arrangeRawData.Add("@start_timestamp", startTimstamp);
break;
case "end":
var endTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
arrangeRawData.Add("@end_timestamp", endTimstamp);
break;
}
}
}
//區間內資料筆數
if (history["int"] != null && history["int"].HasValues)
{
var count = Convert.ToInt32(histories["obj"]["int"]["@val"].ToString());
arrangeRawData.Add("@count_rawdata", count);
}
//整合數值(最大、最小、平均、總和)
if (history["real"] != null && history["real"].HasValues)
{
foreach (var real in history["real"])
{
var name = real["@name"].ToString();
switch (name)
{
case "min":
var min = Convert.ToDecimal(real["@val"].ToString());
arrangeRawData.Add("@min_rawdata", min);
break;
case "max":
var max = Convert.ToDecimal(real["@val"].ToString());
arrangeRawData.Add("@max_rawdata", max);
break;
case "avg":
var avg = Convert.ToDecimal(real["@val"].ToString());
arrangeRawData.Add("@avg_rawdata", avg);
break;
case "sum":
var sum = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
arrangeRawData.Add("@sum_rawdata", sum);
break;
}
}
}
arrangeRawData.Add("@is_complete", 1);
arrangeRawData.Add("@repeat_times", 0);
arrangeRawData.Add("@fail_reason", null);
arrangeRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
arrangeRawDatas.Add(arrangeRawData);
}
}
else
{ //單筆資料
Dictionary<string, object> arrangeRawData = new Dictionary<string, object>();
arrangeRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
arrangeRawData.Add("@point", deviceNumberPoint.Point);
//時間
if (histories["obj"]["abstime"] != null && histories["obj"]["abstime"].HasValues)
{
foreach (var abstime in histories["obj"]["abstime"])
{
var name = abstime["@name"].ToString();
switch (name)
{
case "start":
var startTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
arrangeRawData.Add("@start_timestamp", startTimstamp);
break;
case "end":
var endTimstamp = Convert.ToDateTime(abstime["@val"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
arrangeRawData.Add("@end_timestamp", endTimstamp);
break;
}
}
}
//區間內資料筆數
if (histories["obj"]["int"] != null && histories["obj"]["int"].HasValues)
{
var count = Convert.ToInt32(histories["obj"]["int"]["@val"].ToString());
arrangeRawData.Add("@count_rawdata", count);
}
//整合數值(最大、最小、平均、總和)
if (histories["obj"]["real"] != null && histories["obj"]["real"].HasValues)
{
foreach (var real in histories["obj"]["real"])
{
var name = real["@name"].ToString();
switch (name)
{
case "min":
var min = Convert.ToDecimal(real["@val"].ToString());
arrangeRawData.Add("@min_rawdata", min);
break;
case "max":
var max = Convert.ToDecimal(real["@val"].ToString());
arrangeRawData.Add("@max_rawdata", max);
break;
case "avg":
var avg = Convert.ToDecimal(real["@val"].ToString());
arrangeRawData.Add("@avg_rawdata", avg);
break;
case "sum":
var sum = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
arrangeRawData.Add("@sum_rawdata", sum);
break;
}
}
}
arrangeRawData.Add("@is_complete", 1);
arrangeRawData.Add("@repeat_times", 0);
arrangeRawData.Add("@fail_reason", null);
arrangeRawData.Add("@updated_at", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
arrangeRawDatas.Add(arrangeRawData);
}
}
return arrangeRawDatas;
}
}
}

View File

@ -1,640 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var welcome = Welcome.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Welcome
{
[JsonProperty("success")]
[JsonConverter(typeof(ParseStringConverter))]
public bool Success { get; set; }
[JsonProperty("result")]
public Result Result { get; set; }
[JsonProperty("records")]
public Records Records { get; set; }
}
public partial class Records
{
[JsonProperty("datasetDescription")]
public DatasetDescription DatasetDescription { get; set; }
[JsonProperty("Earthquake")]
public Earthquake[] Earthquake { get; set; }
}
public partial class Earthquake
{
[JsonProperty("EarthquakeNo")]
public long EarthquakeNo { get; set; }
[JsonProperty("ReportType")]
public DatasetDescription ReportType { get; set; }
[JsonProperty("ReportColor")]
public ReportColor ReportColor { get; set; }
[JsonProperty("ReportContent")]
public string ReportContent { get; set; }
[JsonProperty("ReportImageURI")]
public Uri ReportImageUri { get; set; }
[JsonProperty("ReportRemark")]
public ReportRemark ReportRemark { get; set; }
[JsonProperty("Web")]
public Uri Web { get; set; }
[JsonProperty("ShakemapImageURI")]
public Uri ShakemapImageUri { get; set; }
[JsonProperty("EarthquakeInfo")]
public EarthquakeInfo EarthquakeInfo { get; set; }
[JsonProperty("Intensity")]
public Intensity Intensity { get; set; }
}
public partial class EarthquakeInfo
{
[JsonProperty("OriginTime")]
public DateTimeOffset OriginTime { get; set; }
[JsonProperty("Source")]
public Source Source { get; set; }
[JsonProperty("FocalDepth")]
public double FocalDepth { get; set; }
[JsonProperty("Epicenter")]
public Epicenter Epicenter { get; set; }
[JsonProperty("EarthquakeMagnitude")]
public EarthquakeMagnitude EarthquakeMagnitude { get; set; }
}
public partial class EarthquakeMagnitude
{
[JsonProperty("MagnitudeType")]
public MagnitudeType MagnitudeType { get; set; }
[JsonProperty("MagnitudeValue")]
public double MagnitudeValue { get; set; }
}
public partial class Epicenter
{
[JsonProperty("Location")]
public string Location { get; set; }
[JsonProperty("EpicenterLatitude")]
public double EpicenterLatitude { get; set; }
[JsonProperty("EpicenterLongitude")]
public double EpicenterLongitude { get; set; }
}
public partial class Intensity
{
[JsonProperty("ShakingArea")]
public ShakingArea[] ShakingArea { get; set; }
}
public partial class ShakingArea
{
[JsonProperty("AreaDesc")]
public string AreaDesc { get; set; }
[JsonProperty("CountyName")]
public string CountyName { get; set; }
[JsonProperty("InfoStatus", NullValueHandling = NullValueHandling.Ignore)]
public InfoStatus? InfoStatus { get; set; }
[JsonProperty("AreaIntensity")]
public AreaIntensityEnum AreaIntensity { get; set; }
[JsonProperty("EqStation")]
public EqStation[] EqStation { get; set; }
}
public partial class EqStation
{
[JsonProperty("pga", NullValueHandling = NullValueHandling.Ignore)]
public Pga Pga { get; set; }
[JsonProperty("pgv", NullValueHandling = NullValueHandling.Ignore)]
public Pga Pgv { get; set; }
[JsonProperty("StationName")]
public string StationName { get; set; }
[JsonProperty("StationID")]
public string StationId { get; set; }
[JsonProperty("InfoStatus", NullValueHandling = NullValueHandling.Ignore)]
public InfoStatus? InfoStatus { get; set; }
[JsonProperty("BackAzimuth")]
public double BackAzimuth { get; set; }
[JsonProperty("EpicenterDistance")]
public double EpicenterDistance { get; set; }
[JsonProperty("SeismicIntensity")]
public AreaIntensityEnum SeismicIntensity { get; set; }
[JsonProperty("StationLatitude")]
public double StationLatitude { get; set; }
[JsonProperty("StationLongitude")]
public double StationLongitude { get; set; }
[JsonProperty("WaveImageURI", NullValueHandling = NullValueHandling.Ignore)]
public Uri WaveImageUri { get; set; }
}
public partial class Pga
{
[JsonProperty("unit")]
public Unit Unit { get; set; }
[JsonProperty("EWComponent")]
public double EwComponent { get; set; }
[JsonProperty("NSComponent")]
public double NsComponent { get; set; }
[JsonProperty("VComponent")]
public double VComponent { get; set; }
[JsonProperty("IntScaleValue")]
public double IntScaleValue { get; set; }
}
public partial class Result
{
[JsonProperty("resource_id")]
public string ResourceId { get; set; }
[JsonProperty("fields")]
public Field[] Fields { get; set; }
}
public partial class Field
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("type")]
public TypeEnum Type { get; set; }
}
public enum DatasetDescription { };
public enum MagnitudeType { };
public enum Source { };
public enum AreaIntensityEnum { The1級, The2級, The3級, The4級 };
public enum InfoStatus { Observe };
public enum Unit { Gal, Kine };
public enum ReportColor { };
public enum ReportRemark { };
public enum TypeEnum { Float, Integer, String, Timestamp };
public partial class Welcome
{
public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
MagnitudeTypeConverter.Singleton,
SourceConverter.Singleton,
AreaIntensityEnumConverter.Singleton,
InfoStatusConverter.Singleton,
UnitConverter.Singleton,
ReportColorConverter.Singleton,
ReportRemarkConverter.Singleton,
DatasetDescriptionConverter.Singleton,
TypeEnumConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class MagnitudeTypeConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(MagnitudeType) || t == typeof(MagnitudeType?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
if (value == "芮氏規模")
{
return MagnitudeType.;
}
throw new Exception("Cannot unmarshal type MagnitudeType");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (MagnitudeType)untypedValue;
if (value == MagnitudeType.)
{
serializer.Serialize(writer, "芮氏規模");
return;
}
throw new Exception("Cannot marshal type MagnitudeType");
}
public static readonly MagnitudeTypeConverter Singleton = new MagnitudeTypeConverter();
}
internal class SourceConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(Source) || t == typeof(Source?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
if (value == "中央氣象局")
{
return Source.;
}
throw new Exception("Cannot unmarshal type Source");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (Source)untypedValue;
if (value == Source.)
{
serializer.Serialize(writer, "中央氣象局");
return;
}
throw new Exception("Cannot marshal type Source");
}
public static readonly SourceConverter Singleton = new SourceConverter();
}
internal class AreaIntensityEnumConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(AreaIntensityEnum) || t == typeof(AreaIntensityEnum?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
switch (value)
{
case "1級":
return AreaIntensityEnum.The1級;
case "2級":
return AreaIntensityEnum.The2級;
case "3級":
return AreaIntensityEnum.The3級;
case "4級":
return AreaIntensityEnum.The4級;
}
throw new Exception("Cannot unmarshal type AreaIntensityEnum");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (AreaIntensityEnum)untypedValue;
switch (value)
{
case AreaIntensityEnum.The1級:
serializer.Serialize(writer, "1級");
return;
case AreaIntensityEnum.The2級:
serializer.Serialize(writer, "2級");
return;
case AreaIntensityEnum.The3級:
serializer.Serialize(writer, "3級");
return;
case AreaIntensityEnum.The4級:
serializer.Serialize(writer, "4級");
return;
}
throw new Exception("Cannot marshal type AreaIntensityEnum");
}
public static readonly AreaIntensityEnumConverter Singleton = new AreaIntensityEnumConverter();
}
internal class InfoStatusConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(InfoStatus) || t == typeof(InfoStatus?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
if (value == "observe")
{
return InfoStatus.Observe;
}
throw new Exception("Cannot unmarshal type InfoStatus");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (InfoStatus)untypedValue;
if (value == InfoStatus.Observe)
{
serializer.Serialize(writer, "observe");
return;
}
throw new Exception("Cannot marshal type InfoStatus");
}
public static readonly InfoStatusConverter Singleton = new InfoStatusConverter();
}
internal class UnitConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(Unit) || t == typeof(Unit?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
switch (value)
{
case "gal":
return Unit.Gal;
case "kine":
return Unit.Kine;
}
throw new Exception("Cannot unmarshal type Unit");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (Unit)untypedValue;
switch (value)
{
case Unit.Gal:
serializer.Serialize(writer, "gal");
return;
case Unit.Kine:
serializer.Serialize(writer, "kine");
return;
}
throw new Exception("Cannot marshal type Unit");
}
public static readonly UnitConverter Singleton = new UnitConverter();
}
internal class ReportColorConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ReportColor) || t == typeof(ReportColor?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
if (value == "綠色")
{
return ReportColor.;
}
throw new Exception("Cannot unmarshal type ReportColor");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (ReportColor)untypedValue;
if (value == ReportColor.)
{
serializer.Serialize(writer, "綠色");
return;
}
throw new Exception("Cannot marshal type ReportColor");
}
public static readonly ReportColorConverter Singleton = new ReportColorConverter();
}
internal class ReportRemarkConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ReportRemark) || t == typeof(ReportRemark?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
if (value == "本報告係中央氣象局地震觀測網即時地震資料地震速報之結果。")
{
return ReportRemark.;
}
throw new Exception("Cannot unmarshal type ReportRemark");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (ReportRemark)untypedValue;
if (value == ReportRemark.)
{
serializer.Serialize(writer, "本報告係中央氣象局地震觀測網即時地震資料地震速報之結果。");
return;
}
throw new Exception("Cannot marshal type ReportRemark");
}
public static readonly ReportRemarkConverter Singleton = new ReportRemarkConverter();
}
internal class DatasetDescriptionConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(DatasetDescription) || t == typeof(DatasetDescription?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
if (value == "地震報告")
{
return DatasetDescription.;
}
throw new Exception("Cannot unmarshal type DatasetDescription");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (DatasetDescription)untypedValue;
if (value == DatasetDescription.)
{
serializer.Serialize(writer, "地震報告");
return;
}
throw new Exception("Cannot marshal type DatasetDescription");
}
public static readonly DatasetDescriptionConverter Singleton = new DatasetDescriptionConverter();
}
internal class TypeEnumConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(TypeEnum) || t == typeof(TypeEnum?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
switch (value)
{
case "Float":
return TypeEnum.Float;
case "Integer":
return TypeEnum.Integer;
case "String":
return TypeEnum.String;
case "Timestamp":
return TypeEnum.Timestamp;
}
throw new Exception("Cannot unmarshal type TypeEnum");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (TypeEnum)untypedValue;
switch (value)
{
case TypeEnum.Float:
serializer.Serialize(writer, "Float");
return;
case TypeEnum.Integer:
serializer.Serialize(writer, "Integer");
return;
case TypeEnum.String:
serializer.Serialize(writer, "String");
return;
case TypeEnum.Timestamp:
serializer.Serialize(writer, "Timestamp");
return;
}
throw new Exception("Cannot marshal type TypeEnum");
}
public static readonly TypeEnumConverter Singleton = new TypeEnumConverter();
}
internal class ParseStringConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(bool) || t == typeof(bool?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
bool b;
if (Boolean.TryParse(value, out b))
{
return b;
}
throw new Exception("Cannot unmarshal type bool");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (bool)untypedValue;
var boolString = value ? "true" : "false";
serializer.Serialize(writer, boolString);
return;
}
public static readonly ParseStringConverter Singleton = new ParseStringConverter();
}
}

View File

@ -1,213 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var welcome = Welcome.FromJson(jsonString);
namespace RainApi
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Welcome
{
[JsonProperty("?xml")]
public Xml Xml { get; set; }
[JsonProperty("alert")]
public Alert Alert { get; set; }
}
public partial class Alert
{
[JsonProperty("@xmlns")]
public string Xmlns { get; set; }
[JsonProperty("identifier")]
public string Identifier { get; set; }
[JsonProperty("sender")]
public string Sender { get; set; }
[JsonProperty("sent")]
public DateTimeOffset Sent { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("msgType")]
public string MsgType { get; set; }
[JsonProperty("scope")]
public string Scope { get; set; }
[JsonProperty("references")]
public string References { get; set; }
[JsonProperty("info")]
public Info Info { get; set; }
}
public partial class Info
{
[JsonProperty("language")]
public string Language { get; set; }
[JsonProperty("category")]
public string Category { get; set; }
[JsonProperty("event")]
public string Event { get; set; }
[JsonProperty("urgency")]
public string Urgency { get; set; }
[JsonProperty("severity")]
public string Severity { get; set; }
[JsonProperty("certainty")]
public string Certainty { get; set; }
[JsonProperty("eventCode")]
public EventCode EventCode { get; set; }
[JsonProperty("effective")]
public DateTimeOffset Effective { get; set; }
[JsonProperty("onset")]
public DateTimeOffset Onset { get; set; }
[JsonProperty("expires")]
public DateTimeOffset Expires { get; set; }
[JsonProperty("senderName")]
public string SenderName { get; set; }
[JsonProperty("headline")]
public string Headline { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("instruction")]
public string Instruction { get; set; }
[JsonProperty("web")]
public Uri Web { get; set; }
[JsonProperty("parameter")]
public EventCode Parameter { get; set; }
[JsonProperty("area")]
public List<Area> Area { get; set; }
}
public partial class Area
{
[JsonProperty("areaDesc")]
public string AreaDesc { get; set; }
[JsonProperty("geocode")]
public EventCode Geocode { get; set; }
}
public partial class EventCode
{
[JsonProperty("valueName")]
public string ValueName { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
public partial class Xml
{
[JsonProperty("@version")]
public string Version { get; set; }
[JsonProperty("@encoding")]
public string Encoding { get; set; }
}
public enum ValueName { AlertTitle, ProfileCapTwpEvent10, TaiwanGeocode103 };
public partial class Welcome
{
public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ValueNameConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ValueNameConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ValueName) || t == typeof(ValueName?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
switch (value)
{
case "Taiwan_Geocode_103":
return ValueName.TaiwanGeocode103;
case "alert_title":
return ValueName.AlertTitle;
case "profile:CAP-TWP:Event:1.0":
return ValueName.ProfileCapTwpEvent10;
}
throw new Exception("Cannot unmarshal type ValueName");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (ValueName)untypedValue;
switch (value)
{
case ValueName.TaiwanGeocode103:
serializer.Serialize(writer, "Taiwan_Geocode_103");
return;
case ValueName.AlertTitle:
serializer.Serialize(writer, "alert_title");
return;
case ValueName.ProfileCapTwpEvent10:
serializer.Serialize(writer, "profile:CAP-TWP:Event:1.0");
return;
}
throw new Exception("Cannot marshal type ValueName");
}
public static readonly ValueNameConverter Singleton = new ValueNameConverter();
}
}

View File

@ -1,81 +0,0 @@
using Microsoft.Extensions.Options;
using Backend.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Threading.Tasks;
using BackendWorkerService.Services.Interface;
using Microsoft.Extensions.Logging;
namespace BackendWorkerService.Services.Implement
{
public class SendEmailService : ISendEmailService
{
private readonly ILogger<SendEmailService> logger;
private readonly IOptions<SMTPConfig> _options;
private SMTPConfig smtp;
public SendEmailService(ILogger<SendEmailService> logger, IOptions<SMTPConfig> options)
{
this.logger = logger;
smtp = options.Value;
}
public bool Send(int id, List<string> recipientEmails, string subject, string content)
{
try
{
logger.LogInformation("【SendEmailSMSService】【Email開始寄送】[任務編號]{0}", id);
MailMessage MyMail = new MailMessage();
MyMail.SubjectEncoding = System.Text.Encoding.UTF8;//郵件標題編碼
MyMail.BodyEncoding = System.Text.Encoding.UTF8; //郵件內容編碼
MyMail.IsBodyHtml = true; //是否使用html格式
var mailFrom = $"FIC IBMS管理系統通知 <{smtp.UserName}>";
MyMail.From = new System.Net.Mail.MailAddress(mailFrom); //寄件人
foreach (var email in recipientEmails)
{
MyMail.To.Add(email); //設定收件者Email
}
MyMail.Subject = subject; //主題
MyMail.Body = content; //設定信件內容
//讀取 SMTP Config
SmtpClient MySMTP = new SmtpClient(smtp.Host, smtp.Port);
MySMTP.EnableSsl = smtp.EnableSsl;
MySMTP.Credentials = new System.Net.NetworkCredential(smtp.UserName, smtp.Password);
try
{
MySMTP.Send(MyMail);
MySMTP.Dispose();
MyMail.Dispose(); //釋放資源
logger.LogInformation("【SendEmailSMSService】【Email寄送成功】[任務編號]{0}", id);
return true;
}
catch(Exception exception)
{
logger.LogError("【SendEmailSMSService】【Email寄送失敗】[任務編號]{0}", id);
logger.LogError("【SendEmailSMSService】【Email寄送失敗】[Exception]{0}", exception.ToString());
return false;
}
}
catch (Exception exception)
{
logger.LogError("【SendEmailSMSService】【Email寄送失敗】[任務編號]{0}", id);
logger.LogError("【SendEmailSMSService】【Email寄送失敗】[Exception]{0}", exception.ToString());
throw;
//return false;
}
}
}
}

View File

@ -1,54 +0,0 @@
using BackendWorkerService.Services.Interface;
using Microsoft. Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
namespace BackendWorkerService.Services.Implement
{
class SendLineNotifyService: ISendLineNotifyService
{
private readonly ILogger<SendLineNotifyService> logger;
public SendLineNotifyService(ILogger<SendLineNotifyService> logger)
{
this.logger = logger;
}
public bool Send(int id, string lineToken, string message)
{
try
{
logger.LogInformation("【SendLineNotifyService】【Line Notify開始發送】[任務編號]{0}", id);
HttpWebRequest Postrequest = (HttpWebRequest)WebRequest.Create("https://notify-api.line.me/api/notify?message=" + message);
Postrequest.Method = "POST";
Postrequest.Headers.Add("Authorization", "Bearer " + lineToken);
Postrequest.PreAuthenticate = true;
HttpWebResponse response = (HttpWebResponse)Postrequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var final = JObject.Parse(responseString);
var get = final["status"].ToString();
if (get != "200")
{
logger.LogError("【SendLineNotifyService】【Line Notify發送失敗】[任務編號]{0}", id);
logger.LogError("【SendLineNotifyService】【Line Notify發送失敗】[失敗內容]{0}", responseString);
return false;
}
logger.LogInformation("【SendLineNotifyService】【Line Notify發送成功】[任務編號]{0}", id);
return true;
}
catch (Exception exception)
{
logger.LogError("【SendLineNotifyService】【Line Notify發送失敗】[任務編號]{0}", id);
logger.LogError("【SendLineNotifyService】【Line Notify發送失敗】[Exception]{0}", exception.ToString());
throw;
//return false;
}
}
}
}

View File

@ -1,84 +0,0 @@
using Backend.Models;
using BackendWorkerService.Services.Interface;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
namespace BackendWorkerService.Services.Implement
{
class SendSMSService : ISendSMSService
{
private readonly ILogger<SendSMSService> logger;
private readonly IOptions<SMSConfig> _options;
private SMSConfig sms;
public SendSMSService(ILogger<SendSMSService> logger, IOptions<SMSConfig> options)
{
this.logger = logger;
sms = options.Value;
sms.Encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(sms.UserName + ":" + sms.Password));
}
public bool Send(int id, string phone, string content)
{
try
{
logger.LogError("【SendSMSService】【SMS開始寄送】[任務編號]{0}", id);
//設定傳送的Request
HttpWebRequest Postrequest = (HttpWebRequest)WebRequest.Create(sms.Api);
Postrequest.Method = "POST";
Postrequest.Headers.Add("Authorization", "Basic " + sms.Encoded);
Postrequest.PreAuthenticate = true;
using (var streamWriter = new StreamWriter(Postrequest.GetRequestStream()))
{
string json = string.Format("<real val=\"{0},{1}\"/>", phone, content);
streamWriter.Write(json);
}
//設定回傳的Request
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);
if (resultVal.ContainsKey("obj"))
{
var display_split = resultVal["obj"]["@display"].ToString().Split(' ');
var responseStatus = display_split[display_split.Length - 1];
if (responseStatus == "{ok}")
{
logger.LogInformation("【SendSMSService】【SMS寄送成功】[任務編號]{0}", id);
return true;
}
}
else
{
logger.LogError("【SendSMSService】【SMS寄送失敗】[任務編號]{0}", id);
logger.LogError("【SendSMSService】【SMS寄送失敗】[失敗內容]{0}", resultVal);
return false;
}
return false;
}
catch (Exception exception)
{
logger.LogError("【SendSMSService】【SMS寄送失敗】[任務編號]{0}", id);
logger.LogError("【SendSMSService】【SMS寄送失敗】[Exception]{0}", exception.ToString());
throw;
//return false;
}
}
}
}

View File

@ -1,213 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var welcome = Welcome.FromJson(jsonString);
namespace TyphoonApi
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Welcome
{
[JsonProperty("?xml")]
public Xml Xml { get; set; }
[JsonProperty("alert")]
public Alert Alert { get; set; }
}
public partial class Alert
{
[JsonProperty("@xmlns")]
public string Xmlns { get; set; }
[JsonProperty("identifier")]
public string Identifier { get; set; }
[JsonProperty("sender")]
public string Sender { get; set; }
[JsonProperty("sent")]
public DateTimeOffset Sent { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("msgType")]
public string MsgType { get; set; }
[JsonProperty("scope")]
public string Scope { get; set; }
[JsonProperty("references")]
public string References { get; set; }
[JsonProperty("info")]
public Info Info { get; set; }
}
public partial class Info
{
[JsonProperty("language")]
public string Language { get; set; }
[JsonProperty("category")]
public string Category { get; set; }
[JsonProperty("event")]
public string Event { get; set; }
[JsonProperty("urgency")]
public string Urgency { get; set; }
[JsonProperty("severity")]
public string Severity { get; set; }
[JsonProperty("certainty")]
public string Certainty { get; set; }
[JsonProperty("eventCode")]
public EventCode EventCode { get; set; }
[JsonProperty("effective")]
public DateTimeOffset Effective { get; set; }
[JsonProperty("onset")]
public DateTimeOffset Onset { get; set; }
[JsonProperty("expires")]
public DateTimeOffset Expires { get; set; }
[JsonProperty("senderName")]
public string SenderName { get; set; }
[JsonProperty("headline")]
public string Headline { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("instruction")]
public string Instruction { get; set; }
[JsonProperty("web")]
public Uri Web { get; set; }
[JsonProperty("parameter")]
public EventCode Parameter { get; set; }
[JsonProperty("area")]
public List<Area> Area { get; set; }
}
public partial class Area
{
[JsonProperty("areaDesc")]
public string AreaDesc { get; set; }
[JsonProperty("geocode")]
public EventCode Geocode { get; set; }
}
public partial class EventCode
{
[JsonProperty("valueName")]
public string ValueName { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
public partial class Xml
{
[JsonProperty("@version")]
public string Version { get; set; }
[JsonProperty("@encoding")]
public string Encoding { get; set; }
}
public enum ValueName { AlertTitle, ProfileCapTwpEvent10, TaiwanGeocode103 };
public partial class Welcome
{
public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ValueNameConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ValueNameConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ValueName) || t == typeof(ValueName?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var value = serializer.Deserialize<string>(reader);
switch (value)
{
case "Taiwan_Geocode_103":
return ValueName.TaiwanGeocode103;
case "alert_title":
return ValueName.AlertTitle;
case "profile:CAP-TWP:Event:1.0":
return ValueName.ProfileCapTwpEvent10;
}
throw new Exception("Cannot unmarshal type ValueName");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (ValueName)untypedValue;
switch (value)
{
case ValueName.TaiwanGeocode103:
serializer.Serialize(writer, "Taiwan_Geocode_103");
return;
case ValueName.AlertTitle:
serializer.Serialize(writer, "alert_title");
return;
case ValueName.ProfileCapTwpEvent10:
serializer.Serialize(writer, "profile:CAP-TWP:Event:1.0");
return;
}
throw new Exception("Cannot marshal type ValueName");
}
public static readonly ValueNameConverter Singleton = new ValueNameConverter();
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BackendWorkerService.Services.Interface
{
public interface ISendEmailService
{
bool Send(int id, List<string> recipientEmails, string subject, string content);
}
}

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BackendWorkerService.Services.Interface
{
public interface ISendLineNotifyService
{
bool Send(int id, string lineToken, string message);
}
}

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BackendWorkerService.Services.Interface
{
public interface ISendSMSService
{
bool Send(int id, string phone, string message);
}
}

View File

@ -107,8 +107,6 @@ namespace Backend
services.AddTransient<IBackEndConfigHelper, BackEndConfigHelper>();
#endregion DBHelper ª`¤J
#region Repository ª`¤J
services.AddTransient<IBackendRepository, BackendRepository>();
services.AddTransient<IFrontendRepository, FrontendRepository>();
@ -121,12 +119,6 @@ namespace Backend
services.AddTransient<IBackgroundServiceMsSqlRepository, BackgroundServiceMsSqlRepository>();
#endregion Repository ª`¤J
#region Quartz服務
services.AddTransient<IJobFactory, SingletonJobFactory>();
services.AddTransient<ISchedulerFactory, StdSchedulerFactory>();
services.AddHostedService<QuartzHostedService>();
#endregion
#region JWT ª`¤J
services.AddTransient<IJwtHelpers, JwtHelpers>();
services
@ -163,20 +155,6 @@ namespace Backend
});
#endregion JWT ª`¤J
#region ( )
services.AddSingleton<ArchiveElectricMeterDayJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(ArchiveElectricMeterDayJob), cronExpression: Configuration.GetValue<string>("BackgroundServiceCron:ArchiveElectricMeterDayJob"))
);
#endregion
//#region 定時取得氣象API
//services.AddSingleton<WeatherAPIJob>();
//services.AddSingleton(
//new JobSchedule(jobType: typeof(WeatherAPIJob), cronExpression: Configuration.GetValue<string>("BackgroundServiceCron:WeatherAPIJob"))
//);
//#endregion
double loginExpireMinute = this.Configuration.GetValue<double>("LoginExpireMinute");
services.AddSession(options =>
{

View File

@ -12,17 +12,6 @@
"SignKey": "TaipeiDome123456", ////16
"JwtLifeSeconds": 3600
},
"LoggerPath": "C:\\Project\\ASP.NET\\BIMS\\Backend",
"BackgroundServiceCron": {
"ExecutionBackgroundServicePlanJob": "0 0 2 * * ?",
"MessageNotificationJob": "0 0 2 * * ?",
"DataDeliveryJob": "0 0 2 * * ?",
"RegularUpdateDBTableJob": "0 0 2 * * ?",
"ParkingJob": "0 0 2 * * ?",
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
"ArchiveElectricMeterDayJob": "0 0 2 * * ?",
"WeatherAPIJob": "0/5 * * * * ?"
},
"DBConfig": {
"MySqlDBConfig": {
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
@ -32,6 +21,7 @@
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
//"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office
//"Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //mcut
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
},
@ -39,7 +29,7 @@
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
}
//"MSSqlDBConfig": {

View File

@ -12,7 +12,6 @@
"SignKey": "TaipeiDome123456", ////16
"JwtLifeSeconds": 3600
},
"LoggerPath": "C:\\Project\\ASP.NET\\BIMS\\Backend",
"DBConfig": {
"MySqlDBConfig": {
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
@ -28,7 +27,7 @@
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
}
//"MSSqlDBConfig": {

View File

@ -50,23 +50,23 @@ namespace BackendWorkerService
//services.AddHostedService<Worker>();
#region
//#region 訊息通
#region SMPT配置
services.AddTransient<ISendEmailService, SendEmailService>();
services.Configure<SMTPConfig>(configuration.GetSection("SMTPConfig"));
#endregion
//#region SMPT配置
//services.AddTransient<ISendEmailService, SendEmailService>();
//services.Configure<SMTPConfig>(configuration.GetSection("SMTPConfig"));
//#endregion
#region SMS配置
services.AddTransient<ISendSMSService, SendSMSService>();
services.Configure<SMSConfig>(configuration.GetSection("SMSConfig"));
#endregion
//#region SMS配置
//services.AddTransient<ISendSMSService, SendSMSService>();
//services.Configure<SMSConfig>(configuration.GetSection("SMSConfig"));
//#endregion
#region Line Notify配置
services.AddTransient<ISendLineNotifyService, SendLineNotifyService>();
#endregion
//#region Line Notify配置
//services.AddTransient<ISendLineNotifyService, SendLineNotifyService>();
//#endregion
#endregion
//#endregion 訊息通
#region DBHelper
services.Configure<DBConfig>(configuration.GetSection("DBConfig"));
@ -93,10 +93,6 @@ namespace BackendWorkerService
services.AddTransient<ISchedulerFactory, StdSchedulerFactory>();
services.AddHostedService<QuartzHostedService>();
//#region 背景執行計畫(設定1min執行一次)
//services.AddSingleton<ExecutionBackgroundServicePlanJob>();
//services.AddSingleton(
@ -138,6 +134,7 @@ namespace BackendWorkerService
//new JobSchedule(jobType: typeof(ArchiveElectricMeterHourJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:ArchiveElectricMeterHourJob"))
//);
//#endregion
#region ( )
services.AddSingleton<ArchiveElectricMeterDayJob>();
services.AddSingleton(
@ -145,12 +142,12 @@ namespace BackendWorkerService
);
#endregion
#region API
services.AddSingleton<Quartz.Jobs.WeatherAPIJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(Quartz.Jobs.WeatherAPIJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:WeatherAPIJob"))
);
#endregion
//#region 定時取得氣象API
//services.AddSingleton<Quartz.Jobs.WeatherAPIJob>();
//services.AddSingleton(
//new JobSchedule(jobType: typeof(Quartz.Jobs.WeatherAPIJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:WeatherAPIJob"))
//);
//#endregion
}).ConfigureLogging((hostContext, logFactory) => {
IConfiguration configuration = hostContext.Configuration;

View File

@ -125,7 +125,7 @@ namespace BackendWorkerService.Quartz.Jobs
{
try
{
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Day", "任務開始");
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Day", "水電表天任務開始");
var preDay = now.AddDays(-1); //取得前一天
var dbDateName = preDay.Year.ToString().PadLeft(4, '0') + preDay.Month.ToString().PadLeft(2, '0');
@ -581,7 +581,7 @@ namespace BackendWorkerService.Quartz.Jobs
{
try
{
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Week", "任務開始");
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Week", "水電表周任務開始");
int week = Convert.ToInt32(now.DayOfWeek);
week = week == 0 ? 7 : week;
@ -931,7 +931,7 @@ namespace BackendWorkerService.Quartz.Jobs
{
try
{
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Month", "任務開始");
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Month", "水電表月任務開始");
var FirstDay = now.AddDays(-now.Day + 1);
var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day);

View File

@ -1,7 +1,10 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

View File

@ -6,6 +6,7 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
"LoggerPath": "C:\\inetpub\\Taipei_dome_background_service\\Logs",
"BackgroundServiceCron": {
"ExecutionBackgroundServicePlanJob": "0 0 2 * * ?",
"MessageNotificationJob": "0 0 2 * * ?",
@ -13,17 +14,10 @@
"RegularUpdateDBTableJob": "0 0 2 * * ?",
"ParkingJob": "0 0 2 * * ?",
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
"ArchiveElectricMeterDayJob": "0 0 2 * * ?",
"WeatherAPIJob": "0/5 * * * * ?"
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
"WeatherAPIJob": "0 0 2 * * ?"
},
"DBConfig": {
//"MySqlDBConfig": {
// "Server": "TNi6aupYHPZT8ZU177KTKw==", //172.16.220.251
// "Port": "mkF51jVbg40V5K5eTh2Ckw==",
// "Database": "VvfWH/59gQguY2eA2xBCug==",
// "Root": "IV8Ec1Ng2AWAnkBafXy2kg==",
// "Password": "Jue6jMFRi11meN6xbdKwDA=="
//},
"MySqlDBConfig": {
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
@ -38,24 +32,9 @@
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
}
//"MSSqlDBConfig": { //greencloud.fic.com.tw,1433
// "Server": "ueFp+VFb200lhh1Uctc97WH0/tX6tfXYU2v1oxCWuuM=",
// "Port": "S5cUXKnKOacFtFy9+0dtpw==",
// "Database": "VvfWH/59gQguY2eA2xBCug==",
// "Root": "+plVKQ+enAqt7BYV2uMQng==",
// "Password": "0O24es2ZRF5uoJ4aU+YCdg=="
//}
//"MSSqlDBConfig": {
// "Server": "zp3Nilx0PISEEC4caZWqCg==", //172.16.220.250
// "Port": "7puf4kd9qJ/q0fq2QASWeQ==",
// "Database": "VvfWH/59gQguY2eA2xBCug==",
// "Root": "sD8GZ9UPiIQGU6dU011/4A==",
// "Password": "Jue6jMFRi11meN6xbdKwDA=="
//}
},
"SMTPConfig": {
"Host": "smtp.gmail.com",

View File

@ -8,19 +8,16 @@
},
"LoggerPath": "C:\\inetpub\\Taipei_dome_background_service\\Logs",
"BackgroundServiceCron": {
"ExecutionBackgroundServicePlanJob": "0/5 * * * * ?",
"MessageNotificationJob": "0 0/30 * * * ?",
"DataDeliveryJob": "0 0/5 * * * ?",
"RegularUpdateDBTableJob": "0 0 2 * * ?"
"ExecutionBackgroundServicePlanJob": "0 0 2 * * ?",
"MessageNotificationJob": "0 0 2 * * ?",
"DataDeliveryJob": "0 0 2 * * ?",
"RegularUpdateDBTableJob": "0 0 2 * * ?",
"ParkingJob": "0 0 2 * * ?",
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
"WeatherAPIJob": "0 0 2 * * ?"
},
"DBConfig": {
//"MySqlDBConfig": {
// "Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
// "Port": "js2LutKe+rdjzdxMPQUrvQ==",
// "Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
// "Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
// "Password": "FVAPxztxpY4gJJKQ/se4bQ=="
//},
"MySqlDBConfig": {
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
@ -35,16 +32,9 @@
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
}
//"MSSqlDBConfig": {
// "Server": "avZg8PA8C9GVgYZBgEKzCg==",
// "Port": "lJA0KPkG6RvFfTgWiXFyUw==",
// "Database": "VvfWH/59gQguY2eA2xBCug==",
// "Root": "sD8GZ9UPiIQGU6dU011/4A==",
// "Password": "2gi7rOmGha2VdXC5vtHxhg=="
//}
},
"SMTPConfig": {
"Host": "smtp.gmail.com",

View File

@ -1,526 +1,192 @@
<?xml version="1.0" encoding="UTF-8"?>
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
<identifier>CWB-Weather_extremely-rain_202306010655001</identifier>
<identifier>CWB-Weather_extremely-rain_202306060340001</identifier>
<sender>weather@cwb.gov.tw</sender>
<sent>2023-06-01T07:02:17+08:00</sent>
<sent>2023-06-06T03:45:20+08:00</sent>
<status>Actual</status>
<msgType>Update</msgType>
<msgType>Cancel</msgType>
<scope>Public</scope>
<references>weather@cwb.gov.tw,CWB-Weather_extremely-rain_202306010345001,2023-06-01T03:56:19+08:00</references>
<references>weather@cwb.gov.tw,CWB-Weather_extremely-rain_202306060045001,2023-06-06T00:50:36+08:00 weather@cwb.gov.tw,CWB-Weather_extremely-rain_202306052245001,2023-06-05T22:54:54+08:00 weather@cwb.gov.tw,CWB-Weather_extremely-rain_202306052220001,2023-06-05T22:25:45+08:00</references>
<info>
<language>zh-TW</language>
<category>Met</category>
<event>降雨</event>
<responseType>Monitor</responseType>
<urgency>Future</urgency>
<severity>Moderate</severity>
<certainty>Likely</certainty>
<urgency>Past</urgency>
<severity>Minor</severity>
<certainty>Observed</certainty>
<eventCode>
<valueName>profile:CAP-TWP:Event:1.0</valueName>
<value>rainfall</value>
</eventCode>
<effective>2023-06-01T06:55:00+08:00</effective>
<onset>2023-06-01T06:59:00+08:00</onset>
<expires>2023-06-01T11:00:00+08:00</expires>
<effective>2023-06-06T03:40:00+08:00</effective>
<onset>2023-06-06T03:40:00+08:00</onset>
<expires>2023-06-06T03:55:20+08:00</expires>
<senderName>中央氣象局</senderName>
<headline>雨特報</headline>
<headline>解除豪雨特報</headline>
<description>
颱風外圍環流影響,今(1)日大臺北、桃園、新竹、宜蘭地區有局部大雨發生的機率,請注意瞬間大雨、強陣風及溪水暴漲,山區請注意落石及坍方
由於降雨趨於緩和,發生大雨或豪雨的機率降低,故解除豪雨特報
</description>
<instruction></instruction>
<web>https://www.cwb.gov.tw/V8/C/P/Warning/FIFOWS.html</web>
<parameter>
<valueName>alert_title</valueName>
<value>大雨特報</value>
</parameter>
<parameter>
<valueName>severity_level</valueName>
<value>大雨</value>
</parameter>
<parameter>
<valueName>alert_color</valueName>
<value>黃色</value>
</parameter>
<parameter>
<valueName>website_color</valueName>
<value>255,255,0</value>
<value>豪雨特報</value>
</parameter>
<area>
<areaDesc>新竹縣橫山鄉</areaDesc>
<area>
<areaDesc>基隆市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000408</value>
<value>10017</value>
</geocode>
</area><area>
<areaDesc>新竹縣北埔鄉</areaDesc>
</area>
<area>
<areaDesc>臺北市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000409</value>
<value>63</value>
</geocode>
</area><area>
<areaDesc>桃園市觀音區</areaDesc>
</area>
<area>
<areaDesc>新北市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6801200</value>
<value>65</value>
</geocode>
</area><area>
<areaDesc>桃園市復興區</areaDesc>
</area>
<area>
<areaDesc>桃園市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6801300</value>
<value>68</value>
</geocode>
</area><area>
<areaDesc>臺北市信義區</areaDesc>
</area>
<area>
<areaDesc>新竹市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300200</value>
<value>10018</value>
</geocode>
</area><area>
<areaDesc>桃園市新屋區</areaDesc>
</area>
<area>
<areaDesc>新竹縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6801100</value>
<value>10004</value>
</geocode>
</area><area>
<areaDesc>新竹縣竹東鎮</areaDesc>
</area>
<area>
<areaDesc>苗栗縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000402</value>
<value>10005</value>
</geocode>
</area><area>
<areaDesc>臺北市文山區</areaDesc>
</area>
<area>
<areaDesc>臺中市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300800</value>
<value>66</value>
</geocode>
</area><area>
<areaDesc>新竹縣竹北市</areaDesc>
</area>
<area>
<areaDesc>彰化縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000401</value>
<value>10007</value>
</geocode>
</area><area>
<areaDesc>新竹縣新豐鄉</areaDesc>
</area>
<area>
<areaDesc>雲林縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000406</value>
<value>10009</value>
</geocode>
</area><area>
<areaDesc>臺北市松山區</areaDesc>
</area>
<area>
<areaDesc>南投縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300100</value>
<value>10008</value>
</geocode>
</area><area>
<areaDesc>新竹縣關西鎮</areaDesc>
</area>
<area>
<areaDesc>嘉義縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000404</value>
<value>10010</value>
</geocode>
</area><area>
<areaDesc>新竹縣湖口鄉</areaDesc>
</area>
<area>
<areaDesc>嘉義市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000405</value>
<value>10020</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣冬山鄉</areaDesc>
</area>
<area>
<areaDesc>臺南市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000208</value>
<value>67</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣五結鄉</areaDesc>
</area>
<area>
<areaDesc>高雄市</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000209</value>
<value>64</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣頭城鎮</areaDesc>
</area>
<area>
<areaDesc>屏東縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000204</value>
<value>10013</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣礁溪鄉</areaDesc>
</area>
<area>
<areaDesc>宜蘭縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000205</value>
<value>10002</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣壯圍鄉</areaDesc>
</area>
<area>
<areaDesc>花蓮縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000206</value>
<value>10015</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣員山鄉</areaDesc>
</area>
<area>
<areaDesc>臺東縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000207</value>
<value>10014</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣宜蘭市</areaDesc>
</area>
<area>
<areaDesc>澎湖縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000201</value>
<value>10016</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣羅東鎮</areaDesc>
</area>
<area>
<areaDesc>金門縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000202</value>
<value>09020</value>
</geocode>
</area><area>
<areaDesc>臺北市大安區</areaDesc>
</area>
<area>
<areaDesc>連江縣</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300300</value>
</geocode>
</area><area>
<areaDesc>新北市三重區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500200</value>
</geocode>
</area><area>
<areaDesc>新北市中和區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500300</value>
</geocode>
</area><area>
<areaDesc>新竹縣尖石鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000412</value>
</geocode>
</area><area>
<areaDesc>新北市板橋區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500100</value>
</geocode>
</area><area>
<areaDesc>新北市新店區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500600</value>
</geocode>
</area><area>
<areaDesc>新北市樹林區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500700</value>
</geocode>
</area><area>
<areaDesc>新北市永和區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500400</value>
</geocode>
</area><area>
<areaDesc>新北市新莊區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500500</value>
</geocode>
</area><area>
<areaDesc>新北市鶯歌區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500800</value>
</geocode>
</area><area>
<areaDesc>新北市三峽區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6500900</value>
</geocode>
</area><area>
<areaDesc>新北市萬里區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502800</value>
</geocode>
</area><area>
<areaDesc>臺北市中山區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300400</value>
</geocode>
</area><area>
<areaDesc>新北市烏來區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502900</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣大同鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000211</value>
</geocode>
</area><area>
<areaDesc>新竹縣新埔鎮</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000403</value>
</geocode>
</area><area>
<areaDesc>新北市坪林區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502000</value>
</geocode>
</area><area>
<areaDesc>新北市三芝區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502100</value>
</geocode>
</area><area>
<areaDesc>新北市石門區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502200</value>
</geocode>
</area><area>
<areaDesc>桃園市大園區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800600</value>
</geocode>
</area><area>
<areaDesc>新北市平溪區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502400</value>
</geocode>
</area><area>
<areaDesc>新北市雙溪區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502500</value>
</geocode>
</area><area>
<areaDesc>新北市貢寮區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502600</value>
</geocode>
</area><area>
<areaDesc>新北市金山區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502700</value>
</geocode>
</area><area>
<areaDesc>臺北市大同區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300600</value>
</geocode>
</area><area>
<areaDesc>臺北市士林區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6301100</value>
</geocode>
</area><area>
<areaDesc>臺北市中正區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300500</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣三星鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000210</value>
</geocode>
</area><area>
<areaDesc>新竹縣峨眉鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000411</value>
</geocode>
</area><area>
<areaDesc>臺北市北投區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6301200</value>
</geocode>
</area><area>
<areaDesc>新竹縣五峰鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000413</value>
</geocode>
</area><area>
<areaDesc>新竹縣芎林鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000407</value>
</geocode>
</area><area>
<areaDesc>桃園市龍潭區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800900</value>
</geocode>
</area><area>
<areaDesc>桃園市八德區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800800</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣蘇澳鎮</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000203</value>
</geocode>
</area><area>
<areaDesc>桃園市桃園區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800100</value>
</geocode>
</area><area>
<areaDesc>桃園市大溪區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800300</value>
</geocode>
</area><area>
<areaDesc>臺北市萬華區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300700</value>
</geocode>
</area><area>
<areaDesc>桃園市蘆竹區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800500</value>
</geocode>
</area><area>
<areaDesc>桃園市楊梅區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800400</value>
</geocode>
</area><area>
<areaDesc>桃園市龜山區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800700</value>
</geocode>
</area><area>
<areaDesc>臺北市內湖區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6301000</value>
</geocode>
</area><area>
<areaDesc>新北市五股區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501500</value>
</geocode>
</area><area>
<areaDesc>新北市蘆洲區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501400</value>
</geocode>
</area><area>
<areaDesc>新北市林口區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501700</value>
</geocode>
</area><area>
<areaDesc>新北市泰山區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501600</value>
</geocode>
</area><area>
<areaDesc>新北市汐止區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501100</value>
</geocode>
</area><area>
<areaDesc>臺北市南港區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6300900</value>
</geocode>
</area><area>
<areaDesc>新北市土城區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501300</value>
</geocode>
</area><area>
<areaDesc>新北市瑞芳區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501200</value>
</geocode>
</area><area>
<areaDesc>宜蘭縣南澳鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000212</value>
</geocode>
</area><area>
<areaDesc>桃園市中壢區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6800200</value>
</geocode>
</area><area>
<areaDesc>新北市石碇區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501900</value>
</geocode>
</area><area>
<areaDesc>新北市深坑區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501800</value>
</geocode>
</area><area>
<areaDesc>桃園市平鎮區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6801000</value>
</geocode>
</area><area>
<areaDesc>新竹縣寶山鄉</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>1000410</value>
</geocode>
</area><area>
<areaDesc>新北市淡水區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6501000</value>
</geocode>
</area><area>
<areaDesc>新北市八里區</areaDesc>
<geocode>
<valueName>Taiwan_Geocode_103</valueName>
<value>6502300</value>
<value>09007</value>
</geocode>
</area>
</info>
</alert>

View File

@ -217,6 +217,8 @@
pageAct.alrSelSysMain = []
pageAct.alrSelSysSub = [];
pageAct.selAllSysSub = false;
pageAct.addSelMain = null;
pageAct.addSelSub = null;
first = true;
// let dataAlarm = [];
var historyTable = null;
@ -368,7 +370,10 @@
let alr_tableData = alr_table.row(alr_elem).data();
$('#inpErrCode').html(`<option value = ${alr_tableData.uuid}>${alr_tableData.msgText}</option>`);
$('#inpStaTime').val(displayDate(new Date(Date.now()), "date").replaceAll('/', '-'));
let deviceNumber = null
let deviceNumber = null;
let system = $(this).data("system");
pageAct.addSelMain = system.split("-")[0];
pageAct.addSelSub = system.split("-")[1];
deviceNumber = pageAct.AreaTag + "_" + alr_tableData.buildingFloorName_zh.toString().split('-')[0] + "_" + alr_tableData.alarmClass.toString().split('_')[0] + "_"
+ alr_tableData.alarmClass.toString().split('_')[1] + "_" + alr_tableData.buildingFloorName_zh.toString().split('-')[1] + "_" + alr_tableData.sourceName_zh.toString().split('-')[0] + "_"
@ -387,6 +392,7 @@
});
onEvent('click', '#alr_OpeRecSendBtn', function () {
let form = $("#alr_opeRecForm");
$(form).validate({
rules: {
@ -413,8 +419,8 @@
fd.append("error_code", $('#inpErrCode').val());
fd.append("location", "台北" + $('#buiActDrop').text() + pageAct.floor);
fd.append("location_code", pageAct.AreaTag + pageAct.buiTag + pageAct.floor);
fd.append("device_system_category_layer2", pageAct.selSysMain);
fd.append("device_system_category_layer3", pageAct.selSysSub);
fd.append("device_system_category_layer2", pageAct.addSelMain);
fd.append("device_system_category_layer3", pageAct.addSelSub);
fd.append("work_type", parseInt($('#inpWorTyp').val()));
fd.append("fix_do", $('#inpFixDo').val());
fd.append("fix_do_code", $('#inpFixDoCode').val());
@ -771,8 +777,8 @@
{
"title": "派工/維運單號",
"data": "formId",
"render": function (data) {
return data ?? `<td><a href="#" id="alr_recModal" class="btn btn-info" data-toggle="modal" data-target="#alr_opeRecModal">+ 維修單</a></td>`;
"render": function (data, type, row, meta) {
return data ?? `<td><a href="#" id="alr_recModal" class="btn btn-info" data-toggle="modal" data-target="#alr_opeRecModal" data-system='${row.alarmClass.includes("_") ? row.alarmClass.split('_')[0] + "-" + row.alarmClass.split('_')[1] : row.alarmClass}'>+ 維修單</a></td>`;
}
}
];
@ -781,6 +787,7 @@
$(loadEle).Loading("close");
}
function AlertList(data) {
objSendData.Data = [];
$.each(data, function (i, v) {