diff --git a/SolarPower/Quartz/Jobs/CalcAvgPowerStationJob.cs b/SolarPower/Quartz/Jobs/CalcAvgPowerStationJob.cs index 8b8bd1f..f57a33b 100644 --- a/SolarPower/Quartz/Jobs/CalcAvgPowerStationJob.cs +++ b/SolarPower/Quartz/Jobs/CalcAvgPowerStationJob.cs @@ -212,77 +212,92 @@ namespace SolarPower.Quartz.Jobs var dateNowDay = DateTimeNow.AddDays(-1).ToString("yyyy-MM-dd"); var dateNowMonth = DateTimeNow.AddDays(-1).ToString("yyyy-MM"); + Root2 observation = null; + #region 氣象觀測(取資料) - logger.LogInformation("【CalcAvgPowerStationJob】【開始取得氣象觀測】"); - var client = new HttpClient(); - var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=Wx,PoP&sort=time"; - HttpResponseMessage response = client.GetAsync(UVUri).Result; - String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString(); - Root2 observation = JsonConvert.DeserializeObject(jsonUVs); - logger.LogInformation("【CalcAvgPowerStationJob】【取得成功氣象觀測】"); - #endregion - - foreach (var location in observation.Records.Location) + try { - WeatherForecast weatherForecast = new WeatherForecast(); - weatherForecast.LocationName = location.LocationName; + logger.LogInformation("【CalcAvgPowerStationJob】【開始取得氣象觀測】"); + var client = new HttpClient(); + var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=Wx,PoP&sort=time"; + HttpResponseMessage response = client.GetAsync(UVUri).Result; + String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString(); + observation = JsonConvert.DeserializeObject(jsonUVs); + logger.LogInformation("【CalcAvgPowerStationJob】【取得成功氣象觀測】"); + } + catch (Exception ex) + { + logger.LogError("【CalcAvgPowerStationJob】【取得失敗氣象觀測】"); + logger.LogError("【{0}】{1}", "CalcPowerStationJob", ex.Message); + observation = null; + } - List SubweatherForecasts = new List(); - - foreach (var a in location.WeatherElement) + #endregion + if (observation != null) + { + foreach (var location in observation.Records.Location) { - if (a.ElementName == "Wx") + WeatherForecast weatherForecast = new WeatherForecast(); + weatherForecast.LocationName = location.LocationName; + + List SubweatherForecasts = new List(); + + foreach (var a in location.WeatherElement) { - foreach (var time in a.Time) + if (a.ElementName == "Wx") + { + foreach (var time in a.Time) + { + int index = 0; + if (location.WeatherElement[0].ElementName == "Wx") + { + weatherForecast = new WeatherForecast(); + weatherForecast.LocationName = location.LocationName; + weatherForecast.StartTime = time.StartTime.ToString(); + weatherForecast.EndTime = time.EndTime.ToString(); + weatherForecast.Wx = time.Parameter.ParameterName; + weatherForecast.WxValue = time.Parameter.ParameterValue; + SubweatherForecasts.Add(weatherForecast); + + } + else + { + SubweatherForecasts[index].StartTime = time.StartTime.ToString(); + SubweatherForecasts[index].EndTime = time.EndTime.ToString(); + SubweatherForecasts[index].Wx = time.Parameter.ParameterName; + SubweatherForecasts[index].WxValue = time.Parameter.ParameterValue; + //SubweatherForecasts.Add(weatherForecast); + index++; + } + //weatherForecasts.Add(weatherForecast); + } + } + if (a.ElementName == "PoP") { int index = 0; - if (location.WeatherElement[0].ElementName == "Wx") + foreach (var time in a.Time) { - weatherForecast = new WeatherForecast(); - weatherForecast.LocationName = location.LocationName; - weatherForecast.StartTime = time.StartTime.ToString(); - weatherForecast.EndTime = time.EndTime.ToString(); - weatherForecast.Wx = time.Parameter.ParameterName; - weatherForecast.WxValue = time.Parameter.ParameterValue; - SubweatherForecasts.Add(weatherForecast); + if (location.WeatherElement[0].ElementName == "PoP") + { + weatherForecast = new WeatherForecast(); + weatherForecast.LocationName = location.LocationName; + weatherForecast.PoP = time.Parameter.ParameterName; + SubweatherForecasts.Add(weatherForecast); + } + else + { + SubweatherForecasts[index].PoP = time.Parameter.ParameterName; - } - else - { - SubweatherForecasts[index].StartTime = time.StartTime.ToString(); - SubweatherForecasts[index].EndTime = time.EndTime.ToString(); - SubweatherForecasts[index].Wx = time.Parameter.ParameterName; - SubweatherForecasts[index].WxValue = time.Parameter.ParameterValue; - //SubweatherForecasts.Add(weatherForecast); - index++; - } - //weatherForecasts.Add(weatherForecast); - } - } - if (a.ElementName == "PoP") - { - int index = 0; - foreach (var time in a.Time) - { - if (location.WeatherElement[0].ElementName == "PoP") - { - weatherForecast = new WeatherForecast(); - weatherForecast.LocationName = location.LocationName; - weatherForecast.PoP = time.Parameter.ParameterName; - SubweatherForecasts.Add(weatherForecast); - } - else - { - SubweatherForecasts[index].PoP = time.Parameter.ParameterName; - - //SubweatherForecasts.Add(weatherForecast); - index++; + //SubweatherForecasts.Add(weatherForecast); + index++; + } } } } + weatherForecasts.AddRange(SubweatherForecasts); } - weatherForecasts.AddRange(SubweatherForecasts); } + List weather_forecast_properties = new List() { "LocationName", diff --git a/SolarPower/Quartz/Jobs/CalcPowerStationJob.cs b/SolarPower/Quartz/Jobs/CalcPowerStationJob.cs index c8a016e..e2f69a7 100644 --- a/SolarPower/Quartz/Jobs/CalcPowerStationJob.cs +++ b/SolarPower/Quartz/Jobs/CalcPowerStationJob.cs @@ -40,6 +40,8 @@ namespace SolarPower.Quartz.Jobs var DateTimeNow = DateTime.Now; var dateTime = DateTimeNow.AddHours(-1).ToString("yyyy-MM-dd HH"); + var hasException = false; + Root2 observation = null; if (this.environment.IsDevelopment()) @@ -88,312 +90,316 @@ namespace SolarPower.Quartz.Jobs #region step2. 從電站的DB及電站編號找出該電站的控制器 foreach (var powerStation in powerStations) { - 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)) + try { - logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); - var history = await powerStationRepository.GetPowerStationHistoryPerHour(dateTime, full_table_name); - logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); - logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的每小時歷史資料】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(history)); - var lastmoneyhistorybyhour = await powerStationRepository.GetLastMoneyAndCarbonInHour(powerStation.Id, 0, dateTime); + var calcPowerStation = new PowerStation(); + calcPowerStation.Id = powerStation.Id; - if (history != null) + #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.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); - history.PowerStationId = powerStation.Id; - history.Timestamp = Convert.ToDateTime(history.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); + logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + var history = await powerStationRepository.GetPowerStationHistoryPerHour(dateTime, full_table_name); + logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的每小時歷史資料】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(history)); + var lastmoneyhistorybyhour = await powerStationRepository.GetLastMoneyAndCarbonInHour(powerStation.Id, 0, dateTime); - #region 計算單一電站每小時發電量、發電金額等資料 - - #region 發電量 - //每小時發電量(直接填寫 - calcPowerStation.kwh = history.KWH; - //今日發電量(直接填寫 - calcPowerStation.Today_kWh = history.TodayKWh; - //總發電量(直接填寫 - calcPowerStation.Total_kWh = history.TotalKWH; - #endregion - - #region 發電金額 - //發電金額 - switch (powerStation.SolarType) + if (history != null) { - case (int)SolarTypeEnum.SelfSold: //自建躉售 - //今日發電金額 計算方式:todaykWh * 授電費率 - calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate; - history.MONEY = history.KWH * powerStation.PowerRate; + logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + history.PowerStationId = powerStation.Id; + history.Timestamp = Convert.ToDateTime(history.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); - //總發電金額 計算方式:totalkWh * 授電費率 - calcPowerStation.Total_Money = history.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; + #region 計算單一電站每小時發電量、發電金額等資料 - foreach (var landBuilding in landBuildings) - { - sumLeaseRate += landBuilding.LeaseRate; - } - //avgLeaseRate = sumLeaseRate / landBuildings.Count(); + #region 發電量 + //每小時發電量(直接填寫 + calcPowerStation.kwh = history.KWH; + //今日發電量(直接填寫 + calcPowerStation.Today_kWh = history.TodayKWh; + //總發電量(直接填寫 + calcPowerStation.Total_kWh = history.TotalKWH; + #endregion - //今日發電金額計算方式:todaykWh * 出借費率(各個土地房屋租借比率平均) - calcPowerStation.Today_Money = history.TodayKWh * sumLeaseRate; - - history.MONEY = history.KWH * sumLeaseRate; - //總發電金額 計算方式:totalkWh * 授電費率 - calcPowerStation.Total_Money = history.TotalKWH * sumLeaseRate; - break; - case (int)SolarTypeEnum.SelfUse: //自建自用 - //今日發電金額 計算方式:todaykWh * 授電費率 - calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate; - - history.MONEY = history.KWH * powerStation.PowerRate; - - //總發電金額 計算方式:totalkWh * 授電費率 - calcPowerStation.Total_Money = history.TotalKWH * powerStation.PowerRate; - break; - } - #endregion - - #region kWh/kWp - //直接填寫 - calcPowerStation.Today_kwhkwp = history.KWHKWP; - #endregion - - #region PR - //直接填寫 - calcPowerStation.Today_PR = history.PR; - #endregion - - #region 減碳量 - carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate")); - - //今日減碳量( 今日發電量 * (0.554/1000)[抓資料庫值] - calcPowerStation.Today_Carbon = history.TodayKWh * carbonRate; - - history.CARBON = history.KWH * carbonRate; - //總減碳量(總發電量 * (0.554/1000)[抓資料庫值] - calcPowerStation.Total_Carbon = history.TotalKWH * carbonRate; - - if (lastmoneyhistorybyhour != null) - { - history.TODAYCARBON = lastmoneyhistorybyhour.TODAYCARBON + history.KWH * carbonRate; - history.TOTALCARBON = lastmoneyhistorybyhour.TOTALCARBON + history.KWH * carbonRate; - history.TODAYMONEY = lastmoneyhistorybyhour.TODAYMONEY + history.KWH * powerStation.PowerRate; - history.TOTALMONEY = lastmoneyhistorybyhour.TOTALMONEY + history.KWH * powerStation.PowerRate; - } - else - { - history.TODAYCARBON = history.KWH * carbonRate; - history.TOTALCARBON = history.KWH * carbonRate; - history.TODAYMONEY = history.KWH * powerStation.PowerRate; - history.TOTALMONEY = history.KWH * powerStation.PowerRate; - } - - #endregion - - #region 發電時間 - calcPowerStation.SolarHour = history.SolarHour; - #endregion - #endregion - - powerStationHistoriesHour.Add(history); - - logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); - } - #endregion - - #region step2-2. 取得該電站的當前這小時的日照度歷史資料 - //1. 找出該電站所有日照計設備(包含共享 - logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime); - var deviceInfos = await powerStationRepository.GetListPyrheliometerByPowerStationId(powerStation.Id, powerStation.SiteDB); - logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime); - logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的日照計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(deviceInfos)); - - if (deviceInfos != null && deviceInfos.Count() > 0) - { - //2. 計算該電站所有日照計設的每小時的平均在依照日照計數量平均 - logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime); - var pyrheliometerHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, deviceInfos, 0); - - if (pyrheliometerHistory != null) - { - calcPowerStation.Today_irradiance = pyrheliometerHistory.Irradiance; - - pyrheliometerHistory.Timestamp = Convert.ToDateTime(pyrheliometerHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); - pyrheliometerHistory.PowerStationId = powerStation.Id; - pyrheliometerHistoriesHour.Add(pyrheliometerHistory); - } - logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime); - } - //2. 計算該電站所有溫度計設的每小時的平均在依照溫度計數量平均 - // 找出該電站所有溫度計設備(包含共享 - logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime); - var tempdeviceInfos = await powerStationRepository.GetListTempByPowerStationId(powerStation.Id, powerStation.SiteDB); - logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime); - logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的溫度計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(tempdeviceInfos)); - if (tempdeviceInfos != null && tempdeviceInfos.Count() > 0) - { - logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime); - var tempHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, tempdeviceInfos, 1); - if (tempHistory != null) - { - tempHistory.Timestamp = Convert.ToDateTime(tempHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); - tempHistory.PowerStationId = powerStation.Id; - TempHistoriesHour.Add(tempHistory); - - logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime); - } - } - #endregion - - calcPowerStations.Add(calcPowerStation); - } - - #region step2-3. 計算該電站所有逆變器每小時值 - logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{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("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime); - logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的逆變器設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(inverterIds)); - - 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 exist_inverter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, inverter_table_name); - - if (!string.IsNullOrEmpty(exist_inverter_table) && inverterIds != null && inverterIds.Count() > 0) - { - logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{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("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime); - } - #endregion - - #region step2-4. 計算該電站所有sensoravg - var seneoravg_table_name = String.Format("s{0}01_sensoravg", powerStation.Code); - var full_seneoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, seneoravg_table_name); - var exist_seneoravg_table = await powerStationRepository.ExistTable(powerStation.SiteDB, seneoravg_table_name); - if (!string.IsNullOrEmpty(exist_seneoravg_table)) - { - logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime); - var sensorAvgHistory = await powerStationRepository.CalcSensorAvgHistory(dateTime, full_seneoravg_table_name); - logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{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); - } - } - #endregion - - #region step2-5. 計算該電站meter - 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); - if (!string.IsNullOrEmpty(exist_meter_table)) - { - logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime); - var meterHistory = await powerStationRepository.CalcMeterHistory(dateTime, full_meter_table_name); - logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{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); - } - } - #endregion - - #region 確認是否有觀測站(沒有則新增) - 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(','); - var nowLocation = Math.Sqrt(Math.Pow(Convert.ToDouble(powerLocation[0]) - Convert.ToDouble(Location.Lat), 2) + Math.Pow(Convert.ToDouble(powerLocation[1]) - Convert.ToDouble(Location.Lon), 2)); - if (nowLocation < shortLocation) + #region 發電金額 + //發電金額 + switch (powerStation.SolarType) { - shortLocation = nowLocation; - weatherStationId = Location.StationId; - calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue); + case (int)SolarTypeEnum.SelfSold: //自建躉售 + //今日發電金額 計算方式:todaykWh * 授電費率 + calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate; + history.MONEY = history.KWH * powerStation.PowerRate; + + //總發電金額 計算方式:totalkWh * 授電費率 + calcPowerStation.Total_Money = history.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; + } + //avgLeaseRate = sumLeaseRate / landBuildings.Count(); + + //今日發電金額計算方式:todaykWh * 出借費率(各個土地房屋租借比率平均) + calcPowerStation.Today_Money = history.TodayKWh * sumLeaseRate; + + history.MONEY = history.KWH * sumLeaseRate; + //總發電金額 計算方式:totalkWh * 授電費率 + calcPowerStation.Total_Money = history.TotalKWH * sumLeaseRate; + break; + case (int)SolarTypeEnum.SelfUse: //自建自用 + //今日發電金額 計算方式:todaykWh * 授電費率 + calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate; + + history.MONEY = history.KWH * powerStation.PowerRate; + + //總發電金額 計算方式:totalkWh * 授電費率 + calcPowerStation.Total_Money = history.TotalKWH * powerStation.PowerRate; + break; + } + #endregion + + #region kWh/kWp + //直接填寫 + calcPowerStation.Today_kwhkwp = history.KWHKWP; + #endregion + + #region PR + //直接填寫 + calcPowerStation.Today_PR = history.PR; + #endregion + + #region 減碳量 + carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate")); + + //今日減碳量( 今日發電量 * (0.554/1000)[抓資料庫值] + calcPowerStation.Today_Carbon = history.TodayKWh * carbonRate; + + history.CARBON = history.KWH * carbonRate; + //總減碳量(總發電量 * (0.554/1000)[抓資料庫值] + calcPowerStation.Total_Carbon = history.TotalKWH * carbonRate; + + if (lastmoneyhistorybyhour != null) + { + history.TODAYCARBON = lastmoneyhistorybyhour.TODAYCARBON + history.KWH * carbonRate; + history.TOTALCARBON = lastmoneyhistorybyhour.TOTALCARBON + history.KWH * carbonRate; + history.TODAYMONEY = lastmoneyhistorybyhour.TODAYMONEY + history.KWH * powerStation.PowerRate; + history.TOTALMONEY = lastmoneyhistorybyhour.TOTALMONEY + history.KWH * powerStation.PowerRate; + } + else + { + history.TODAYCARBON = history.KWH * carbonRate; + history.TOTALCARBON = history.KWH * carbonRate; + history.TODAYMONEY = history.KWH * powerStation.PowerRate; + history.TOTALMONEY = history.KWH * powerStation.PowerRate; + } + + #endregion + + #region 發電時間 + calcPowerStation.SolarHour = history.SolarHour; + #endregion + #endregion + + powerStationHistoriesHour.Add(history); + + logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); + } + #endregion + + #region step2-2. 取得該電站的當前這小時的日照度歷史資料 + //1. 找出該電站所有日照計設備(包含共享 + logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime); + var deviceInfos = await powerStationRepository.GetListPyrheliometerByPowerStationId(powerStation.Id, powerStation.SiteDB); + logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的日照計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(deviceInfos)); + + if (deviceInfos != null && deviceInfos.Count() > 0) + { + //2. 計算該電站所有日照計設的每小時的平均在依照日照計數量平均 + logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime); + var pyrheliometerHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, deviceInfos, 0); + + if (pyrheliometerHistory != null) + { + calcPowerStation.Today_irradiance = pyrheliometerHistory.Irradiance; + + pyrheliometerHistory.Timestamp = Convert.ToDateTime(pyrheliometerHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); + pyrheliometerHistory.PowerStationId = powerStation.Id; + pyrheliometerHistoriesHour.Add(pyrheliometerHistory); + } + logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime); + } + //2. 計算該電站所有溫度計設的每小時的平均在依照溫度計數量平均 + // 找出該電站所有溫度計設備(包含共享 + logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime); + var tempdeviceInfos = await powerStationRepository.GetListTempByPowerStationId(powerStation.Id, powerStation.SiteDB); + logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的溫度計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(tempdeviceInfos)); + if (tempdeviceInfos != null && tempdeviceInfos.Count() > 0) + { + logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime); + var tempHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, tempdeviceInfos, 1); + if (tempHistory != null) + { + tempHistory.Timestamp = Convert.ToDateTime(tempHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); + tempHistory.PowerStationId = powerStation.Id; + TempHistoriesHour.Add(tempHistory); + + logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime); } } + #endregion + + calcPowerStations.Add(calcPowerStation); } - calcPowerStation.WeathersStationId = weatherStationId; - } - #endregion + #region step2-3. 計算該電站所有逆變器每小時值 + logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{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("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime); + logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的逆變器設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(inverterIds)); - WeatherObservation weatherObservation = new WeatherObservation(); - if (powerStation.WeathersStationId != null && observation != null) - { - foreach (var Location in observation.Records.Location) + 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 exist_inverter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, inverter_table_name); + + if (!string.IsNullOrEmpty(exist_inverter_table) && inverterIds != null && inverterIds.Count() > 0) { - if (Location.StationId == powerStation.WeathersStationId) + logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{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; - 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; + 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("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime); + } + #endregion + + #region step2-4. 計算該電站所有sensoravg + var seneoravg_table_name = String.Format("s{0}01_sensoravg", powerStation.Code); + var full_seneoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, seneoravg_table_name); + var exist_seneoravg_table = await powerStationRepository.ExistTable(powerStation.SiteDB, seneoravg_table_name); + if (!string.IsNullOrEmpty(exist_seneoravg_table)) + { + logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime); + var sensorAvgHistory = await powerStationRepository.CalcSensorAvgHistory(dateTime, full_seneoravg_table_name); + logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{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); } } - weatherObservations.Add(weatherObservation); - } + #endregion - logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); - var weather = await powerStationRepository.SelectNowWeather(powerStation.CityId); - logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); - if (weather != null) + #region step2-5. 計算該電站meter + 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); + if (!string.IsNullOrEmpty(exist_meter_table)) + { + logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime); + var meterHistory = await powerStationRepository.CalcMeterHistory(dateTime, full_meter_table_name); + logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{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); + } + } + #endregion + + #region 確認是否有觀測站(沒有則新增) + 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(','); + var nowLocation = Math.Sqrt(Math.Pow(Convert.ToDouble(powerLocation[0]) - Convert.ToDouble(Location.Lat), 2) + Math.Pow(Convert.ToDouble(powerLocation[1]) - Convert.ToDouble(Location.Lon), 2)); + if (nowLocation < shortLocation) + { + shortLocation = nowLocation; + weatherStationId = Location.StationId; + calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue); + } + } + } + + calcPowerStation.WeathersStationId = weatherStationId; + } + #endregion + + 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("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); + var weather = await powerStationRepository.SelectNowWeather(powerStation.CityId); + logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); + if (weather != null) + { + calcPowerStation.TodayWeather = weather.WeatherKey; + calcPowerStation.RateOfRain = weather.PoP; + } + } + catch (Exception exception) { - calcPowerStation.TodayWeather = weather.WeatherKey; - calcPowerStation.RateOfRain = weather.PoP; + logger.LogError("【{0}】{1}", "CalcPowerStationJob", exception.Message); } - - - } #endregion