1456 lines
98 KiB
C#
1456 lines
98 KiB
C#
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;
|
||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||
using BackendWorkerService.Quartz;
|
||
using BackendWorkerService.Quartz.Jobs;
|
||
using Microsoft.Extensions.Logging;
|
||
using Org.BouncyCastle.Asn1.Pkcs;
|
||
using NPOI.SS.Formula.Functions;
|
||
using MySqlX.XDevAPI.Relational;
|
||
|
||
namespace BackendWorkerService.Services.Implement
|
||
{
|
||
/// <summary>
|
||
/// 電錶補償歸檔
|
||
/// </summary>
|
||
public class ProcEletricMeterService
|
||
{
|
||
private readonly ILogger<ProcEletricMeterService> logger;
|
||
private readonly IBackgroundServiceRepository backgroundServiceRepository;
|
||
private readonly IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository;
|
||
|
||
public ProcEletricMeterService(
|
||
ILogger<ProcEletricMeterService> logger,
|
||
IBackgroundServiceRepository backgroundServiceRepository,
|
||
IBackgroundServiceMsSqlRepository backgroundServiceMySqlRepository)
|
||
{
|
||
this.logger = logger;
|
||
this.backgroundServiceRepository = backgroundServiceRepository;
|
||
this.backgroundServiceMsSqlRepository = backgroundServiceMySqlRepository;
|
||
}
|
||
|
||
public async Task<bool> ArchiveData()
|
||
{
|
||
bool result = false;
|
||
int repeatTimes = 0;
|
||
string targetTable = string.Empty;
|
||
string sql_error_day = string.Empty;
|
||
|
||
EDFunction ed = new EDFunction();
|
||
XmlDocument xmlDocument = new XmlDocument();
|
||
var obixApiConfig = new ObixApiConfig();
|
||
string encoded = string.Empty;
|
||
//異常清單
|
||
Dictionary<string, string> dicError = new Dictionary<string, string>();
|
||
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");
|
||
var buildingStation = await backgroundServiceRepository.GetAllAsync<BuildStation>("select SUBSTRING_INDEX(system_value, '/', 1) system_value, system_key from variable where system_type = 'dashboard_total_elec' and deleted = 0 and (SUBSTRING_INDEX(system_value, '/', 1) != '' and SUBSTRING_INDEX(system_value, '/', 1) is not null)");
|
||
|
||
#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 AND (point = 'KWH' or point = 'RCV')";
|
||
|
||
//MY 新增/修改sql format
|
||
var MYsql_update_format = @"
|
||
UPDATE {0} SET
|
||
count_rawdata = @count_rawdata,
|
||
min_rawdata = round(@min_rawdata, 2),
|
||
max_rawdata = round(@max_rawdata, 2),
|
||
kwh_result = round(@max_rawdata, 2) - round(@min_rawdata, 2),
|
||
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,
|
||
kwh_result,
|
||
avg_rawdata,
|
||
sum_rawdata,
|
||
is_complete,
|
||
repeat_times,
|
||
fail_reason)
|
||
SELECT
|
||
@device_number,
|
||
@point,
|
||
@start_timestamp,
|
||
@end_timestamp,
|
||
@count_rawdata,
|
||
round(@min_rawdata, 2),
|
||
round(@max_rawdata, 2),
|
||
round(@max_rawdata, 2) - round(@min_rawdata, 2),
|
||
@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 = round(@min_rawdata, 2),
|
||
max_rawdata = round(@max_rawdata, 2),
|
||
kwh_result = round(@max_rawdata, 2) - round(@min_rawdata, 2),
|
||
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,
|
||
kwh_result
|
||
avg_rawdata,
|
||
sum_rawdata,
|
||
is_complete,
|
||
repeat_times,
|
||
fail_reason)
|
||
VALUES (
|
||
@device_number,
|
||
@point,
|
||
@start_timestamp,
|
||
@end_timestamp,
|
||
@count_rawdata,
|
||
round(@min_rawdata, 2),
|
||
round(@max_rawdata, 2),
|
||
round(@max_rawdata, 2) - round(@min_rawdata, 2),
|
||
@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/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
// //HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/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 天歸檔補償
|
||
#region 電錶補償 day
|
||
string schema = await backgroundServiceRepository.GetOneAsync<string>(@"
|
||
select system_value from variable where system_type = 'project_name' and deleted = 0");
|
||
//取得所有須補償的設備資訊
|
||
//targetTable = await backgroundServiceRepository.GetOneAsync<string>($@"
|
||
// select table_name
|
||
// from information_schema.`TABLES`
|
||
// where TABLE_NAME like 'archive_electric_meter_day%' and TABLE_SCHEMA = '{schema.Split('/')[0]}'
|
||
// order by TABLE_NAME desc limit 1 ");
|
||
var archiveTables = await backgroundServiceRepository.GetAllAsync<archiveTable>($@"
|
||
select archive_yyyymm from
|
||
(
|
||
select CONCAT(
|
||
'archive_electric_meter_day_',
|
||
year(start_timestamp),
|
||
case when MONTH(start_timestamp) < 10 then CONCAT('0' , MONTH(start_timestamp)) else MONTH(start_timestamp) end
|
||
) archive_yyyymm
|
||
from archive_electric_meter_month
|
||
where point = 'KWH' and is_complete = 0
|
||
)a
|
||
group by archive_yyyymm");
|
||
|
||
//if (!string.IsNullOrEmpty(targetTable))
|
||
//{
|
||
foreach (var tb_yyyymm in archiveTables)
|
||
{
|
||
targetTable = tb_yyyymm.archive_yyyymm;
|
||
sql_error_day = $@"SELECT * FROM {targetTable} WHERE is_complete = 0 AND repeat_times < @RepeatTimes AND (point = 'KWH' or point = 'RCV')";
|
||
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 startTimestamp = string.Format("{0}+08:00", DateTime.Parse(error_day.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
var startTimestamp = string.Format("{0}T00:00:00.000+08:00", DateTime.Parse(error_day.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
var endTimestamp = "";
|
||
//var endTimestamp = string.Format("{0}+08:00", error_day.End_timestamp.Replace(" ", "T"));
|
||
if (DateTime.Parse(error_day.Start_timestamp).ToString("yyyy-MM-dd") == DateTime.Parse(error_day.End_timestamp).ToString("yyyy-MM-dd"))
|
||
{
|
||
//同一天為 舊有格式 採用 endtime
|
||
endTimestamp = string.Format("{0}T00:00:10.000+08:00", DateTime.Parse(error_day.End_timestamp).AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
}
|
||
else
|
||
{ //不同天為新格式 採用 Start_timestamp
|
||
endTimestamp = string.Format("{0}T00:00:10.000+08:00", DateTime.Parse(error_day.Start_timestamp).AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
}
|
||
|
||
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
<abstime name='start' val='{startTimestamp}' />
|
||
<abstime name='end' val='{endTimestamp}' />
|
||
<reltime name='interval' val = 'PT2D' />
|
||
</obj>";
|
||
|
||
string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/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);
|
||
}
|
||
|
||
try
|
||
{
|
||
HttpWebResponse archiveDayResponse = (HttpWebResponse)archiveDayRequest.GetResponse();
|
||
var archiveDayResponseContent = new StreamReader(archiveDayResponse.GetResponseStream()).ReadToEnd();
|
||
|
||
xmlDocument.LoadXml(archiveDayResponseContent);
|
||
string archiveDayJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||
|
||
// logger.LogInformation( Environment.NewLine + " json = " + archiveDayJson + Environment.NewLine);
|
||
|
||
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, ref dicError);
|
||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||
{
|
||
electricArchiveDayRawDatas.AddRange(ArrangeRawDatas);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
logger.LogError("【ArchiveElectricMeterDayJob】【補償機制 - 天】【任務失敗】Device_number=" + error_day.Device_number + " point = " + error_day.Point + " date =" + error_day + " startTimestamp" + startTimestamp + " endTimestamp =" + endTimestamp);
|
||
logger.LogError("【ArchiveElectricMeterDayJob】【補償機制 - 天】【任務失敗】[Exception]:{0}", ex.ToString() + Environment.NewLine);
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
#region 月總計
|
||
string yyyymm = targetTable.Split('_')[targetTable.Split('_').Length - 1]; //取出 archive_electric_meter_day_202308 的最後一段 202308
|
||
string yyyy = yyyymm.Substring(0, 4);
|
||
string mm = yyyymm.Remove(0, 4);
|
||
//先清空 該月份的數據
|
||
string sql = @$"update archive_electric_meter_month set count_rawdata = 0, kwh_result = 0, max_rawdata = 0,
|
||
min_rawdata = 0, repeat_times = 0, is_complete = 0, fail_reason = null, updated_at = null
|
||
where `point` = 'KWH' and date(start_timestamp) = CONCAT('{yyyy}-{mm}', '-01'); ";
|
||
|
||
try
|
||
{
|
||
await backgroundServiceRepository.ExecuteSql(sql);
|
||
|
||
sql = $@"update archive_electric_meter_month a
|
||
join (
|
||
select device_number, `point`
|
||
, CONCAT('{yyyy}-{mm}', '-01') start_timestamp
|
||
, LAST_DAY('{yyyy}/{mm}/01') end_timestamp
|
||
, sum(count_rawdata) count_rawdata
|
||
, sum(kwh_result) kwh_result
|
||
, max(max_rawdata) max_rawdata
|
||
, MIN(min_rawdata) min_rawdata
|
||
from {targetTable} where point = 'KWH'
|
||
group by device_number, `point`
|
||
) b on a.device_number = b.device_number and a.`point` = b.`point` and date(a.start_timestamp) = date(b.start_timestamp)
|
||
set a.count_rawdata = b.count_rawdata, a.kwh_result = b.kwh_result, a.max_rawdata = b.max_rawdata, a.min_rawdata = b.min_rawdata, a.is_complete = 1, updated_at = now();";
|
||
await backgroundServiceRepository.ExecuteSql(sql);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//await task_Detail.WorkFail("ArchiveElectricMeterDayJob", "Compensate", ex.ToString());
|
||
logger.LogError("【ArchiveElectricMeterDayJob】【補償機制 - 月總計】【任務失敗】");
|
||
logger.LogError("【ArchiveElectricMeterDayJob】【補償機制 - 月總計】【任務失敗】[Exception]:{0}", ex.ToString() + Environment.NewLine + sql);
|
||
}
|
||
#endregion
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion 電錶補償 day
|
||
|
||
#region 水錶補償 day
|
||
|
||
targetTable = await backgroundServiceRepository.GetOneAsync<string>($@"
|
||
select table_name
|
||
from information_schema.`TABLES`
|
||
where TABLE_NAME like 'archive_water_meter_day%' and TABLE_SCHEMA = '{schema.Split('/')[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)
|
||
{
|
||
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 startTimestamp = string.Format("{0}+08:00", DateTime.Parse(error_day.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
var startTimestamp = string.Format("{0}T00:00:00.000+08:00", DateTime.Parse(error_day.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
|
||
//var endTimestamp = string.Format("{0}+08:00", error_day.End_timestamp.Replace(" ", "T"));
|
||
var endTimestamp = string.Format("{0}T00:00:01.000+08:00", DateTime.Parse(error_day.End_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
|
||
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
<abstime name='start' val='{startTimestamp}' />
|
||
<abstime name='end' val='{endTimestamp}' />
|
||
<reltime name='interval' val = 'PT2D' />
|
||
</obj>";
|
||
|
||
string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/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, ref dicError);
|
||
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 水錶補償 day
|
||
|
||
#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 startTimestamp = string.Format("{0}T00:00:00.000+08:00", DateTime.Parse(error_week.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
|
||
//var endTimestamp = string.Format("{0}+08:00", error_week.End_timestamp.Replace(" ", "T"));
|
||
var endTimestamp = string.Format("{0}T00:00:01.000+08:00", DateTime.Parse(error_week.End_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
//var endTimestamp = string.Format("{0}T00:00:01.000+08:00", DateTime.Parse(error_week.End_timestamp).ToString("dd/MM/yyyy").Replace(" ", "T"));
|
||
|
||
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
<abstime name='start' val='{startTimestamp}' />
|
||
<abstime name='end' val='{endTimestamp}' />
|
||
<reltime name='interval' val = 'PT8D' />
|
||
</obj>";
|
||
|
||
string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/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, ref dicError);
|
||
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 startTimestamp = string.Format("{0}T00:00:00.000+08:00", DateTime.Parse(error_week.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
var endTimestamp = string.Format("{0}T00:00:01.000+08:00", DateTime.Parse(error_week.End_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
<abstime name='start' val='{startTimestamp}' />
|
||
<abstime name='end' val='{endTimestamp}' />
|
||
<reltime name='interval' val = 'PT8D' />
|
||
</obj>";
|
||
|
||
string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
//HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/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, ref dicError);
|
||
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 startTimestamp = string.Format("{0}T00:00:00.000+08:00", DateTime.Parse(error_month.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
|
||
// var endTimestamp = string.Format("{0}T00:00:01.000+08:00", DateTime.Parse(error_month.End_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
|
||
// var startDateTime = Convert.ToDateTime(error_month.Start_timestamp);
|
||
// var dayInMonth = DateTime.DaysInMonth(startDateTime.Year, startDateTime.Month) + 1; //比原定的多加 1天
|
||
|
||
// var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
// <abstime name='start' val='{startTimestamp}' />
|
||
// <abstime name='end' val='{endTimestamp}' />
|
||
// <reltime name='interval' val = 'PT{dayInMonth}D' />
|
||
// </obj>";
|
||
|
||
// string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
// var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
// device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
// and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
// and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
// and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
// HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
// //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/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_error_update, electricArchiveMonthRawDatas);
|
||
// }
|
||
//}
|
||
|
||
//targetTable = "archive_water_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 startTimestamp = string.Format("{0}T00:00:00.000+08:00", DateTime.Parse(error_month.Start_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
// var endTimestamp = string.Format("{0}T00:00:01.000+08:00", DateTime.Parse(error_month.End_timestamp).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
|
||
|
||
// var startDateTime = Convert.ToDateTime(error_month.Start_timestamp);
|
||
// var dayInMonth = DateTime.DaysInMonth(startDateTime.Year, startDateTime.Month) + 1; //比原定的多加 1天
|
||
|
||
// var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
// <abstime name='start' val='{startTimestamp}' />
|
||
// <abstime name='end' val='{endTimestamp}' />
|
||
// <reltime name='interval' val = 'PT{dayInMonth}D' />
|
||
// </obj>";
|
||
|
||
// string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
// var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
// device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
// and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
// and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
// and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
// HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
// //HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/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_error_update, waterArchiveMonthRawDatas);
|
||
// }
|
||
//}
|
||
#endregion 月歸檔補償
|
||
|
||
result = true;
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
logger.LogError("【ProcEletricMeterService】【補償機制 - 任務失敗】");
|
||
logger.LogError("【ProcEletricMeterService】【補償機制 - 任務失敗】[Exception]:{0} {1}", exception.ToString());
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 獲取 Niagara 資料,並儲存於 List 中
|
||
/// </summary>
|
||
/// <param name="device_number"></param>
|
||
/// <param name="xmlDocument"></param>
|
||
/// <param name="DeviceNumberPoints"></param>
|
||
/// <param name="obixApiConfig"></param>
|
||
/// <param name="encoded"></param>
|
||
/// <param name="startTimestamp"></param>
|
||
/// <param name="endTimestamp"></param>
|
||
/// <param name="historyQueryFilter"></param>
|
||
/// <param name="waterArchiveDayRawDatas"></param>
|
||
public void obixData_collect(XmlDocument xmlDocument, List<DeviceNumberPoint> DeviceNumberPoints, ObixApiConfig obixApiConfig, string encoded, List<Dictionary<string, object>> resultArchiveDayRawDatas, ref Dictionary<string, string> dicError)
|
||
{
|
||
|
||
#region 水電錶 save to DB start
|
||
logger.LogInformation($@"s0 DeviceNumberPoints.Count() = {DeviceNumberPoints.Count().ToString()}");
|
||
foreach (var deviceNumberPoint in DeviceNumberPoints)
|
||
{
|
||
if (deviceNumberPoint.DeviceNumber == "NTPC_G6_EE_E4_B1F_CB1_WHT_N1") //NTPC_G6_EE_E4_B1F_CB2_WHT_N1 NTPC_G6_EE_E4_B1F_MVCB_WHT_N1
|
||
{
|
||
logger.LogInformation($@"s1 devie_number = NTPC_G6_EE_E4_B1F_CB1_WHT_N1 archive_lastDate={deviceNumberPoint.archive_lastDate}");
|
||
}
|
||
if (deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd"))
|
||
{
|
||
logger.LogInformation($@" foreach (var deviceNumberPoint in DeviceNumberPoints) 判斷為今天 不用跑 deviceNumberPoint.archive_lastDate = {deviceNumberPoint.archive_lastDate} "); // ----------- log
|
||
continue; //如果是今天 就不要用歸檔了
|
||
}
|
||
|
||
//var startDay = string.Format("{0}T00:00:00.000+08:00", deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd");
|
||
var endDay = System.DateTime.Now.ToString("yyyy-MM-dd");
|
||
|
||
//var startDay = string.Format("{0}T00:00:00.000+08:00", deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
//var endDay = System.DateTime.Now.AddDays(-29).ToString();
|
||
|
||
//logger.LogInformation($@"before startDay = {startDay} endDay={endDay}"); // ----------- log
|
||
|
||
#region
|
||
foreach (DateTime day in EachDay(startDay, endDay))
|
||
{
|
||
if (day.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd"))
|
||
{
|
||
//logger.LogInformation($@"s2 foreach (DateTime day in EachDay(startDay, endDay)) 判斷為今天 不用跑 day = {day} "); // ----------- log
|
||
break; //如果是今天 就不要用歸檔了
|
||
}
|
||
//logger.LogInformation(@$"obix query for {deviceNumberPoint.DeviceNumber} day = {day.ToString("yyyy-MM-dd")}");
|
||
|
||
var sDay = string.Format("{0}T00:00:00.000+08:00", day.ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
var eDay = string.Format("{0}T00:01:00.000+08:00", day.AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T"));
|
||
|
||
|
||
string historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
<abstime name='start' val='{sDay}' />
|
||
<abstime name='end' val='{eDay}' />
|
||
<reltime name='interval' val = 'PT2D' />
|
||
</obj>";
|
||
string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
|
||
//logger.LogInformation($@" {device_number} after sDay = {sDay} eDay={eDay}"); // ----------- log
|
||
|
||
var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
|
||
HttpWebRequest archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||
archiveRequest.Method = "POST";
|
||
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||
archiveRequest.PreAuthenticate = true;
|
||
|
||
// logger.LogInformation($@"url= {$"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/" + Environment.NewLine} {device_number} station = {station} task= {startDay} ~ {endDay} action ={sDay} ~ {eDay}"); // ----------- log
|
||
|
||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||
{
|
||
reqStream.Write(byteArray, 0, byteArray.Length);
|
||
}
|
||
|
||
var archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||
var archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||
archiveResponse.Dispose();
|
||
archiveResponse.Close();
|
||
|
||
xmlDocument.LoadXml(archiveResponseContent);
|
||
var archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||
var archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||
//if (device_number == "NTPC_G6_EE_E4_B1F_CB3_WHT_N1_KWH")
|
||
//{
|
||
// logger.LogError("obixData_collect - NTPC_G6_EE_E4_B1F_CB3_WHT_N1_KWH json = " + archiveJsonResult);
|
||
//}
|
||
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||
{
|
||
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
|
||
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult); archiveJsonResult
|
||
logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveJsonResult);
|
||
Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
|
||
archiveDayRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
|
||
archiveDayRawData.Add("@point", deviceNumberPoint.Point);
|
||
archiveDayRawData.Add("@start_timestamp", sDay.Replace("T", " ").Substring(0, 19));
|
||
archiveDayRawData.Add("@end_timestamp", eDay.Replace("T", " ").Substring(0, 19));
|
||
archiveDayRawData.Add("@is_complete", 0);
|
||
archiveDayRawData.Add("@repeat_times", 0);
|
||
archiveDayRawData.Add("@fail_reason", archiveJson);
|
||
|
||
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"));
|
||
|
||
//object vv = null;
|
||
//archiveDayRawData.TryGetValue("@start_timestamp",out vv).ToString();
|
||
//var cc = vv.ToString();
|
||
|
||
resultArchiveDayRawDatas.Add(archiveDayRawData);
|
||
if (!dicError.ContainsKey(deviceNumberPoint.DeviceNumber))
|
||
{
|
||
dicError.Add(deviceNumberPoint.DeviceNumber, day.ToString("yyyy-MM-dd")); //記錄異常設備與日期
|
||
}
|
||
}
|
||
|
||
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||
{
|
||
//logger.LogInformation("【ArchiveElectricMeterDayJob】【天歸檔】【OK】{0}", archiveJsonResult);
|
||
|
||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult, ref dicError); // <-- 解析內容中 也有判斷是否 max == 0 的收集
|
||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||
{
|
||
//logger.LogInformation(@$"obix result {deviceNumberPoint.DeviceNumber} day = {day.ToString("yyyy-MM-dd")} ArrangeRawDatas.count() = {ArrangeRawDatas.Count().ToString()}");
|
||
resultArchiveDayRawDatas.AddRange(ArrangeRawDatas);
|
||
}
|
||
else
|
||
{
|
||
if (!dicError.ContainsKey(deviceNumberPoint.DeviceNumber))
|
||
{
|
||
dicError.Add(deviceNumberPoint.DeviceNumber, day.ToString("yyyy-MM-dd")); //記錄異常設備與日期
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
#endregion 水電錶作業 save to DB end
|
||
|
||
string funish = string.Empty;
|
||
}
|
||
|
||
public void obixData_collect_range(XmlDocument xmlDocument, List<DeviceNumberPoint> DeviceNumberPoints, ObixApiConfig obixApiConfig, string encoded, List<Dictionary<string, object>> resultArchiveDayRawDatas)
|
||
{
|
||
//異常清單
|
||
Dictionary<string, string> dicError = new Dictionary<string, string>(); //僅需要記錄在 day 此處不需要
|
||
#region 水電錶 save to DB start
|
||
// 需要先 group by DeviceNumberPoints 因為已經展開日期
|
||
//var DevicePoints = DeviceNumberPoints
|
||
// .GroupBy(x => new { _FullDeviceNumberPoint = x.FullDeviceNumberPoint })
|
||
// .Select(x => new DeviceNumberPoint { FullDeviceNumberPoint = x.Key._FullDeviceNumberPoint }).ToList();
|
||
|
||
//logger.LogInformation($@"before groupby DeviceNumberPoints.Count() = {DeviceNumberPoints.Count().ToString()} after DevicePoints.Count() = {DevicePoints.Count().ToString()}"); // ----------- log
|
||
// string last_deviceNumber = string.Empty;
|
||
foreach (var deviceNumberPoint in DeviceNumberPoints)
|
||
{
|
||
//if (string.IsNullOrEmpty(last_deviceNumber)) last_deviceNumber = deviceNumberPoint.DeviceNumber;
|
||
//if (deviceNumberPoint.DeviceNumber == "NTPC_G6_EE_E4_B1F_CB3_WHT_N1")
|
||
//{
|
||
// logger.LogInformation($@"s1 devie_number = NTPC_G6_EE_E4_B1F_CB3_WHT_N1 archive_lastDate={deviceNumberPoint.archive_lastDate}");
|
||
//}
|
||
//if (deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd"))
|
||
//{
|
||
// logger.LogInformation($@" foreach (var deviceNumberPoint in DeviceNumberPoints) 判斷為今天 不用跑 deviceNumberPoint.archive_lastDate = {deviceNumberPoint.archive_lastDate} "); // ----------- log
|
||
// continue; //如果是今天 就不要用歸檔了
|
||
//}
|
||
|
||
var startDay = deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd");
|
||
var endDay = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
|
||
DateTime today = DateTime.Now;
|
||
|
||
logger.LogInformation($@"before startDay = {startDay} endDay={endDay}"); // ----------- log
|
||
|
||
#region
|
||
foreach (DateTime month in EachMonth(startDay, endDay))
|
||
{
|
||
// 需要比原定日期增加 1天:因 Niagara 內部判斷為 < lastData, 並未包含結束當天 add by jiahao @2023-09-16
|
||
//var dayInMonth = DateTime.DaysInMonth(day.Year, day.Month) +1; 、、(DateTime.Now - DateTime.Parse(startDay)).Days
|
||
var startTimestamp = "";
|
||
var endTimestamp = "";
|
||
var dayInMonth = 0;
|
||
// 區分當月與其他月份
|
||
if (month.ToString("yyyy-MM") == System.DateTime.Now.AddDays(-1).ToString("yyyy-MM"))
|
||
{
|
||
var preDay = today.AddDays(-1); //取得前一天
|
||
|
||
dayInMonth = DateTime.DaysInMonth(preDay.Year, preDay.Month);
|
||
var FirstDay = new DateTime(preDay.Year, preDay.Month, 1);
|
||
var LastDay = today;
|
||
startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd"));
|
||
endTimestamp = string.Format("{0}T00:01:00.000+08:00", LastDay.ToString("yyyy-MM-dd"));
|
||
}
|
||
else
|
||
{
|
||
dayInMonth = DateTime.DaysInMonth(month.Year, month.Month);
|
||
var FirstDay = new DateTime(month.Year, month.Month, 1);
|
||
var LastDay = new DateTime(month.Year, month.Month, dayInMonth).AddDays(1);
|
||
|
||
startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd"));
|
||
|
||
endTimestamp = string.Format("{0}T00:01:00.000+08:00", LastDay.ToString("yyyy-MM-dd"));
|
||
|
||
}
|
||
//var dayInMonth = (DateTime.Now - DateTime.Parse(today.ToString("yyyy-MM-") + "01")).Days + 1;
|
||
|
||
|
||
//var startTimestamp = string.Format("{0}T00:00:00.000+08:00", today.ToString("yyyy-MM-") + "01");
|
||
////var endTimestamp = string.Format("{0}T23:59:59.000+08:00", LastDay.ToString("yyyy-MM-dd"));
|
||
////var endTimestamp = string.Format("{0}T00:00:10.000+08:00", day.AddMonths(1).ToString("yyyy-MM-") + "01"); // by jiahao @2023-09-26
|
||
//var endTimestamp = string.Format("{0}T00:00:10.000+08:00", DateTime.Now.ToString("yyyy-MM-dd")); // by jiahao @2023-10-03
|
||
|
||
var historyQueryFilter = $@"<obj is='obix: HistoryFilter'>
|
||
<abstime name='start' val='{startTimestamp}' />
|
||
<abstime name='end' val='{endTimestamp}' />
|
||
<reltime name='interval' val = 'PT{(dayInMonth + 1)}D' />
|
||
</obj>";
|
||
|
||
|
||
string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "");
|
||
var station = backgroundServiceRepository.GetOneAsync<string>($@"select parent_path from import_niagara_item_history where device_building_tag = '{device_number.Split("_")[1].Replace("$3", "")}' and
|
||
device_system_tag = '{device_number.Split("_")[2]}' and device_name_tag = '{device_number.Split("_")[3]}'
|
||
and device_floor_tag = '{device_number.Split("_")[4]}' and device_master_tag = '{device_number.Split("_")[5]}'
|
||
and device_last_name_tag = '{device_number.Split("_")[6]}' and device_serial_tag = '{device_number.Split("_")[7]}'
|
||
and device_point_name = '{device_number.Split("_")[8]}'").Result;
|
||
HttpWebRequest archiveRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/");
|
||
//HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/H_E1_B1F_MVCB_MVCBH_V1/~historyRollup/");
|
||
archiveRequest.Method = "POST";
|
||
archiveRequest.Headers.Add("Authorization", "Basic " + encoded);
|
||
archiveRequest.PreAuthenticate = true;
|
||
|
||
|
||
byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter);
|
||
using (Stream reqStream = archiveRequest.GetRequestStream())
|
||
{
|
||
reqStream.Write(byteArray, 0, byteArray.Length);
|
||
}
|
||
|
||
var archiveResponse = (HttpWebResponse)archiveRequest.GetResponse();
|
||
var archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd();
|
||
archiveResponse.Dispose();
|
||
archiveResponse.Close();
|
||
|
||
//logger.LogInformation(@$"【ArchiveElectricMeterMonth】{device_number} startTimestamp={startTimestamp} endTimestamp= {endTimestamp} interval = PT{dayInMonth.ToString()}D url = {$"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", "")}/~historyRollup/"}");
|
||
|
||
|
||
xmlDocument.LoadXml(archiveResponseContent);
|
||
var archiveJson = JsonConvert.SerializeXmlNode(xmlDocument);
|
||
var archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson);
|
||
|
||
|
||
//if (device_number == "NTPC_D8_EE_E4_RF_Total_WHT_N1" || device_number == "NTPC_D8_EE_E4_RF_H2_WHT_N1")
|
||
//{
|
||
logger.LogInformation(@$"{device_number} json = {archiveJsonResult}");
|
||
//}
|
||
if (archiveJsonResult.ContainsKey("err")) //抓取錯誤
|
||
{
|
||
//logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】");
|
||
logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveJsonResult);
|
||
|
||
Dictionary<string, object> archiveDayRawData = new Dictionary<string, object>();
|
||
archiveDayRawData.Add("@device_number", deviceNumberPoint.DeviceNumber);
|
||
archiveDayRawData.Add("@point", deviceNumberPoint.Point);
|
||
archiveDayRawData.Add("@start_timestamp", startTimestamp.Replace("T", " ").Substring(0, 19));
|
||
archiveDayRawData.Add("@end_timestamp", endTimestamp.Replace("T", " ").Substring(0, 19));
|
||
archiveDayRawData.Add("@is_complete", 0);
|
||
archiveDayRawData.Add("@repeat_times", 0);
|
||
archiveDayRawData.Add("@fail_reason", archiveJson);
|
||
|
||
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"));
|
||
|
||
resultArchiveDayRawDatas.Add(archiveDayRawData);
|
||
}
|
||
|
||
if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容
|
||
{
|
||
var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult, ref dicError);
|
||
if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0)
|
||
{
|
||
resultArchiveDayRawDatas.AddRange(ArrangeRawDatas);
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
#endregion 水電錶作業 save to DB end
|
||
}
|
||
|
||
private List<Dictionary<string, object>> ArrangeRawData(DeviceNumberPoint deviceNumberPoint, JObject jsonResult, ref Dictionary<string, string> dicError)
|
||
{
|
||
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 = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
|
||
arrangeRawData.Add("@min_rawdata", min);
|
||
break;
|
||
case "max":
|
||
var max = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
|
||
arrangeRawData.Add("@max_rawdata", max);
|
||
|
||
//add by jiahao 2023-09-26
|
||
//if (max == 0)
|
||
//{
|
||
// if (!dicError.ContainsKey(deviceNumberPoint.DeviceNumber))
|
||
// {
|
||
// dicError.Add(deviceNumberPoint.DeviceNumber, arrangeRawData["@start_timestamp"].ToString()); //記錄異常設備與日期
|
||
// }
|
||
//}
|
||
|
||
break;
|
||
case "avg":
|
||
var avg = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
|
||
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 = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
|
||
arrangeRawData.Add("@min_rawdata", min);
|
||
break;
|
||
case "max":
|
||
var max = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
|
||
arrangeRawData.Add("@max_rawdata", max);
|
||
|
||
//add by jiahao 2023-09-26
|
||
//if (max == 0)
|
||
//{
|
||
// if (!dicError.ContainsKey(deviceNumberPoint.DeviceNumber))
|
||
// {
|
||
// dicError.Add(deviceNumberPoint.DeviceNumber, arrangeRawData["@start_timestamp"].ToString()); //記錄異常設備與日期
|
||
// }
|
||
//}
|
||
|
||
break;
|
||
case "avg":
|
||
var avg = Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float);
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 回傳區間內的每一天
|
||
/// </summary>
|
||
/// <param name="from"></param>
|
||
/// <param name="thru"></param>
|
||
/// <returns></returns>
|
||
public IEnumerable<DateTime> EachDay(string from, string thru)
|
||
{
|
||
var strtday = DateTime.Parse(from).AddDays(-15); //每次重做 2天 // 20241106 因明志Niagara最多存14天資料,故考慮資料回補的狀況增多至15天
|
||
var endday = DateTime.Parse(thru);
|
||
for (var day = strtday.Date; day.Date <= endday.Date; day = day.AddDays(1))
|
||
yield return day;
|
||
}
|
||
public IEnumerable<DateTime> EachMonth(string from, string thru)
|
||
{
|
||
var strtday = DateTime.Parse(from).AddMonths(-1);
|
||
var endday = DateTime.Parse(thru);
|
||
|
||
for (var _month = strtday.Date; _month <= endday; _month = _month.AddMonths(1))
|
||
{
|
||
yield return _month;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|