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; namespace BackendWorkerService.Services.Implement { /// /// 電錶補償歸檔 /// 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 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; 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(sqlArchive); repeatTimes = Convert.ToInt32(variableArchive.Where(x => x.Name == "RepeatTimes").Select(x => x.Value).FirstOrDefault()); var saveToMSDB = await backgroundServiceRepository.GetOneAsync("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(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(); var station = await backgroundServiceRepository.GetOneAsync($@"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)); #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 = @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(sql_error_hour, new { RepeatTimes = repeatTimes }).ToList(); // List> archiveHourRawDatas = new List>(); // 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 = $@" // // // // "; // HttpWebRequest archiveHourRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~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 archiveDayRawData = new Dictionary(); // 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 天歸檔補償 string schema = await backgroundServiceRepository.GetOneAsync(@" select system_value from variable where system_type = 'project_name' and deleted = 0"); //取得所有須補償的設備資訊 targetTable = await backgroundServiceRepository.GetOneAsync($@" 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 "); if (!string.IsNullOrEmpty(targetTable)) { sql_error_day = string.Format(sql_error_format, targetTable); var electric_error_days = await backgroundServiceRepository.GetAllAsync(sql_error_day, new { RepeatTimes = repeatTimes }); List> electricArchiveDayRawDatas = new List>(); 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 = $@" "; HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~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 archiveDayRawData = new Dictionary(); 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); } } } } targetTable = await backgroundServiceRepository.GetOneAsync($@" 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(sql_error_day, new { RepeatTimes = repeatTimes }); List> waterArchiveDayRawDatas = new List>(); 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 = $@" "; HttpWebRequest archiveDayRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~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 archiveDayRawData = new Dictionary(); 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(sql_error_week, new { RepeatTimes = repeatTimes }); List> electricArchiveWeekRawDatas = new List>(); 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 = $@" "; HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~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 archiveWeekRawData = new Dictionary(); 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(sql_error_week, new { RepeatTimes = repeatTimes }); List> waterArchiveWeekRawDatas = new List>(); 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 = $@" "; HttpWebRequest archiveWeekRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~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 archiveWeekRawData = new Dictionary(); 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(sql_error_month, new { RepeatTimes = repeatTimes }); List> electricArchiveMonthRawDatas = new List>(); 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 = $@" "; HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~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 archiveMonthRawData = new Dictionary(); 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(sql_error_month, new { RepeatTimes = repeatTimes }); List> waterArchiveMonthRawDatas = new List>(); 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 = $@" "; HttpWebRequest archiveMonthRequest = (HttpWebRequest)WebRequest.Create($"{obixApiConfig.ApiBase}obix/histories/{station}/{deviceNumberPoint.FullDeviceNumberPoint}/~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 archiveMonthRawData = new Dictionary(); 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) { throw exception; } return result; } private List> ArrangeRawData(DeviceNumberPoint deviceNumberPoint, JObject jsonResult) { List> arrangeRawDatas = new List>(); try { 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 arrangeRawData = new Dictionary(); 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 = real["@val"].ToString() == "NaN" ? -1 : Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float); arrangeRawData.Add("@min_rawdata", min); break; case "max": var max = real["@val"].ToString() == "NaN" ? -1 : Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float); arrangeRawData.Add("@max_rawdata", max); break; case "avg": var avg = real["@val"].ToString() == "NaN" ? -1 : 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 arrangeRawData = new Dictionary(); 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 = real["@val"].ToString() == "NaN" ? -1 : Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float); arrangeRawData.Add("@min_rawdata", min); break; case "max": var max = real["@val"].ToString() == "NaN" ? -1 : Decimal.Parse(real["@val"].ToString(), System.Globalization.NumberStyles.Float); arrangeRawData.Add("@max_rawdata", max); break; case "avg": var avg = real["@val"].ToString() == "NaN" ? -1 : 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; } catch (Exception ex) { return arrangeRawDatas; } } } }