Merge branch 'master' of https://gitea.mjm-staging.developers-homelab.net/BIMS/BIMS
This commit is contained in:
commit
4a4a96e13d
@ -429,7 +429,7 @@ namespace Backend.Controllers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var sqlString = @$"SELECT A.floor_guid, A.full_name, InitMapName + '.svg' AS 'initMapName', A.priority, A.created_at
|
var sqlString = @$"SELECT A.floor_guid, A.full_name, CONCAT(InitMapName, '.svg') AS 'initMapName', A.priority, A.created_at
|
||||||
FROM floor A
|
FROM floor A
|
||||||
WHERE deleted = @deleted
|
WHERE deleted = @deleted
|
||||||
AND A.building_tag = @building_tag
|
AND A.building_tag = @building_tag
|
||||||
|
@ -113,13 +113,14 @@ namespace Backend.Controllers
|
|||||||
building = data.GroupBy(x => x.tag_name.Split("_")[1]).Select(x => x.Key).ToList();
|
building = data.GroupBy(x => x.tag_name.Split("_")[1]).Select(x => x.Key).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
string LightSwitchLevel = await niagaraDataSynchronizeRepository.getLightSwitchLevel(); //獲取照明開關 是否在 device or device_node
|
//string LightSwitchLevel = await niagaraDataSynchronizeRepository.getLightSwitchLevel(); //獲取照明開關 是否在 device or device_node
|
||||||
await niagaraDataSynchronizeRepository.InsertNiagaraTagList(ds, building, tag_quantity); // 匯入 MySQL table: import_niagara_tag
|
//await niagaraDataSynchronizeRepository.InsertNiagaraTagList(ds, building, tag_quantity); // 匯入 MySQL table: import_niagara_tag
|
||||||
await niagaraDataSynchronizeRepository.DeviceComparison(LightSwitchLevel);
|
//await niagaraDataSynchronizeRepository.DeviceComparison(LightSwitchLevel);
|
||||||
await niagaraDataSynchronizeRepository.CheckDiffFullNameAndCover();
|
//await niagaraDataSynchronizeRepository.CheckDiffFullNameAndCover();
|
||||||
await niagaraDataSynchronizeRepository.CheckFullNameEmptyReplaceByDeviceName();
|
//await niagaraDataSynchronizeRepository.CheckFullNameEmptyReplaceByDeviceName();
|
||||||
await niagaraDataSynchronizeRepository.InsertBuildingMenu();
|
//await niagaraDataSynchronizeRepository.InsertBuildingMenu();
|
||||||
await niagaraDataSynchronizeRepository.InsertSubSystemFloor();
|
//await niagaraDataSynchronizeRepository.InsertSubSystemFloor();
|
||||||
|
await this.DeviceDisasterAsync();
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
apiResult.Code = "0000";
|
apiResult.Code = "0000";
|
||||||
@ -221,5 +222,32 @@ namespace Backend.Controllers
|
|||||||
|
|
||||||
return apiResult;
|
return apiResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task DeviceDisasterAsync()
|
||||||
|
{
|
||||||
|
var sqlObix = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'obixConfig'";
|
||||||
|
var variableObix = await backendRepository.GetAllAsync<Backend.Models.KeyValue>(sqlObix);
|
||||||
|
var obixApiConfig = new Models.ObixApiConfig();
|
||||||
|
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();
|
||||||
|
obixApiConfig.TagQuantity = variableObix.Where(x => x.Name == "tag_quantity").Select(x => x.Value).FirstOrDefault();
|
||||||
|
|
||||||
|
if (obixApiConfig.TagQuantity == "5")
|
||||||
|
{
|
||||||
|
List<Device_value_disaster> dv = new List<Device_value_disaster>();
|
||||||
|
List<string> urlSlots = await backendRepository.GetAllAsync<string>("select obixSlot from building where deleted = 0");
|
||||||
|
List<string> disasterTag = await backendRepository.GetAllAsync<string>("select system_value from variable where system_type = 'disaster' and deleted = 0");
|
||||||
|
webRequestService svc = new webRequestService();
|
||||||
|
foreach(var dt in disasterTag)
|
||||||
|
{
|
||||||
|
string bql = "neql:hs:geoAddr=\"ER" + dt + "\"";
|
||||||
|
dv.AddRange(svc.obixDevDisaster(obixApiConfig.ApiBase + "obix/config/Arena/Program/ObixQuery/query/", bql, obixApiConfig.TagQuantity, obixApiConfig.UserName,
|
||||||
|
obixApiConfig.Password, dt));
|
||||||
|
}
|
||||||
|
|
||||||
|
await niagaraDataSynchronizeRepository.DeviceDisasterAysnc(dv);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
Backend/Models/DeviceDisaster.cs
Normal file
13
Backend/Models/DeviceDisaster.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace Backend.Models
|
||||||
|
{
|
||||||
|
public class DeviceDisasterOutput
|
||||||
|
{
|
||||||
|
public string device_guid { get; set; }
|
||||||
|
public string device_building_tag { get; set; }
|
||||||
|
public string device_system_tag { get; set; }
|
||||||
|
public string device_name_tag { get; set; }
|
||||||
|
public string device_floor_tag { get; set; }
|
||||||
|
public string device_serial_tag { get; set; }
|
||||||
|
public string device_number { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -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
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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); ;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -327,6 +327,120 @@ namespace Backend.Services.Implement
|
|||||||
|
|
||||||
return result.Where(x => x.full_name != null).ToList();
|
return result.Where(x => x.full_name != null).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Device_value_disaster> obixDevDisaster(string urlString, string bql, string tag_quantity, string acc, string pass, string dt)
|
||||||
|
{
|
||||||
|
List<Device_value_disaster> result = new List<Device_value_disaster>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//String username = "obixUser";
|
||||||
|
//String password = "Admin123456";
|
||||||
|
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(acc + ":" + pass));
|
||||||
|
String API_Url = urlString;
|
||||||
|
|
||||||
|
HttpWebRequest Postrequest = (HttpWebRequest)WebRequest.Create(API_Url);
|
||||||
|
Postrequest.Method = "POST";
|
||||||
|
Postrequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
|
Postrequest.PreAuthenticate = true;
|
||||||
|
|
||||||
|
using (var streamWriter = new StreamWriter(Postrequest.GetRequestStream()))
|
||||||
|
{
|
||||||
|
string json = "<str val='" + bql + "'/>";
|
||||||
|
|
||||||
|
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);
|
||||||
|
bool welcome = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Welcome.FromJson(jsonText);
|
||||||
|
welcome = true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (welcome)
|
||||||
|
{
|
||||||
|
var data = Welcome.FromJson(jsonText);
|
||||||
|
if (data.Obj.Str != null)
|
||||||
|
{
|
||||||
|
foreach (var item in data.Obj.Str)
|
||||||
|
{
|
||||||
|
Device_value_disaster row = new Device_value_disaster();
|
||||||
|
row.value = item.Val;
|
||||||
|
string[] s1 = item.Val.Split(',');
|
||||||
|
string[] s2 = s1[0].Split('/');
|
||||||
|
row.tag_name = "";
|
||||||
|
row.disasterValue = dt;
|
||||||
|
|
||||||
|
for (int i = 0; i < s2.Length; i++)
|
||||||
|
{
|
||||||
|
if (i == s2.Length - 2)
|
||||||
|
{
|
||||||
|
row.point_name = s2[i];
|
||||||
|
}
|
||||||
|
else if (i == 1)
|
||||||
|
{
|
||||||
|
row.tag_name += s2[i];
|
||||||
|
}
|
||||||
|
else if (i > 1 && i < s2.Length - 2)
|
||||||
|
{
|
||||||
|
row.tag_name += "_" + s2[i].Replace("$3", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.Add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var data = WelcomeSingle.FromJson(jsonText);
|
||||||
|
|
||||||
|
if (data.Obj.Str != null)
|
||||||
|
{
|
||||||
|
var item = data.Obj.Str;
|
||||||
|
Device_value_disaster row = new Device_value_disaster();
|
||||||
|
row.value = item.Val;
|
||||||
|
string[] s1 = item.Val.Split(',');
|
||||||
|
string[] s2 = s1[0].Split('/');
|
||||||
|
row.tag_name = "";
|
||||||
|
row.disasterValue = dt;
|
||||||
|
|
||||||
|
for (int i = 0; i < s2.Length; i++)
|
||||||
|
{
|
||||||
|
if (i == s2.Length - 2)
|
||||||
|
{
|
||||||
|
row.point_name = s2[i];
|
||||||
|
}
|
||||||
|
else if (i == 1)
|
||||||
|
{
|
||||||
|
row.tag_name += s2[i];
|
||||||
|
}
|
||||||
|
else if (i > 1 && i < s2.Length - 2)
|
||||||
|
{
|
||||||
|
row.tag_name += "_" + s2[i].Replace("$3", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.Add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
var a = e;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//private static void getRefData(string urlString, string encoded, List<control_point> conPoint, List<ImpNiaItem> result, Welcome data ) //obixHistory data
|
//private static void getRefData(string urlString, string encoded, List<control_point> conPoint, List<ImpNiaItem> result, Welcome data ) //obixHistory data
|
||||||
//{
|
//{
|
||||||
// foreach (var item in data.Obj.Ref)
|
// foreach (var item in data.Obj.Ref)
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,11 +22,6 @@ using Microsoft.IdentityModel.Tokens;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Backend.Quartz.Jobs;
|
|
||||||
using Backend.Quartz;
|
|
||||||
using Quartz.Impl;
|
|
||||||
using Quartz.Spi;
|
|
||||||
using Quartz;
|
|
||||||
|
|
||||||
namespace Backend
|
namespace Backend
|
||||||
{
|
{
|
||||||
@ -107,8 +102,6 @@ namespace Backend
|
|||||||
services.AddTransient<IBackEndConfigHelper, BackEndConfigHelper>();
|
services.AddTransient<IBackEndConfigHelper, BackEndConfigHelper>();
|
||||||
#endregion DBHelper ª`¤J
|
#endregion DBHelper ª`¤J
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region Repository ª`¤J
|
#region Repository ª`¤J
|
||||||
services.AddTransient<IBackendRepository, BackendRepository>();
|
services.AddTransient<IBackendRepository, BackendRepository>();
|
||||||
services.AddTransient<IFrontendRepository, FrontendRepository>();
|
services.AddTransient<IFrontendRepository, FrontendRepository>();
|
||||||
@ -121,12 +114,6 @@ namespace Backend
|
|||||||
services.AddTransient<IBackgroundServiceMsSqlRepository, BackgroundServiceMsSqlRepository>();
|
services.AddTransient<IBackgroundServiceMsSqlRepository, BackgroundServiceMsSqlRepository>();
|
||||||
#endregion Repository ª`¤J
|
#endregion Repository ª`¤J
|
||||||
|
|
||||||
#region 添加Quartz服務
|
|
||||||
services.AddTransient<IJobFactory, SingletonJobFactory>();
|
|
||||||
services.AddTransient<ISchedulerFactory, StdSchedulerFactory>();
|
|
||||||
services.AddHostedService<QuartzHostedService>();
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region JWT ª`¤J
|
#region JWT ª`¤J
|
||||||
services.AddTransient<IJwtHelpers, JwtHelpers>();
|
services.AddTransient<IJwtHelpers, JwtHelpers>();
|
||||||
services
|
services
|
||||||
@ -163,20 +150,6 @@ namespace Backend
|
|||||||
});
|
});
|
||||||
#endregion JWT ª`¤J
|
#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");
|
double loginExpireMinute = this.Configuration.GetValue<double>("LoginExpireMinute");
|
||||||
services.AddSession(options =>
|
services.AddSession(options =>
|
||||||
{
|
{
|
||||||
|
@ -12,17 +12,6 @@
|
|||||||
"SignKey": "TaipeiDome123456", //簽章//最少16字元
|
"SignKey": "TaipeiDome123456", //簽章//最少16字元
|
||||||
"JwtLifeSeconds": 3600
|
"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": {
|
"DBConfig": {
|
||||||
"MySqlDBConfig": {
|
"MySqlDBConfig": {
|
||||||
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
||||||
@ -32,6 +21,7 @@
|
|||||||
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
||||||
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
||||||
//"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office
|
//"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office
|
||||||
|
//"Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //mcut
|
||||||
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
||||||
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
||||||
},
|
},
|
||||||
@ -39,7 +29,7 @@
|
|||||||
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
||||||
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
||||||
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
||||||
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
|
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
|
||||||
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
||||||
}
|
}
|
||||||
//"MSSqlDBConfig": {
|
//"MSSqlDBConfig": {
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
"SignKey": "TaipeiDome123456", //簽章//最少16字元
|
"SignKey": "TaipeiDome123456", //簽章//最少16字元
|
||||||
"JwtLifeSeconds": 3600
|
"JwtLifeSeconds": 3600
|
||||||
},
|
},
|
||||||
"LoggerPath": "C:\\Project\\ASP.NET\\BIMS\\Backend",
|
|
||||||
"DBConfig": {
|
"DBConfig": {
|
||||||
"MySqlDBConfig": {
|
"MySqlDBConfig": {
|
||||||
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
||||||
@ -28,7 +27,7 @@
|
|||||||
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
||||||
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
||||||
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
||||||
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
|
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
|
||||||
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
||||||
}
|
}
|
||||||
//"MSSqlDBConfig": {
|
//"MSSqlDBConfig": {
|
||||||
|
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 105 KiB |
@ -50,23 +50,23 @@ namespace BackendWorkerService
|
|||||||
|
|
||||||
//services.AddHostedService<Worker>();
|
//services.AddHostedService<Worker>();
|
||||||
|
|
||||||
#region 訊息通知
|
//#region 訊息通知
|
||||||
|
|
||||||
#region SMPT配置
|
//#region SMPT配置
|
||||||
services.AddTransient<ISendEmailService, SendEmailService>();
|
//services.AddTransient<ISendEmailService, SendEmailService>();
|
||||||
services.Configure<SMTPConfig>(configuration.GetSection("SMTPConfig"));
|
//services.Configure<SMTPConfig>(configuration.GetSection("SMTPConfig"));
|
||||||
#endregion
|
//#endregion
|
||||||
|
|
||||||
#region SMS配置
|
//#region SMS配置
|
||||||
services.AddTransient<ISendSMSService, SendSMSService>();
|
//services.AddTransient<ISendSMSService, SendSMSService>();
|
||||||
services.Configure<SMSConfig>(configuration.GetSection("SMSConfig"));
|
//services.Configure<SMSConfig>(configuration.GetSection("SMSConfig"));
|
||||||
#endregion
|
//#endregion
|
||||||
|
|
||||||
#region Line Notify配置
|
//#region Line Notify配置
|
||||||
services.AddTransient<ISendLineNotifyService, SendLineNotifyService>();
|
//services.AddTransient<ISendLineNotifyService, SendLineNotifyService>();
|
||||||
#endregion
|
//#endregion
|
||||||
|
|
||||||
#endregion 訊息通知
|
//#endregion 訊息通知
|
||||||
|
|
||||||
#region DBHelper 注入
|
#region DBHelper 注入
|
||||||
services.Configure<DBConfig>(configuration.GetSection("DBConfig"));
|
services.Configure<DBConfig>(configuration.GetSection("DBConfig"));
|
||||||
@ -93,10 +93,6 @@ namespace BackendWorkerService
|
|||||||
services.AddTransient<ISchedulerFactory, StdSchedulerFactory>();
|
services.AddTransient<ISchedulerFactory, StdSchedulerFactory>();
|
||||||
services.AddHostedService<QuartzHostedService>();
|
services.AddHostedService<QuartzHostedService>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#region 背景執行計畫(設定1min執行一次)
|
//#region 背景執行計畫(設定1min執行一次)
|
||||||
//services.AddSingleton<ExecutionBackgroundServicePlanJob>();
|
//services.AddSingleton<ExecutionBackgroundServicePlanJob>();
|
||||||
//services.AddSingleton(
|
//services.AddSingleton(
|
||||||
@ -138,6 +134,7 @@ namespace BackendWorkerService
|
|||||||
//new JobSchedule(jobType: typeof(ArchiveElectricMeterHourJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:ArchiveElectricMeterHourJob"))
|
//new JobSchedule(jobType: typeof(ArchiveElectricMeterHourJob), cronExpression: configuration.GetValue<string>("BackgroundServiceCron:ArchiveElectricMeterHourJob"))
|
||||||
//);
|
//);
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
#region 電錶歸檔(設定每 天 執行一次)
|
#region 電錶歸檔(設定每 天 執行一次)
|
||||||
services.AddSingleton<ArchiveElectricMeterDayJob>();
|
services.AddSingleton<ArchiveElectricMeterDayJob>();
|
||||||
services.AddSingleton(
|
services.AddSingleton(
|
||||||
|
@ -55,13 +55,20 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
EDFunction ed = new EDFunction();
|
EDFunction ed = new EDFunction();
|
||||||
XmlDocument xmlDocument = new XmlDocument();
|
XmlDocument xmlDocument = new XmlDocument();
|
||||||
|
|
||||||
|
ServicePointManager.DefaultConnectionLimit = 10;
|
||||||
var sqlArchive = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'archiveConfig'";
|
var sqlArchive = $@"SELECT system_value as Value, system_key as Name FROM variable WHERE deleted = 0 AND system_type = 'archiveConfig'";
|
||||||
var saveToMSDB = await backgroundServiceRepository.GetOneAsync<string>("select system_value from variable where system_type = 'save_to_ms_db' and deleted = 0");
|
var saveToMSDB = await backgroundServiceRepository.GetOneAsync<string>("select system_value from variable where system_type = 'save_to_ms_db' and deleted = 0");
|
||||||
|
|
||||||
var variableArchive = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlArchive);
|
var variableArchive = await backgroundServiceRepository.GetAllAsync<KeyValue>(sqlArchive);
|
||||||
var electricMeterGuid = variableArchive.Where(x => x.Name == "ElectricMeterGuid").Select(x => x.Value).FirstOrDefault();
|
var electricMeterGuid = variableArchive.Where(x => x.Name == "ElectricMeterGuid").Select(x => x.Value).FirstOrDefault();
|
||||||
var waterMeterGuid = variableArchive.Where(x => x.Name == "WaterMeterGuid").Select(x => x.Value).FirstOrDefault();
|
var waterMeterGuid = variableArchive.Where(x => x.Name == "WaterMeterGuid").Select(x => x.Value).FirstOrDefault();
|
||||||
|
|
||||||
|
#region http variable
|
||||||
|
HttpWebRequest archiveRequest = null;
|
||||||
|
HttpWebResponse archiveResponse = null;
|
||||||
|
string archiveResponseContent = null;
|
||||||
|
string archiveJson = null;
|
||||||
|
JObject archiveJsonResult = new JObject();
|
||||||
|
#endregion
|
||||||
#region 找出所有電錶設備
|
#region 找出所有電錶設備
|
||||||
var sWhere = "deleted = 0 AND device_name_tag = @sub_system_guid";
|
var sWhere = "deleted = 0 AND device_name_tag = @sub_system_guid";
|
||||||
var electricMeters = await backgroundServiceRepository.GetAllAsync<Device>("device", sWhere, new { sub_system_guid = electricMeterGuid });
|
var electricMeters = await backgroundServiceRepository.GetAllAsync<Device>("device", sWhere, new { sub_system_guid = electricMeterGuid });
|
||||||
@ -80,12 +87,15 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
{
|
{
|
||||||
foreach (var point in electricPoints)
|
foreach (var point in electricPoints)
|
||||||
{
|
{
|
||||||
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
|
if (electricMeter.device_building_tag == point.device_building_tag)
|
||||||
deviceNumberPoint.DeviceNumber = electricMeter.Device_number;
|
{
|
||||||
deviceNumberPoint.Point = point.points;
|
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
|
||||||
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", electricMeter.Device_number, point.points);
|
deviceNumberPoint.DeviceNumber = electricMeter.Device_number;
|
||||||
|
deviceNumberPoint.Point = point.points;
|
||||||
|
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", electricMeter.Device_number, point.points);
|
||||||
|
|
||||||
electricDeviceNumberPoints.Add(deviceNumberPoint);
|
electricDeviceNumberPoints.Add(deviceNumberPoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion 組合出所有電錶設備點位
|
#endregion 組合出所有電錶設備點位
|
||||||
@ -95,12 +105,15 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
{
|
{
|
||||||
foreach (var point in waterPoints)
|
foreach (var point in waterPoints)
|
||||||
{
|
{
|
||||||
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
|
if (waterMeter.device_building_tag == point.device_building_tag)
|
||||||
deviceNumberPoint.DeviceNumber = waterMeter.Device_number;
|
{
|
||||||
deviceNumberPoint.Point = point.points;
|
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
|
||||||
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", waterMeter.Device_number, point.points);
|
deviceNumberPoint.DeviceNumber = waterMeter.Device_number;
|
||||||
|
deviceNumberPoint.Point = point.points;
|
||||||
|
deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", waterMeter.Device_number, point.points);
|
||||||
|
|
||||||
waterDeviceNumberPoints.Add(deviceNumberPoint);
|
waterDeviceNumberPoints.Add(deviceNumberPoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion 組合出所有電錶設備點位
|
#endregion 組合出所有電錶設備點位
|
||||||
@ -114,7 +127,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
|
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.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());
|
obixApiConfig.Password = ed.AESDecrypt(variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault());
|
||||||
|
var station = await backgroundServiceRepository.GetOneAsync<string>($@"select system_value from variable where system_type = 'obixStatus' and deleted = 0");
|
||||||
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
|
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
|
||||||
#endregion 取得obix 設定
|
#endregion 取得obix 設定
|
||||||
|
|
||||||
@ -125,7 +138,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Day", "任務開始");
|
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Day", "水電表天任務開始");
|
||||||
var preDay = now.AddDays(-1); //取得前一天
|
var preDay = now.AddDays(-1); //取得前一天
|
||||||
var dbDateName = preDay.Year.ToString().PadLeft(4, '0') + preDay.Month.ToString().PadLeft(2, '0');
|
var dbDateName = preDay.Year.ToString().PadLeft(4, '0') + preDay.Month.ToString().PadLeft(2, '0');
|
||||||
|
|
||||||
@ -147,26 +160,28 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
foreach (var deviceNumberPoint in electricDeviceNumberPoints)
|
foreach (var deviceNumberPoint in electricDeviceNumberPoints)
|
||||||
{
|
{
|
||||||
|
|
||||||
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveDayRequest.Method = "POST";
|
archiveRequest.Method = "POST";
|
||||||
archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveDayRequest.PreAuthenticate = true;
|
archiveRequest.PreAuthenticate = true;
|
||||||
|
|
||||||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||||||
using (Stream reqStream = archiveDayRequest.GetRequestStream())
|
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||||||
{
|
{
|
||||||
reqStream.Write(byteArray, 0, byteArray.Length);
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpWebResponse archiveDayResponse = (HttpWebResponse)archiveDayRequest.GetResponse();
|
archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||||||
var archiveDayResponseContent = new StreamReader(archiveDayResponse.GetResponseStream()).ReadToEnd();
|
archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
|
||||||
xmlDocument.LoadXml(archiveDayResponseContent);
|
xmlDocument.LoadXml(archiveResponseContent);
|
||||||
string archiveDayJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||||||
JObject archiveDayJsonResult = (JObject)JsonConvert.DeserializeObject(archiveDayJson);
|
archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||||||
|
|
||||||
if (archiveDayJsonResult.ContainsKey("err")) //抓取錯誤
|
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||||||
{
|
{
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
|
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult);
|
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult);
|
||||||
@ -178,7 +193,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
archiveDayRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
archiveDayRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
||||||
archiveDayRawData.Add("@is_complete", 0);
|
archiveDayRawData.Add("@is_complete", 0);
|
||||||
archiveDayRawData.Add("@repeat_times", 0);
|
archiveDayRawData.Add("@repeat_times", 0);
|
||||||
archiveDayRawData.Add("@fail_reason", archiveDayJson);
|
archiveDayRawData.Add("@fail_reason", archiveJson);
|
||||||
|
|
||||||
archiveDayRawData.Add("@count_rawdata", 0);
|
archiveDayRawData.Add("@count_rawdata", 0);
|
||||||
archiveDayRawData.Add("@min_rawdata", 0);
|
archiveDayRawData.Add("@min_rawdata", 0);
|
||||||
@ -190,9 +205,9 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
electericArchiveDayRawDatas.Add(archiveDayRawData);
|
electericArchiveDayRawDatas.Add(archiveDayRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archiveDayJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||||||
{
|
{
|
||||||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveDayJsonResult);
|
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
|
||||||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||||||
{
|
{
|
||||||
electericArchiveDayRawDatas.AddRange(ArrangeRawDatas);
|
electericArchiveDayRawDatas.AddRange(ArrangeRawDatas);
|
||||||
@ -202,26 +217,29 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
foreach (var deviceNumberPoint in waterDeviceNumberPoints)
|
foreach (var deviceNumberPoint in waterDeviceNumberPoints)
|
||||||
{
|
{
|
||||||
|
|
||||||
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveDayRequest.Method = "POST";
|
archiveRequest.Method = "POST";
|
||||||
archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveDayRequest.PreAuthenticate = true;
|
archiveRequest.PreAuthenticate = true;
|
||||||
|
|
||||||
|
|
||||||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||||||
using (Stream reqStream = archiveDayRequest.GetRequestStream())
|
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||||||
{
|
{
|
||||||
reqStream.Write(byteArray, 0, byteArray.Length);
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpWebResponse archiveDayResponse = (HttpWebResponse)archiveDayRequest.GetResponse();
|
archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||||||
var archiveDayResponseContent = new StreamReader(archiveDayResponse.GetResponseStream()).ReadToEnd();
|
archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
|
||||||
xmlDocument.LoadXml(archiveDayResponseContent);
|
xmlDocument.LoadXml(archiveResponseContent);
|
||||||
string archiveDayJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||||||
JObject archiveDayJsonResult = (JObject)JsonConvert.DeserializeObject(archiveDayJson);
|
archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||||||
|
|
||||||
if (archiveDayJsonResult.ContainsKey("err")) //抓取錯誤
|
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||||||
{
|
{
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
|
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult);
|
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult);
|
||||||
@ -233,7 +251,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
archiveDayRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
archiveDayRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
||||||
archiveDayRawData.Add("@is_complete", 0);
|
archiveDayRawData.Add("@is_complete", 0);
|
||||||
archiveDayRawData.Add("@repeat_times", 0);
|
archiveDayRawData.Add("@repeat_times", 0);
|
||||||
archiveDayRawData.Add("@fail_reason", archiveDayJson);
|
archiveDayRawData.Add("@fail_reason", archiveJson);
|
||||||
|
|
||||||
archiveDayRawData.Add("@count_rawdata", 0);
|
archiveDayRawData.Add("@count_rawdata", 0);
|
||||||
archiveDayRawData.Add("@min_rawdata", 0);
|
archiveDayRawData.Add("@min_rawdata", 0);
|
||||||
@ -245,9 +263,9 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
waterArchiveDayRawDatas.Add(archiveDayRawData);
|
waterArchiveDayRawDatas.Add(archiveDayRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archiveDayJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||||||
{
|
{
|
||||||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveDayJsonResult);
|
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
|
||||||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||||||
{
|
{
|
||||||
waterArchiveDayRawDatas.AddRange(ArrangeRawDatas);
|
waterArchiveDayRawDatas.AddRange(ArrangeRawDatas);
|
||||||
@ -573,6 +591,14 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【任務失敗】");
|
logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【任務失敗】");
|
||||||
logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【任務失敗】[Exception]:{0}", exception.ToString());
|
logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【任務失敗】[Exception]:{0}", exception.ToString());
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (archiveResponse != null)
|
||||||
|
{
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion 天歸檔
|
#endregion 天歸檔
|
||||||
|
|
||||||
@ -581,7 +607,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Week", "任務開始");
|
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Week", "水電表周任務開始");
|
||||||
int week = Convert.ToInt32(now.DayOfWeek);
|
int week = Convert.ToInt32(now.DayOfWeek);
|
||||||
week = week == 0 ? 7 : week;
|
week = week == 0 ? 7 : week;
|
||||||
|
|
||||||
@ -602,26 +628,29 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
List<Dictionary<string, object>> waterArchiveWeekRawDatas = new List<Dictionary<string, object>>();
|
List<Dictionary<string, object>> waterArchiveWeekRawDatas = new List<Dictionary<string, object>>();
|
||||||
foreach (var deviceNumberPoint in electricDeviceNumberPoints)
|
foreach (var deviceNumberPoint in electricDeviceNumberPoints)
|
||||||
{
|
{
|
||||||
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveWeekRequest.Method = "POST";
|
archiveRequest.Method = "POST";
|
||||||
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveWeekRequest.PreAuthenticate = true;
|
archiveRequest.PreAuthenticate = true;
|
||||||
|
|
||||||
|
|
||||||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||||||
using (Stream reqStream = archiveWeekRequest.GetRequestStream())
|
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||||||
{
|
{
|
||||||
reqStream.Write(byteArray, 0, byteArray.Length);
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpWebResponse archiveWeekResponse = (HttpWebResponse)archiveWeekRequest.GetResponse();
|
archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||||||
var archiveWeekResponseContent = new StreamReader(archiveWeekResponse.GetResponseStream()).ReadToEnd();
|
archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
|
||||||
xmlDocument.LoadXml(archiveWeekResponseContent);
|
xmlDocument.LoadXml(archiveResponseContent);
|
||||||
string archiveWeekJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||||||
JObject archiveWeekJsonResult = (JObject)JsonConvert.DeserializeObject(archiveWeekJson);
|
archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||||||
|
|
||||||
if (archiveWeekJsonResult.ContainsKey("err")) //抓取錯誤
|
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||||||
{
|
{
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】");
|
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】");
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveWeekJsonResult);
|
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveWeekJsonResult);
|
||||||
@ -633,7 +662,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
archiveWeekRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
archiveWeekRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
||||||
archiveWeekRawData.Add("@is_complete", 0);
|
archiveWeekRawData.Add("@is_complete", 0);
|
||||||
archiveWeekRawData.Add("@repeat_times", 0);
|
archiveWeekRawData.Add("@repeat_times", 0);
|
||||||
archiveWeekRawData.Add("@fail_reason", archiveWeekJson);
|
archiveWeekRawData.Add("@fail_reason", archiveJson);
|
||||||
|
|
||||||
archiveWeekRawData.Add("@count_rawdata", 0);
|
archiveWeekRawData.Add("@count_rawdata", 0);
|
||||||
archiveWeekRawData.Add("@min_rawdata", 0);
|
archiveWeekRawData.Add("@min_rawdata", 0);
|
||||||
@ -645,9 +674,9 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
electricArchiveWeekRawDatas.Add(archiveWeekRawData);
|
electricArchiveWeekRawDatas.Add(archiveWeekRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archiveWeekJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||||||
{
|
{
|
||||||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveWeekJsonResult);
|
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
|
||||||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||||||
{
|
{
|
||||||
electricArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
|
electricArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
|
||||||
@ -656,26 +685,28 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
}
|
}
|
||||||
foreach (var deviceNumberPoint in waterDeviceNumberPoints)
|
foreach (var deviceNumberPoint in waterDeviceNumberPoints)
|
||||||
{
|
{
|
||||||
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveWeekRequest.Method = "POST";
|
archiveRequest.Method = "POST";
|
||||||
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveWeekRequest.PreAuthenticate = true;
|
archiveRequest.PreAuthenticate = true;
|
||||||
|
|
||||||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||||||
using (Stream reqStream = archiveWeekRequest.GetRequestStream())
|
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||||||
{
|
{
|
||||||
reqStream.Write(byteArray, 0, byteArray.Length);
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpWebResponse archiveWeekResponse = (HttpWebResponse)archiveWeekRequest.GetResponse();
|
archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||||||
var archiveWeekResponseContent = new StreamReader(archiveWeekResponse.GetResponseStream()).ReadToEnd();
|
archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
|
||||||
xmlDocument.LoadXml(archiveWeekResponseContent);
|
xmlDocument.LoadXml(archiveResponseContent);
|
||||||
string archiveWeekJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||||||
JObject archiveWeekJsonResult = (JObject)JsonConvert.DeserializeObject(archiveWeekJson);
|
archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||||||
|
|
||||||
if (archiveWeekJsonResult.ContainsKey("err")) //抓取錯誤
|
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||||||
{
|
{
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】");
|
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】");
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveWeekJsonResult);
|
//logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveWeekJsonResult);
|
||||||
@ -687,7 +718,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
archiveWeekRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
archiveWeekRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
||||||
archiveWeekRawData.Add("@is_complete", 0);
|
archiveWeekRawData.Add("@is_complete", 0);
|
||||||
archiveWeekRawData.Add("@repeat_times", 0);
|
archiveWeekRawData.Add("@repeat_times", 0);
|
||||||
archiveWeekRawData.Add("@fail_reason", archiveWeekJson);
|
archiveWeekRawData.Add("@fail_reason", archiveJson);
|
||||||
|
|
||||||
archiveWeekRawData.Add("@count_rawdata", 0);
|
archiveWeekRawData.Add("@count_rawdata", 0);
|
||||||
archiveWeekRawData.Add("@min_rawdata", 0);
|
archiveWeekRawData.Add("@min_rawdata", 0);
|
||||||
@ -699,9 +730,9 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
waterArchiveWeekRawDatas.Add(archiveWeekRawData);
|
waterArchiveWeekRawDatas.Add(archiveWeekRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archiveWeekJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||||||
{
|
{
|
||||||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveWeekJsonResult);
|
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
|
||||||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||||||
{
|
{
|
||||||
waterArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
|
waterArchiveWeekRawDatas.AddRange(ArrangeRawDatas);
|
||||||
@ -923,6 +954,14 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【任務失敗】");
|
logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【任務失敗】");
|
||||||
logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【任務失敗】[Exception]:{0}", exception.ToString());
|
logger.LogError("【ArchiveElectricMeterDayJob】【週歸檔】【任務失敗】[Exception]:{0}", exception.ToString());
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (archiveResponse != null)
|
||||||
|
{
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion 週歸檔
|
#endregion 週歸檔
|
||||||
|
|
||||||
@ -931,7 +970,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Month", "任務開始");
|
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Month", "水電表月任務開始");
|
||||||
var FirstDay = now.AddDays(-now.Day + 1);
|
var FirstDay = now.AddDays(-now.Day + 1);
|
||||||
var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day);
|
var LastDay = now.AddMonths(1).AddDays(-now.AddMonths(1).Day);
|
||||||
|
|
||||||
@ -954,26 +993,28 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
List<Dictionary<string, object>> waterArchiveMonthRawDatas = new List<Dictionary<string, object>>();
|
List<Dictionary<string, object>> waterArchiveMonthRawDatas = new List<Dictionary<string, object>>();
|
||||||
foreach (var deviceNumberPoint in electricDeviceNumberPoints)
|
foreach (var deviceNumberPoint in electricDeviceNumberPoints)
|
||||||
{
|
{
|
||||||
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveMonthRequest.Method = "POST";
|
archiveRequest.Method = "POST";
|
||||||
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveMonthRequest.PreAuthenticate = true;
|
archiveRequest.PreAuthenticate = true;
|
||||||
|
|
||||||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||||||
using (Stream reqStream = archiveMonthRequest.GetRequestStream())
|
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||||||
{
|
{
|
||||||
reqStream.Write(byteArray, 0, byteArray.Length);
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpWebResponse archiveMonthResponse = (HttpWebResponse)archiveMonthRequest.GetResponse();
|
archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||||||
var archiveMonthResponseContent = new StreamReader(archiveMonthResponse.GetResponseStream()).ReadToEnd();
|
archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
|
||||||
xmlDocument.LoadXml(archiveMonthResponseContent);
|
xmlDocument.LoadXml(archiveResponseContent);
|
||||||
string archiveMonthJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||||||
JObject archiveMonthJsonResult = (JObject)JsonConvert.DeserializeObject(archiveMonthJson);
|
archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||||||
|
|
||||||
if (archiveMonthJsonResult.ContainsKey("err")) //抓取錯誤
|
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||||||
{
|
{
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】");
|
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】");
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult);
|
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult);
|
||||||
@ -985,7 +1026,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
||||||
archiveMonthRawData.Add("@is_complete", 0);
|
archiveMonthRawData.Add("@is_complete", 0);
|
||||||
archiveMonthRawData.Add("@repeat_times", 0);
|
archiveMonthRawData.Add("@repeat_times", 0);
|
||||||
archiveMonthRawData.Add("@fail_reason", archiveMonthJson);
|
archiveMonthRawData.Add("@fail_reason", archiveJson);
|
||||||
|
|
||||||
archiveMonthRawData.Add("@count_rawdata", 0);
|
archiveMonthRawData.Add("@count_rawdata", 0);
|
||||||
archiveMonthRawData.Add("@min_rawdata", 0);
|
archiveMonthRawData.Add("@min_rawdata", 0);
|
||||||
@ -997,9 +1038,9 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
electricArchiveMonthRawDatas.Add(archiveMonthRawData);
|
electricArchiveMonthRawDatas.Add(archiveMonthRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archiveMonthJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||||||
{
|
{
|
||||||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveMonthJsonResult);
|
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
|
||||||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||||||
{
|
{
|
||||||
electricArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
|
electricArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
|
||||||
@ -1008,26 +1049,29 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
}
|
}
|
||||||
foreach (var deviceNumberPoint in waterDeviceNumberPoints)
|
foreach (var deviceNumberPoint in waterDeviceNumberPoints)
|
||||||
{
|
{
|
||||||
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveMonthRequest.Method = "POST";
|
archiveRequest.Method = "POST";
|
||||||
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveMonthRequest.PreAuthenticate = true;
|
archiveRequest.PreAuthenticate = true;
|
||||||
|
|
||||||
|
|
||||||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||||||
using (Stream reqStream = archiveMonthRequest.GetRequestStream())
|
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||||||
{
|
{
|
||||||
reqStream.Write(byteArray, 0, byteArray.Length);
|
reqStream.Write(byteArray, 0, byteArray.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpWebResponse archiveMonthResponse = (HttpWebResponse)archiveMonthRequest.GetResponse();
|
archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||||||
var archiveMonthResponseContent = new StreamReader(archiveMonthResponse.GetResponseStream()).ReadToEnd();
|
archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
|
||||||
xmlDocument.LoadXml(archiveMonthResponseContent);
|
xmlDocument.LoadXml(archiveResponseContent);
|
||||||
string archiveMonthJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||||||
JObject archiveMonthJsonResult = (JObject)JsonConvert.DeserializeObject(archiveMonthJson);
|
archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||||||
|
|
||||||
if (archiveMonthJsonResult.ContainsKey("err")) //抓取錯誤
|
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||||||
{
|
{
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】");
|
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】");
|
||||||
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult);
|
//logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveMonthJsonResult);
|
||||||
@ -1039,7 +1083,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
archiveMonthRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
||||||
archiveMonthRawData.Add("@is_complete", 0);
|
archiveMonthRawData.Add("@is_complete", 0);
|
||||||
archiveMonthRawData.Add("@repeat_times", 0);
|
archiveMonthRawData.Add("@repeat_times", 0);
|
||||||
archiveMonthRawData.Add("@fail_reason", archiveMonthJson);
|
archiveMonthRawData.Add("@fail_reason", archiveJson);
|
||||||
|
|
||||||
archiveMonthRawData.Add("@count_rawdata", 0);
|
archiveMonthRawData.Add("@count_rawdata", 0);
|
||||||
archiveMonthRawData.Add("@min_rawdata", 0);
|
archiveMonthRawData.Add("@min_rawdata", 0);
|
||||||
@ -1051,9 +1095,9 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
waterArchiveMonthRawDatas.Add(archiveMonthRawData);
|
waterArchiveMonthRawDatas.Add(archiveMonthRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archiveMonthJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||||||
{
|
{
|
||||||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveMonthJsonResult);
|
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult);
|
||||||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||||||
{
|
{
|
||||||
waterArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
|
waterArchiveMonthRawDatas.AddRange(ArrangeRawDatas);
|
||||||
@ -1268,6 +1312,14 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】");
|
logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】");
|
||||||
logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】[Exception]:{0}", exception.ToString());
|
logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】[Exception]:{0}", exception.ToString());
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (archiveResponse != null)
|
||||||
|
{
|
||||||
|
archiveResponse.Dispose();
|
||||||
|
archiveResponse.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion 月歸檔
|
#endregion 月歸檔
|
||||||
|
|
||||||
@ -1277,7 +1329,7 @@ namespace BackendWorkerService.Quartz.Jobs
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Compensate", "任務開始");
|
await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Compensate", "補償機制任務開始");
|
||||||
ProcEletricMeterService procEletricMeterService = new ProcEletricMeterService(backgroundServiceRepository, backgroundServiceMsSqlRepository);
|
ProcEletricMeterService procEletricMeterService = new ProcEletricMeterService(backgroundServiceRepository, backgroundServiceMsSqlRepository);
|
||||||
await procEletricMeterService.ArchiveData();
|
await procEletricMeterService.ArchiveData();
|
||||||
await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Compensate", "任務完成");
|
await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Compensate", "任務完成");
|
||||||
|
@ -16,6 +16,7 @@ using Repository.Helper;
|
|||||||
using Repository.BackendRepository.Interface;
|
using Repository.BackendRepository.Interface;
|
||||||
using Repository.BackendRepository.Implement;
|
using Repository.BackendRepository.Implement;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
|
|
||||||
namespace BackendWorkerService.Services.Implement
|
namespace BackendWorkerService.Services.Implement
|
||||||
{
|
{
|
||||||
@ -39,6 +40,7 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
int repeatTimes = 0;
|
int repeatTimes = 0;
|
||||||
string targetTable = string.Empty;
|
string targetTable = string.Empty;
|
||||||
|
string sql_error_day = string.Empty;
|
||||||
|
|
||||||
EDFunction ed = new EDFunction();
|
EDFunction ed = new EDFunction();
|
||||||
XmlDocument xmlDocument = new XmlDocument();
|
XmlDocument xmlDocument = new XmlDocument();
|
||||||
@ -61,12 +63,12 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
obixApiConfig.ApiBase = variableObix.Where(x => x.Name == "ApiBase").Select(x => x.Value).FirstOrDefault();
|
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.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();
|
obixApiConfig.Password = variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault();
|
||||||
|
var station = await backgroundServiceRepository.GetOneAsync<string>($@"select system_value from variable where system_type = 'obixStatus' and deleted = 0");
|
||||||
encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
|
encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password));
|
||||||
#endregion 取得obix 設定
|
#endregion 取得obix 設定
|
||||||
|
|
||||||
//取得錯誤的設備sql format
|
//取得錯誤的設備sql format
|
||||||
var sql_error_format = @"SELECT * FROM {0} WHERE is_complete = 0 AND repeat_times < @RepeatTimes";
|
var sql_error_format = @"SELECT * FROM {0} WHERE is_complete = 0 AND repeat_times < @RepeatTimes AND (point = 'KWH' or point = 'RCV')";
|
||||||
|
|
||||||
//MY 新增/修改sql format
|
//MY 新增/修改sql format
|
||||||
var MYsql_update_format = @"
|
var MYsql_update_format = @"
|
||||||
@ -113,7 +115,7 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
WHERE ROW_COUNT() = 0;";
|
WHERE ROW_COUNT() = 0;";
|
||||||
//新增/修改sql format
|
//新增/修改sql format
|
||||||
var sql_update_format = @"BEGIN TRANSACTION;
|
var sql_update_format = @"BEGIN TRANSACTION;
|
||||||
|
|
||||||
UPDATE {0} SET
|
UPDATE {0} SET
|
||||||
count_rawdata = @count_rawdata,
|
count_rawdata = @count_rawdata,
|
||||||
min_rawdata = @min_rawdata,
|
min_rawdata = @min_rawdata,
|
||||||
@ -187,8 +189,8 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
// <reltime name='interval' val = 'PT1H' />
|
// <reltime name='interval' val = 'PT1H' />
|
||||||
// </obj>";
|
// </obj>";
|
||||||
|
|
||||||
// HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
// HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
// //HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
// //HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
// archiveHourRequest.Method = "POST";
|
// archiveHourRequest.Method = "POST";
|
||||||
// archiveHourRequest.Headers.Add("Authorization", "Basic " + encoded);
|
// archiveHourRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
// archiveHourRequest.PreAuthenticate = true;
|
// archiveHourRequest.PreAuthenticate = true;
|
||||||
@ -248,96 +250,110 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
#endregion 時歸檔補償
|
#endregion 時歸檔補償
|
||||||
|
|
||||||
#region 天歸檔補償
|
#region 天歸檔補償
|
||||||
|
string schema = await backgroundServiceRepository.GetOneAsync<string>(@"
|
||||||
|
select system_value from variable where system_type = 'project_name' and deleted = 0");
|
||||||
//取得所有須補償的設備資訊
|
//取得所有須補償的設備資訊
|
||||||
targetTable = "archive_electric_meter_day";
|
targetTable = await backgroundServiceRepository.GetOneAsync<string>($@"
|
||||||
var sql_error_day = string.Format(sql_error_format, targetTable);
|
select table_name
|
||||||
var electric_error_days = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_day, new { RepeatTimes = repeatTimes });
|
from information_schema.`TABLES`
|
||||||
List<Dictionary<string, object>> electricArchiveDayRawDatas = new List<Dictionary<string, object>>();
|
where TABLE_NAME like 'archive_electric_meter_day%' and TABLE_SCHEMA = '{schema.Split('/')[0]}'
|
||||||
if (electric_error_days.Count() > 0)
|
order by TABLE_NAME desc limit 1 ");
|
||||||
|
if (!string.IsNullOrEmpty(targetTable))
|
||||||
{
|
{
|
||||||
foreach (var error_day in electric_error_days)
|
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)
|
||||||
{
|
{
|
||||||
DeviceNumberPoint deviceNumberPoint = new DeviceNumberPoint();
|
foreach (var error_day in electric_error_days)
|
||||||
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);
|
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);
|
||||||
|
|
||||||
HttpWebResponse archiveDayResponse = (HttpWebResponse)archiveDayRequest.GetResponse();
|
var startTimestamp = string.Format("{0}+08:00", error_day.Start_timestamp.Replace(" ", "T"));
|
||||||
var archiveDayResponseContent = new StreamReader(archiveDayResponse.GetResponseStream()).ReadToEnd();
|
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>";
|
||||||
|
|
||||||
xmlDocument.LoadXml(archiveDayResponseContent);
|
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
string archiveDayJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
JObject archiveDayJsonResult = (JObject)JsonConvert.DeserializeObject(archiveDayJson);
|
archiveDayRequest.Method = "POST";
|
||||||
|
archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
|
archiveDayRequest.PreAuthenticate = true;
|
||||||
|
|
||||||
if (archiveDayJsonResult.ContainsKey("err")) //抓取錯誤
|
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||||||
{
|
using (Stream reqStream = archiveDayRequest.GetRequestStream())
|
||||||
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);
|
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);
|
||||||
|
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, electricArchiveDayRawDatas);
|
||||||
|
if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1")
|
||||||
|
{
|
||||||
|
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, electricArchiveDayRawDatas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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";
|
targetTable = await backgroundServiceRepository.GetOneAsync<string>($@"
|
||||||
sql_error_day = string.Format(sql_error_format, targetTable);
|
select table_name
|
||||||
var water_error_days = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_day, new { RepeatTimes = repeatTimes });
|
from information_schema.`TABLES`
|
||||||
List<Dictionary<string, object>> waterArchiveDayRawDatas = new List<Dictionary<string, object>>();
|
where TABLE_NAME like 'archive_water_meter_day%' and TABLE_SCHEMA = '{schema.Split('/')[0]}'
|
||||||
if (water_error_days.Count() > 0)
|
order by TABLE_NAME desc limit 1 ");
|
||||||
|
if (!string.IsNullOrEmpty(targetTable))
|
||||||
|
{
|
||||||
|
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)
|
foreach (var error_day in water_error_days)
|
||||||
{
|
{
|
||||||
@ -348,15 +364,14 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
|
|
||||||
var startTimestamp = string.Format("{0}+08:00", error_day.Start_timestamp.Replace(" ", "T"));
|
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 endTimestamp = string.Format("{0}+08:00", error_day.End_timestamp.Replace(" ", "T"));
|
||||||
|
|
||||||
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||||||
<abstime name='start' val='{startTimestamp}' />
|
<abstime name='start' val='{startTimestamp}' />
|
||||||
<abstime name='end' val='{endTimestamp}' />
|
<abstime name='end' val='{endTimestamp}' />
|
||||||
<reltime name='interval' val = 'PT1D' />
|
<reltime name='interval' val = 'PT1D' />
|
||||||
</obj>";
|
</obj>";
|
||||||
|
|
||||||
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveDayRequest.Method = "POST";
|
archiveDayRequest.Method = "POST";
|
||||||
archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveDayRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveDayRequest.PreAuthenticate = true;
|
archiveDayRequest.PreAuthenticate = true;
|
||||||
@ -416,6 +431,7 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, waterArchiveDayRawDatas);
|
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, waterArchiveDayRawDatas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endregion 天歸檔補償
|
#endregion 天歸檔補償
|
||||||
|
|
||||||
#region 週歸檔補償
|
#region 週歸檔補償
|
||||||
@ -442,8 +458,8 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
<reltime name='interval' val = 'PT7D' />
|
<reltime name='interval' val = 'PT7D' />
|
||||||
</obj>";
|
</obj>";
|
||||||
|
|
||||||
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveWeekRequest.Method = "POST";
|
archiveWeekRequest.Method = "POST";
|
||||||
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveWeekRequest.PreAuthenticate = true;
|
archiveWeekRequest.PreAuthenticate = true;
|
||||||
@ -526,8 +542,8 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
<reltime name='interval' val = 'PT7D' />
|
<reltime name='interval' val = 'PT7D' />
|
||||||
</obj>";
|
</obj>";
|
||||||
|
|
||||||
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveWeekRequest.Method = "POST";
|
archiveWeekRequest.Method = "POST";
|
||||||
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveWeekRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveWeekRequest.PreAuthenticate = true;
|
archiveWeekRequest.PreAuthenticate = true;
|
||||||
@ -616,8 +632,8 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
<reltime name='interval' val = 'PT{dayInMonth}D' />
|
<reltime name='interval' val = 'PT{dayInMonth}D' />
|
||||||
</obj>";
|
</obj>";
|
||||||
|
|
||||||
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveMonthRequest.Method = "POST";
|
archiveMonthRequest.Method = "POST";
|
||||||
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveMonthRequest.PreAuthenticate = true;
|
archiveMonthRequest.PreAuthenticate = true;
|
||||||
@ -674,11 +690,11 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
{
|
{
|
||||||
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, electricArchiveMonthRawDatas);
|
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, electricArchiveMonthRawDatas);
|
||||||
}
|
}
|
||||||
await backgroundServiceRepository.ExecuteSql(MYsql_update_format, electricArchiveMonthRawDatas);
|
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, electricArchiveMonthRawDatas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
targetTable = "archive_electric_meter_month";
|
targetTable = "archive_water_meter_month";
|
||||||
sql_error_month = string.Format(sql_error_format, targetTable);
|
sql_error_month = string.Format(sql_error_format, targetTable);
|
||||||
var water_error_months = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_month, new { RepeatTimes = repeatTimes });
|
var water_error_months = await backgroundServiceRepository.GetAllAsync<ArchiveElectricMeter>(sql_error_month, new { RepeatTimes = repeatTimes });
|
||||||
List<Dictionary<string, object>> waterArchiveMonthRawDatas = new List<Dictionary<string, object>>();
|
List<Dictionary<string, object>> waterArchiveMonthRawDatas = new List<Dictionary<string, object>>();
|
||||||
@ -703,8 +719,8 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
<reltime name='interval' val = 'PT{dayInMonth}D' />
|
<reltime name='interval' val = 'PT{dayInMonth}D' />
|
||||||
</obj>";
|
</obj>";
|
||||||
|
|
||||||
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~historyRollup/");
|
||||||
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/FIC_Center/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
//HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||||||
archiveMonthRequest.Method = "POST";
|
archiveMonthRequest.Method = "POST";
|
||||||
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
|
archiveMonthRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||||||
archiveMonthRequest.PreAuthenticate = true;
|
archiveMonthRequest.PreAuthenticate = true;
|
||||||
@ -761,7 +777,7 @@ namespace BackendWorkerService.Services.Implement
|
|||||||
{
|
{
|
||||||
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, waterArchiveMonthRawDatas);
|
await backgroundServiceMsSqlRepository.ExecuteSql(sql_error_update, waterArchiveMonthRawDatas);
|
||||||
}
|
}
|
||||||
await backgroundServiceRepository.ExecuteSql(MYsql_update_format, waterArchiveMonthRawDatas);
|
await backgroundServiceRepository.ExecuteSql(Mysql_error_update, waterArchiveMonthRawDatas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion 月歸檔補償
|
#endregion 月歸檔補償
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
"Microsoft.Hosting.Lifetime": "Information"
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"LoggerPath": "C:\\inetpub\\Taipei_dome_background_service\\Logs",
|
||||||
"BackgroundServiceCron": {
|
"BackgroundServiceCron": {
|
||||||
"ExecutionBackgroundServicePlanJob": "0 0 2 * * ?",
|
"ExecutionBackgroundServicePlanJob": "0 0 2 * * ?",
|
||||||
"MessageNotificationJob": "0 0 2 * * ?",
|
"MessageNotificationJob": "0 0 2 * * ?",
|
||||||
@ -13,24 +14,18 @@
|
|||||||
"RegularUpdateDBTableJob": "0 0 2 * * ?",
|
"RegularUpdateDBTableJob": "0 0 2 * * ?",
|
||||||
"ParkingJob": "0 0 2 * * ?",
|
"ParkingJob": "0 0 2 * * ?",
|
||||||
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
|
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
|
||||||
"ArchiveElectricMeterDayJob": "0 0 2 * * ?",
|
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
|
||||||
"WeatherAPIJob": "0/5 * * * * ?"
|
"WeatherAPIJob": "0 0 2 * * ?"
|
||||||
},
|
},
|
||||||
"DBConfig": {
|
"DBConfig": {
|
||||||
//"MySqlDBConfig": {
|
|
||||||
// "Server": "TNi6aupYHPZT8ZU177KTKw==", //172.16.220.251
|
|
||||||
// "Port": "mkF51jVbg40V5K5eTh2Ckw==",
|
|
||||||
// "Database": "VvfWH/59gQguY2eA2xBCug==",
|
|
||||||
// "Root": "IV8Ec1Ng2AWAnkBafXy2kg==",
|
|
||||||
// "Password": "Jue6jMFRi11meN6xbdKwDA=="
|
|
||||||
//},
|
|
||||||
"MySqlDBConfig": {
|
"MySqlDBConfig": {
|
||||||
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
||||||
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
|
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
|
||||||
//"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
|
//"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
|
||||||
//"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
|
//"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
|
||||||
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
//"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
||||||
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
||||||
|
"Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //mcut
|
||||||
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
||||||
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
||||||
},
|
},
|
||||||
@ -38,24 +33,9 @@
|
|||||||
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
||||||
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
||||||
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
||||||
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
|
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
|
||||||
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
"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": {
|
"SMTPConfig": {
|
||||||
"Host": "smtp.gmail.com",
|
"Host": "smtp.gmail.com",
|
||||||
|
@ -8,26 +8,24 @@
|
|||||||
},
|
},
|
||||||
"LoggerPath": "C:\\inetpub\\Taipei_dome_background_service\\Logs",
|
"LoggerPath": "C:\\inetpub\\Taipei_dome_background_service\\Logs",
|
||||||
"BackgroundServiceCron": {
|
"BackgroundServiceCron": {
|
||||||
"ExecutionBackgroundServicePlanJob": "0/5 * * * * ?",
|
"ExecutionBackgroundServicePlanJob": "0 0 2 * * ?",
|
||||||
"MessageNotificationJob": "0 0/30 * * * ?",
|
"MessageNotificationJob": "0 0 2 * * ?",
|
||||||
"DataDeliveryJob": "0 0/5 * * * ?",
|
"DataDeliveryJob": "0 0 2 * * ?",
|
||||||
"RegularUpdateDBTableJob": "0 0 2 * * ?"
|
"RegularUpdateDBTableJob": "0 0 2 * * ?",
|
||||||
|
"ParkingJob": "0 0 2 * * ?",
|
||||||
|
"ArchiveElectricMeterHourJob": "0 0 2 * * ?",
|
||||||
|
"ArchiveElectricMeterDayJob": "0/5 * * * * ?",
|
||||||
|
"WeatherAPIJob": "0 0 2 * * ?"
|
||||||
},
|
},
|
||||||
"DBConfig": {
|
"DBConfig": {
|
||||||
//"MySqlDBConfig": {
|
|
||||||
// "Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
|
||||||
// "Port": "js2LutKe+rdjzdxMPQUrvQ==",
|
|
||||||
// "Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
|
|
||||||
// "Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
|
||||||
// "Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
|
||||||
//},
|
|
||||||
"MySqlDBConfig": {
|
"MySqlDBConfig": {
|
||||||
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
"Server": "FYlY+w0XDIz+jmF2rlZWJw==", //0.201
|
||||||
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
|
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
|
||||||
//"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
|
//"Database": "VJB2XC+lAtzuHObDGMVOAA==", //30
|
||||||
//"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
|
//"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
|
||||||
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
//"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
||||||
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
||||||
|
"Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //mcut
|
||||||
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
||||||
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
||||||
},
|
},
|
||||||
@ -35,16 +33,9 @@
|
|||||||
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
||||||
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
||||||
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
||||||
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
|
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
|
||||||
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
||||||
}
|
}
|
||||||
//"MSSqlDBConfig": {
|
|
||||||
// "Server": "avZg8PA8C9GVgYZBgEKzCg==",
|
|
||||||
// "Port": "lJA0KPkG6RvFfTgWiXFyUw==",
|
|
||||||
// "Database": "VvfWH/59gQguY2eA2xBCug==",
|
|
||||||
// "Root": "sD8GZ9UPiIQGU6dU011/4A==",
|
|
||||||
// "Password": "2gi7rOmGha2VdXC5vtHxhg=="
|
|
||||||
//}
|
|
||||||
},
|
},
|
||||||
"SMTPConfig": {
|
"SMTPConfig": {
|
||||||
"Host": "smtp.gmail.com",
|
"Host": "smtp.gmail.com",
|
||||||
|
@ -1,526 +1,192 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
|
<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>
|
<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>
|
<status>Actual</status>
|
||||||
<msgType>Update</msgType>
|
<msgType>Cancel</msgType>
|
||||||
<scope>Public</scope>
|
<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>
|
<info>
|
||||||
<language>zh-TW</language>
|
<language>zh-TW</language>
|
||||||
<category>Met</category>
|
<category>Met</category>
|
||||||
<event>降雨</event>
|
<event>降雨</event>
|
||||||
<responseType>Monitor</responseType>
|
<urgency>Past</urgency>
|
||||||
<urgency>Future</urgency>
|
<severity>Minor</severity>
|
||||||
<severity>Moderate</severity>
|
<certainty>Observed</certainty>
|
||||||
<certainty>Likely</certainty>
|
|
||||||
<eventCode>
|
<eventCode>
|
||||||
<valueName>profile:CAP-TWP:Event:1.0</valueName>
|
<valueName>profile:CAP-TWP:Event:1.0</valueName>
|
||||||
<value>rainfall</value>
|
<value>rainfall</value>
|
||||||
</eventCode>
|
</eventCode>
|
||||||
<effective>2023-06-01T06:55:00+08:00</effective>
|
<effective>2023-06-06T03:40:00+08:00</effective>
|
||||||
<onset>2023-06-01T06:59:00+08:00</onset>
|
<onset>2023-06-06T03:40:00+08:00</onset>
|
||||||
<expires>2023-06-01T11:00:00+08:00</expires>
|
<expires>2023-06-06T03:55:20+08:00</expires>
|
||||||
<senderName>中央氣象局</senderName>
|
<senderName>中央氣象局</senderName>
|
||||||
<headline>大雨特報</headline>
|
<headline>解除豪雨特報</headline>
|
||||||
<description>
|
<description>
|
||||||
颱風外圍環流影響,今(1)日大臺北、桃園、新竹、宜蘭地區有局部大雨發生的機率,請注意瞬間大雨、強陣風及溪水暴漲,山區請注意落石及坍方。
|
由於降雨趨於緩和,發生大雨或豪雨的機率降低,故解除豪雨特報。
|
||||||
</description>
|
</description>
|
||||||
|
<instruction></instruction>
|
||||||
<web>https://www.cwb.gov.tw/V8/C/P/Warning/FIFOWS.html</web>
|
<web>https://www.cwb.gov.tw/V8/C/P/Warning/FIFOWS.html</web>
|
||||||
<parameter>
|
<parameter>
|
||||||
<valueName>alert_title</valueName>
|
<valueName>alert_title</valueName>
|
||||||
<value>大雨特報</value>
|
<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>
|
|
||||||
</parameter>
|
</parameter>
|
||||||
|
|
||||||
<area>
|
<area>
|
||||||
<areaDesc>新竹縣橫山鄉</areaDesc>
|
<areaDesc>基隆市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000408</value>
|
<value>10017</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>新竹縣北埔鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>臺北市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000409</value>
|
<value>63</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>桃園市觀音區</areaDesc>
|
<area>
|
||||||
|
<areaDesc>新北市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>6801200</value>
|
<value>65</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>桃園市復興區</areaDesc>
|
<area>
|
||||||
|
<areaDesc>桃園市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>6801300</value>
|
<value>68</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>臺北市信義區</areaDesc>
|
<area>
|
||||||
|
<areaDesc>新竹市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>6300200</value>
|
<value>10018</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>桃園市新屋區</areaDesc>
|
<area>
|
||||||
|
<areaDesc>新竹縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>6801100</value>
|
<value>10004</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>新竹縣竹東鎮</areaDesc>
|
<area>
|
||||||
|
<areaDesc>苗栗縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000402</value>
|
<value>10005</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>臺北市文山區</areaDesc>
|
<area>
|
||||||
|
<areaDesc>臺中市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>6300800</value>
|
<value>66</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>新竹縣竹北市</areaDesc>
|
<area>
|
||||||
|
<areaDesc>彰化縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000401</value>
|
<value>10007</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>新竹縣新豐鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>雲林縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000406</value>
|
<value>10009</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>臺北市松山區</areaDesc>
|
<area>
|
||||||
|
<areaDesc>南投縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>6300100</value>
|
<value>10008</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>新竹縣關西鎮</areaDesc>
|
<area>
|
||||||
|
<areaDesc>嘉義縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000404</value>
|
<value>10010</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>新竹縣湖口鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>嘉義市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000405</value>
|
<value>10020</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣冬山鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>臺南市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000208</value>
|
<value>67</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣五結鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>高雄市</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000209</value>
|
<value>64</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣頭城鎮</areaDesc>
|
<area>
|
||||||
|
<areaDesc>屏東縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000204</value>
|
<value>10013</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣礁溪鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>宜蘭縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000205</value>
|
<value>10002</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣壯圍鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>花蓮縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000206</value>
|
<value>10015</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣員山鄉</areaDesc>
|
<area>
|
||||||
|
<areaDesc>臺東縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000207</value>
|
<value>10014</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣宜蘭市</areaDesc>
|
<area>
|
||||||
|
<areaDesc>澎湖縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000201</value>
|
<value>10016</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>宜蘭縣羅東鎮</areaDesc>
|
<area>
|
||||||
|
<areaDesc>金門縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>1000202</value>
|
<value>09020</value>
|
||||||
</geocode>
|
</geocode>
|
||||||
</area><area>
|
</area>
|
||||||
<areaDesc>臺北市大安區</areaDesc>
|
<area>
|
||||||
|
<areaDesc>連江縣</areaDesc>
|
||||||
<geocode>
|
<geocode>
|
||||||
<valueName>Taiwan_Geocode_103</valueName>
|
<valueName>Taiwan_Geocode_103</valueName>
|
||||||
<value>6300300</value>
|
<value>09007</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>
|
|
||||||
</geocode>
|
</geocode>
|
||||||
</area>
|
</area>
|
||||||
</info>
|
</info>
|
||||||
|
|
||||||
</alert>
|
</alert>
|
@ -208,6 +208,140 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal center 維修-->
|
||||||
|
<div class="modal fade" id="alr_opeRecModal_2" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 id="alr_opeRecTitle" class="modal-title">
|
||||||
|
</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true"><i class="fal fa-times"></i></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form id="alr_opeRecForm_2">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpNumber_2">表單編號</label>
|
||||||
|
<input type="text" id="alr_inpNumber_2" name="" class="form-control" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpErrCode_2">異常編號</label>
|
||||||
|
<select class="form-control" id="alr_inpErrCode_2" name="alr_inpErrCode_2" disabled>
|
||||||
|
<option value=''>未選擇</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpStaTime_2">預計開始時間</label>
|
||||||
|
<input type="date" id="alr_inpStaTime_2" name="alr_inpStaTime_2" class="form-control" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpWorTyp_2">項目</label>
|
||||||
|
<select class="form-control custom-select-ri" id="alr_inpWorTyp_2" name="alr_inpWorTyp_2" disabled>
|
||||||
|
<option value=2 selected>維修</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpFixDo_2">維修項目</label>
|
||||||
|
<input type="text" id="alr_inpFixDo_2" name="alr_inpFixDo_2" class="form-control" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpFixDoCode_2">維修項目代碼(設備編號)</label>
|
||||||
|
<select class="form-control" id="alr_inpFixDoCode_2" name="alr_inpFixDoCode_2" disabled>
|
||||||
|
<option value=''>未選擇</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpFixFirm_2">負責廠商</label>
|
||||||
|
<select class="form-control" id="alr_inpFixFirm_2" name="alr_inpFixFirm_2" disabled>
|
||||||
|
<option value=''>未選擇</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpStatus_2">狀態</label>
|
||||||
|
<div class="form-control" id="alr_inpStatus_2">
|
||||||
|
<div class="row container">
|
||||||
|
<div class="">
|
||||||
|
<input class="custom-radio-input" type="radio" name="alr_inpSta_2" id="alr_inpSta_2_0" value="0" data-value="0" checked disabled>
|
||||||
|
<label class="form-label" for="alr_inpSta_0">未完成</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="px-4">
|
||||||
|
<input class="custom-radio-input" type="radio" name="alr_inpSta_2" id="alr_inpSta_2_1" value="1" data-value="1" disabled>
|
||||||
|
<label class="form-label" for="alr_inpSta_1">完成</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpWorPerId_2">工作人員編號</label>
|
||||||
|
<select class="form-control" id="alr_inpWorPerId_2" name="alr_inpWorPerId_2" disabled>
|
||||||
|
<option value=''>未選擇</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpNotice_2">注意事項</label>
|
||||||
|
<textarea class="form-control" type="text" id="alr_inpNotice_2" name="alr_inpNotice_2" rows="7" disabled></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label" for="alr_inpDescription_2">結果描述</label>
|
||||||
|
<textarea class="form-control" type="text" id="alr_inpDescription_2" name="alr_inpDescription_2" rows="7" disabled></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label">上傳檔案</label>
|
||||||
|
<div id='alr_ope_forImage_2' class="col-sm-12 forimage mt-2 p-0">
|
||||||
|
</div>
|
||||||
|
<div id='alr_ope_forFile_2' class="col-sm-12 forfile mt-2 p-0">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group dropzone" id="ope_dropZone_2">
|
||||||
|
<div class="dz-message">
|
||||||
|
<div class="drag-icon-cph">
|
||||||
|
<i class="material-icons">backup</i>
|
||||||
|
</div>
|
||||||
|
<h3>選擇一個文件或拖放到這裡</h3>
|
||||||
|
<p class="mb-0 col-grey">
|
||||||
|
PDF檔案不超過 10MB
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="fallback">
|
||||||
|
<input name="file" type="file" multiple disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" id="alr_OpeRecCanBtn_2" data-dismiss="modal">關閉</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
pageAct.selSysMain = null;
|
pageAct.selSysMain = null;
|
||||||
pageAct.selSysSub = null;
|
pageAct.selSysSub = null;
|
||||||
@ -217,6 +351,8 @@
|
|||||||
pageAct.alrSelSysMain = []
|
pageAct.alrSelSysMain = []
|
||||||
pageAct.alrSelSysSub = [];
|
pageAct.alrSelSysSub = [];
|
||||||
pageAct.selAllSysSub = false;
|
pageAct.selAllSysSub = false;
|
||||||
|
pageAct.addSelMain = null;
|
||||||
|
pageAct.addSelSub = null;
|
||||||
first = true;
|
first = true;
|
||||||
// let dataAlarm = [];
|
// let dataAlarm = [];
|
||||||
var historyTable = null;
|
var historyTable = null;
|
||||||
@ -368,7 +504,10 @@
|
|||||||
let alr_tableData = alr_table.row(alr_elem).data();
|
let alr_tableData = alr_table.row(alr_elem).data();
|
||||||
$('#inpErrCode').html(`<option value = ${alr_tableData.uuid}>${alr_tableData.msgText}</option>`);
|
$('#inpErrCode').html(`<option value = ${alr_tableData.uuid}>${alr_tableData.msgText}</option>`);
|
||||||
$('#inpStaTime').val(displayDate(new Date(Date.now()), "date").replaceAll('/', '-'));
|
$('#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] + "_"
|
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] + "_"
|
+ alr_tableData.alarmClass.toString().split('_')[1] + "_" + alr_tableData.buildingFloorName_zh.toString().split('-')[1] + "_" + alr_tableData.sourceName_zh.toString().split('-')[0] + "_"
|
||||||
@ -387,6 +526,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
onEvent('click', '#alr_OpeRecSendBtn', function () {
|
onEvent('click', '#alr_OpeRecSendBtn', function () {
|
||||||
|
|
||||||
let form = $("#alr_opeRecForm");
|
let form = $("#alr_opeRecForm");
|
||||||
$(form).validate({
|
$(form).validate({
|
||||||
rules: {
|
rules: {
|
||||||
@ -413,8 +553,8 @@
|
|||||||
fd.append("error_code", $('#inpErrCode').val());
|
fd.append("error_code", $('#inpErrCode').val());
|
||||||
fd.append("location", "台北" + $('#buiActDrop').text() + pageAct.floor);
|
fd.append("location", "台北" + $('#buiActDrop').text() + pageAct.floor);
|
||||||
fd.append("location_code", pageAct.AreaTag + pageAct.buiTag + 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_layer2", pageAct.addSelMain);
|
||||||
fd.append("device_system_category_layer3", pageAct.selSysSub);
|
fd.append("device_system_category_layer3", pageAct.addSelSub);
|
||||||
fd.append("work_type", parseInt($('#inpWorTyp').val()));
|
fd.append("work_type", parseInt($('#inpWorTyp').val()));
|
||||||
fd.append("fix_do", $('#inpFixDo').val());
|
fd.append("fix_do", $('#inpFixDo').val());
|
||||||
fd.append("fix_do_code", $('#inpFixDoCode').val());
|
fd.append("fix_do_code", $('#inpFixDoCode').val());
|
||||||
@ -735,7 +875,7 @@
|
|||||||
{
|
{
|
||||||
"title": "設備名稱",
|
"title": "設備名稱",
|
||||||
"data": "sourceName_zh",
|
"data": "sourceName_zh",
|
||||||
render: (data) => {
|
"render" : function (data) {
|
||||||
return allDevices.find(d => d.device_number === data)?.full_name || ""
|
return allDevices.find(d => d.device_number === data)?.full_name || ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -771,8 +911,11 @@
|
|||||||
{
|
{
|
||||||
"title": "派工/維運單號",
|
"title": "派工/維運單號",
|
||||||
"data": "formId",
|
"data": "formId",
|
||||||
"render": function (data) {
|
"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">+ 維修單</a></td>`;
|
|
||||||
|
return data != null
|
||||||
|
? `<td><a href="#" id="readOpeRecBtn" data-toggle="modal" data-target="#alr_opeRecModal_2" data-formid="${data}">${data}</a></td>`
|
||||||
|
: `<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 +924,7 @@
|
|||||||
$(loadEle).Loading("close");
|
$(loadEle).Loading("close");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function AlertList(data) {
|
function AlertList(data) {
|
||||||
objSendData.Data = [];
|
objSendData.Data = [];
|
||||||
$.each(data, function (i, v) {
|
$.each(data, function (i, v) {
|
||||||
@ -802,7 +946,8 @@
|
|||||||
function selDevice() {
|
function selDevice() {
|
||||||
let url = baseApiUrl + "/operation/DevList";
|
let url = baseApiUrl + "/operation/DevList";
|
||||||
let lsst = [];
|
let lsst = [];
|
||||||
$('input[data-type=sub]').map(function (i, v) { lsst.push($(v).prop('id')); });
|
lsst.push(pageAct.addSelSub);
|
||||||
|
//$('input[data-type=sub]').map(function (i, v) { lsst.push($(v).prop('id')); });
|
||||||
sendData = {
|
sendData = {
|
||||||
device_area_tag: pageAct.AreaTag,
|
device_area_tag: pageAct.AreaTag,
|
||||||
device_building_tag: pageAct.buiTag,
|
device_building_tag: pageAct.buiTag,
|
||||||
@ -815,6 +960,7 @@
|
|||||||
} else {
|
} else {
|
||||||
strHtml = ``;
|
strHtml = ``;
|
||||||
$("#inpFixDoCode").html();
|
$("#inpFixDoCode").html();
|
||||||
|
$("#alr_inpFixDoCode_2").html();
|
||||||
$.each(res.data, (index, roleObj) => {
|
$.each(res.data, (index, roleObj) => {
|
||||||
strHtml += `<option value='${roleObj.device_number}' data-floor=${roleObj.device_floor_tag} data-main=${roleObj.device_system_tag} data-sub=${roleObj.device_name_tag} hidden>${roleObj.device_name}</option>`;
|
strHtml += `<option value='${roleObj.device_number}' data-floor=${roleObj.device_floor_tag} data-main=${roleObj.device_system_tag} data-sub=${roleObj.device_name_tag} hidden>${roleObj.device_name}</option>`;
|
||||||
|
|
||||||
@ -826,6 +972,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
$("#inpFixDoCode").html(strHtml);
|
$("#inpFixDoCode").html(strHtml);
|
||||||
|
$("#alr_inpFixDoCode_2").html(strHtml);
|
||||||
}
|
}
|
||||||
}, null, "POST").send();
|
}, null, "POST").send();
|
||||||
}
|
}
|
||||||
@ -837,31 +984,38 @@
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
$("#inpWorPerId").html();
|
$("#inpWorPerId").html();
|
||||||
|
$("#alr_inpWorPerId_2").html();
|
||||||
strHtml = ``;
|
strHtml = ``;
|
||||||
strHtml += `<option value=''>未選擇</option>`;
|
strHtml += `<option value=''>未選擇</option>`;
|
||||||
$.each(res.data, (index, roleObj) => {
|
$.each(res.data, (index, roleObj) => {
|
||||||
strHtml += `<option value='${roleObj.userinfo_guid}'>${roleObj.full_name}</option>`;
|
strHtml += `<option value='${roleObj.userinfo_guid}'>${roleObj.full_name}</option>`;
|
||||||
})
|
})
|
||||||
$("#inpWorPerId").html(strHtml);
|
$("#inpWorPerId").html(strHtml);
|
||||||
|
$("#alr_inpWorPerId_2").html(strHtml);
|
||||||
}
|
}
|
||||||
}, null, "POST").send();
|
}, null, "POST").send();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selOpeFir() {
|
function selOpeFir() {
|
||||||
let url = baseApiUrl + "/operation/OpeFirSel";
|
let url = baseApiUrl + "/operation/OpeFirSel";
|
||||||
objSendData.Data = { sub_system_tag: $('input[data-type=sub]').map(function (i, v) { return $(v).prop('id'); }).toArray() };
|
let lsst = [];
|
||||||
|
lsst.push(pageAct.addSelSub);
|
||||||
|
objSendData.Data = { sub_system_tag: lsst };
|
||||||
|
//objSendData.Data = { sub_system_tag: $('input[data-type=sub]').map(function (i, v) { return $(v).prop('id'); }).toArray() };
|
||||||
// console.log(objSendData.Data)
|
// console.log(objSendData.Data)
|
||||||
ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
|
ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
|
||||||
if (!res || res.code != "0000" || !res.data) {
|
if (!res || res.code != "0000" || !res.data) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$("#inpFixFirm").html();
|
$("#inpFixFirm").html();
|
||||||
|
$("#alr_inpFixFirm_2").html();
|
||||||
strHtml = ``;
|
strHtml = ``;
|
||||||
strHtml += `<option value=''>未選擇</option>`;
|
strHtml += `<option value=''>未選擇</option>`;
|
||||||
$.each(res.data, (index, roleObj) => {
|
$.each(res.data, (index, roleObj) => {
|
||||||
strHtml += `<option value='${roleObj.id}'>${roleObj.name}</option>`;
|
strHtml += `<option value='${roleObj.id}'>${roleObj.name}</option>`;
|
||||||
})
|
})
|
||||||
$("#inpFixFirm").html(strHtml);
|
$("#inpFixFirm").html(strHtml);
|
||||||
|
$("#alr_inpFixFirm_2").html(strHtml);
|
||||||
}
|
}
|
||||||
}, null, "POST").send();
|
}, null, "POST").send();
|
||||||
}
|
}
|
||||||
@ -925,4 +1079,111 @@
|
|||||||
$.post(window.location.origin + '/obix/alarm/' + devUuid + '/ack', '<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>', null, "text");
|
$.post(window.location.origin + '/obix/alarm/' + devUuid + '/ack', '<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>', null, "text");
|
||||||
getData();
|
getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEvent('click', '#readOpeRecBtn', function () {
|
||||||
|
|
||||||
|
|
||||||
|
$('#alr_ope_forImage').html('');
|
||||||
|
$('#alr_ope_forFile').html('');
|
||||||
|
$('#alr_ope_forImage_2').html('');
|
||||||
|
$('#alr_ope_forFile_2').html('');
|
||||||
|
$('#alr_inpStatus_2 [name=alr_inpSta_2]').prop("disabled", false);
|
||||||
|
|
||||||
|
pageAct.imageFile = [];
|
||||||
|
$('#alr_opeRecTitle').html("讀取維修");
|
||||||
|
let url = baseApiUrl + "/operation/OpeRecRead";
|
||||||
|
objSendData.Data = { formId: $(this).data("formid") };
|
||||||
|
ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
|
||||||
|
if (!res || res.code != "0000" || !res.data) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pageAct.sysSub = res.data.device_system_category_layer3;
|
||||||
|
pageAct.number = res.data.fix_do_code;
|
||||||
|
pageAct.addSelSub = res.data.device_system_category_layer3;
|
||||||
|
selUser();
|
||||||
|
selDevice();
|
||||||
|
selOpeFir();
|
||||||
|
errCodeList();
|
||||||
|
$('#alr_inpNumber_2').val(res.data.formId);
|
||||||
|
$('#alr_inpWorTyp_2').val(res.data.work_type);
|
||||||
|
$('#alr_inpFixDo_2').val(res.data.fix_do);
|
||||||
|
$('#alr_inpFixDoCode_2').val(res.data.fix_do_code);
|
||||||
|
$('#alr_inpFixFirm_2').val(res.data.fix_firm);
|
||||||
|
$('#alr_inpStatus_2 [name=alr_inpSta_2][data-value=' + res.data.status + ']').click();
|
||||||
|
$('#alr_inpStatus_2 [name=alr_inpSta_2][data-value=' + (res.data.status > 0 ? 0 : 1) + ']').prop("disabled", true);
|
||||||
|
$('#alr_inpWorPerId_2').val(res.data.work_person_id);
|
||||||
|
$('#alr_inpStaTime_2').val(displayDate(res.data.start_time, 'date').replaceAll('/', '-'));
|
||||||
|
$('#alr_inpNotice_2').val(res.data.notice == null ? "" : res.data.notice);
|
||||||
|
$('#alr_inpDescription_2').val(res.data.description == null ? "" : res.data.description);
|
||||||
|
|
||||||
|
ope_imgHtml = null;
|
||||||
|
$.each(res.data.lorf, function (i, v) {
|
||||||
|
|
||||||
|
let extName = v.ori_file_name.split('.')[1];
|
||||||
|
|
||||||
|
if (/\.(jpe?g|png|gif)$/i.test(v.ori_file_name)) {
|
||||||
|
|
||||||
|
ope_colI = creEle("i", null, null, null, ["fa fa-times"]);
|
||||||
|
ope_colBtn = creBtn(null, null, "btnDelImg", ["btn-dark m-1"]);
|
||||||
|
ope_colImg = creImg("img", null, null, null, null, { filename: v.ori_file_name, savename: v.save_file_name }, { style: "margin-left: 30px; margin-top: 10px", height: "70px", width: "70px", src: baseApiUrl + "/upload/operation/" + v.save_file_name + "." + extName });
|
||||||
|
ope_colA = creEle("a", null, null, null, null, null, { href: baseApiUrl + "/upload/operation/" + v.save_file_name + "." + extName, download: v.ori_file_name, target: "_blank" });
|
||||||
|
ope_imgHtml = creEle("span", null, null, null, ["file-item m-1"], { id: v.id }, null);
|
||||||
|
|
||||||
|
ope_colA.append(ope_colImg);
|
||||||
|
ope_imgHtml.append(ope_colA);
|
||||||
|
ope_colBtn.append(ope_colI);
|
||||||
|
ope_imgHtml.append(ope_colBtn);
|
||||||
|
$('#alr_ope_forImage_2').append(ope_imgHtml ? ope_imgHtml.outerHtml() : null);
|
||||||
|
}
|
||||||
|
else if (/\.(xls?x|doc?x|ptt?x|pdf|zip|rar|7zip|txt|odt|xml|rtf|ods|odp|pps?x)$/i.test(v.ori_file_name)) {
|
||||||
|
icons = null
|
||||||
|
if (extName == "xlsx" || extName == "xls")
|
||||||
|
icons = "fas fa-file-excel";
|
||||||
|
else if (extName == "pdf" || extName == "ods")
|
||||||
|
icons = "fas fa-file-pdf";
|
||||||
|
else if (extName == "doc" || extName == "docx")
|
||||||
|
icons = "fas fa-file-word";
|
||||||
|
else
|
||||||
|
icons = "fas fa-file-alt";
|
||||||
|
|
||||||
|
ope_colI = creEle("i", null, null, null, ["fa fa-times"]);
|
||||||
|
ope_colBtn = creBtn(null, null, "btnDelImg", ["btn-dark m-1"]);
|
||||||
|
ope_colBtn.append(ope_colI);
|
||||||
|
|
||||||
|
ope_colI = creEle("i", null, null, null, [icons + " fa-3x m-1"]);
|
||||||
|
ope_colA = creEle("a", v.ori_file_name, null, null, null, null, { href: baseApiUrl + "/upload/operation/" + v.save_file_name + "." + extName, download: v.ori_file_name, target: "_blank" });
|
||||||
|
ope_imgHtml = creEle("div", null, null, null, ["file-item"], { id: v.id }, null);
|
||||||
|
|
||||||
|
ope_imgHtml.append(ope_colI);
|
||||||
|
ope_imgHtml.append(ope_colA);
|
||||||
|
ope_imgHtml.append(ope_colBtn);
|
||||||
|
$('#alr_ope_forFile_2').append(ope_imgHtml ? ope_imgHtml.outerHtml() : null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, null, "POST").send()
|
||||||
|
});
|
||||||
|
|
||||||
|
function errCodeList() {
|
||||||
|
$(loadEle).Loading("start");
|
||||||
|
let _pathArr = pageAct.number.split("_"); //TPE_B1_ELEV_EL_R2F_NA_ELEV1_N1
|
||||||
|
let _devicePath = _pathArr[0] + "_" + _pathArr[1] + "_" + _pathArr[2] + "_" + _pathArr[3] + "_" + _pathArr[4] + "_" + _pathArr[5];
|
||||||
|
getOneDeviceAlarmTop10ByBaja(_devicePath, callbackForErr);
|
||||||
|
$(loadEle).Loading("close");
|
||||||
|
}
|
||||||
|
|
||||||
|
function callbackForErr(res) {
|
||||||
|
res = JSON.parse(res);
|
||||||
|
strHtml = ``;
|
||||||
|
|
||||||
|
$.each(res.data, function (i, v) {
|
||||||
|
msg = v.msgText != null ? ($.trim(v.msgText.toString()).length > 0 ? v.msgText.split(':')[0] : '') : '';
|
||||||
|
strHtml += `<option value=${v.uuid}>${v.uuid}</option>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.count > 0)
|
||||||
|
$('#alr_inpErrCode_2').html(strHtml);
|
||||||
|
|
||||||
|
$(loadEle).Loading("close");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
@ -190,7 +190,7 @@ class YTNoticeBlock {
|
|||||||
checkCanShow = function (notice = null) {
|
checkCanShow = function (notice = null) {
|
||||||
let lastNoticeOffset = $(this.noticeContainer).find(".toast").last().offset();
|
let lastNoticeOffset = $(this.noticeContainer).find(".toast").last().offset();
|
||||||
if ($(this.noticeContainer).find(".toast").last().length == 0) {
|
if ($(this.noticeContainer).find(".toast").last().length == 0) {
|
||||||
return true;
|
return notice.canShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($(notice.obj.container).is(":visible")) {
|
if ($(notice.obj.container).is(":visible")) {
|
||||||
|
@ -67,5 +67,35 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
}
|
}
|
||||||
return Ok(apiResult);
|
return Ok(apiResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/Dashboard/GetTotalElec")]
|
||||||
|
public async Task<ActionResult<ApiResult<List<TotalElec>>>> GetTotalElec()
|
||||||
|
{
|
||||||
|
ApiResult<List<TotalElec>> apiResult = new ApiResult<List<TotalElec>>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sqlString = $@"SELECT
|
||||||
|
system_key AS 'building_tag',
|
||||||
|
system_value AS 'device_number',
|
||||||
|
system_remark AS 'remark'
|
||||||
|
FROM variable
|
||||||
|
WHERE
|
||||||
|
system_type = 'dashboard_total_elec'
|
||||||
|
AND deleted = '0'";
|
||||||
|
var ess = await backendRepository.GetAllAsync<TotalElec>(sqlString);
|
||||||
|
|
||||||
|
apiResult.Code = "0000";
|
||||||
|
apiResult.Data = ess;
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
apiResult.Code = "9999";
|
||||||
|
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
|
||||||
|
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
|
||||||
|
return Ok(apiResult);
|
||||||
|
}
|
||||||
|
return Ok(apiResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,16 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
string deviceQue = "";
|
||||||
|
string disasQue = "";
|
||||||
|
if (selectdevice.selectbuilding != null && selectdevice.selectbuilding.Count > 0)
|
||||||
|
deviceQue += $" AND d.device_building_tag in @building_tag ";
|
||||||
|
if (selectdevice.select_Floors != null && selectdevice.select_Floors.Count > 0)
|
||||||
|
deviceQue += $" AND d.device_floor_tag in @floor ";
|
||||||
|
if (selectdevice.select_Layer3 != null && selectdevice.select_Layer3.Count > 0)
|
||||||
|
deviceQue += $" AND d.device_name_tag IN @layer3 ";
|
||||||
|
if (selectdevice.select_disasters != null && selectdevice.select_disasters.Count > 0)
|
||||||
|
disasQue = " where dd.device_system_value IN @disasters ";
|
||||||
|
|
||||||
var sqlString = @$"select
|
var sqlString = @$"select
|
||||||
d.device_guid,
|
d.device_guid,
|
||||||
@ -140,9 +150,8 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
(SELECT *
|
(SELECT *
|
||||||
FROM device d
|
FROM device d
|
||||||
WHERE d.deleted = 0
|
WHERE d.deleted = 0
|
||||||
AND d.device_building_tag = '{selectdevice.selectbuilding}'
|
{deviceQue}
|
||||||
AND d.device_floor_tag in @floor
|
) d
|
||||||
AND d.device_name_tag IN @layer3) d
|
|
||||||
left join floor on floor.full_name = d.device_floor_tag and floor.building_tag = d.device_building_tag
|
left join floor on floor.full_name = d.device_floor_tag and floor.building_tag = d.device_building_tag
|
||||||
left join (
|
left join (
|
||||||
SELECT
|
SELECT
|
||||||
@ -158,10 +167,11 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
left join device_disaster dd on dd.device_guid = d.device_guid
|
left join device_disaster dd on dd.device_guid = d.device_guid
|
||||||
left join (select * from variable v where v.system_type = 'disaster') ddd on ddd.system_value = dd.device_system_value
|
left join (select * from variable v where v.system_type = 'disaster') ddd on ddd.system_value = dd.device_system_value
|
||||||
LEFT JOIN building b ON b.deleted = 0 AND d.device_building_tag = b.building_tag
|
LEFT JOIN building b ON b.deleted = 0 AND d.device_building_tag = b.building_tag
|
||||||
where dd.device_system_value IN @disasters
|
{disasQue}
|
||||||
ORDER BY d.device_number
|
ORDER BY d.device_number
|
||||||
";
|
";
|
||||||
Variable = await backendRepository.GetAllAsync<deviceMenu>(sqlString, new { disasters= selectdevice.select_disasters, floor = selectdevice.select_Floors, layer3 = selectdevice.select_Layer3 });
|
Variable = await backendRepository.GetAllAsync<deviceMenu>(sqlString, new { disasters= selectdevice.select_disasters, building_tag = selectdevice.selectbuilding,
|
||||||
|
floor = selectdevice.select_Floors, layer3 = selectdevice.select_Layer3 });
|
||||||
|
|
||||||
apiResult.Code = "0000";
|
apiResult.Code = "0000";
|
||||||
apiResult.Data = Variable;
|
apiResult.Data = Variable;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using FrontendWebApi.Models;
|
using FrontendWebApi.Models;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MySqlX.XDevAPI;
|
||||||
using NPOI.SS.UserModel;
|
using NPOI.SS.UserModel;
|
||||||
using NPOI.XSSF.UserModel;
|
using NPOI.XSSF.UserModel;
|
||||||
using Repository.BackendRepository.Interface;
|
using Repository.BackendRepository.Interface;
|
||||||
@ -75,9 +76,21 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
string sqlGroup = "";
|
string sqlGroup = "";
|
||||||
string sqlAvgRawData = "";
|
string sqlAvgRawData = "";
|
||||||
string dbDateName = startTime.Split("-")[0].ToString().PadLeft(4, '0') + startTime.Split("-")[1].ToString().PadLeft(2, '0');
|
string dbDateName = startTime.Split("-")[0].ToString().PadLeft(4, '0') + startTime.Split("-")[1].ToString().PadLeft(2, '0');
|
||||||
|
string buildingSql = "";
|
||||||
|
string tag_quantity = await backendRepository.GetOneAsync<string>("select system_value from variable where system_type = 'obixConfig' and system_key = 'tag_quantity' and deleted = 0");
|
||||||
|
|
||||||
|
if (tag_quantity == "5")
|
||||||
|
buildingSql = " and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag ";
|
||||||
|
else
|
||||||
|
buildingSql = " and SUBSTRING_INDEX(SUBSTRING_INDEX(device_number, '_', 2), '_', -1) = @building_tag ";
|
||||||
|
|
||||||
if (input.floor_tag.Count > 0)
|
if (input.floor_tag.Count > 0)
|
||||||
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
|
{
|
||||||
|
if (tag_quantity == "5")
|
||||||
|
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
|
||||||
|
else
|
||||||
|
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 5), '_', -1) in @floor_tag ";
|
||||||
|
}
|
||||||
|
|
||||||
if (input.tableType == "year")
|
if (input.tableType == "year")
|
||||||
{
|
{
|
||||||
@ -88,6 +101,15 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata, start_timestamp, end_timestamp ";
|
sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata, start_timestamp, end_timestamp ";
|
||||||
|
|
||||||
var table = input.tableType == "year" ? "archive_electric_meter_month" : "archive_electric_meter_" + input.tableType + (input.tableType == "day" ? "_" + dbDateName : "");
|
var table = input.tableType == "year" ? "archive_electric_meter_month" : "archive_electric_meter_" + input.tableType + (input.tableType == "day" ? "_" + dbDateName : "");
|
||||||
|
var schema = await backendRepository.GetOneAsync<string>($"select system_value from variable where system_type = 'project_name'");
|
||||||
|
var isTable = await backendRepository.GetOneAsync<string>($"select table_name from information_schema.tables where table_name = '{table}' and table_schema = '{schema.Split('/')[0]}'");
|
||||||
|
if (string.IsNullOrEmpty(isTable)) //check for has table or not
|
||||||
|
{
|
||||||
|
apiResult.Code = "0000";
|
||||||
|
apiResult.Data = new List<HydroMeterOutput>() { };
|
||||||
|
return Ok(apiResult);
|
||||||
|
}
|
||||||
|
|
||||||
var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
|
var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
|
||||||
var aemmEndDate = input.tableType == "year" ? $"year(DATE_ADD(fd.date, INTERVAL +1 {input.tableType}))" : $"DATE_ADD(fd.date, INTERVAL +1 {input.tableType})";
|
var aemmEndDate = input.tableType == "year" ? $"year(DATE_ADD(fd.date, INTERVAL +1 {input.tableType}))" : $"DATE_ADD(fd.date, INTERVAL +1 {input.tableType})";
|
||||||
var aemmStaDate = input.tableType == "year" ? "year(fd.date)" : "fd.date";
|
var aemmStaDate = input.tableType == "year" ? "year(fd.date)" : "fd.date";
|
||||||
@ -104,7 +126,7 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
(
|
(
|
||||||
select device_number
|
select device_number
|
||||||
from {table}
|
from {table}
|
||||||
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag
|
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' {buildingSql}
|
||||||
{sqlWhere}
|
{sqlWhere}
|
||||||
group by device_number
|
group by device_number
|
||||||
) dn
|
) dn
|
||||||
@ -113,23 +135,44 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
left join (
|
left join (
|
||||||
select device_number, {sqlAvgRawData}
|
select device_number, {sqlAvgRawData}
|
||||||
from {table}
|
from {table}
|
||||||
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag
|
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'KWH' {buildingSql}
|
||||||
{sqlWhere} {sqlGroup}
|
{sqlWhere} {sqlGroup}
|
||||||
) aemm on aemm.start_timestamp >= {aemmStaDate} and aemm.end_timestamp < {aemmEndDate} and aemm.device_number = fd.device_number
|
) aemm on aemm.start_timestamp >= {aemmStaDate} and aemm.end_timestamp < {aemmEndDate} and aemm.device_number = fd.device_number
|
||||||
order by fd.device_number, fd.date";
|
order by fd.device_number, fd.date";
|
||||||
var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
|
var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
|
||||||
new { startTime = startTime, endtime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat });
|
new { startTime = startTime, endtime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat });
|
||||||
var list = rawData
|
|
||||||
|
List<HydroMeterOutput> list = new List<HydroMeterOutput>();
|
||||||
|
if (tag_quantity == "5")
|
||||||
|
{
|
||||||
|
list = rawData
|
||||||
.GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4] })
|
.GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4] })
|
||||||
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
|
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list = rawData
|
||||||
|
.GroupBy(x => new { building_tag = x.device_number.Split("_")[1], floor_tag = x.device_number.Split("_")[4], device_serial_tag = x.device_number.Split("_")[7] })
|
||||||
|
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var l in list)
|
foreach (var l in list)
|
||||||
{
|
{
|
||||||
l.rawData = new List<HydroMeterRawDataOutput>();
|
l.rawData = new List<HydroMeterRawDataOutput>();
|
||||||
l.rawData.AddRange(
|
if (tag_quantity == "5")
|
||||||
rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
|
{
|
||||||
);
|
l.rawData.AddRange(
|
||||||
|
rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l.rawData.AddRange(
|
||||||
|
rawData.Where(x => x.device_number.Split("_")[1] == l.building_tag && x.device_number.Split("_")[4] == l.floor_tag && x.device_number.Split("_")[7] == l.device_serial_tag)
|
||||||
|
);
|
||||||
|
}
|
||||||
l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
|
l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
|
||||||
new { building_tag = l.building_tag });
|
new { building_tag = l.building_tag });
|
||||||
l.total = l.rawData.Sum(x => x.avg_rawdata).ToString();
|
l.total = l.rawData.Sum(x => x.avg_rawdata).ToString();
|
||||||
@ -204,8 +247,21 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
string sqlWhere = "";
|
string sqlWhere = "";
|
||||||
string sqlGroup = "";
|
string sqlGroup = "";
|
||||||
string sqlAvgRawData = "";
|
string sqlAvgRawData = "";
|
||||||
|
string buildingSql = "";
|
||||||
|
string tag_quantity = await backendRepository.GetOneAsync<string>("select system_value from variable where system_type = 'obixConfig' and system_key = 'tag_quantity' and deleted = 0");
|
||||||
|
|
||||||
|
if (tag_quantity == "5")
|
||||||
|
buildingSql = " and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag ";
|
||||||
|
else
|
||||||
|
buildingSql = " and SUBSTRING_INDEX(SUBSTRING_INDEX(device_number, '_', 2), '_', -1) = @building_tag ";
|
||||||
|
|
||||||
if (input.floor_tag.Count > 0)
|
if (input.floor_tag.Count > 0)
|
||||||
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
|
{
|
||||||
|
if (tag_quantity == "5")
|
||||||
|
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 3), '_', -1) in @floor_tag ";
|
||||||
|
else
|
||||||
|
sqlWhere = $@" and substring_index(substring_index(device_number, '_', 5), '_', -1) in @floor_tag ";
|
||||||
|
}
|
||||||
|
|
||||||
if (input.tableType == "year")
|
if (input.tableType == "year")
|
||||||
{
|
{
|
||||||
@ -216,7 +272,18 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata, start_timestamp, end_timestamp ";
|
sqlAvgRawData = " round(avg_rawdata, 2) as avg_rawdata, start_timestamp, end_timestamp ";
|
||||||
|
|
||||||
var table = input.tableType == "year" ? "archive_electric_meter_month" : "archive_electric_meter_" + input.tableType + (input.tableType == "day" ? "_" + dbDateName : "");
|
var table = input.tableType == "year" ? "archive_electric_meter_month" : "archive_electric_meter_" + input.tableType + (input.tableType == "day" ? "_" + dbDateName : "");
|
||||||
|
var schema = await backendRepository.GetOneAsync<string>($"select system_value from variable where system_type = 'project_name'");
|
||||||
|
var isTable = await backendRepository.GetOneAsync<string>($"select table_name from information_schema.tables where table_name = '{table}' and table_schema = '{schema.Split('/')[0]}'");
|
||||||
|
if (string.IsNullOrEmpty(isTable)) //check for has table or not
|
||||||
|
{
|
||||||
|
apiResult.Code = "0000";
|
||||||
|
apiResult.Data = new List<HydroMeterOutput>() { };
|
||||||
|
return Ok(apiResult);
|
||||||
|
}
|
||||||
|
|
||||||
var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
|
var dateFormat = input.tableType == "day" || input.tableType == "week" ? "%Y-%m-%d" : input.tableType == "month" ? "%Y-%m" : input.tableType == "year" ? "%Y" : null;
|
||||||
|
var aemmEndDate = input.tableType == "year" ? $"year(DATE_ADD(fd.date, INTERVAL +1 {input.tableType}))" : $"DATE_ADD(fd.date, INTERVAL +1 {input.tableType})";
|
||||||
|
var aemmStaDate = input.tableType == "year" ? "year(fd.date)" : "fd.date";
|
||||||
var sql = $@"set @i = -1;
|
var sql = $@"set @i = -1;
|
||||||
select fd.device_number, aemm.avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp
|
select fd.device_number, aemm.avg_rawdata, DATE_FORMAT(fd.date, @dateFormat) as timestamp
|
||||||
from (
|
from (
|
||||||
@ -230,7 +297,7 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
(
|
(
|
||||||
select device_number
|
select device_number
|
||||||
from {table}
|
from {table}
|
||||||
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag
|
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' {buildingSql}
|
||||||
{sqlWhere}
|
{sqlWhere}
|
||||||
group by device_number
|
group by device_number
|
||||||
) dn
|
) dn
|
||||||
@ -239,24 +306,45 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
left join (
|
left join (
|
||||||
select device_number, {sqlAvgRawData}
|
select device_number, {sqlAvgRawData}
|
||||||
from {table}
|
from {table}
|
||||||
where start_timestamp >= @startTime and end_timestamp < @endTime and point = 'RCV' and SUBSTRING_INDEX(device_number, '_', 1) = @building_tag
|
where start_timestamp >= {aemmStaDate} and end_timestamp < {aemmEndDate} and point = 'RCV' {buildingSql}
|
||||||
{sqlWhere} {sqlGroup}
|
{sqlWhere} {sqlGroup}
|
||||||
) aemm on aemm.start_timestamp >= fd.date and aemm.end_timestamp < DATE_ADD(fd.date, INTERVAL +1 {input.tableType}) and aemm.device_number = fd.device_number
|
) aemm on aemm.start_timestamp >= fd.date and aemm.end_timestamp < DATE_ADD(fd.date, INTERVAL +1 {input.tableType}) and aemm.device_number = fd.device_number
|
||||||
order by fd.device_number, fd.date";
|
order by fd.device_number, fd.date";
|
||||||
|
|
||||||
var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
|
var rawData = await backendRepository.GetAllAsync<HydroMeterRawDataOutput>(sql,
|
||||||
new { startTime = startTime, endTime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat });
|
new { startTime = startTime, endTime = endTime, building_tag = input.building_tag, floor_tag = input.floor_tag, dateFormat = dateFormat });
|
||||||
var list = rawData
|
|
||||||
|
List<HydroMeterOutput> list = new List<HydroMeterOutput>();
|
||||||
|
if (tag_quantity == "5")
|
||||||
|
{
|
||||||
|
list = rawData
|
||||||
.GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4] })
|
.GroupBy(x => new { building_tag = x.device_number.Split("_")[0], floor_tag = x.device_number.Split("_")[2], device_serial_tag = x.device_number.Split("_")[4] })
|
||||||
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
|
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list = rawData
|
||||||
|
.GroupBy(x => new { building_tag = x.device_number.Split("_")[1], floor_tag = x.device_number.Split("_")[4], device_serial_tag = x.device_number.Split("_")[7] })
|
||||||
|
.Select(x => new HydroMeterOutput { building_tag = x.Key.building_tag, floor_tag = x.Key.floor_tag, device_serial_tag = x.Key.device_serial_tag })
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var l in list)
|
foreach (var l in list)
|
||||||
{
|
{
|
||||||
l.rawData = new List<HydroMeterRawDataOutput>();
|
l.rawData = new List<HydroMeterRawDataOutput>();
|
||||||
l.rawData.AddRange(
|
if (tag_quantity == "5")
|
||||||
rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
|
{
|
||||||
);
|
l.rawData.AddRange(
|
||||||
|
rawData.Where(x => x.device_number.Split("_")[0] == l.building_tag && x.device_number.Split("_")[2] == l.floor_tag && x.device_number.Split("_")[4] == l.device_serial_tag)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l.rawData.AddRange(
|
||||||
|
rawData.Where(x => x.device_number.Split("_")[1] == l.building_tag && x.device_number.Split("_")[4] == l.floor_tag && x.device_number.Split("_")[7] == l.device_serial_tag)
|
||||||
|
);
|
||||||
|
}
|
||||||
l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
|
l.building_name = await backendRepository.GetOneAsync<string>("select full_name from building where building_tag = @building_tag and deleted = 0",
|
||||||
new { building_tag = l.building_tag });
|
new { building_tag = l.building_tag });
|
||||||
l.total = l.rawData.Sum(x => x.avg_rawdata).ToString();
|
l.total = l.rawData.Sum(x => x.avg_rawdata).ToString();
|
||||||
|
@ -1156,7 +1156,7 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
from operation_record opr
|
from operation_record opr
|
||||||
left join device d on opr.fix_do_code = d.device_number
|
left join device d on opr.fix_do_code = d.device_number
|
||||||
left join userinfo ui on opr.work_person_id = ui.userinfo_guid
|
left join userinfo ui on opr.work_person_id = ui.userinfo_guid
|
||||||
where opr.deleted = 0 and opr.id = @id";
|
where opr.deleted = 0 and (opr.id = @id or opr.formId = '{ofl.formId}')";
|
||||||
|
|
||||||
var param = new { @id = ofl.id };
|
var param = new { @id = ofl.id };
|
||||||
|
|
||||||
@ -1226,8 +1226,8 @@ namespace FrontendWebApi.ApiControllers
|
|||||||
{ "@end_time", or.end_time},
|
{ "@end_time", or.end_time},
|
||||||
{ "@work_time", or.work_time},
|
{ "@work_time", or.work_time},
|
||||||
{ "@finish_time", or.finish_time},
|
{ "@finish_time", or.finish_time},
|
||||||
{ "@notice", or.notice},
|
{ "@notice", or.notice == "null" ? null : or.notice},
|
||||||
{ "@description", or.description},
|
{ "@description", or.description == "null" ? null : or.description},
|
||||||
{ "@created_by", myUser.userinfo_guid},
|
{ "@created_by", myUser.userinfo_guid},
|
||||||
{ "@created_at", DateTime.Now}
|
{ "@created_at", DateTime.Now}
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FrontendWebApi.Controllers
|
||||||
|
{
|
||||||
|
public class EmergencyHardwareMenuController : MyBaseController<EmergencyHardwareMenuController>
|
||||||
|
{
|
||||||
|
private readonly ILogger<EmergencyHardwareMenuController> _logger;
|
||||||
|
|
||||||
|
public EmergencyHardwareMenuController(ILogger<EmergencyHardwareMenuController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,4 +7,11 @@
|
|||||||
public int DispatchCnt{ get; set; }
|
public int DispatchCnt{ get; set; }
|
||||||
public int NotDispatchCnt { get; set; }
|
public int NotDispatchCnt { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TotalElec
|
||||||
|
{
|
||||||
|
public string building_tag { get; set; }
|
||||||
|
public string device_number { get; set; }
|
||||||
|
public string remark { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ namespace FrontendWebApi.Models
|
|||||||
public class selectdevice
|
public class selectdevice
|
||||||
{
|
{
|
||||||
public List<int> select_disasters { get; set; }
|
public List<int> select_disasters { get; set; }
|
||||||
public string selectbuilding { get; set; }
|
public List<string> selectbuilding { get; set; }
|
||||||
public List<string> select_Floors { get; set; }
|
public List<string> select_Floors { get; set; }
|
||||||
public List<string> select_Layer3 { get; set; }
|
public List<string> select_Layer3 { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ namespace FrontendWebApi.Models
|
|||||||
public List<string> main_system_tag { get; set; }//大类tag
|
public List<string> main_system_tag { get; set; }//大类tag
|
||||||
public List<string> sub_system_tag { get; set; }//小类tag
|
public List<string> sub_system_tag { get; set; }//小类tag
|
||||||
public byte? work_type { get; set; } // 1:保養, 2:維修
|
public byte? work_type { get; set; } // 1:保養, 2:維修
|
||||||
|
public string formId { get; set; } //異常代碼
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BuildingList
|
public class BuildingList
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@{
|
@{
|
||||||
ViewData["MainNum"] = "4";
|
ViewData["MainNum"] = "4";
|
||||||
ViewData["SubNum"] = "2";
|
ViewData["SubNum"] = "3";
|
||||||
ViewData["Title"] = "聯絡清單";
|
ViewData["Title"] = "聯絡清單";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,23 +15,28 @@
|
|||||||
<div class="col-xl-12">
|
<div class="col-xl-12">
|
||||||
<div id="panel-5" class="panel">
|
<div id="panel-5" class="panel">
|
||||||
<div class="panel-container show">
|
<div class="panel-container show">
|
||||||
<div class="panel-hdr">
|
@*<div class="panel-hdr">
|
||||||
<div class="col-auto">顯示類型</div>
|
<div class="col-auto">顯示類型</div>
|
||||||
<div class="col" id="show-mode">
|
<div class="col" id="show-mode">
|
||||||
<button type="button" class="btn btn-success" onclick="ChangeMode('alarm', this)">事件清單</button>
|
<button type="button" class="btn btn-success" onclick="ChangeMode('alarm', this)">事件清單</button>
|
||||||
<button type="button" class="btn btn-secondary" onclick="ChangeMode('normal', this)">緊急應變硬體清單</button>
|
<button type="button" class="btn btn-secondary" onclick="ChangeMode('normal', this)">緊急應變硬體清單</button>
|
||||||
<button type="button" class="btn btn-secondary float-right" onclick="OnSimulationExercise('', '',1)">模擬演練</button>
|
<button type="button" class="btn btn-secondary float-right" onclick="OnSimulationExercise('', '',1)">模擬演練</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>*@
|
||||||
<div class="panel-hdr">
|
<div class="panel-hdr">
|
||||||
<div class="col-auto">防災類別</div>
|
<div class="col-auto">防災類別</div>
|
||||||
<div class="col" id="disaster">防災類別</div>
|
<div class="col" id="disaster">防災類別
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<button type="button" class="btn btn-secondary" onclick="OnSimulationExercise('', '',1)">模擬演練</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-hdr">
|
<div class="panel-hdr">
|
||||||
<div class="col-auto">棟別</div>
|
<div class="col-auto">棟別 </div>
|
||||||
<div class="col" id="building">棟別</div>
|
<div class="col" id="building">棟別</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-hdr">
|
@*<div class="panel-hdr">
|
||||||
<div class="col-auto">樓層</div>
|
<div class="col-auto">樓層</div>
|
||||||
<div class="col" id="floors">棟別</div>
|
<div class="col" id="floors">棟別</div>
|
||||||
</div>
|
</div>
|
||||||
@ -42,7 +47,7 @@
|
|||||||
<div class="panel-hdr">
|
<div class="panel-hdr">
|
||||||
<div class="col-auto">設備小類</div>
|
<div class="col-auto">設備小類</div>
|
||||||
<div class="col" id="layer3">設備大類</div>
|
<div class="col" id="layer3">設備大類</div>
|
||||||
</div>
|
</div>*@
|
||||||
<div class="panel-container">
|
<div class="panel-container">
|
||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<div class="frame-wrap">
|
<div class="frame-wrap">
|
||||||
@ -322,7 +327,7 @@
|
|||||||
temp_alarm_device = []; //暫存所有的報警設備
|
temp_alarm_device = []; //暫存所有的報警設備
|
||||||
var backfill_building_device_amount = [], backfill_layer2_device_amount = [], backfill_layer3_device_amount = [];
|
var backfill_building_device_amount = [], backfill_layer2_device_amount = [], backfill_layer3_device_amount = [];
|
||||||
var backfill_building_alarm_device_amount = [], backfill_layer2_alarm_device_amount = [], backfill_layer3_alarm_device_amount = [];
|
var backfill_building_alarm_device_amount = [], backfill_layer2_alarm_device_amount = [], backfill_layer3_alarm_device_amount = [];
|
||||||
var select_all_disaster = false, select_all_floor = false,
|
var select_all_disaster = false, select_all_floor = false,select_all_building = false,
|
||||||
select_all_layer2 = false, select_all_layer3 = false;
|
select_all_layer2 = false, select_all_layer3 = false;
|
||||||
|
|
||||||
var changeBuilding = "";
|
var changeBuilding = "";
|
||||||
@ -340,7 +345,7 @@
|
|||||||
var SelectedFilter =
|
var SelectedFilter =
|
||||||
{
|
{
|
||||||
disasters: [],
|
disasters: [],
|
||||||
building_tag: '',
|
building_tag: [],
|
||||||
floor_guids: [],
|
floor_guids: [],
|
||||||
layer2: [],
|
layer2: [],
|
||||||
layer3: []
|
layer3: []
|
||||||
@ -890,7 +895,7 @@
|
|||||||
SelectedFilter.disasters.push(disaster);
|
SelectedFilter.disasters.push(disaster);
|
||||||
$(e).removeClass('btn-outline-success').addClass('btn-success');
|
$(e).removeClass('btn-outline-success').addClass('btn-success');
|
||||||
}
|
}
|
||||||
|
|
||||||
is_need_reload = true;
|
is_need_reload = true;
|
||||||
ChangeFilterBuilding();
|
ChangeFilterBuilding();
|
||||||
UpdateDeviceAmount();
|
UpdateDeviceAmount();
|
||||||
@ -925,11 +930,11 @@
|
|||||||
</div>`;*@
|
</div>`;*@
|
||||||
|
|
||||||
html += `<div class="btn-group ml-2" onclick="SelectBuilding('${building.tag}',this)">
|
html += `<div class="btn-group ml-2" onclick="SelectBuilding('${building.tag}',this)">
|
||||||
<button type="button" class="btn btn-secondary">${building.name}</button>
|
<button type="button" class="btn btn-secondary" data-tag="${building.tag}" >${building.name}</button>
|
||||||
<button type="button" class="btn btn-secondary building_device_amount" id="${building.tag}_device_amount">0</button>
|
<button type="button" class="btn btn-secondary building_device_amount" data-tag="${building.tag}" id="${building.tag}_device_amount">0</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
|
$('#building').append(`<button type="button" class="btn btn-secondary waves-effect waves-themed d-inline-block ml-2" onclick="AllBuilding()"> 全選 </button>`);
|
||||||
$('#building').append(html);
|
$('#building').append(html);
|
||||||
|
|
||||||
$('#building').find('div').first().click();
|
$('#building').find('div').first().click();
|
||||||
@ -940,6 +945,7 @@
|
|||||||
html += '<button type="button" class="btn btn-secondary ml-2" onclick="SelectBuilding(\'' + building.tag + '\',this)">' + building.name + '</button>';
|
html += '<button type="button" class="btn btn-secondary ml-2" onclick="SelectBuilding(\'' + building.tag + '\',this)">' + building.name + '</button>';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#building').append(`<button type="button" class="btn btn-secondary waves-effect waves-themed d-inline-block ml-2" onclick="AllBuilding()"> 全選 </button>`);
|
||||||
$('#building').append(html);
|
$('#building').append(html);
|
||||||
|
|
||||||
$('#building').find('button').first().click();
|
$('#building').find('button').first().click();
|
||||||
@ -948,51 +954,71 @@
|
|||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
//#region 計算現有勾選棟別
|
||||||
|
function resetCalSelectBuilding(){
|
||||||
|
SelectedFilter.building_tag = [];
|
||||||
|
$('#building').find('button.btn-success').each((index,ele) => {
|
||||||
|
let ele_building_tag = $(ele).data("tag");
|
||||||
|
if(SelectedFilter.building_tag.indexOf(ele_building_tag) == -1){
|
||||||
|
SelectedFilter.building_tag.push(ele_building_tag);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log(SelectedFilter.building_tag)
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
//#region 選擇棟別
|
//#region 選擇棟別
|
||||||
function SelectBuilding(building_tag, e) {
|
function SelectBuilding(building_tag, e) {
|
||||||
$('#building').find('button').removeClass('btn-success').addClass('btn-secondary')
|
//$('#building').find('button').removeClass('btn-success').addClass('btn-secondary')
|
||||||
|
|
||||||
SelectedFilter.building_tag = building_tag;
|
|
||||||
if (show_mode == 'alarm') {
|
if (show_mode == 'alarm') {
|
||||||
$(e).find('button').addClass('btn-success');
|
if($(e).find("button.btn-success").length > 0){
|
||||||
|
$(e).find('button').removeClass('btn-success').addClass('btn-secondary');
|
||||||
|
} else {
|
||||||
|
$(e).find('button').removeClass('btn-secondary').addClass('btn-success');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$(e).addClass('btn-success');
|
$(e).addClass('btn-success');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetCalSelectBuilding();
|
||||||
|
|
||||||
is_need_reload = true;
|
is_need_reload = true;
|
||||||
ChangeFilterFloor();
|
ChangeFilterFloor();
|
||||||
UpdateDeviceAmount();
|
UpdateDeviceAmount();
|
||||||
|
ResetDeviceTable();
|
||||||
@*console.log("SelectedFilter", SelectedFilter);*@
|
@*console.log("SelectedFilter", SelectedFilter);*@
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region 修改過濾條件(樓層)
|
//#region 修改過濾條件(樓層)
|
||||||
function ChangeFilterFloor() {
|
function ChangeFilterFloor() {
|
||||||
temp_all_floor = [];
|
//temp_all_floor = [];
|
||||||
all_device_group.forEach(function (disaster, disaster_index) {
|
//all_device_group.forEach(function (disaster, disaster_index) {
|
||||||
if (SelectedFilter.disasters.findIndex(x => x == disaster.value) > -1) { //抓取已選擇的防災類型的棟別內容
|
// if (SelectedFilter.disasters.findIndex(x => x == disaster.value) > -1) { //抓取已選擇的防災類型的棟別內容
|
||||||
disaster.groupBuildings.forEach(function (building, building_index) {
|
// disaster.groupBuildings.forEach(function (building, building_index) {
|
||||||
if (building.tag == SelectedFilter.building_tag) { //抓取選擇棟別的底下樓層
|
// if (building.tag == SelectedFilter.building_tag) { //抓取選擇棟別的底下樓層
|
||||||
building.groupFloors.forEach(function (floor, floor_index) {
|
// building.groupFloors.forEach(function (floor, floor_index) {
|
||||||
if (temp_all_floor.findIndex(x => x.name == floor.name) < 0) { //表示未加入,需加入
|
// if (temp_all_floor.findIndex(x => x.name == floor.name) < 0) { //表示未加入,需加入
|
||||||
temp_all_floor.push(floor);
|
// temp_all_floor.push(floor);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
//});
|
||||||
|
|
||||||
$("#floors").empty();
|
//$("#floors").empty();
|
||||||
$("#floors").append(`<button type="button" class="btn btn-secondary ml-2 mb-2" onclick="AllFloor()">全選</button>`);
|
//$("#floors").append(`<button type="button" class="btn btn-secondary ml-2 mb-2" onclick="AllFloor()">全選</button>`);
|
||||||
var html = "";
|
//var html = "";
|
||||||
temp_all_floor.forEach(function (floor, floor_index) {
|
//temp_all_floor.forEach(function (floor, floor_index) {
|
||||||
html += '<button type="button" class="btn btn-outline-success ml-2 mb-2" onclick="SelectFloor(\'' + floor.name + '\',this)">' + floor.name + '</button>';
|
// html += '<button type="button" class="btn btn-outline-success ml-2 mb-2" onclick="SelectFloor(\'' + floor.name + '\',this)">' + floor.name + '</button>';
|
||||||
});
|
//});
|
||||||
$('#floors').append(html);
|
//$('#floors').append(html);
|
||||||
|
|
||||||
select_all_floor = false;
|
//select_all_floor = false;
|
||||||
$('#floors').find('button').first().click();
|
//$('#floors').find('button').first().click();
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@ -1041,51 +1067,68 @@
|
|||||||
|
|
||||||
//#region 修改過濾條件(大類)
|
//#region 修改過濾條件(大類)
|
||||||
function ChangeFilterLayer2() {
|
function ChangeFilterLayer2() {
|
||||||
temp_all_layer2 = [];
|
//temp_all_layer2 = [];
|
||||||
all_device_group.forEach(function (disaster, disaster_index) {
|
//all_device_group.forEach(function (disaster, disaster_index) {
|
||||||
if (SelectedFilter.disasters.findIndex(x => x == disaster.value) > -1) { //抓取選擇防災類型的底下棟別
|
// if (SelectedFilter.disasters.findIndex(x => x == disaster.value) > -1) { //抓取選擇防災類型的底下棟別
|
||||||
disaster.groupBuildings.forEach(function (building, building_index) {
|
// disaster.groupBuildings.forEach(function (building, building_index) {
|
||||||
if (building.tag == SelectedFilter.building_tag) { //抓取選擇棟別的底下樓層
|
// if (building.tag == SelectedFilter.building_tag) { //抓取選擇棟別的底下樓層
|
||||||
building.groupFloors.forEach(function (floor, floor_index) {
|
// building.groupFloors.forEach(function (floor, floor_index) {
|
||||||
if (SelectedFilter.floor_guids.findIndex(x => x == floor.name) > -1) { //抓取選擇樓層的底下大類
|
// if (SelectedFilter.floor_guids.findIndex(x => x == floor.name) > -1) { //抓取選擇樓層的底下大類
|
||||||
floor.groupLayer2s.forEach(function (layer2, layer2_index) {
|
// floor.groupLayer2s.forEach(function (layer2, layer2_index) {
|
||||||
if (temp_all_layer2.findIndex(x => x.value == layer2.value) < 0) {
|
// if (temp_all_layer2.findIndex(x => x.value == layer2.value) < 0) {
|
||||||
temp_all_layer2.push(layer2);
|
// temp_all_layer2.push(layer2);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
//});
|
||||||
|
|
||||||
$("#layer2").empty();
|
//$("#layer2").empty();
|
||||||
$("#layer2").append(`<div class="ml-2 mb-2" style="position: relative; display: inline-flex; vertical-align: middle" onclick="AllLayer2()">
|
//$("#layer2").append(`<div class="ml-2 mb-2" style="position: relative; display: inline-flex; vertical-align: middle" onclick="AllLayer2()">
|
||||||
<button type="button" class="btn btn-secondary">全選</button>
|
// <button type="button" class="btn btn-secondary">全選</button>
|
||||||
</div>`);
|
// </div>`);
|
||||||
var html = "";
|
//var html = "";
|
||||||
temp_all_layer2.forEach(function (layer2, layer2_index) {
|
//temp_all_layer2.forEach(function (layer2, layer2_index) {
|
||||||
|
|
||||||
var layer2_device_amount = backfill_layer2_device_amount.filter(x => x.value == layer2.value && x.building_tag == SelectedFilter.building_tag)[0];
|
// var layer2_device_amount = backfill_layer2_device_amount.filter(x => x.value == layer2.value && x.building_tag == SelectedFilter.building_tag)[0];
|
||||||
|
|
||||||
@*html += `
|
// @*html += `
|
||||||
<div class="btn-group ml-2 mb-2" onclick="SelectLayer2('${layer2.value}',this)">
|
// <div class="btn-group ml-2 mb-2" onclick="SelectLayer2('${layer2.value}',this)">
|
||||||
<button type="button" class="btn btn-outline-success">${layer2.name}</button>
|
// <button type="button" class="btn btn-outline-success">${layer2.name}</button>
|
||||||
<button type="button" class="btn btn-outline-success device_amount" id="${layer2_device_amount.building_tag}_${layer2_device_amount.value}_device_amount">${layer2_device_amount.device_amount}</button>
|
// <button type="button" class="btn btn-outline-success device_amount" id="${layer2_device_amount.building_tag}_${layer2_device_amount.value}_device_amount">${layer2_device_amount.device_amount}</button>
|
||||||
</div>`;*@
|
// </div>`;*@
|
||||||
|
|
||||||
html += `
|
// html += `
|
||||||
<div class="btn-group ml-2 mb-2" onclick="SelectLayer2('${layer2.value}',this)">
|
// <div class="btn-group ml-2 mb-2" onclick="SelectLayer2('${layer2.value}',this)">
|
||||||
<button type="button" class="btn btn-outline-success">${layer2.name}</button>
|
// <button type="button" class="btn btn-outline-success">${layer2.name}</button>
|
||||||
<button type="button" class="btn btn-outline-success device_amount" id="${layer2_device_amount.building_tag}_${layer2_device_amount.value}_device_amount">0</button>
|
// <button type="button" class="btn btn-outline-success device_amount" id="${layer2_device_amount.building_tag}_${layer2_device_amount.value}_device_amount">0</button>
|
||||||
</div>`;
|
// </div>`;
|
||||||
|
|
||||||
});
|
//});
|
||||||
$('#layer2').append(html);
|
//$('#layer2').append(html);
|
||||||
|
|
||||||
select_all_layer2 = false;
|
//select_all_layer2 = false;
|
||||||
$('#layer2').find('div').first().click();
|
//$('#layer2').find('div').first().click();
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region 全選棟別
|
||||||
|
function AllBuilding() {
|
||||||
|
if (select_all_building) { //全選 -> 取消全選
|
||||||
|
select_all_building = false;
|
||||||
|
$('#building').find('div > button.btn-success').removeClass('btn-success').addClass('btn-secondary');
|
||||||
|
} else { //取消全選 -> 全選
|
||||||
|
select_all_building = true;
|
||||||
|
$('#building').find('div > button.btn-secondary').removeClass('btn-secondary').addClass('btn-success');
|
||||||
|
}
|
||||||
|
|
||||||
|
resetCalSelectBuilding();
|
||||||
|
is_need_reload = true;
|
||||||
|
UpdateDeviceAmount();
|
||||||
|
@*console.log("SelectedFilter", SelectedFilter);*@
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@ -1134,65 +1177,65 @@
|
|||||||
|
|
||||||
//#region 修改過濾條件(小類)
|
//#region 修改過濾條件(小類)
|
||||||
function ChangeFilterLayer3() {
|
function ChangeFilterLayer3() {
|
||||||
temp_all_layer3 = [];
|
//temp_all_layer3 = [];
|
||||||
all_device_group.forEach(function (disaster, disaster_index) {
|
//all_device_group.forEach(function (disaster, disaster_index) {
|
||||||
if (SelectedFilter.disasters.findIndex(x => x == disaster.value) > -1) { //抓取選擇防災類型的底下棟別
|
// if (SelectedFilter.disasters.findIndex(x => x == disaster.value) > -1) { //抓取選擇防災類型的底下棟別
|
||||||
disaster.groupBuildings.forEach(function (building, building_index) {
|
// disaster.groupBuildings.forEach(function (building, building_index) {
|
||||||
if (building.tag == SelectedFilter.building_tag) { //抓取選擇棟別的底下樓層
|
// if (building.tag == SelectedFilter.building_tag) { //抓取選擇棟別的底下樓層
|
||||||
building.groupFloors.forEach(function (floor, floor_index) {
|
// building.groupFloors.forEach(function (floor, floor_index) {
|
||||||
if (SelectedFilter.floor_guids.findIndex(x => x == floor.name) > -1) { //抓取選擇樓層的底下大類
|
// if (SelectedFilter.floor_guids.findIndex(x => x == floor.name) > -1) { //抓取選擇樓層的底下大類
|
||||||
floor.groupLayer2s.forEach(function (layer2, layer2_index) {
|
// floor.groupLayer2s.forEach(function (layer2, layer2_index) {
|
||||||
if (SelectedFilter.layer2.findIndex(x => x == layer2.value) > -1) { //抓取選擇大類的底下小類
|
// if (SelectedFilter.layer2.findIndex(x => x == layer2.value) > -1) { //抓取選擇大類的底下小類
|
||||||
layer2.groupLayer3s.forEach(function (layer3, layer3_index) {
|
// layer2.groupLayer3s.forEach(function (layer3, layer3_index) {
|
||||||
var new_layer3 = {
|
// var new_layer3 = {
|
||||||
name: layer3.name,
|
// name: layer3.name,
|
||||||
value: layer3.value,
|
// value: layer3.value,
|
||||||
device_amount: layer3.device_amount
|
// device_amount: layer3.device_amount
|
||||||
}
|
// }
|
||||||
|
|
||||||
var temp_device_amount = new_layer3.device_amount;
|
// var temp_device_amount = new_layer3.device_amount;
|
||||||
var temp_layer3_index = temp_all_layer3.findIndex(x => x.value == layer3.value);
|
// var temp_layer3_index = temp_all_layer3.findIndex(x => x.value == layer3.value);
|
||||||
if (temp_layer3_index < 0) {
|
// if (temp_layer3_index < 0) {
|
||||||
temp_all_layer3.push(new_layer3);
|
// temp_all_layer3.push(new_layer3);
|
||||||
} else {
|
// } else {
|
||||||
temp_all_layer3[temp_layer3_index].device_amount += temp_device_amount;
|
// temp_all_layer3[temp_layer3_index].device_amount += temp_device_amount;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
//});
|
||||||
|
|
||||||
$("#layer3").empty();
|
//$("#layer3").empty();
|
||||||
$("#layer3").append(`<div class="ml-2 mb-2" style="position: relative; display: inline-flex; vertical-align: middle" onclick="AllLayer3()">
|
//$("#layer3").append(`<div class="ml-2 mb-2" style="position: relative; display: inline-flex; vertical-align: middle" onclick="AllLayer3()">
|
||||||
<button type="button" class="btn btn-secondary">全選</button>
|
// <button type="button" class="btn btn-secondary">全選</button>
|
||||||
</div>`);
|
// </div>`);
|
||||||
var html = "";
|
//var html = "";
|
||||||
temp_all_layer3.forEach(function (layer3, layer3_index) {
|
//temp_all_layer3.forEach(function (layer3, layer3_index) {
|
||||||
|
|
||||||
var layer3_device_amount = backfill_layer3_device_amount.filter(x => x.layer3 == layer3.value && x.building_tag == SelectedFilter.building_tag)[0];
|
// var layer3_device_amount = backfill_layer3_device_amount.filter(x => x.layer3 == layer3.value && x.building_tag == SelectedFilter.building_tag)[0];
|
||||||
|
|
||||||
@*html += `
|
// @*html += `
|
||||||
<div class="btn-group ml-2 mb-2" onclick="SelectLayer3('${layer3.value}',this)">
|
// <div class="btn-group ml-2 mb-2" onclick="SelectLayer3('${layer3.value}',this)">
|
||||||
<button type="button" class="btn btn-outline-success">${layer3.name}</button>
|
// <button type="button" class="btn btn-outline-success">${layer3.name}</button>
|
||||||
<button type="button" class="btn btn-outline-success device_amount" id="${layer3_device_amount.building_tag}_${layer3_device_amount.layer3}_device_amount">${layer3_device_amount.device_amount}</button>
|
// <button type="button" class="btn btn-outline-success device_amount" id="${layer3_device_amount.building_tag}_${layer3_device_amount.layer3}_device_amount">${layer3_device_amount.device_amount}</button>
|
||||||
</div>`;*@
|
// </div>`;*@
|
||||||
|
|
||||||
html += `
|
// html += `
|
||||||
<div class="btn-group ml-2 mb-2" onclick="SelectLayer3('${layer3.value}',this)">
|
// <div class="btn-group ml-2 mb-2" onclick="SelectLayer3('${layer3.value}',this)">
|
||||||
<button type="button" class="btn btn-outline-success">${layer3.name}</button>
|
// <button type="button" class="btn btn-outline-success">${layer3.name}</button>
|
||||||
<button type="button" class="btn btn-outline-success device_amount" id="${layer3_device_amount.building_tag}_${layer3_device_amount.layer3}_device_amount">0</button>
|
// <button type="button" class="btn btn-outline-success device_amount" id="${layer3_device_amount.building_tag}_${layer3_device_amount.layer3}_device_amount">0</button>
|
||||||
</div>`;
|
// </div>`;
|
||||||
});
|
//});
|
||||||
|
|
||||||
$('#layer3').append(html);
|
//$('#layer3').append(html);
|
||||||
|
|
||||||
select_all_layer3 = false;
|
//select_all_layer3 = false;
|
||||||
$('#layer3').find('div').first().click();
|
//$('#layer3').find('div').first().click();
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@ -1241,9 +1284,7 @@
|
|||||||
function ResetDeviceTable() {
|
function ResetDeviceTable() {
|
||||||
|
|
||||||
if ((SelectedFilter.disasters == null || SelectedFilter.disasters.length <= 0)
|
if ((SelectedFilter.disasters == null || SelectedFilter.disasters.length <= 0)
|
||||||
|| (SelectedFilter.building_tag == null || SelectedFilter.building_tag == "")
|
|| (SelectedFilter.building_tag == null || SelectedFilter.building_tag.length <= 0)
|
||||||
|| (SelectedFilter.floor_guids == null || SelectedFilter.floor_guids.length <= 0)
|
|
||||||
|| (SelectedFilter.layer3 == null || SelectedFilter.layer3.length <= 0)
|
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1327,7 +1368,7 @@
|
|||||||
// de_number = $(e).parent().parent().attr('de-number');
|
// de_number = $(e).parent().parent().attr('de-number');
|
||||||
var url = "/api/EmergencyDevice/SaveAndOpenSimulationExercise";
|
var url = "/api/EmergencyDevice/SaveAndOpenSimulationExercise";
|
||||||
var send_data = {
|
var send_data = {
|
||||||
build: SelectedFilter.building_tag,
|
build: SelectedFilter.building_tag[0] ?? null,
|
||||||
disaster: disaster,
|
disaster: disaster,
|
||||||
type: type,
|
type: type,
|
||||||
device: guid
|
device: guid
|
||||||
|
1950
FrontendWebApi/Views/EmergencyHardwareMenu/Index.cshtml
Normal file
1950
FrontendWebApi/Views/EmergencyHardwareMenu/Index.cshtml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
@{
|
@{
|
||||||
ViewData["MainNum"] = "4";
|
ViewData["MainNum"] = "4";
|
||||||
ViewData["SubNum"] = "3";
|
ViewData["SubNum"] = "4";
|
||||||
ViewData["Title"] = "紀錄查詢";
|
ViewData["Title"] = "紀錄查詢";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@{
|
@{
|
||||||
ViewData["MainNum"] = "4";
|
ViewData["MainNum"] = "4";
|
||||||
ViewData["SubNum"] = "5";
|
ViewData["SubNum"] = "6";
|
||||||
ViewData["Title"] = "AED裝置設定";
|
ViewData["Title"] = "AED裝置設定";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@{
|
@{
|
||||||
ViewData["MainNum"] = "4";
|
ViewData["MainNum"] = "4";
|
||||||
ViewData["SubNum"] = "4";
|
ViewData["SubNum"] = "5";
|
||||||
ViewData["Title"] = "滅火器設定";
|
ViewData["Title"] = "滅火器設定";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,14 +89,22 @@
|
|||||||
@if (ViewBag.role.Contains("EmergencyDeviceMenuIndex"))
|
@if (ViewBag.role.Contains("EmergencyDeviceMenuIndex"))
|
||||||
{
|
{
|
||||||
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "1" ? "active" : "")">
|
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "1" ? "active" : "")">
|
||||||
<a asp-controller="EmergencyDeviceMenu" asp-action="Index" title="設備總覽" data-filter-tags="utilities disabled item">
|
<a asp-controller="EmergencyDeviceMenu" asp-action="Index" title="事件清單" data-filter-tags="utilities disabled item">
|
||||||
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">設備總覽</span>
|
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">事件清單</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
@if (ViewBag.role.Contains("EmergencyHardwareIndex"))
|
||||||
|
{
|
||||||
|
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "2" ? "active" : "")">
|
||||||
|
<a asp-controller="EmergencyHardwareMenu" asp-action="Index" title="緊急應變硬體清單" data-filter-tags="utilities disabled item">
|
||||||
|
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">緊急應變硬體清單</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@if (ViewBag.role.Contains("EmergencyContactIndex"))
|
@if (ViewBag.role.Contains("EmergencyContactIndex"))
|
||||||
{
|
{
|
||||||
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "2" ? "active" : "")">
|
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "3" ? "active" : "")">
|
||||||
<a asp-controller="EmergencyContact" asp-action="Index" title="聯絡清單" data-filter-tags="utilities disabled item">
|
<a asp-controller="EmergencyContact" asp-action="Index" title="聯絡清單" data-filter-tags="utilities disabled item">
|
||||||
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">聯絡清單</span>
|
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">聯絡清單</span>
|
||||||
</a>
|
</a>
|
||||||
@ -104,7 +112,7 @@
|
|||||||
}
|
}
|
||||||
@if (ViewBag.role.Contains("EmergencyRecordIndex"))
|
@if (ViewBag.role.Contains("EmergencyRecordIndex"))
|
||||||
{
|
{
|
||||||
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "3" ? "active" : "")">
|
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "4" ? "active" : "")">
|
||||||
<a asp-controller="EmergencyRecord" asp-action="Index" title="紀錄查詢" data-filter-tags="utilities disabled item">
|
<a asp-controller="EmergencyRecord" asp-action="Index" title="紀錄查詢" data-filter-tags="utilities disabled item">
|
||||||
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">紀錄查詢</span>
|
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">紀錄查詢</span>
|
||||||
</a>
|
</a>
|
||||||
@ -113,7 +121,7 @@
|
|||||||
|
|
||||||
@if (ViewBag.role.Contains("RescueDeviceFireExtinguisher"))
|
@if (ViewBag.role.Contains("RescueDeviceFireExtinguisher"))
|
||||||
{
|
{
|
||||||
<li class="@(ViewData["MainNum"] == "3" && ViewData["SubNum"] == "4" ? "active" : "")">
|
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "5" ? "active" : "")">
|
||||||
<a asp-controller="RescueDevice" asp-action="FireExtinguisher" title="滅火器設定" data-filter-tags="utilities disabled item">
|
<a asp-controller="RescueDevice" asp-action="FireExtinguisher" title="滅火器設定" data-filter-tags="utilities disabled item">
|
||||||
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">滅火器設定</span>
|
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">滅火器設定</span>
|
||||||
</a>
|
</a>
|
||||||
@ -121,7 +129,7 @@
|
|||||||
}
|
}
|
||||||
@if (ViewBag.role.Contains("RescueDeviceAED"))
|
@if (ViewBag.role.Contains("RescueDeviceAED"))
|
||||||
{
|
{
|
||||||
<li class="@(ViewData["MainNum"] == "3" && ViewData["SubNum"] == "5" ? "active" : "")">
|
<li class="@(ViewData["MainNum"] == "4" && ViewData["SubNum"] == "6" ? "active" : "")">
|
||||||
<a asp-controller="RescueDevice" asp-action="AED" title="AED裝置設定" data-filter-tags="utilities disabled item">
|
<a asp-controller="RescueDevice" asp-action="AED" title="AED裝置設定" data-filter-tags="utilities disabled item">
|
||||||
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">AED裝置設定</span>
|
<span class="nav-link-text" data-i18n="nav.utilities_disabled_item">AED裝置設定</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
||||||
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
||||||
//"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office
|
//"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office
|
||||||
|
//"Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //MCUT
|
||||||
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
"Root": "SzdxEgaJJ7tcTCrUl2zKsA==",
|
||||||
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
"Password": "FVAPxztxpY4gJJKQ/se4bQ=="
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
|
"Port": "js2LutKe+rdjzdxMPQUrvQ==",
|
||||||
//"Database": "VJB2XC+lAtzuHObDGMVOAA==", //三菱
|
//"Database": "VJB2XC+lAtzuHObDGMVOAA==", //三菱
|
||||||
//"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
|
//"Database": "IgYBsgG2VLKKxFb64j7LOA==", //wsp
|
||||||
|
//"Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //MCUT
|
||||||
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome
|
||||||
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
//"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel
|
||||||
//"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office
|
//"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office
|
||||||
@ -34,7 +35,7 @@
|
|||||||
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
"Server": "bJm+UAtbeaTjDmp/A5ep2w==", //0.130
|
||||||
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
"Port": "S5cUXKnKOacFtFy9+0dtpw==",
|
||||||
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
"Database": "VvfWH/59gQguY2eA2xBCug==", //taipei_dome
|
||||||
"Root": "sD8GZ9UPiIQGU6dU011/4A==",
|
"Root": "4GCCJGAXzLa8ecdmPAkYKg==",
|
||||||
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
"Password": "0O24es2ZRF5uoJ4aU+YCdg=="
|
||||||
}
|
}
|
||||||
//"MSSqlDBConfig": {
|
//"MSSqlDBConfig": {
|
||||||
|
@ -12,6 +12,7 @@ using Repository.Models;
|
|||||||
using System.Data.SqlTypes;
|
using System.Data.SqlTypes;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using Org.BouncyCastle.Utilities.Collections;
|
||||||
|
|
||||||
namespace Repository.BackendRepository.Implement
|
namespace Repository.BackendRepository.Implement
|
||||||
{
|
{
|
||||||
@ -858,5 +859,59 @@ namespace Repository.BackendRepository.Implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task DeviceDisasterAysnc(List<Device_value_disaster> dv)
|
||||||
|
{
|
||||||
|
using (IDbConnection conn = GetDbConnection())
|
||||||
|
{
|
||||||
|
conn.Open();
|
||||||
|
using (TransactionScope scope = new TransactionScope((TransactionScopeOption)TransactionScopeAsyncFlowOption.Enabled, new TimeSpan(0, 5, 0)))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("select * from device_disaster;");
|
||||||
|
var deviceDisaster = (await conn.QueryAsync<DeviceDisasterOutput>(sb.ToString())).ToList();
|
||||||
|
sb.Clear();
|
||||||
|
sb.Append("select * from device where deleted = 0;");
|
||||||
|
var device = (await conn.QueryAsync<DeviceDisasterOutput>(sb.ToString())).ToList();
|
||||||
|
dv = dv.Where(x => device.Any(d => d.device_number == x.value.Split('/')[6])).ToList();
|
||||||
|
|
||||||
|
sb.Clear();
|
||||||
|
var updateList = dv.Where(x => deviceDisaster.Any(dd => dd.device_number == x.value.Split('/')[6] && dd.device_system_value != x.disasterValue));
|
||||||
|
foreach (var d in updateList)
|
||||||
|
{
|
||||||
|
string device_number = d.value.Split('/')[6];
|
||||||
|
sb.Append($"update device_disaster set device_system_value = '{d.disasterValue}' where device_number = '{device_number}'; ");
|
||||||
|
}
|
||||||
|
|
||||||
|
var insertList = dv.Where(x => !deviceDisaster.Any(dd => dd.device_number == x.value.Split('/')[6]));
|
||||||
|
foreach (var d in insertList)
|
||||||
|
{
|
||||||
|
string device_number = d.value.Split('/')[6];
|
||||||
|
string device_guid = device.Where(x => x.device_number == device_number).Select(x => x.device_guid).FirstOrDefault();
|
||||||
|
string device_system_tag = device.Where(x => x.device_number == device_number).Select(x => x.device_system_tag).FirstOrDefault();
|
||||||
|
string device_name_tag = device.Where(x => x.device_number == device_number).Select(x => x.device_name_tag).FirstOrDefault();
|
||||||
|
sb.Append($@"
|
||||||
|
insert into device_disaster
|
||||||
|
(device_guid, device_system_value, device_building_tag, device_system_tag, device_name_tag, device_floor_tag, device_serial_tag, device_number)
|
||||||
|
values ('{device_guid}', '{d.disasterValue}', '{device_number.Split('_')[0]}', '{device_system_tag}', '{device_name_tag}', '{device_number.Split('_')[2]}',
|
||||||
|
'{device_number.Split('_')[4]}', '{device_number}'); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sb.ToString()))
|
||||||
|
await conn.ExecuteAsync(sb.ToString());
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
conn.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,5 +70,6 @@ namespace Repository.BackendRepository.Interface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task InsertSubSystemFloor();
|
Task InsertSubSystemFloor();
|
||||||
|
Task DeviceDisasterAysnc(List<Device_value_disaster> dv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,4 +131,26 @@ namespace Repository.Models
|
|||||||
public string displayName { get; set; }
|
public string displayName { get; set; }
|
||||||
public bool isHistory { get; set; }
|
public bool isHistory { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DeviceDisasterOutput
|
||||||
|
{
|
||||||
|
public string device_guid { get; set; }
|
||||||
|
public string device_building_tag { get; set; }
|
||||||
|
public string device_system_tag { get; set; }
|
||||||
|
public string device_name_tag { get; set; }
|
||||||
|
public string device_floor_tag { get; set; }
|
||||||
|
public string device_serial_tag { get; set; }
|
||||||
|
public string device_number { get; set; }
|
||||||
|
public string device_system_value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Device_value_disaster
|
||||||
|
{
|
||||||
|
public string value { get; set; }
|
||||||
|
public string tag_name { get; set; }
|
||||||
|
public string point_name { get; set; }
|
||||||
|
public string building { get; set; }
|
||||||
|
public string displayName { get; set; }
|
||||||
|
public string disasterValue { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,6 @@ namespace Repository.Models
|
|||||||
|
|
||||||
public partial class Obj
|
public partial class Obj
|
||||||
{
|
{
|
||||||
[JsonProperty("@href")]
|
|
||||||
public string? href { get; set; }
|
|
||||||
[JsonProperty("@icon")]
|
|
||||||
public string? icon { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("@display")]
|
[JsonProperty("@display")]
|
||||||
public string Display { get; set; }
|
public string Display { get; set; }
|
||||||
|
|
||||||
@ -38,11 +33,7 @@ namespace Repository.Models
|
|||||||
public Uri XmlnsXsi { get; set; }
|
public Uri XmlnsXsi { get; set; }
|
||||||
|
|
||||||
[JsonProperty("str")]
|
[JsonProperty("str")]
|
||||||
public Str[] Str { get; set; }
|
public List<Str> Str { get; set; }
|
||||||
|
|
||||||
[JsonProperty("ref")]
|
|
||||||
public Str[] Ref { get; set; }
|
|
||||||
//public Ref Ref { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class Str
|
public partial class Str
|
||||||
@ -55,25 +46,6 @@ namespace Repository.Models
|
|||||||
|
|
||||||
[JsonProperty("@href")]
|
[JsonProperty("@href")]
|
||||||
public string Href { get; set; }
|
public string Href { get; set; }
|
||||||
[JsonProperty("@display")]
|
|
||||||
public string display { get; set; }
|
|
||||||
[JsonProperty("@_icon")]
|
|
||||||
public string _icon { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Ref
|
|
||||||
{
|
|
||||||
[JsonProperty("_name")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("_href")]
|
|
||||||
public string Href { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("_display")]
|
|
||||||
public string Display { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("_icon")]
|
|
||||||
public string Icon { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class Xml
|
public partial class Xml
|
||||||
|
82
Repository/Models/quickTypeSingle.cs
Normal file
82
Repository/Models/quickTypeSingle.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
|
namespace Repository.Models
|
||||||
|
{
|
||||||
|
public partial class WelcomeSingle
|
||||||
|
{
|
||||||
|
[JsonProperty("?xml")]
|
||||||
|
public XmlSingle Xml { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("?xml-stylesheet")]
|
||||||
|
public string XmlStylesheet { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("obj")]
|
||||||
|
public ObjSingle Obj { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class ObjSingle
|
||||||
|
{
|
||||||
|
[JsonProperty("@display")]
|
||||||
|
public string Display { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("@xmlns")]
|
||||||
|
public Uri Xmlns { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("@xsi:schemaLocation")]
|
||||||
|
public Uri XsiSchemaLocation { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("@xmlns:xsi")]
|
||||||
|
public Uri XmlnsXsi { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("str")]
|
||||||
|
public Str Str { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class StrSingle
|
||||||
|
{
|
||||||
|
[JsonProperty("@name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("@val")]
|
||||||
|
public string Val { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("@href")]
|
||||||
|
public string Href { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class XmlSingle
|
||||||
|
{
|
||||||
|
[JsonProperty("@version")]
|
||||||
|
public string Version { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("@encoding")]
|
||||||
|
public string Encoding { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class WelcomeSingle
|
||||||
|
{
|
||||||
|
public static WelcomeSingle FromJson(string json) => JsonConvert.DeserializeObject<WelcomeSingle>(json, Models.ConverterSingle.Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SerializeSingle
|
||||||
|
{
|
||||||
|
public static string ToJson(this WelcomeSingle self) => JsonConvert.SerializeObject(self, Models.ConverterSingle.Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class ConverterSingle
|
||||||
|
{
|
||||||
|
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
||||||
|
DateParseHandling = DateParseHandling.None,
|
||||||
|
Converters =
|
||||||
|
{
|
||||||
|
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user