diff --git a/SolarPower/Quartz/Jobs/CalcPowerStationJobV2.cs b/SolarPower/Quartz/Jobs/CalcPowerStationJobV2.cs new file mode 100644 index 0000000..f3c2c2b --- /dev/null +++ b/SolarPower/Quartz/Jobs/CalcPowerStationJobV2.cs @@ -0,0 +1,852 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Quartz; +using SolarPower.Models.PowerStation; +using SolarPower.Repository.Interface; +using SolarPower.Services.Implement; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; + +namespace SolarPower.Quartz.Jobs +{ + [DisallowConcurrentExecution] + public class CalcPowerStationJobV2 : IJob + { + private readonly ILogger logger; + private readonly IPowerStationRepository powerStationRepository; + private readonly IConfiguration Configuration; + + public IWebHostEnvironment environment; + + private double carbonRate; + string calcPowerStationTime = ""; + + public CalcPowerStationJobV2( + ILogger logger, + IPowerStationRepository powerStationRepository, + IWebHostEnvironment environment, + IConfiguration Configuration) + { + this.logger = logger; + this.powerStationRepository = powerStationRepository; + this.environment = environment; + this.Configuration = Configuration; + } + + public async Task Execute(IJobExecutionContext context) + { + try + { + var DateTimeNow = DateTime.Now; + var dateTime = DateTimeNow.AddHours(-1).ToString("yyyy-MM-dd HH"); + logger.LogInformation("【CalcPowerStationJobV2】【任務開始】"); + + #region step1. 找出所有電站 + logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站資料】"); + var powerStations = await powerStationRepository.GetAllAsync(); + logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站資料】"); + logger.LogInformation("【CalcPowerStationJobV2】【電站資料"); + #endregion + + await ArchiveStation(powerStations, dateTime); + await ArchiveStationForPowerStationWithWinForm(powerStations, dateTime); + await ArchiveSensorWithWinForm(powerStations, dateTime); + await ArchiveInverter(powerStations, dateTime); + await ArchiveSensoravg(powerStations, dateTime); + await ArchiveMeter(powerStations, dateTime); + await ArchiveWeather(powerStations, dateTime); + + logger.LogInformation("【CalcPowerStationJobV2】【任務完成】"); + } + catch (Exception exception) + { + logger.LogError("【CalcPowerStationJobV2】[Exception] - {0}", exception.Message); + if (exception.InnerException != null) + { + logger.LogError("【CalcPowerStationJobV2】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + + private async Task ArchiveStation(List powerStations, string dateTime) + { + List powerStationHistoriesHour = new List(); + List calcPowerStations = new List(); + foreach (var powerStation in powerStations) + { + try + { + #region step2-1. 取得該電站的當前這小時的歷史資料 + var table_name = String.Format("s{1}01_station", powerStation.SiteDB, powerStation.Code); + var full_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, table_name); + var exist = await powerStationRepository.ExistTable(powerStation.SiteDB, table_name); + + if (string.IsNullOrEmpty(exist)) + { + logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_station資料表】"); + } + else + { + logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + var history = await powerStationRepository.GetPowerStationHistoryPerHour(dateTime, full_table_name); + + if (history == null) + { + logger.LogWarning("【CalcPowerStationJobV2】【查無電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + } + else + { + logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJobV2】【電站[{0}]在{1}的每小時歷史資料】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(history)); + + logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + history.PowerStationId = powerStation.Id; + history.Timestamp = Convert.ToDateTime(history.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); + + #region 計算單一電站每小時發電量、發電金額等資料 for history + + #region 發電金額 + history.MONEY = history.KWH * powerStation.PowerRate; + history.TODAYMONEY = history.TodayKWh * powerStation.PowerRate; + history.TOTALMONEY = history.TotalKWH * powerStation.PowerRate; + #endregion + + #region 減碳量 + carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate")); + history.CARBON = history.KWH * carbonRate; + history.TODAYCARBON = history.TodayKWh * carbonRate; + history.TOTALCARBON = history.TotalKWH * carbonRate; + #endregion + + #endregion + + powerStationHistoriesHour.Add(history); + + logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + } + } + #endregion + } + catch (Exception exception) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[Exception] - {0}", exception.Message); + if (exception.InnerException != null) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + if (!environment.IsDevelopment()) + { + #region step3. 將historiers INSERT 到 power_station_history_hour 資料表 + List history_properties = new List() + { + "PowerStationId", + "TIMESTAMP", + "SITEID", + "SITETYPE", + "KWH", + "TODAYKWH", + "TOTALKWH", + "KWHKWP", + "PR", + "MP", + "SolarHour", + "MONEY", + "CARBON", + "TODAYMONEY", + "TOTALMONEY", + "TODAYCARBON", + "TOTALCARBON" + }; + logger.LogInformation("【Insert PowerStationHistoryHour】【ArchiveStation】【開始寫入 PowerStationHistoryHour 資料】- {0}", dateTime); + await powerStationRepository.AddPowerStationHistory(powerStationHistoriesHour, history_properties); + logger.LogInformation("【Insert PowerStationHistoryHour】【ArchiveStation】【完成寫入 PowerStationHistoryHour 資料】- {0}", dateTime); + #endregion + } + } + + private async Task ArchiveStationForPowerStation(List powerStations, string dateTime) + { + List powerStationHistoriesHour = new List(); + List calcPowerStations = new List(); + foreach (var powerStation in powerStations) + { + try + { + var calcPowerStation = new PowerStation(); + calcPowerStation.Id = powerStation.Id; + #region step2-1. 取得該電站的當前這小時的歷史資料 + var table_name = String.Format("s{1}01_station", powerStation.SiteDB, powerStation.Code); + var full_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, table_name); + var exist = await powerStationRepository.ExistTable(powerStation.SiteDB, table_name); + + if (string.IsNullOrEmpty(exist)) + { + logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_station資料表】"); + } + else + { + #region 計算單一電站每小時發電量、發電金額等資料 for calcPowerStation + var dateTimeforPowerStation = DateTime.Now.AddHours(-1).ToString("yyyy-MM-dd");//取當天 + logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的每小時歷史資料 for calcPowerStation】", powerStation.Code, dateTimeforPowerStation); + var history_for_powerStation = await powerStationRepository.GetPowerStationHistoryPerHourForPowerStation(dateTimeforPowerStation, full_table_name); + if (history_for_powerStation == null) + { + logger.LogWarning("【CalcPowerStationJobV2】【查無電站[{0}]在{1}的每小時歷史資料 for calcPowerStation;發電量、發電金額等資料設定為0】", powerStation.Code, dateTimeforPowerStation); + calcPowerStation.kwh = 0; + calcPowerStation.Today_kWh = 0; + calcPowerStation.Total_kWh = 0; + calcPowerStation.Today_Money = 0; + calcPowerStation.Total_Money = 0; + calcPowerStation.Today_kwhkwp = 0; + calcPowerStation.Today_PR = 0; + calcPowerStation.Today_Carbon = 0; + calcPowerStation.Total_Carbon = 0; + calcPowerStation.SolarHour = 0; + } + else + { + logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的每小時歷史資料 for calcPowerStation】", powerStation.Code, dateTimeforPowerStation); + #region 發電量 + //每小時發電量(直接填寫 + calcPowerStation.kwh = history_for_powerStation.KWH; + //今日發電量(直接填寫 + calcPowerStation.Today_kWh = history_for_powerStation.TodayKWh; + //總發電量(直接填寫 + calcPowerStation.Total_kWh = history_for_powerStation.TotalKWH; + #endregion + + #region 發電金額 + history_for_powerStation.MONEY = history_for_powerStation.KWH * powerStation.PowerRate; + history_for_powerStation.TODAYMONEY = history_for_powerStation.TodayKWh * powerStation.PowerRate; + history_for_powerStation.TOTALMONEY = history_for_powerStation.TotalKWH * powerStation.PowerRate; + + //即時發電金額 + switch (powerStation.SolarType) + { + case (int)SolarTypeEnum.SelfSold: //自建躉售 + //今日發電金額 計算方式:todaykWh * 授電費率 + calcPowerStation.Today_Money = history_for_powerStation.TodayKWh * powerStation.PowerRate; + + ////總發電金額 計算方式:totalkWh * 授電費率 + calcPowerStation.Total_Money = history_for_powerStation.TotalKWH * powerStation.PowerRate; + break; + case (int)SolarTypeEnum.HireSold: //租建躉售 + //找出該電站的所有土地房屋資訊 + var landBuildings = await powerStationRepository.GetAllLandBuildingInfoByPowerStationId(powerStation.Id, powerStation.SiteDB); + var sumLeaseRate = 0.00; + var avgLeaseRate = 0.00; + + foreach (var landBuilding in landBuildings) + { + sumLeaseRate += landBuilding.LeaseRate; + } + + calcPowerStation.Today_Money = history_for_powerStation.TodayKWh * powerStation.PowerRate * sumLeaseRate / 100; + calcPowerStation.Total_Money = history_for_powerStation.TotalKWH * powerStation.PowerRate * sumLeaseRate / 100; + + break; + case (int)SolarTypeEnum.SelfUse: //自建自用 + + //今日發電金額 計算方式:todaykWh * 授電費率 + calcPowerStation.Today_Money = history_for_powerStation.TodayKWh * powerStation.PowerRate; + + //總發電金額 計算方式:totalkWh * 授電費率 + calcPowerStation.Total_Money = history_for_powerStation.TotalKWH * powerStation.PowerRate; + break; + } + #endregion + + #region kWh/kWp + ////直接填寫 + calcPowerStation.Today_kwhkwp = history_for_powerStation.KWHKWP; + #endregion + + #region PR + //直接填寫 + calcPowerStation.Today_PR = history_for_powerStation.PR; + #endregion + + #region 減碳量 + carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate")); + history_for_powerStation.CARBON = history_for_powerStation.KWH * carbonRate; + history_for_powerStation.TODAYCARBON = history_for_powerStation.TodayKWh * carbonRate; + history_for_powerStation.TOTALCARBON = history_for_powerStation.TotalKWH * carbonRate; + + //今日減碳量( 今日發電量 * (0.554/1000)[抓資料庫值] + calcPowerStation.Today_Carbon = history_for_powerStation.TodayKWh * carbonRate; + + //總減碳量(總發電量 * (0.554/1000)[抓資料庫值] + calcPowerStation.Total_Carbon = history_for_powerStation.TotalKWH * carbonRate; + #endregion + + #region 發電時間 + calcPowerStation.SolarHour = history_for_powerStation.SolarHour; + #endregion + + #region 取拿到資料的時間 + calcPowerStationTime = history_for_powerStation.Timestamp; + #endregion + } + #endregion + + string dateTimeForCalc; + if (calcPowerStationTime != "") + { + dateTimeForCalc = calcPowerStationTime; + } + else + { + dateTimeForCalc = dateTime; + } + + logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime); + var deviceInfos = await powerStationRepository.GetListPyrheliometerByPowerStationId(powerStation.Id, powerStation.SiteDB); + logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJobV2】【電站[{0}]在{1}的日照計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(deviceInfos)); + + if (deviceInfos != null && deviceInfos.Count() > 0) + { + var pyrheliometerHistory_for_calcPowerStation = await powerStationRepository.CalcSensorHistoryPerHour(dateTimeForCalc, deviceInfos, Convert.ToInt32(SensorTypeEnum.PYR)); + if (pyrheliometerHistory_for_calcPowerStation != null) + { + calcPowerStation.Today_irradiance = pyrheliometerHistory_for_calcPowerStation.Irradiance; + logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的日照計的平均值】", powerStation.Code, dateTime); + } + else + { + logger.LogWarning("【CalcPowerStationJobV2】【查無結果電站[{0}]在{1}的日照計的平均值】", powerStation.Code, dateTime); + } + } + calcPowerStations.Add(calcPowerStation); + logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + } + #endregion + } + catch (Exception exception) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[Exception] - {0}", exception.Message); + if (exception.InnerException != null) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + if (!environment.IsDevelopment()) + { + #region step5. calcPowerStations UPDATE 到 power_station 資料表 + List power_station_properties = new List() + { + "Id", + "kwh", + "Today_kwh", + "Total_kwh", + "today_kwhkwp", + "today_money", + "total_money", + "today_PR", + "today_carbon", + "total_carbon", + "today_irradiance", + "SolarHour", + "WeathersStationId", + "TodayWeatherTemp", + "TodayWeather", + "RateOfRain" + }; + logger.LogInformation("【update Power_Station】【ArchiveStation】【開始更新 Power_Station 資料】- {0}", dateTime); + await powerStationRepository.UpdateList(calcPowerStations, power_station_properties); + logger.LogInformation("【update Power_Station】【ArchiveStation】【完成更新 Power_Station 資料】- {0}", dateTime); + #endregion + } + } + + private async Task ArchiveStationForPowerStationWithWinForm(List powerStations, string dateTime) + { + logger.LogInformation("【CalcPowerStationJobV2】【開始計算全電站在{0}的發電量等資訊】", dateTime); + #region step2-2. 取得該電站的當前這小時的發電量等歷史資料 + //使用winform function + var Connection_string = Configuration.GetValue("mySql"); + SensorHourlyService sensorHourlyService = new SensorHourlyService(Connection_string); + await sensorHourlyService.ArchiveStationHourly(); + logger.LogInformation("【CalcPowerStationJobV2】【更新完成全電站在{0}的發電量等資訊】", dateTime); + #endregion + } + + private async Task ArchiveSensorWithWinForm(List powerStations, string dateTime) + { + foreach (var powerStation in powerStations) + { + try + { + var sensoravg_table_name = String.Format("s{1}01_sensoravg", powerStation.SiteDB, powerStation.Code); + var full_sensoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, sensoravg_table_name); + var sensoravg_table_exist = await powerStationRepository.ExistTable(powerStation.SiteDB, sensoravg_table_name); + if (string.IsNullOrEmpty(sensoravg_table_exist)) + { + logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_sensoravg資料表】"); + } + else + { + logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的設備資訊】", powerStation.Code, dateTime); + #region step2-2. 取得該電站的當前這小時的設備歷史資料 + //使用winform function + var Connection_string = Configuration.GetValue("mySql"); + SensorHourlyService sensorHourlyService = new SensorHourlyService(Connection_string); + sensorHourlyService.ArchiveSensorHourly(powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJobV2】【更新完成電站[{0}]在{1}的設備資訊】", powerStation.Code, dateTime); + #endregion + } + } + catch (Exception exception) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveSensor】[Exception] - {0}", exception.Message); + if (exception.InnerException != null) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveSensor】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + } + + private async Task ArchiveInverter(List powerStations, string dateTime) + { + List inverterHistoriesHour = new List(); + foreach (var powerStation in powerStations) + { + #region step2-3. 計算該電站所有逆變器每小時值 + + var inverter_table_name = String.Format("s{0}01_inv", powerStation.Code); + var full_inverter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, inverter_table_name); + var inverter_exist = await powerStationRepository.ExistTable(powerStation.SiteDB, inverter_table_name); + if (string.IsNullOrEmpty(inverter_exist)) + { + logger.LogError("【CalcPowerStationJobV2】【查無電站[0]的s{0}01_inv資料表】", powerStation.Code); + } + else + { + try + { + logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime); + var controllers = await powerStationRepository.GetAllDeviceControllerId(powerStation.Id, powerStation.SiteDB); + var inverters = await powerStationRepository.InverterTable(controllers, powerStation.SiteDB); + var inverterIds = inverters.Where(x => x.Enabled == 1 && x.Status != 0).Select(x => x.InverterId).ToList(); + logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJobV2】【電站[{0}]在{1}的逆變器設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(inverterIds)); + + if (inverterIds != null && inverterIds.Count() > 0) + { + logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime); + var inverterHistories = await powerStationRepository.CalcInverterHisyortHourData(dateTime, powerStation.SiteDB, full_inverter_table_name, inverterIds); + //取得日照計要找的欄位資訊 + var pyrheliometer = await powerStationRepository.GetFirstPyrheliometerInfo(powerStation.Id, powerStation.SiteDB); + var pyrheliometerValue = await powerStationRepository.GetFirstPyrheliometerValue(dateTime, pyrheliometer.DBName, pyrheliometer.TableName, pyrheliometer.ColName); + foreach (var inverterHistory in inverterHistories) + { + inverterHistory.Irradiance = pyrheliometerValue; + inverterHistory.DC1KW = inverterHistory.DC1W / 1000; + inverterHistory.DC2KW = inverterHistory.DC2W / 1000; + inverterHistory.DC3KW = inverterHistory.DC3W / 1000; + inverterHistory.DC4KW = inverterHistory.DC4W / 1000; + inverterHistory.DC5KW = inverterHistory.DC5W / 1000; + + inverterHistory.DCKW = (inverterHistory.DC1W + inverterHistory.DC2W + inverterHistory.DC3W + inverterHistory.DC4W + inverterHistory.DC5W) / 1000; + inverterHistory.ACKW = (inverterHistory.AC1W + inverterHistory.AC2W + inverterHistory.AC3W) / 1000; + + inverterHistory.TIMESTAMP = Convert.ToDateTime(inverterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); + inverterHistory.PowerStationId = powerStation.Id; + + inverterHistoriesHour.Add(inverterHistory); + } + logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime); + } + } + catch (Exception ex) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveInverter】【計算失敗電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime); + logger.LogError("【CalcPowerStationJobV2】【ArchiveInverter】【失敗原因】- {0}", ex.Message); + } + } + #endregion + } + if (!environment.IsDevelopment()) + { + #region step6. 將 inverter INSERT 到 inverter_history_hour 資料表 + List inverter_history_properties = new List() + { + "PowerStationId", + "INVERTERID", + "TIMESTAMP", + "Irradiance", + "AC1V", + "AC1A", + "AC1W", + "AC1F", + "AC1WH", + "AC2V", + "AC2A", + "AC2W", + "AC2F", + "AC2WH", + "AC3V", + "AC3A", + "AC3W", + "AC3F", + "AC3WH", + "DC1V", + "DC1A", + "DC1W", + "DC1KW", + "DC1WH", + "DC2V", + "DC2A", + "DC2W", + "DC2KW", + "DC2WH", + "DC3V", + "DC3A", + "DC3W", + "DC3KW", + "DC3WH", + "DC4V", + "DC4A", + "DC4W", + "DC4KW", + "DC4WH", + "DC5V", + "DC5A", + "DC5W", + "DC5KW", + "DC5WH", + "PR", + "RA1", + "RA2", + "RA3", + "RA4", + "RA5", + "DCKW", + "ACKW", + "KWH", + "TODAYKWH", + "TOTALKWH", + "KWHKWP", + }; + logger.LogInformation("【Insert InverterHistoryHour】【ArchiveInverter】【開始寫入 inverter_history_hour 資料】- {0}", dateTime); + await powerStationRepository.AddInverterHistory(inverterHistoriesHour, inverter_history_properties); + logger.LogInformation("【Insert InverterHistoryHour】【ArchiveInverter】【完成寫入 inverter_history_hour 資料】- {0}", dateTime); + #endregion + } + } + + private async Task ArchiveSensoravg(List powerStations, string dateTime) + { + List sensorAvgHistoryHour = new List(); + foreach (var powerStation in powerStations) + { + try + { + var sensoravg_table_name = String.Format("s{1}01_sensoravg", powerStation.SiteDB, powerStation.Code); + var full_sensoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, sensoravg_table_name); + var sensoravg_table_exist = await powerStationRepository.ExistTable(powerStation.SiteDB, sensoravg_table_name); + #region step2-4. 計算該電站所有sensoravg + try + { + if (!string.IsNullOrEmpty(sensoravg_table_exist)) + { + logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime); + var sensorAvgHistory = await powerStationRepository.CalcSensorAvgHistory(dateTime, full_sensoravg_table_name); + logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime); + + if (sensorAvgHistory != null) + { + sensorAvgHistory.PowerStationId = powerStation.Id; + sensorAvgHistory.TIMESTAMP = Convert.ToDateTime(sensorAvgHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); + + sensorAvgHistoryHour.Add(sensorAvgHistory); + } + } + } + catch (Exception ex) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】【計算失敗電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime); + logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】【失敗原因】- {0}", ex.Message); + } + #endregion + } + catch (Exception exception) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】[Exception] - {0}", exception.Message); + if (exception.InnerException != null) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + if (!environment.IsDevelopment()) + { + #region step7. 將 sensoravg INSERT 到 sensoravg_history_hour 資料表 + List sensoravg_history_properties = new List() + { + "PowerStationId", + "TIMESTAMP", + "SENSORAVG01", + "SENSORAVG02", + "SENSORAVG03", + "SENSORAVG04", + "SENSORAVG05", + "SENSORAVG06", + "SENSORAVG07", + "SENSORAVG08", + "SENSORAVG09", + "SENSORAVG10", + "SENSORAVG11", + "SENSORAVG12", + "SENSORAVG13", + "SENSORAVG14", + "SENSORAVG15", + "SENSORAVG16", + "SENSORAVG17", + "SENSORAVG18", + "SENSORAVG19", + "SENSORAVG20", + "SENSORAVG21", + "SENSORAVG22", + "SENSORAVG23", + "SENSORAVG24", + "SENSORAVG25", + "SENSORAVG26", + "SENSORAVG27", + "SENSORAVG28", + "SENSORAVG29", + "SENSORAVG30", + "SENSORAVG31", + "SENSORAVG32", + "SENSORAVG33", + "SENSORAVG34", + "SENSORAVG35", + "SENSORAVG36", + "SENSORAVG37", + "SENSORAVG38", + "SENSORAVG39", + "SENSORAVG40", + "SENSORAVG41", + "SENSORAVG42", + "SENSORAVG43", + "SENSORAVG44", + "SENSORAVG45", + "SENSORAVG46", + "SENSORAVG47", + "SENSORAVG48", + "SENSORAVG49", + "SENSORAVG50", + }; + logger.LogInformation("【Insert SensoravgHistoryHour】【ArchiveSensoravg】【開始寫入 sensoravg_history_hour 資料】- {0}", dateTime); + await powerStationRepository.AddSensorAvgHistory(sensorAvgHistoryHour, sensoravg_history_properties); + logger.LogInformation("【Insert SensoravgHistoryHour】【ArchiveSensoravg】【完成寫入 sensoravg_history_hour 資料】- {0}", dateTime); + #endregion + } + } + + private async Task ArchiveMeter(List powerStations, string dateTime) + { + List meterHistoriesHour = new List(); + foreach (var powerStation in powerStations) + { + try + { + var meter_table_name = String.Format("s{0}01_meter", powerStation.Code); + var full_meter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, meter_table_name); + var exist_meter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, meter_table_name); + #region step2-5. 計算該電站meter + try + { + if (string.IsNullOrEmpty(exist_meter_table)) + { + logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_meter資料表】"); + } + else + { + logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime); + var meterHistory = await powerStationRepository.CalcMeterHistory(dateTime, full_meter_table_name); + logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime); + + if (meterHistory != null) + { + meterHistory.PowerStationId = powerStation.Id; + meterHistory.TIMESTAMP = Convert.ToDateTime(meterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); + + meterHistoriesHour.Add(meterHistory); + } + } + } + catch (Exception ex) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】【計算失敗電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime); + logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】【失敗原因】- {0}", ex.Message); + } + #endregion + } + catch (Exception exception) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】[Exception] - {0}", exception.Message); + if (exception.InnerException != null) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + if (!environment.IsDevelopment()) + { + #region step8. 將 meter INSERT 到 meter_history_hour 資料表 + List memter_history_properties = new List() + { + "PowerStationId", + "TIMESTAMP", + "METERID", + "V_AB", + "V_BC", + "V_CA", + "I_A", + "I_B", + "I_C", + "I_C", + "P", + "F", + "INPUT_KWH", + "OUTPUT_KWH" + }; + logger.LogInformation("【Insert MeterHistoryHour】【ArchiveMeter】【開始寫入 meter_history_hour 資料】- {0}", dateTime); + await powerStationRepository.AddMeterHistory(meterHistoriesHour, memter_history_properties); + logger.LogInformation("【Insert MeterHistoryHour】【ArchiveMeter】【完成寫入 meter_history_hour 資料】- {0}", dateTime); + #endregion + } + } + + private async Task ArchiveWeather(List powerStations, string dateTime) + { + Root2 observation = null; + List weatherObservations = new List(); + #region 氣象觀測(取資料) + try + { + logger.LogInformation("【CalcPowerStationJobV2】【開始取得氣象觀測】"); + var client = new HttpClient(); + var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=TIME,TEMP"; + HttpResponseMessage response = client.GetAsync(UVUri).Result; + String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString(); + observation = JsonConvert.DeserializeObject(jsonUVs); + logger.LogInformation("【CalcPowerStationJobV2】【取得成功氣象觀測】"); + } + catch (Exception ex) + { + logger.LogError("【CalcPowerStationJobV2】【取得失敗氣象觀測】"); + logger.LogError("【{0}】{1}", "CalcPowerStationJobV2", ex.Message); + observation = null; + } + #endregion + foreach (var powerStation in powerStations) + { + try + { + var calcPowerStation = new PowerStation(); + calcPowerStation.Id = powerStation.Id; + #region 確認是否有觀測站(沒有則新增) + try + { + if (powerStation.WeathersStationId == null) + { + var weatherStationId = ""; + double shortLocation = 9999; + foreach (var Location in observation.Records.Location) + { + + if (powerStation.Coordinate != null) + { + var powerLocation = powerStation.Coordinate.Split(','); + double p1 = Convert.ToDouble(powerLocation[0].Replace("°", string.Empty)); + double p2 = Convert.ToDouble(powerLocation[1].Replace("°", string.Empty)); + double dLat = Convert.ToDouble(Location.Lat); + double dLon = Convert.ToDouble(Location.Lon); + double x = Math.Pow(p1 - dLat, 2); + double y = Math.Pow(p2 - dLon, 2); + var nowLocation = Math.Sqrt(x + y); + if (nowLocation < shortLocation) + { + shortLocation = nowLocation; + weatherStationId = Location.StationId; + calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue); + } + } + } + + calcPowerStation.WeathersStationId = weatherStationId; + } + + WeatherObservation weatherObservation = new WeatherObservation(); + if (powerStation.WeathersStationId != null && observation != null) + { + foreach (var Location in observation.Records.Location) + { + if (Location.StationId == powerStation.WeathersStationId) + { + calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue); + weatherObservation.PowerStationId = powerStation.Id; + weatherObservation.Temp = Convert.ToDouble(Location.WeatherElement[0].ElementValue); + weatherObservation.ObsTime = !string.IsNullOrEmpty(Location.Time.ObsTime) ? Convert.ToInt32(Location.Time.ObsTime.Substring(0, 4)) >= 1971 ? Location.Time.ObsTime : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + calcPowerStation.WeathersStationId = powerStation.WeathersStationId; + break; + } + } + weatherObservations.Add(weatherObservation); + } + + logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); + var weather = await powerStationRepository.SelectNowWeather(powerStation.CityId); + logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); + if (weather != null) + { + calcPowerStation.TodayWeather = weather.WeatherKey; + calcPowerStation.RateOfRain = weather.PoP; + } + } + catch (Exception ex) + { + logger.LogError("【CalcPowerStationJobV2】【ArchiveWeather】【取得失敗電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); + logger.LogError("【CalcPowerStationJobV2】【ArchiveWeather】【失敗原因】- {0}", ex.Message); + } + #endregion + } + catch (Exception exception) + { + //logger.LogError("【CalcPowerStationJobV2】[Exception] - {0}", exception.Message); + if (exception.InnerException != null) + { + //logger.LogError("【CalcPowerStationJobV2】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + if (!environment.IsDevelopment()) + { + #region step9. 新增天氣資訊 + List weather_observation_properties = new List() + { + "PowerStationId", + "ObsTime", + "Temp" + }; + logger.LogInformation("【Insert WeatherObservation】【ArchiveWeather】【開始寫入 weather_observation 資料】- {0}", dateTime); + await powerStationRepository.AddWeatherObservation(weatherObservations, weather_observation_properties); + logger.LogInformation("【Insert WeatherObservation】【ArchiveWeather】【完成寫入 weather_observation 資料】- {0}", dateTime); + #endregion + } + } + + } +} diff --git a/SolarPower/Services/Implement/SensorHourlyService.cs b/SolarPower/Services/Implement/SensorHourlyService.cs new file mode 100644 index 0000000..b57d3f6 --- /dev/null +++ b/SolarPower/Services/Implement/SensorHourlyService.cs @@ -0,0 +1,107 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using solarApp.Service; +using Microsoft.Extensions.Logging; +using System.Configuration; + +namespace SolarPower.Services.Implement +{ + public class SensorHourlyService + { + ILogger _logger; + procArchiveSensorHourly sensorSvc; + procArchiveHourly HourSvc; + string Connection1 = string.Empty; + + public SensorHourlyService(string Connection_parame = null, ILogger logger = null) + { + if (!string.IsNullOrEmpty(Connection_parame)) + { + Connection1 = Connection_parame; + } + else + { + Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; + } + sensorSvc = new procArchiveSensorHourly(Connection1); + HourSvc = new procArchiveHourly(Connection1); + if (logger != null) + { + _logger = logger; + } + } + + + + public void ArchiveSensorHourly(string code, string dateTime) + { + #region 歸檔 Sensor + try + { + if (_logger != null) + { + _logger.LogInformation("【SenSorHourlyService】【ArchiveSensorHourly】使用winform,開始執行[{0}]在{1}寫入資料", code, dateTime); + } + sensorSvc.insertData(code, dateTime); + if (_logger != null) + { + _logger.LogInformation("【SenSorHourlyService】【ArchiveSensorHourly】完成執行[{0}]在{1}寫入資料", code, dateTime); + } + } + catch (Exception exception) + { + if (_logger != null) + { + _logger.LogError("【SenSorHourlyService】【ArchiveSensorHourly】[Exception] - {0}", exception.Message); + } + if (exception.InnerException != null) + { + if (_logger != null) + { + _logger.LogError("【SenSorHourlyService】【ArchiveSensorHourly】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + #endregion + if (_logger != null) + { + _logger.LogInformation("【SenSorHourlyService】【ArchiveSensorHourly】[執行完成] "); + } + } + + public Task ArchiveStationHourly() + { + bool result = false; + #region 歸檔 Station + try + { + HourSvc.proc_s1_site(); + result = true; + } + catch (Exception exception) + { + if (_logger != null) + { + _logger.LogError("【SenSorHourlyService】【ArchiveStationHourly】[Exception] - {0}", exception.Message); + } + if (exception.InnerException != null) + { + if (_logger != null) + { + _logger.LogError("【SenSorHourlyService】【ArchiveStationHourly】[InnerException] - {0}", exception.InnerException.Message); + } + } + } + #endregion + if (_logger != null) + { + _logger.LogInformation("【SenSorHourlyService】【ArchiveStationHourly】[執行完成] "); + } + return Task.FromResult(result); + } + + } +} diff --git a/SolarPower/Startup.cs b/SolarPower/Startup.cs index 6b749ed..fcc705c 100644 --- a/SolarPower/Startup.cs +++ b/SolarPower/Startup.cs @@ -116,11 +116,19 @@ namespace SolarPower ); //#endregion + ////#region pqoqqT(CI5) + //services.AddSingleton(); + //services.AddSingleton( + //new JobSchedule(jobType: typeof(CalcPowerStationJob), cronExpression: Configuration.GetValue("BackgroundServiceCron:CalcPowerStationJob")) + ////new JobSchedule(jobType: typeof(CalcPowerStationJob), cronExpression: "0/10 * * * * ?") + //); + ////#endregion + //#region pqoqqT(CI5) - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton( - new JobSchedule(jobType: typeof(CalcPowerStationJob), cronExpression: Configuration.GetValue("BackgroundServiceCron:CalcPowerStationJob")) - //new JobSchedule(jobType: typeof(CalcPowerStationJob), cronExpression: "0/10 * * * * ?") + new JobSchedule(jobType: typeof(CalcPowerStationJobV2), cronExpression: Configuration.GetValue("BackgroundServiceCron:CalcPowerStationJobV2")) + //new JobSchedule(jobType: typeof(CalcPowerStationJobV2), cronExpression: "0/10 * * * * ?") ); //#endregion diff --git a/SolarPower/appsettings.Development.json b/SolarPower/appsettings.Development.json index 61c6373..a99f73e 100644 --- a/SolarPower/appsettings.Development.json +++ b/SolarPower/appsettings.Development.json @@ -15,7 +15,8 @@ // "Root": "mWlR2HshQNhRRE34jg4kdg==", // "Password": "y4uPqlH9ncTgR/I07qpwaA==" //}, - "mySql": "server=210.61.91.43;user=idafenweb;Database=solar_master;Port=10068;password=P@ssw0rd;charset='utf8';pooling=true;sslmode=none;", + //"mySql": "server=210.61.91.43;user=idafenweb;Database=solar_master;Port=10068;password=P@ssw0rd;charset='utf8';pooling=true;sslmode=none;", + "mySql": "server=60.251.164.103;user=webuser;Database=solar_master;Port=11306;password=FICadmin99;charset='utf8';pooling=true;sslmode=none;", // "DBConfig": { "Server": "AVXfxd+IRlLtJ0MCi9HU1g==", @@ -34,6 +35,7 @@ //}, "BackgroundServiceCron": { "CalcPowerStationJob": "0 05 * * * ?", + "CalcPowerStationJobV2": "0 05 * * * ?", "CalcAvgPowerStationJob": "0 12 0 * * ?", "OperationScheduleJob": "0 0 8 * * ?", "CalcInverter15minJob": "0 2/15 * * * ?", diff --git a/SolarPower/appsettings.json b/SolarPower/appsettings.json index 5d1ba96..3153171 100644 --- a/SolarPower/appsettings.json +++ b/SolarPower/appsettings.json @@ -36,6 +36,7 @@ }, "BackgroundServiceCron": { "CalcPowerStationJob": "0 05 * * * ?", + "CalcPowerStationJobV2": "0 05 * * * ?", "CalcAvgPowerStationJob": "0 12 0 * * ?", "OperationScheduleJob": "0 0 8 * * ?", "CalcInverter15minJob": "0 2/15 * * * ?", diff --git a/solarApp/Service/getStationSvc.cs b/solarApp/Service/getStationSvc.cs index 730f73b..7c71f36 100644 --- a/solarApp/Service/getStationSvc.cs +++ b/solarApp/Service/getStationSvc.cs @@ -13,7 +13,20 @@ namespace solarApp.Service /// public class getStationSvc { - string Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; + string Connection1 = ""; + public getStationSvc(string Connection_parame = null) + { + if (!string.IsNullOrEmpty(Connection_parame)) + { + Connection1 = Connection_parame; + } + else + { + Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; + } + + } + //string Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; protected string tableName = "power_station"; /// /// 電站 Raw Data @@ -195,7 +208,7 @@ namespace solarApp.Service string sql = @" select * from power_station where deleted = 0 and `status`= 1"; - List ds = conn.Query(sql).AsList(); + List ds = conn.Query(sql, commandTimeout: 600).AsList(); conn.Close(); return ds; } diff --git a/solarApp/Service/procArchiveHourly.cs b/solarApp/Service/procArchiveHourly.cs index be0c5a0..b3712bf 100644 --- a/solarApp/Service/procArchiveHourly.cs +++ b/solarApp/Service/procArchiveHourly.cs @@ -6,18 +6,31 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using solarApp.Model; using static solarApp.Model.weather_model; +using System.Configuration; namespace solarApp.Service { public class procArchiveHourly { - // private readonly ILogger logger; private readonly ILogger logger; private double carbonRate; //public procArchiveHourly(ILogger logger) //{ // this.logger = logger; //} + string Connection1 = string.Empty; + + public procArchiveHourly(string Connection_parame = null) + { + if (!string.IsNullOrEmpty(Connection_parame)) + { + Connection1 = Connection_parame; + } + else + { + Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; + } + } public List proc_s1_site() { List calcPowerStations = new List(); try @@ -36,8 +49,7 @@ namespace solarApp.Service #region step1. 找出所有電站 // logger.LogInformation("【CalcPowerStationJob】【開始取得電站資料】"); - //var powerStations = powerStationRepository.GetAllAsync(); - getStationSvc stationSvc = new getStationSvc(); + getStationSvc stationSvc = new getStationSvc(Connection1); var powerStations = stationSvc.get_powerStation(); // logger.LogInformation("【CalcPowerStationJob】【取得成功電站資料】"); // logger.LogInformation("【CalcPowerStationJob】【電站資料】 - {0}", System.Text.Json.JsonSerializer.Serialize(powerStations)); @@ -55,22 +67,22 @@ namespace solarApp.Service List weatherObservations = new List(); #region 氣象觀測(取資料) - try - { - // logger.LogInformation("【CalcPowerStationJob】【開始取得氣象觀測】"); - var client = new HttpClient(); - var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=TIME,TEMP"; - HttpResponseMessage response = client.GetAsync(UVUri).Result; - String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString(); - observation = JsonConvert.DeserializeObject(jsonUVs); - // logger.LogInformation("【CalcPowerStationJob】【取得成功氣象觀測】"); - } - catch (Exception ex) - { - // logger.LogError("【CalcPowerStationJob】【取得失敗氣象觀測】"); - // logger.LogError("【{0}】{1}", "CalcPowerStationJob", ex.Message); - observation = null; - } + //try + //{ + // // logger.LogInformation("【CalcPowerStationJob】【開始取得氣象觀測】"); + // var client = new HttpClient(); + // var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=TIME,TEMP"; + // HttpResponseMessage response = client.GetAsync(UVUri).Result; + // String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString(); + // observation = JsonConvert.DeserializeObject(jsonUVs); + // // logger.LogInformation("【CalcPowerStationJob】【取得成功氣象觀測】"); + //} + //catch (Exception ex) + //{ + // // logger.LogError("【CalcPowerStationJob】【取得失敗氣象觀測】"); + // // logger.LogError("【{0}】{1}", "CalcPowerStationJob", ex.Message); + // observation = null; + //} #endregion #region step2. 從電站的DB及電站編號找出該電站的控制器 diff --git a/solarApp/Service/procArchiveSensorHourly.cs b/solarApp/Service/procArchiveSensorHourly.cs index ad64454..fe052f1 100644 --- a/solarApp/Service/procArchiveSensorHourly.cs +++ b/solarApp/Service/procArchiveSensorHourly.cs @@ -20,7 +20,7 @@ namespace solarApp.Service public string _date1 { get; set; } //public string _date2 { get; set; } public string _powerStationID { get; set; } - public procArchiveSensorHourly(string Connection_parame = null, ILogger logger = null) + public procArchiveSensorHourly(string Connection_parame = null) { if (!string.IsNullOrEmpty(Connection_parame)) { @@ -31,10 +31,6 @@ namespace solarApp.Service Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; } - if (logger != null) - { - _logger = logger; - } } public bool get_siteInfo() @@ -48,13 +44,13 @@ namespace solarApp.Service if (_logger != null) { - _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}逆變器取得電站編號", _siteID, _date1); + _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}取得電站編號", _siteID, _date1); } #region 取得 PowerStationID string sql = @" select id , `code` siteID, siteDB, `name` siteName from solar_master.power_station where `code` = @siteID"; - var ds = conn.Query(sql, new { siteID = _siteID }).AsList(); + var ds = conn.Query(sql, new { siteID = _siteID }, commandTimeout: 600).AsList(); foreach (var item in ds) { _powerStationID = item.id; @@ -64,7 +60,7 @@ namespace solarApp.Service if (_logger != null) { - _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}逆變器取得電站編號 - {2}", _siteID, _date1, _powerStationID); + _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}取得電站編號 - {2}", _siteID, _date1, _powerStationID); } #endregion @@ -76,8 +72,8 @@ namespace solarApp.Service { if (_logger != null) { - _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}逆變器取得電站編號", _siteID, _date1); - _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}逆變器取得電站編號 - [Exception]:{2}", _siteID, _date1, ex.ToString()); + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}取得電站編號", _siteID, _date1); + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}取得電站編號 - [Exception]:{2}", _siteID, _date1, ex.ToString()); } throw ex; @@ -108,7 +104,7 @@ namespace solarApp.Service select a.id, uid, a.PowerStationID, Enabled, SerialNumber, name, type, SensorTypeId, sensorTypeDetailid, DBName, TableName, ColName - from solar_com0002.device a + from {_siteDB}.device a where a.powerstationid = {_powerStationID} and deleted = 0 and Enabled = 1 -- has sharedevice @@ -116,17 +112,17 @@ namespace solarApp.Service select a.id, uid, b.PowerStationID, Enabled, SerialNumber, name, type, SensorTypeId, sensorTypeDetailid, DBName, TableName, ColName - from solar_com0002.device a - join solar_com0002.`SHAREdevice` b on a.id = b.deviceid + from {_siteDB}.device a + join {_siteDB}.`SHAREdevice` b on a.id = b.deviceid where b.powerstationid = {_powerStationID} and deleted = 0 and Enabled = 1 ) x join sensor_type y on x.sensortypeid = y.id join sensor_type_detail z on y.id = z.SensorTypeId"; - var ds = conn.Query(sql); + var ds = conn.Query(sql, commandTimeout: 600); StringBuilder sb_inserr = new StringBuilder(); StringBuilder sb_select = new StringBuilder(); - sb_select.Append($@"select {_powerStationID}, DATE_FORMAT(left(`crdTime`, 13),'%Y-%m-%d %H:%i:%s'), "); + sb_select.Append($@"select {_powerStationID}, CONCAT('{t1}', ':00:00') as 'TIMESTAMP', "); string irrColName = ""; bool isFirst = true; foreach (var item in ds) @@ -139,7 +135,7 @@ namespace solarApp.Service if (isFirst) { sb_inserr.Append($@"{item.SetWhat}"); - sb_select.Append($@"{item.HourType}({item.ColName})"); + sb_select.Append($@"ifnull({item.HourType}({item.ColName}), 0)"); isFirst = false; } else @@ -152,10 +148,10 @@ namespace solarApp.Service var tb = ds.AsList(); sb_select.Append($@" from {tb[0].DBName}.{tb[0].TableName} where Left(crdTime, 13) = '{t1}'"); string dblocation = tb[0].DBName+"."+tb[0].TableName; - sb_inserr.Insert(0, "insert into solar_master.sensor_history_hour(PowerStationId, TIMESTAMP, "); + sb_inserr.Insert(0, "insert into sensor_history_hour(PowerStationId, TIMESTAMP, ");//sensor_history_hour sb_inserr.Append(") "); string ss = sb_inserr.Append(sb_select.ToString()).ToString(); - conn.Execute(ss); + conn.Execute(ss, commandTimeout: 600); if (irrColName != "") { bool a = countIrr(dblocation, irrColName, t1); @@ -204,7 +200,7 @@ namespace solarApp.Service where Left(crdTime, 13) = '{t1}' and {sensorColNum} <> 0 ) a ON a.ctime = b.TIMESTAMP AND a.powerstationid = b.powerstationId SET Irradiance = a.Irr"; - conn.Execute(ss); + conn.Execute(ss, commandTimeout: 600); conn.Close(); } result = true; @@ -252,7 +248,7 @@ namespace solarApp.Service { IrrDay = 0; } - + string sql2 = $@" select IrrDay from solar_master.sensor_history_hour z where powerstationID = {_powerStationID} and LEFT(z.`TIMESTAMP`, 13 ) = '{Convert.ToDateTime(d1).AddHours(-1).ToString("yyyy-MM-dd HH")}' "; @@ -274,11 +270,11 @@ namespace solarApp.Service { IrrDayHour = IrrDay - twoHourAgoIrrDay;// 前一小時的IrrDay - 前兩小時的IrrDay } - + string ss = $@"UPDATE solar_master.sensor_history_hour SET IrrDayHour = {IrrDayHour} WHERE LEFT(TIMESTAMP, 13) = '{t1}' AND PowerStationId = {_powerStationID}"; - conn.Execute(ss); + conn.Execute(ss, commandTimeout: 600); if (_logger != null) { _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}累積日照差更新至資料表的資料", _siteID, _date1); @@ -316,7 +312,7 @@ namespace solarApp.Service string sql = @"delete from solar_master.sensor_history_hour where powerstationID = @powerStationID and left(TIMESTAMP, 10) = @date1"; MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; - cmd.CommandTimeout = 360; + cmd.CommandTimeout = 600; cmd.Parameters.AddWithValue("@date1", clearTime); cmd.Parameters.AddWithValue("@PowerStationID", _powerStationID); cmd.CommandText = sql; diff --git a/solarApp/Service/procSensorSvc.cs b/solarApp/Service/procSensorSvc.cs index 3686086..b3857cc 100644 --- a/solarApp/Service/procSensorSvc.cs +++ b/solarApp/Service/procSensorSvc.cs @@ -32,6 +32,7 @@ namespace solarApp.Service public string _date1 { get; set; } //public string _date2 { get; set; } public string _powerStationID { get; set; } + public bool isFirst { get; set; } //public procSensorSvc(string siteDB, string siteID, string date1, string date2) //{ @@ -73,6 +74,17 @@ namespace solarApp.Service return result; } + public bool archiveSensorHistoryHourData(string siteID, string date1) + { + bool result = false; + _siteID = siteID; + _date1 = date1; + get_siteInfo(); + insert_sensor_for_history_hour(); + result = true; + return result; + } + public bool archiveData_test(string siteID, string date1) { @@ -187,7 +199,6 @@ namespace solarApp.Service { procArchiveLog arclog = new procArchiveLog(); bool result = false; - bool isFirst = true; using (MySqlConnection conn = new MySqlConnection(Connection1)) { conn.Open(); @@ -298,34 +309,34 @@ namespace solarApp.Service // )b on LEFT(a.`TIMESTAMP`, 13) = hour_1 // Set irrDayhour = case when a.`irrday` - b.`irrday` < 0 then 0 else a.`irrday` - b.`irrday` end // where a.powerstationID = {_powerStationID}"; - if (isFirst) - { - sql = $@"DROP TEMPORARY TABLE IF EXISTS `temp_s1`; - create TEMPORARY TABLE temp_s1 - select powerstationID, `TIMESTAMP`, irrday - from sensor_history_hour a - where LEFT(a.TIMESTAMP, 10 ) = '{_date1}'; - ALTER TABLE `temp_s1` ADD INDEX `temp_indexs1` (powerstationID, `TIMESTAMP`);"; - dt_start2 = DateTime.Now; - cmd.CommandText = sql; - int updateCT = cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - duration = DateTime.Now - dt_start2; - arclog.insert_log(_powerStationID, "sensor step0 irrDayHour init", duration.TotalSeconds, "sensor_history_hour", "update sensor hour", "0", "", updateCT.ToString(), conn, cmd); - } + //if (isFirst) + //{ + // sql = $@"DROP TEMPORARY TABLE IF EXISTS `temp_s1`; + // create TEMPORARY TABLE temp_s1 + // select powerstationID, `TIMESTAMP`, irrday + // from sensor_history_hour a + // where LEFT(a.TIMESTAMP, 10 ) = '{_date1}'; + // ALTER TABLE `temp_s1` ADD INDEX `temp_indexs1` (powerstationID, `TIMESTAMP`);"; + // dt_start2 = DateTime.Now; + // cmd.CommandText = sql; + // int updateCT = cmd.ExecuteNonQuery(); + // cmd.Parameters.Clear(); + // duration = DateTime.Now - dt_start2; + // arclog.insert_log(_powerStationID, "sensor step0 irrDayHour init", duration.TotalSeconds, "sensor_history_hour", "update sensor hour", "0", "", updateCT.ToString(), conn, cmd); + //} - sql = $@" update sensor_history_hour a join - (select powerstationID, LEFT(DATE_ADD(`TIMESTAMP`, INTERVAL +1 hour), 13) hour_1, irrday from temp_s1 ) b - on LEFT(a.`TIMESTAMP`, 13) = hour_1 and a.powerstationID = b.powerstationID - Set irrDayhour = case when a.`irrday` - b.`irrday` < 0 then 0 else a.`irrday` - b.`irrday` end - where LEFT(a.TIMESTAMP, 10 ) = '{_date1}' - and a.powerstationID = {_powerStationID} "; - dt_start2 = DateTime.Now; - cmd.CommandText = sql; - int rowCT2 = cmd.ExecuteNonQuery(); - cmd.Parameters.Clear(); - duration = DateTime.Now - dt_start2; - arclog.insert_log(_powerStationID, "sensor step1 for irrDayHour", duration.TotalSeconds, "sensor_history_hour", "update sensor hour", "0", "", rowCT2.ToString(), conn, cmd); + //sql = $@" update sensor_history_hour a join + // (select powerstationID, LEFT(DATE_ADD(`TIMESTAMP`, INTERVAL +1 hour), 13) hour_1, irrday from temp_s1 ) b + // on LEFT(a.`TIMESTAMP`, 13) = hour_1 and a.powerstationID = b.powerstationID + // Set irrDayhour = case when a.`irrday` - b.`irrday` < 0 then 0 else a.`irrday` - b.`irrday` end + // where LEFT(a.TIMESTAMP, 10 ) = '{_date1}' + // and a.powerstationID = {_powerStationID} "; + //dt_start2 = DateTime.Now; + //cmd.CommandText = sql; + //int rowCT2 = cmd.ExecuteNonQuery(); + //cmd.Parameters.Clear(); + //duration = DateTime.Now - dt_start2; + //arclog.insert_log(_powerStationID, "sensor step1 for irrDayHour", duration.TotalSeconds, "sensor_history_hour", "update sensor hour", "0", "", rowCT2.ToString(), conn, cmd); //sql = $@"update sensor_history_hour a join @@ -548,6 +559,66 @@ namespace solarApp.Service return result; } + bool insert_sensor_for_history_hour() + { + procArchiveLog arclog = new procArchiveLog(); + bool result = false; + using (MySqlConnection conn = new MySqlConnection(Connection1)) + { + conn.Open(); + string sql; + //電表 + DateTime dt_start = DateTime.Now; + try + { + #region hour + MySqlCommand cmd = new MySqlCommand(); + cmd.Connection = conn; + cmd.CommandTimeout = 720; + + DateTime dt_start2 = DateTime.Now; + TimeSpan duration = DateTime.Now - dt_start2; + if (isFirst) + { + sql = $@"DROP TEMPORARY TABLE IF EXISTS `temp_s1`; + create TEMPORARY TABLE temp_s1 + select powerstationID, `TIMESTAMP`, irrday + from sensor_history_hour a + where LEFT(a.TIMESTAMP, 10 ) = '{_date1}'; + ALTER TABLE `temp_s1` ADD INDEX `temp_indexs1` (powerstationID, `TIMESTAMP`);"; + dt_start2 = DateTime.Now; + cmd.CommandText = sql; + int updateCT = cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + duration = DateTime.Now - dt_start2; + arclog.insert_log(_powerStationID, "sensor step0 irrDayHour init", duration.TotalSeconds, "sensor_history_hour", "update sensor hour", "0", "", updateCT.ToString(), conn, cmd); + } + + sql = $@" update sensor_history_hour a join + (select powerstationID, LEFT(DATE_ADD(`TIMESTAMP`, INTERVAL +1 hour), 13) hour_1, irrday from temp_s1 ) b + on LEFT(a.`TIMESTAMP`, 13) = hour_1 and a.powerstationID = b.powerstationID + Set irrDayhour = case when a.`irrday` - b.`irrday` < 0 then 0 else a.`irrday` - b.`irrday` end + where LEFT(a.TIMESTAMP, 10 ) = '{_date1}' + and a.powerstationID = {_powerStationID} "; + dt_start2 = DateTime.Now; + cmd.CommandText = sql; + int rowCT2 = cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + duration = DateTime.Now - dt_start2; + arclog.insert_log(_powerStationID, "sensor step1 for irrDayHour", duration.TotalSeconds, "sensor_history_hour", "update sensor hour", "0", "", rowCT2.ToString(), conn, cmd); + #endregion hour + + conn.Close(); + result = true; + } + catch (Exception ex) + { + throw ex; + } + } + return result; + } + public bool archiveMeterData(string siteID, string date1) { diff --git a/solarApp/Service/procSyncError.cs b/solarApp/Service/procSyncError.cs index 2c77194..e0a152d 100644 --- a/solarApp/Service/procSyncError.cs +++ b/solarApp/Service/procSyncError.cs @@ -202,7 +202,7 @@ namespace solarApp.Service using (MySqlConnection conn = new MySqlConnection(Connection1)) { conn.Open(); - string sql = $@"SELECT a.`*`,ns.Id, + string sql = $@"SELECT a.`*`, case priority when 1 then DATE_ADD(dev_time, INTERVAL 24 HOUR) when 2 then DATE_ADD(dev_time, INTERVAL 12 HOUR) else dev_time end emailTime @@ -235,8 +235,7 @@ namespace solarApp.Service left join power_station ps on ps.`Code` = site_id left join operation_record pr on pr.ErrorCode = a.id where sourceState = 1 and datestamp > '{System.DateTime.Now.AddDays(-60).ToString("yyyy-MM-dd")}' and ps.`Code` is not null - ) a LEFT JOIN notice_schedule ns ON a.id = ns.ExceptionId - WHERE ns.Id IS NULL + ) a order by a.id desc limit 1000"; List ds = conn.Query(sql, commandTimeout: 600).AsList(); conn.Close(); diff --git a/solarApp/fmArchive.cs b/solarApp/fmArchive.cs index 4c64354..cf78d38 100644 --- a/solarApp/fmArchive.cs +++ b/solarApp/fmArchive.cs @@ -41,10 +41,13 @@ namespace solarApp //invSvc._siteID01 = lbSiteID_sensor.Text; //invSvc._date1 = date1; //invSvc._date2 = date1; + sensorSvc.isFirst = true; foreach (DateTime day in EachDay(DateTime.Parse(date1), DateTime.Parse(date2))) { //string d1 = day.ToString("yyyy-MM-dd"); sensorSvc.archiveData(lbSiteID_sensor.Text.Substring(0, 9), day.ToString("yyyy-MM-dd")); + sensorSvc.archiveSensorHistoryHourData(lbSiteID_sensor.Text.Substring(0, 9), day.ToString("yyyy-MM-dd"));/////要改 + sensorSvc.isFirst = false; } //sensorSvc._siteDB = lbSiteDB_sensor.Text; //sensorSvc._siteID = lbSiteID_sensor.Text.Substring(0, 9); @@ -280,7 +283,6 @@ namespace solarApp private void bt_archive_Click(object sender, EventArgs e) { - int i = 0; var site_list = stationSvc.get_station_list(); //bt_Sensor.PerformClick(); @@ -305,8 +307,17 @@ namespace solarApp invSvc.archiveData(item.SiteID.Substring(0, 9), day.ToString("yyyy-MM-dd")); siteSvc.archiveData(item.SiteID.Substring(0, 9), day.ToString("yyyy-MM-dd")); invSvc.report_invDay(item.SiteID.Substring(0, 9), day.ToString("yyyy-MM-dd")); - } - i++; + } + } + sensorSvc.isFirst = true; + foreach (var item in site_list) + { + //for sensor_history_hour + foreach (DateTime day in EachDay(DateTime.Parse(date1), DateTime.Parse(date2))) + { + sensorSvc.archiveSensorHistoryHourData(item.SiteID.Substring(0, 9), day.ToString("yyyy-MM-dd"));/////要改 + sensorSvc.isFirst = false; + } } autoTask = true; lbMsgTitle.Text = System.DateTime.Now.ToString() + " 完成!"; diff --git a/solarApp/fmMain.Designer.cs b/solarApp/fmMain.Designer.cs index f0f8b69..0aeb24e 100644 --- a/solarApp/fmMain.Designer.cs +++ b/solarApp/fmMain.Designer.cs @@ -1685,7 +1685,7 @@ namespace solarApp // button1 // this.button1.Cursor = System.Windows.Forms.Cursors.Arrow; - this.button1.Location = new System.Drawing.Point(1352, 51); + this.button1.Location = new System.Drawing.Point(1603, 51); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(94, 29); this.button1.TabIndex = 3; diff --git a/solarApp/fmMain.cs b/solarApp/fmMain.cs index bca851f..fdb59b6 100644 --- a/solarApp/fmMain.cs +++ b/solarApp/fmMain.cs @@ -332,12 +332,12 @@ namespace solarApp if(label13.Text == "solar_master.notice_schedule資料表") { gv_notice_data.DataSource = errorSvc.QueryAlarmorion_orionalarmrecordData(); - label13.Text = "solar_master.notice_schedule資料表"; + label13.Text = "solar_master.alarmorion_orionalarmrecord資料表"; } else { gv_notice_data.DataSource = errorSvc.QueryNoticeData(); - label13.Text = "solar_master.alarmorion_orionalarmrecord資料表"; + label13.Text = "solar_master.notice_schedule資料表"; } } }