From 0eed71c0a40f8b1e4688b522e11cdeaa8008157a Mon Sep 17 00:00:00 2001 From: jiahao Date: Sun, 24 Sep 2023 20:44:30 +0800 Subject: [PATCH] =?UTF-8?q?1.bgService=E6=AD=B8=E6=AA=94=E6=9C=8D=E5=8B=99?= =?UTF-8?q?-=E6=94=B9=E7=82=BA=E8=A3=9C=E5=84=9F=E6=A9=9F=E5=88=B6=202.?= =?UTF-8?q?=E5=89=8D=E5=8F=B0=20api=20=EF=BC=9A=E6=A3=9F=E5=88=A5=E5=90=8D?= =?UTF-8?q?=E7=A8=B1=E4=BF=AE=E6=AD=A3=E3=80=81=E6=AA=94=E6=A1=88=E4=B8=8B?= =?UTF-8?q?=E8=BC=89=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Backend/Models/Device.cs | 23 +- Backend/Models/SystemCategory.cs | 9 + .../Quartz/Jobs/ArchiveElectricMeterDayJob.cs | 885 +++++++++--------- .../Implement/ProcEletricMeterService.cs | 247 +++-- .../ApiControllers/HydroMeterController.cs | 13 +- FrontendWebApi/appsettings.Development.json | 3 +- 6 files changed, 682 insertions(+), 498 deletions(-) diff --git a/Backend/Models/Device.cs b/Backend/Models/Device.cs index 898d9ca..f13c69e 100644 --- a/Backend/Models/Device.cs +++ b/Backend/Models/Device.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Permissions; using System.Threading.Tasks; namespace Backend.Models @@ -77,9 +78,19 @@ namespace Backend.Models public string Device_ip { get; set; } public string Device_port { get; set; } public string device_name_tag { get; set; } - public string device_system_tag { get; set; } + public string device_system_tag { get; set; } public List Device_disasters { get; set; } //防災類型 public List Device_nodes { get; set; } //設備子節點 + + /// + /// 前次成功日期;下次重新歸檔日期 + /// + public System.DateTime archive_lastDate { get; set; } + + /// + /// 前次執行日期 + /// + public System.DateTime archive_lastActionDate { get; set; } } public class DeviceDisaster @@ -264,6 +275,16 @@ namespace Backend.Models public string DeviceNumber { get; set; } public string Point { get; set; } public string FullDeviceNumberPoint { get; set; } + + /// + /// 前次成功日期;下次重新歸檔日期 + /// + public System.DateTime archive_lastDate { get; set; } + + /// + /// 前次執行日期 + /// + //public System.DateTime archive_lastActionDate { get; set; } } public class ImportDevForCoo diff --git a/Backend/Models/SystemCategory.cs b/Backend/Models/SystemCategory.cs index ba54301..203598c 100644 --- a/Backend/Models/SystemCategory.cs +++ b/Backend/Models/SystemCategory.cs @@ -45,6 +45,15 @@ namespace Backend.Models public byte is_bool { get; set; } public byte is_link { get; set; } public int is_show_history { get; set; } + + /// + /// 歸檔作業暫存用 - 啟動的開始日期, value = (table)device.archive_lastDate 前次成功日期 + /// + public string start_archive_day { get; set; } + /// + /// 歸檔作業暫存用 - 啟動的結束日期, value = 執行的當下日期 + /// + public string end_archive_day { get; set; } } public class Checksame diff --git a/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs b/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs index 7fd1e35..4b40988 100644 --- a/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs +++ b/BackendWorkerService/Quartz/Jobs/ArchiveElectricMeterDayJob.cs @@ -79,11 +79,17 @@ namespace BackendWorkerService.Quartz.Jobs string archiveJson = null; JObject archiveJsonResult = new JObject(); #endregion - #region 找出所有電錶設備 - var sWhere_E4 = @$"device_name_tag = '{electricMeterGuid}' "; // and deleted = 0 "; - var sWhere_W1 = @$"device_name_tag = '{waterMeterGuid}'"; // and deleted = 0 "; + #region 找出所有電錶設備 與前次成功日期 + var sWhere_E4 = @$"device_name_tag = '{electricMeterGuid}' and deleted = 0 "; + var sWhere_W1 = @$"device_name_tag = '{waterMeterGuid}' and deleted = 0 "; var electricMeters = await backgroundServiceRepository.GetAllAsync("device", sWhere_E4); var waterMeters = await backgroundServiceRepository.GetAllAsync("device", sWhere_W1); + + var device_test = electricMeters.Where(e => e.Device_number == "NTPC_G6_EE_E4_B1F_CB3_WHT_N1").First(); + if (device_test != null) + { + logger.LogInformation($@"s1 devie_number = NTPC_G6_EE_E4_B1F_CB3_WHT_N1 archive_lastActionDate={device_test.archive_lastActionDate} archive_lastDate={device_test.archive_lastDate}"); + } #endregion 找出所有電錶設備 #region 找出所有電錶系統的點位 @@ -104,7 +110,7 @@ namespace BackendWorkerService.Quartz.Jobs deviceNumberPoint.DeviceNumber = electricMeter.Device_number; deviceNumberPoint.Point = point.points; deviceNumberPoint.FullDeviceNumberPoint = string.Format("{0}_{1}", electricMeter.Device_number, point.points); - + deviceNumberPoint.archive_lastDate = electricMeter.archive_lastDate; electricDeviceNumberPoints.Add(deviceNumberPoint); } } @@ -139,11 +145,8 @@ namespace BackendWorkerService.Quartz.Jobs obixApiConfig.UserName = ed.AESDecrypt(variableObix.Where(x => x.Name == "UserName").Select(x => x.Value).FirstOrDefault()); obixApiConfig.Password = ed.AESDecrypt(variableObix.Where(x => x.Name == "Password").Select(x => x.Value).FirstOrDefault()); String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(obixApiConfig.UserName + ":" + obixApiConfig.Password)); - #endregion 取得obix 設定 + #endregion 取得obix 設定 - var actionDay = DateTime.Now; // -- 改為 指定日期 -- - var startDay = actionDay.AddDays(-1); //開始日期 - var endDay = actionDay; //結束日期 #region 天歸檔 if (!await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Day")) @@ -151,437 +154,37 @@ namespace BackendWorkerService.Quartz.Jobs } else { + //記錄本次作業時間 於 task_detal.lastwork_time + await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Day", "水電表 day 任務開始"); + + #region 從前次 成功日期到昨天為止 + var actionDay = DateTime.Now; // -- 改為 指定日期 -- + var startDay = actionDay.AddDays(-1); //開始日期 + var endDay = actionDay; //結束日期 + + var dbDateName = startDay.Year.ToString().PadLeft(4, '0') + startDay.Month.ToString().PadLeft(2, '0'); + //Create 歸檔用 table + initWork(dbDateName); + try { - //記錄本次作業時間 於 task_detal.lastwork_time - await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Day", "水電表 day 任務開始"); - - var dbDateName = startDay.Year.ToString().PadLeft(4, '0') + startDay.Month.ToString().PadLeft(2, '0'); - - //Create 歸檔用 table - initWork(dbDateName); - - // --------- 需要變成指定日期 ---------------- - var startTimestamp = string.Format("{0}T00:00:00.000+08:00", startDay.ToString("yyyy-MM-dd")); - //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", endDay.ToString("yyyy-MM-dd")); - var endTimestamp = string.Format("{0}T00:00:10.000+08:00", endDay.ToString("yyyy-MM-dd")); - - var historyQueryFilter = $@" - - - - "; - // PT2D 需要設定超過1天 - - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - - //抓取每個設備的資料 - List> electericArchiveDayRawDatas = new List>(); - List> waterArchiveDayRawDatas = new List>(); - - #region old request niagara history by obix - //foreach (var deviceNumberPoint in electricDeviceNumberPoints) + //foreach (var electricMeter in electricMeters) //{ - // device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", ""); - // var station = backgroundServiceRepository.GetOneAsync($@"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; - // if (string.IsNullOrEmpty(station)) - // { - // continue; - // } - // 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); - // } - - // archiveResponse = (HttpWebResponse)archiveRequest.GetResponse(); - // archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd(); - // archiveResponse.Dispose(); - // archiveResponse.Close(); - - // xmlDocument.LoadXml(archiveResponseContent); - // archiveJson = JsonConvert.SerializeXmlNode(xmlDocument); - // archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson); - - // if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 - // { - // //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】"); - // //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult); - - // Dictionary archiveDayRawData = new Dictionary(); - // 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")); - - // electericArchiveDayRawDatas.Add(archiveDayRawData); - // } - - // if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容 - // { - // var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult); - // if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) - // { - // electericArchiveDayRawDatas.AddRange(ArrangeRawDatas); - // } - // } - //} - #endregion old request niagara history by obix - - //request niagara get data - // obixData_collect(ref device_number, xmlDocument, List DeviceNumberPoints, ObixApiConfig obixApiConfig, string encoded, string startTimestamp, string endTimestamp, string historyQueryFilter, List> waterArchiveDayRawDatas) - - //電錶結果收集 - procEletricMeterService.obixData_collect( xmlDocument, electricDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, electericArchiveDayRawDatas); - - //水錶結果收集 - procEletricMeterService.obixData_collect( xmlDocument, waterDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, waterArchiveDayRawDatas); - - stopWatch.Stop(); - logger.LogInformation("【ArchiveElectricMeterDayJob】【天歸檔】【效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds); - - if (electericArchiveDayRawDatas.Count() > 0) - { - var sql = $@" SET FOREIGN_KEY_CHECKS = 1; - UPDATE archive_electric_meter_day_{dbDateName} 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 archive_electric_meter_day_{dbDateName} ( - 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;"; - - var mySql = $@"BEGIN TRANSACTION; - IF OBJECT_ID(N'dbo.archive_electric_meter_day_{dbDateName}', N'U') is null - BEGIN - CREATE TABLE [dbo].[archive_electric_meter_day_{dbDateName}]( - [device_number] [varchar](50) NOT NULL, - [point] [varchar](20) NOT NULL, - [start_timestamp] [datetime] NOT NULL, - [end_timestamp] [datetime] NULL, - [count_rawdata] [int] NULL, - [min_rawdata] [decimal](15, 3) NULL, - [max_rawdata] [decimal](15, 3) NULL, - [kwh_result] [decimal](15, 3) NULL, - [avg_rawdata] [decimal](15, 3) NULL, - [sum_rawdata] [decimal](15, 3) NULL, - [is_complete] [tinyint] NULL, - [repeat_times] [int] NULL, - [fail_reason] [nvarchar](max) NULL, - [created_at] [datetime] NULL, - [updated_at] [datetime] NULL, - CONSTRAINT [PK_archive_electric_meter_day_{dbDateName}] PRIMARY KEY CLUSTERED - ( - [device_number] ASC, - [point] ASC, - [start_timestamp] ASC - )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] - ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] - - ALTER TABLE [dbo].[archive_electric_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_electric_meter_day_{dbDateName}_repeat_times] DEFAULT ((0)) FOR [repeat_times] - - ALTER TABLE [dbo].[archive_electric_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_electric_meter_day_{dbDateName}_created_at] DEFAULT (getdate()) FOR [created_at] - - ALTER TABLE [dbo].[archive_electric_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_electric_meter_day_{dbDateName}_updated_at] DEFAULT (NULL) FOR [updated_at] - - EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'is_complete' - - EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'repeat_times' - - EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'fail_reason' - END - - UPDATE archive_electric_meter_day_{dbDateName} 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 archive_electric_meter_day_{dbDateName} ( - 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;"; - await backgroundServiceRepository.ExecuteSql(sql, electericArchiveDayRawDatas); - if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1") - { - await backgroundServiceMsSqlRepository.ExecuteSql(mySql, electericArchiveDayRawDatas); - } - await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Day", "任務完成"); - - //#region 月總計 - //if (await task_Detail.GetNeedWorkTask("ArchiveElectricMeterDayJob", "Month")) + // startDay = DateTime.Parse(electricMeter.archive_lastDate.ToString("yyyy-MM-dd"));// 起始日 + //endDay = DateTime.Parse(DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd")); // 結束日 + //foreach (DateTime day in procEletricMeterService.EachDay(startDay, endDay)) //{ - // string targetTable = @$"archive_electric_meter_day_{dbDateName}"; - // 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); - // //每次都 update 整個月 - // 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, is_complete = 1"; - // try + // logger.LogInformation(@$"【EachDay】{electricMeter.Device_number} startDay=", startDay + " endDay=" + endDay); + // if (electricMeter.Device_number == "NTPC_G6_EE_E4_B1F_CB3_WHT_N1") // { - // await backgroundServiceMsSqlRepository.ExecuteSql(sql); - // await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Month", "任務完成"); + // logger.LogInformation($@"EachDay devie_number = NTPC_G6_EE_E4_B1F_CB3_WHT_N1 startDay={startDay} endDay={endDay}"); // } - // catch (Exception exception) - // { - // await task_Detail.WorkFail("ArchiveElectricMeterDayJob", "Month", exception.ToString()); - // logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】"); - // logger.LogError("【ArchiveElectricMeterDayJob】【月歸檔】【任務失敗】[Exception]:{0}", exception.ToString()); - // throw; - // } + // 每日資料製作 + await day_proc(procEletricMeterService, saveToMSDB, archiveResponse, electricDeviceNumberPoints, waterDeviceNumberPoints, obixApiConfig, encoded, startDay, endDay, dbDateName); + //} - //#endregion - } - if (waterArchiveDayRawDatas.Count() > 0) - { - var sql = $@" UPDATE archive_water_meter_day_{dbDateName} 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 archive_water_meter_day_{dbDateName} ( - 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;"; - - var mySql = $@"BEGIN TRANSACTION; - IF OBJECT_ID(N'dbo.archive_water_meter_day_{dbDateName}', N'U') is null - BEGIN - CREATE TABLE [dbo].[archive_water_meter_day_{dbDateName}]( - [device_number] [varchar](50) NOT NULL, - [point] [varchar](20) NOT NULL, - [start_timestamp] [datetime] NOT NULL, - [end_timestamp] [datetime] NULL, - [count_rawdata] [int] NULL, - [min_rawdata] [decimal](15, 3) NULL, - [max_rawdata] [decimal](15, 3) NULL, - [kwh_result] [decimal](15, 3) NULL, - [avg_rawdata] [decimal](15, 3) NULL, - [sum_rawdata] [decimal](15, 3) NULL, - [is_complete] [tinyint] NULL, - [repeat_times] [int] NULL, - [fail_reason] [nvarchar](max) NULL, - [created_at] [datetime] NULL, - [updated_at] [datetime] NULL, - CONSTRAINT [PK_archive_water_meter_day_{dbDateName}] PRIMARY KEY CLUSTERED - ( - [device_number] ASC, - [point] ASC, - [start_timestamp] ASC - )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] - ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] - - ALTER TABLE [dbo].[archive_water_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_water_meter_day_{dbDateName}_repeat_times] DEFAULT ((0)) FOR [repeat_times] - - ALTER TABLE [dbo].[archive_water_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_water_meter_day_{dbDateName}_created_at] DEFAULT (getdate()) FOR [created_at] - - ALTER TABLE [dbo].[archive_water_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_water_meter_day_{dbDateName}_updated_at] DEFAULT (NULL) FOR [updated_at] - - EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'is_complete' - - EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'repeat_times' - - EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'fail_reason' - END - - UPDATE archive_water_meter_day_{dbDateName} 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 archive_water_meter_day_{dbDateName} ( - 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;"; - await backgroundServiceRepository.ExecuteSql(sql, waterArchiveDayRawDatas); - if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1") - { - await backgroundServiceMsSqlRepository.ExecuteSql(mySql, waterArchiveDayRawDatas); - } - } + //} + await task_Detail.InsertWorkTime_End("ArchiveElectricMeterDayJob", "Day", "任務完成"); } catch (Exception exception) { @@ -597,6 +200,8 @@ namespace BackendWorkerService.Quartz.Jobs archiveResponse.Close(); } } + + #endregion } #endregion 天歸檔 @@ -1004,11 +609,13 @@ namespace BackendWorkerService.Quartz.Jobs try { await task_Detail.InsertWorkTime("ArchiveElectricMeterDayJob", "Month", "水電表月任務開始"); - var FirstDay = actionDay.AddDays(-actionDay.Day + 1); - var LastDay = actionDay.AddMonths(1).AddDays(-actionDay.AddMonths(1).Day); + //var FirstDay = actionDay.AddDays(-actionDay.Day + 1); + //var LastDay = actionDay.AddMonths(1).AddDays(-actionDay.AddMonths(1).Day); + var FirstDay = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-") + "01"); + var LastDay = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")); // 需要比原定日期增加 1天:因 Niagara 內部判斷為 < lastData, 並未包含結束當天 add by jiahao @2023-09-16 - var dayInMonth = DateTime.DaysInMonth(actionDay.Year, actionDay.Month) + 1; + var dayInMonth = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month) + 1; var startTimestamp = string.Format("{0}T00:00:00.000+08:00", FirstDay.ToString("yyyy-MM-dd")); //var endTimestamp = string.Format("{0}T23:59:59.000+08:00", LastDay.ToString("yyyy-MM-dd")); @@ -1020,6 +627,7 @@ namespace BackendWorkerService.Quartz.Jobs "; + logger.LogInformation("【ArchiveElectricMeterMonth】startTimestamp=", startTimestamp + " endTimestamp=" + endTimestamp); //Stopwatch stopWatch = new Stopwatch(); //stopWatch.Start(); @@ -1029,12 +637,15 @@ namespace BackendWorkerService.Quartz.Jobs //收集 niagara 電錶 Data - procEletricMeterService.obixData_collect(xmlDocument, electricDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, electricArchiveMonthRawDatas); + procEletricMeterService.obixData_collect_range(xmlDocument, electricDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, electricArchiveMonthRawDatas); //水錶結果收集 - procEletricMeterService.obixData_collect(xmlDocument, waterDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, waterArchiveMonthRawDatas); - + procEletricMeterService.obixData_collect_range(xmlDocument, waterDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, waterArchiveMonthRawDatas); + //if (electricMeters.Where(e => e.Device_number == "NTPC_D8_EE_E4_RF_Total_WHT_N1").Count() == 1) + //{ + // logger.LogInformation("【ArchiveElectricMeterDayMonth】有包含 NTPC_D8_EE_E4_RF_Total_WHT_N1 "); + //} #region old request niagara by obix //foreach (var deviceNumberPoint in electricDeviceNumberPoints) //{ @@ -1428,6 +1039,404 @@ namespace BackendWorkerService.Quartz.Jobs } } + private async Task day_proc( ProcEletricMeterService procEletricMeterService, string saveToMSDB, HttpWebResponse archiveResponse, List electricDeviceNumberPoints, List waterDeviceNumberPoints, ObixApiConfig obixApiConfig, string encoded, DateTime startDay, DateTime endDay, string dbDateName) + { + XmlDocument xmlDocument = new XmlDocument(); + + // --------- 需要變成指定日期 ---------------- + + // PT2D 需要設定超過1天 + + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + + //抓取每個設備的資料 + List> electericArchiveDayRawDatas = new List>(); + List> waterArchiveDayRawDatas = new List>(); + + #region old request niagara history by obix + //foreach (var deviceNumberPoint in electricDeviceNumberPoints) + //{ + // device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", ""); + // var station = backgroundServiceRepository.GetOneAsync($@"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; + // if (string.IsNullOrEmpty(station)) + // { + // continue; + // } + // 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); + // } + + // archiveResponse = (HttpWebResponse)archiveRequest.GetResponse(); + // archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd(); + // archiveResponse.Dispose(); + // archiveResponse.Close(); + + // xmlDocument.LoadXml(archiveResponseContent); + // archiveJson = JsonConvert.SerializeXmlNode(xmlDocument); + // archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson); + + // if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 + // { + // //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】"); + // //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult); + + // Dictionary archiveDayRawData = new Dictionary(); + // 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")); + + // electericArchiveDayRawDatas.Add(archiveDayRawData); + // } + + // if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容 + // { + // var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult); + // if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + // { + // electericArchiveDayRawDatas.AddRange(ArrangeRawDatas); + // } + // } + //} + #endregion old request niagara history by obix + + //request niagara get data NTPC_D8_EE_E4_RF_Total_WHT_N1 + //if (electricMeters.Where(e => e.Device_number == "NTPC_D8_EE_E4_RF_Total_WHT_N1").Count() == 1) + //{ + // logger.LogInformation("【ArchiveElectricMeterDayJob】有包含 NTPC_D8_EE_E4_RF_Total_WHT_N1 "); + //} + //if (electricDeviceNumberPoints..Device_number == "NTPC_G6_EE_E4_B1F_CB3_WHT_N1") + //{ + // logger.LogInformation($@"devie_number = NTPC_G6_EE_E4_B1F_CB3_WHT_N1 obix startDay={startTimestamp} endDay={endTimestamp}"); + //} + //電錶結果收集 + // procEletricMeterService.obixData_collect(xmlDocument, electricDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, electericArchiveDayRawDatas); + procEletricMeterService.obixData_collect(xmlDocument, electricDeviceNumberPoints, obixApiConfig, encoded, electericArchiveDayRawDatas); + + //水錶結果收集 + //procEletricMeterService.obixData_collect(xmlDocument, waterDeviceNumberPoints, obixApiConfig, encoded, startTimestamp, endTimestamp, historyQueryFilter, waterArchiveDayRawDatas); + procEletricMeterService.obixData_collect(xmlDocument, waterDeviceNumberPoints, obixApiConfig, encoded, waterArchiveDayRawDatas); + + stopWatch.Stop(); + logger.LogInformation("【ArchiveElectricMeterDayJob】【天歸檔】【效能檢驗】[取得資料花費時間]{0} 毫秒", stopWatch.ElapsedMilliseconds); + + if (electericArchiveDayRawDatas.Count() > 0) + { + var sql = $@" SET FOREIGN_KEY_CHECKS = 1; + UPDATE archive_electric_meter_day_{dbDateName} 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, + archive_lastDate = @updated_at, + archive_lastActionDate = @updated_at + WHERE device_number = @device_number + AND point = @point + AND start_timestamp = @start_timestamp; + + INSERT INTO archive_electric_meter_day_{dbDateName} ( + 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, + archive_lastDate, + archive_lastActionDate) + 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, + @updated_at, + @updated_at, + WHERE ROW_COUNT() = 0;"; + + var mySql = $@"BEGIN TRANSACTION; + IF OBJECT_ID(N'dbo.archive_electric_meter_day_{dbDateName}', N'U') is null + BEGIN + CREATE TABLE [dbo].[archive_electric_meter_day_{dbDateName}]( + [device_number] [varchar](50) NOT NULL, + [point] [varchar](20) NOT NULL, + [start_timestamp] [datetime] NOT NULL, + [end_timestamp] [datetime] NULL, + [count_rawdata] [int] NULL, + [min_rawdata] [decimal](15, 3) NULL, + [max_rawdata] [decimal](15, 3) NULL, + [kwh_result] [decimal](15, 3) NULL, + [avg_rawdata] [decimal](15, 3) NULL, + [sum_rawdata] [decimal](15, 3) NULL, + [is_complete] [tinyint] NULL, + [repeat_times] [int] NULL, + [fail_reason] [nvarchar](max) NULL, + [created_at] [datetime] NULL, + [updated_at] [datetime] NULL, + CONSTRAINT [PK_archive_electric_meter_day_{dbDateName}] PRIMARY KEY CLUSTERED + ( + [device_number] ASC, + [point] ASC, + [start_timestamp] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] + ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] + + ALTER TABLE [dbo].[archive_electric_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_electric_meter_day_{dbDateName}_repeat_times] DEFAULT ((0)) FOR [repeat_times] + + ALTER TABLE [dbo].[archive_electric_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_electric_meter_day_{dbDateName}_created_at] DEFAULT (getdate()) FOR [created_at] + + ALTER TABLE [dbo].[archive_electric_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_electric_meter_day_{dbDateName}_updated_at] DEFAULT (NULL) FOR [updated_at] + + EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'is_complete' + + EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'repeat_times' + + EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_electric_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'fail_reason' + END + + UPDATE archive_electric_meter_day_{dbDateName} 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 archive_electric_meter_day_{dbDateName} ( + 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;"; + + await backgroundServiceRepository.ExecuteSql(sql, electericArchiveDayRawDatas); + if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1") + { + await backgroundServiceMsSqlRepository.ExecuteSql(mySql, electericArchiveDayRawDatas); + } + } + if (waterArchiveDayRawDatas.Count() > 0) + { + var sql = $@" UPDATE archive_water_meter_day_{dbDateName} 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 archive_water_meter_day_{dbDateName} ( + 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;"; + + var mySql = $@"BEGIN TRANSACTION; + IF OBJECT_ID(N'dbo.archive_water_meter_day_{dbDateName}', N'U') is null + BEGIN + CREATE TABLE [dbo].[archive_water_meter_day_{dbDateName}]( + [device_number] [varchar](50) NOT NULL, + [point] [varchar](20) NOT NULL, + [start_timestamp] [datetime] NOT NULL, + [end_timestamp] [datetime] NULL, + [count_rawdata] [int] NULL, + [min_rawdata] [decimal](15, 3) NULL, + [max_rawdata] [decimal](15, 3) NULL, + [kwh_result] [decimal](15, 3) NULL, + [avg_rawdata] [decimal](15, 3) NULL, + [sum_rawdata] [decimal](15, 3) NULL, + [is_complete] [tinyint] NULL, + [repeat_times] [int] NULL, + [fail_reason] [nvarchar](max) NULL, + [created_at] [datetime] NULL, + [updated_at] [datetime] NULL, + CONSTRAINT [PK_archive_water_meter_day_{dbDateName}] PRIMARY KEY CLUSTERED + ( + [device_number] ASC, + [point] ASC, + [start_timestamp] ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] + ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] + + ALTER TABLE [dbo].[archive_water_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_water_meter_day_{dbDateName}_repeat_times] DEFAULT ((0)) FOR [repeat_times] + + ALTER TABLE [dbo].[archive_water_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_water_meter_day_{dbDateName}_created_at] DEFAULT (getdate()) FOR [created_at] + + ALTER TABLE [dbo].[archive_water_meter_day_{dbDateName}] ADD CONSTRAINT [DF_archive_water_meter_day_{dbDateName}_updated_at] DEFAULT (NULL) FOR [updated_at] + + EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'是否完成,0:未完成 1:完成' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'is_complete' + + EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'重複次數' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'repeat_times' + + EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'失敗原因' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'archive_water_meter_day_{dbDateName}', @level2type=N'COLUMN',@level2name=N'fail_reason' + END + + UPDATE archive_water_meter_day_{dbDateName} 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 archive_water_meter_day_{dbDateName} ( + 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;"; + await backgroundServiceRepository.ExecuteSql(sql, waterArchiveDayRawDatas); + if (!string.IsNullOrEmpty(saveToMSDB) && saveToMSDB == "1") + { + await backgroundServiceMsSqlRepository.ExecuteSql(mySql, waterArchiveDayRawDatas); + } + } + + } + ///// ///// 獲取 Niagara 資料,並儲存於 List 中 diff --git a/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs b/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs index bf704d1..54e59f9 100644 --- a/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs +++ b/BackendWorkerService/Services/Implement/ProcEletricMeterService.cs @@ -21,6 +21,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using BackendWorkerService.Quartz; using BackendWorkerService.Quartz.Jobs; using Microsoft.Extensions.Logging; +using Org.BouncyCastle.Asn1.Pkcs; namespace BackendWorkerService.Services.Implement { @@ -425,7 +426,7 @@ namespace BackendWorkerService.Services.Implement 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;"; + 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) @@ -955,78 +956,199 @@ namespace BackendWorkerService.Services.Implement /// /// /// - public void obixData_collect(XmlDocument xmlDocument, List DeviceNumberPoints, ObixApiConfig obixApiConfig, string encoded, string startTimestamp, string endTimestamp, string historyQueryFilter, List> resultArchiveDayRawDatas) + public void obixData_collect(XmlDocument xmlDocument, List DeviceNumberPoints, ObixApiConfig obixApiConfig, string encoded, List> resultArchiveDayRawDatas) { #region 水電錶 save to DB start foreach (var deviceNumberPoint in DeviceNumberPoints) - { - string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", ""); - var station = backgroundServiceRepository.GetOneAsync($@"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; + { + if (deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")) break; //如果是今天 就不要用歸檔了 - byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter); - using (Stream reqStream = archiveRequest.GetRequestStream()) + var startDay = string.Format("{0}T00:00:00.000+08:00", deviceNumberPoint.archive_lastDate.ToString("yyyy-MM-dd").Replace(" ", "T")); + var endDay = ""; + //var endTimestamp = string.Format("{0}+08:00", error_day.End_timestamp.Replace(" ", "T")); + //if (DateTime.Parse(startTimestamp).ToString("yyyy-MM-dd") == DateTime.Parse(endTimestamp).ToString("yyyy-MM-dd")) + //{ + // //同一天為 舊有格式 採用 endtime + // endDay = string.Format("{0}T00:00:10.000+08:00", DateTime.Parse(endTimestamp).AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T")); + //} + //else + //{ //不同天為新格式 採用 Start_timestamp + endDay = string.Format("{0}T00:00:10.000+08:00", DateTime.Parse(endDay).AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T")); + //} + logger.LogInformation($@"before startDay = {startDay} endDay={endDay}"); // ----------- log + + #region + foreach (DateTime day in EachDay(startDay, endDay)) { - reqStream.Write(byteArray, 0, byteArray.Length); - } + if (day.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")) break; //如果是今天 就不要用歸檔了 - var archiveResponse = (HttpWebResponse)archiveRequest.GetResponse(); - var archiveResponseContent = new StreamReader(archiveResponse.GetResponseStream()).ReadToEnd(); - archiveResponse.Dispose(); - archiveResponse.Close(); + var sDay = string.Format("{0}T00:00:00.000+08:00", day.ToString("yyyy-MM-dd").Replace(" ", "T")); + var eDay = string.Format("{0}T00:00:10.000+08:00", day.AddDays(1).ToString("yyyy-MM-dd").Replace(" ", "T")); + logger.LogInformation($@"after sDay = {sDay} eDay={eDay}"); // ----------- log - xmlDocument.LoadXml(archiveResponseContent); - var archiveJson = JsonConvert.SerializeXmlNode(xmlDocument); - var archiveJsonResult = (JObject)JsonConvert.DeserializeObject(archiveJson); + string historyQueryFilter = $@" + + + + "; + string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", ""); + var station = backgroundServiceRepository.GetOneAsync($@"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; - if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 - { - //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】"); - //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult); - Dictionary archiveDayRawData = new Dictionary(); - 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); - if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + byte[] byteArray = Encoding.UTF8.GetBytes(historyQueryFilter); + using (Stream reqStream = archiveRequest.GetRequestStream()) { - resultArchiveDayRawDatas.AddRange(ArrangeRawDatas); + 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_D8_EE_E4_RF_Total_WHT_N1") + //{ + // logger.LogError("obixData_collect - NTPC_D8_EE_E4_RF_Total_WHT_N1 s=" + startTimestamp.Replace("T", " ").Substring(0, 19) + " e = " + endTimestamp.Replace("T", " ").Substring(0, 19) + " json = " + archiveJsonResult); + //} + if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 + { + //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】"); + //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult); + + Dictionary archiveDayRawData = new Dictionary(); + 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")); + + resultArchiveDayRawDatas.Add(archiveDayRawData); + } + + if (archiveJsonResult.ContainsKey("obj")) //表示可以讀取到內容 + { + var ArrangeRawDatas = ArrangeRawData(deviceNumberPoint, archiveJsonResult); + if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + { + resultArchiveDayRawDatas.AddRange(ArrangeRawDatas); + } } } + #endregion } #endregion 水電錶作業 save to DB end } + public void obixData_collect_range(XmlDocument xmlDocument, List DeviceNumberPoints, ObixApiConfig obixApiConfig, string encoded, string startTimestamp, string endTimestamp, string historyQueryFilter, List> resultArchiveDayRawDatas) + { + + #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 + + foreach (var deviceNumberPoint in DevicePoints) + { + #region + // foreach (DateTime day in EachDay(startDay, endDay)) + //{ + string device_number = deviceNumberPoint.FullDeviceNumberPoint.Replace("$3", ""); + var station = backgroundServiceRepository.GetOneAsync($@"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(); + + 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") + //{ + // logger.LogError("obixData_collect - NTPC_D8_EE_E4_RF_Total_WHT_N1 s=" + startTimestamp.Replace("T", " ").Substring(0, 19) + " e = " + endTimestamp.Replace("T", " ").Substring(0, 19) + " json = " + archiveJsonResult); + //} + if (archiveJsonResult.ContainsKey("err")) //抓取錯誤 + { + //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】"); + //logger.LogError("【ArchiveElectricMeterDayJob】【天歸檔】【取得資料失敗】[錯誤內容]:{0}", archiveDayJsonResult); + + Dictionary archiveDayRawData = new Dictionary(); + 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); + if (ArrangeRawDatas != null && ArrangeRawDatas.Count() > 0) + { + resultArchiveDayRawDatas.AddRange(ArrangeRawDatas); + } + } + //} + #endregion + } + + #endregion 水電錶作業 save to DB end + } private List> ArrangeRawData(DeviceNumberPoint deviceNumberPoint, JObject jsonResult) { @@ -1185,6 +1307,25 @@ namespace BackendWorkerService.Services.Implement return arrangeRawDatas; } + /// + /// 回傳區間內的每一天 + /// + /// + /// + /// + public IEnumerable EachDay(string from, string thru) + { + var strtday = DateTime.Parse(from); + var endday = DateTime.Parse(thru); + for (var day = strtday.Date; day.Date <= endday.Date; day = day.AddDays(1)) + yield return day; + + /// 使用方式 + //foreach (DateTime day in EachDay(DateTime.Parse(date1), DateTime.Parse(date2))) + //{ + + //} + } } } diff --git a/FrontendWebApi/ApiControllers/HydroMeterController.cs b/FrontendWebApi/ApiControllers/HydroMeterController.cs index d8fd3d9..b1b025f 100644 --- a/FrontendWebApi/ApiControllers/HydroMeterController.cs +++ b/FrontendWebApi/ApiControllers/HydroMeterController.cs @@ -860,9 +860,11 @@ namespace FrontendWebApi.ApiControllers { bool flag = true; bool total_flag = false; + string outputFileName = input.Mode == HydroMeterInputSearchMode.All ? "用電月份比較_含分盤_" : "用電月份比較_"; if (input.Mode == HydroMeterInputSearchMode.Custom) { //flag = false; + total_flag = true; input.Mode = HydroMeterInputSearchMode.All; } @@ -978,7 +980,7 @@ namespace FrontendWebApi.ApiControllers { "綜合大樓", "體育舘", - "化工館", + "化工電機", "創新大樓", "學人會館", "綠能中心" @@ -999,7 +1001,7 @@ namespace FrontendWebApi.ApiControllers "機械館分盤", "電機館分盤", "學1-4舍空調總盤", - "學五舍總盤", + "學五舍五眷總盤", "8眷舍分盤", "企教分盤", "7眷舍分盤", @@ -1069,7 +1071,7 @@ namespace FrontendWebApi.ApiControllers flag = false; } - if ((flag && buildingName == "化工館" && deviceFullName == "電機館分盤") || (flag && buildingName == "綠能中心" && deviceFullName == "薄膜分盤")) + if ((flag && buildingName == "化工電機" && deviceFullName == "電機館分盤") || (flag && buildingName == "綠能中心" && deviceFullName == "薄膜分盤")) { row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex); cell = row.GetCell(columnIndex++) ?? row.CreateCell(columnIndex++); @@ -1196,7 +1198,8 @@ namespace FrontendWebApi.ApiControllers ms.Flush(); ms.Seek(0, SeekOrigin.Begin); Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition"); - return File(ms, "application/vnd.ms", @$"用電差異比較表{System.DateTime.Now.ToString("yyyyMMddHHmm")}.xlsx"); + + return File(ms, "application/vnd.ms", @$"{outputFileName}{System.DateTime.Now.ToString("yyyyMMddHHmm")}.xlsx"); } [HttpPost] @@ -1285,7 +1288,7 @@ order by e.report_priority, a.priority"; "機械館分盤", "電機館分盤", "學1-4舍空調總盤", - "學五舍總盤", + "學五舍五眷總盤", "8眷舍分盤", "企教分盤", "7眷舍分盤", diff --git a/FrontendWebApi/appsettings.Development.json b/FrontendWebApi/appsettings.Development.json index b87a385..afd6507 100644 --- a/FrontendWebApi/appsettings.Development.json +++ b/FrontendWebApi/appsettings.Development.json @@ -21,7 +21,8 @@ //"Database": "7gWfmZ28HGIJZbxEbK+0yg==", //tpe_dome_dome //"Database": "siTUcDaC/g2yGTMFWD72Kg==", //tpe_dome_hotel //"Database": "iuaY0h0+TWkir44/eZLDqw==", //tpe_dome_office - "Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //MCUT + //"Database": "Rq7Gn4x6LwBvVtl7GY8LbA==", //MCUT + "Database": "j9LOmjFh2/9PpuwnVB8ugqnKdBDJHx1AAT7aTWeh37E=", "Root": "SzdxEgaJJ7tcTCrUl2zKsA==", "Password": "FVAPxztxpY4gJJKQ/se4bQ==" }