using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Quartz;
using SolarPower.Models.PowerStation;
using SolarPower.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace SolarPower.Quartz.Jobs
{
    [DisallowConcurrentExecution]
    public class CalcAvgPowerStationJob : IJob
    {
        private readonly ILogger<CalcAvgPowerStationJob> logger;
        private readonly IPowerStationRepository powerStationRepository;

        public CalcAvgPowerStationJob(ILogger<CalcAvgPowerStationJob> logger, IPowerStationRepository powerStationRepository)
        {
            this.logger = logger;
            this.powerStationRepository = powerStationRepository;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                #region step1. 找出所有電站
                logger.LogInformation("【CalcAvgPowerStationJob】【開始取得電站資料】");
                var powerStations = await powerStationRepository.GetAllAsync();
                logger.LogInformation("【CalcAvgPowerStationJob】【取得成功電站資料】");
                logger.LogInformation("【CalcAvgPowerStationJob】【電站資料】 - {0}", System.Text.Json.JsonSerializer.Serialize(powerStations));
                #endregion

                List<PowerStation> calcAvgPowerStations = new List<PowerStation>();
                List<PowerStationHistoryDay> powerStationHistoryDays = new List<PowerStationHistoryDay>();
                List<PowerStationHistoryMonth> insertPowerStationHistoryMonths = new List<PowerStationHistoryMonth>();
                List<PowerStationHistoryMonth> updatePowerStationHistoryMonths = new List<PowerStationHistoryMonth>();

                List<PyrheliometerHistory> pyrheliometerHistoryDays = new List<PyrheliometerHistory>();
                List<PyrheliometerHistory> insertPyrheliometerHistoryMonths = new List<PyrheliometerHistory>();
                List<PyrheliometerHistory> updatePyrheliometerHistoryMonths = new List<PyrheliometerHistory>();
                List<string> pyrheliometer_history_properties = new List<string>()
                {
                    "PowerStationId",
                    "Timestamp",
                    "Irradiance",
                    "Temperature"
                };

                List<InverterHistory> allofInverterHistorDays = new List<InverterHistory>();
                List<InverterHistory> insertInverterHistoryMonths = new List<InverterHistory>();
                List<InverterHistory> updateInverterHistoryMonths = new List<InverterHistory>();
                List<string> inverter_history_properties = new List<string>()
                {
                    "PowerStationId",
                    "TIMESTAMP",
                    "INVERTERID",
                    "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",
                    "KWHKWP",
                };

                List<SensorAvgHistory> sensorAvgHistoryDays = new List<SensorAvgHistory>();
                List<SensorAvgHistory> insertSensorAvgHistoryMonths = new List<SensorAvgHistory>();
                List<SensorAvgHistory> updateSensorAvgHistoryMonths = new List<SensorAvgHistory>();
                List<string> sensoravg_history_properties = new List<string>()
                {
                    "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",
                };

                List<WeatherForecast> weatherForecasts = new List<WeatherForecast>();

                var DateTimeNow = DateTime.Now;
                var dateNowDay = DateTimeNow.AddDays(-1).ToString("yyyy-MM-dd");
                var dateNowMonth = DateTimeNow.AddDays(-1).ToString("yyyy-MM");

                #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<Root2>(jsonUVs);
                logger.LogInformation("【CalcAvgPowerStationJob】【取得成功氣象觀測】");
                #endregion

                foreach (var location in observation.Records.Location)
                {
                    WeatherForecast weatherForecast = new WeatherForecast();
                    weatherForecast.LocationName = location.LocationName;

                    List<WeatherForecast> SubweatherForecasts = new List<WeatherForecast>();

                    foreach (var a in location.WeatherElement)
                    {
                        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;
                            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++;
                                }
                            }
                        }
                    }
                    weatherForecasts.AddRange(SubweatherForecasts);
                }
                List<string> weather_forecast_properties = new List<string>()
                {
                    "LocationName",
                    "StartTime",
                    "EndTime",
                    "Wx",
                    "WxValue",
                    "PoP"
                };
                await powerStationRepository.AddWeatherForecast(weatherForecasts, weather_forecast_properties);

                #region step2. 歸檔電站的每日資訊
                foreach (var powerStation in powerStations)
                {
                    var calcPowerStation = new PowerStation();
                    calcPowerStation.Id = powerStation.Id;

                    #region step2-1. 計算該電站的30天平均資料
                    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("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}的30天平均資料】", powerStation.Code, dateNowDay);
                        var history = await powerStationRepository.CalcAvgPowerStationHistory30day(dateNowDay, full_table_name);
                        logger.LogInformation("【CalcAvgPowerStationJob】【取得成功電站[{0}]在{1}的30天平均資料】", powerStation.Code, dateNowDay);
                        logger.LogInformation("【CalcAvgPowerStationJob】【電站[{0}]在{1}的30天平均資料】 - {2}", powerStation.Code, dateNowDay, System.Text.Json.JsonSerializer.Serialize(history));
                        if (history != null)
                        {
                            logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}的30天平均資料】", powerStation.Code, dateNowDay);
                            history.PowerStationId = powerStation.Id;

                            #region 計算電站30天的 kWh/kWp 與 PR 值

                            #region 平均kWh/kWp
                            //直接填寫
                            calcPowerStation.Avg_kwhkwp = history.AvgKWHKWP;
                            #endregion

                            #region 平均PR
                            //直接填寫
                            calcPowerStation.Avg_PR = history.AvgPR;
                            #endregion

                            #endregion

                            logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}的30天平均資料】", powerStation.Code, dateNowDay);
                        }

                        #region step2-2 計算電站30天的日照計平均值
                        logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}的30天日照計平均資料】", powerStation.Code, dateNowDay);
                        var avgPyrheliometerHistory = await powerStationRepository.CalcAvgPyrheliometerHistory30day(dateNowDay, powerStation.Id);
                        logger.LogInformation("【CalcAvgPowerStationJob】【取得成功電站[{0}]在{1}的30天日照計平均資料】", powerStation.Code, dateNowDay);
                        logger.LogInformation("【CalcAvgPowerStationJob】【電站[{0}]在{1}的30天日照計平均資料】 - {2}", powerStation.Code, dateNowDay, System.Text.Json.JsonSerializer.Serialize(avgPyrheliometerHistory));
                        if (avgPyrheliometerHistory != null)
                        {
                            calcPowerStation.Avg_irradiance = avgPyrheliometerHistory.AvgIrradiance;
                        }

                        calcAvgPowerStations.Add(calcPowerStation);
                        #endregion
                    }
                    #endregion

                    #region step2-2. 計算該電站昨天的所有值總和
                    if (!string.IsNullOrEmpty(exist))
                    {
                        //電站資訊
                        logger.LogInformation("【CalcAvgPowerStationJob】【開始取得電站[{0}]在{1}的所有值的總和】", powerStation.Code, dateNowDay);
                        var historyDay = await powerStationRepository.GetLastOnePowerStationHistoryByDay(dateNowDay, full_table_name);
                        logger.LogInformation("【CalcAvgPowerStationJob】【取得成功電站[{0}]在{1}的所有值的總和】", powerStation.Code, dateNowDay);
                        logger.LogInformation("【CalcAvgPowerStationJob】【電站[{0}]在{1}的所有值的總和】 - {2}", powerStation.Code, dateNowDay, System.Text.Json.JsonSerializer.Serialize(historyDay));
                        var moneyandcarbon = await powerStationRepository.GetMoneyAndCarbonWithHistoryHour(powerStation.Id, dateNowDay, 1);
                        var lastmoneyhistory = await powerStationRepository.GetLastMoneyAndCarbonInHour(powerStation.Id, 1, "");
                        if (historyDay != null)
                        {
                            historyDay.PowerStationId = powerStation.Id;
                            historyDay.CARBON = moneyandcarbon.CARBON;
                            historyDay.MONEY = moneyandcarbon.MONEY;
                            //historyDay.TODAYCARBON = lastmoneyhistory.TODAYCARBON;
                            //historyDay.TODAYMONEY = lastmoneyhistory.TODAYMONEY ;
                            historyDay.TOTALCARBON = lastmoneyhistory.TOTALCARBON + moneyandcarbon.CARBON;
                            historyDay.TOTALMONEY = lastmoneyhistory.TOTALMONEY + moneyandcarbon.MONEY;

                            //日期轉換
                            historyDay.Timestamp = Convert.ToDateTime(historyDay.Timestamp + ":00:00").ToString("yyyy-MM-dd");
                            powerStationHistoryDays.Add(historyDay);
                        }
                    }

                    //日照計
                    logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}的日照計所有值的平均】", powerStation.Code, dateNowDay);
                    var pyrheliometerHistorDay = await powerStationRepository.CalcPyrheliometerHistoryDayDataByPowerStationId(dateNowDay, powerStation.Id);
                    logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}的日照計所有值的平均】", powerStation.Code, dateNowDay);
                    if (pyrheliometerHistorDay != null)
                    {
                        pyrheliometerHistoryDays.Add(pyrheliometerHistorDay);
                    }

                    //逆變器
                    logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}的逆變器所有值的平均】", powerStation.Code, dateNowDay);
                    var inverterHistoriesDay = await powerStationRepository.CalcInverterHistoryDayDataByPowerStationId(dateNowDay, powerStation.SiteDB, powerStation.Id);
                    logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}的逆變器所有值的平均】", powerStation.Code, dateNowDay);
                    if (inverterHistoriesDay != null)
                    {
                        foreach (var inverterHistoryDay in inverterHistoriesDay)
                        {
                            inverterHistoryDay.DC1KW = inverterHistoryDay.DC1W / 1000;
                            inverterHistoryDay.DC2KW = inverterHistoryDay.DC2W / 1000;
                            inverterHistoryDay.DC3KW = inverterHistoryDay.DC3W / 1000;
                            inverterHistoryDay.DC4KW = inverterHistoryDay.DC4W / 1000;
                            inverterHistoryDay.DC5KW = inverterHistoryDay.DC5W / 1000;

                            inverterHistoryDay.DCKW = (inverterHistoryDay.DC1W + inverterHistoryDay.DC2W + inverterHistoryDay.DC3W + inverterHistoryDay.DC4W + inverterHistoryDay.DC5W) / 1000;
                            inverterHistoryDay.ACKW = (inverterHistoryDay.AC1W + inverterHistoryDay.AC2W + inverterHistoryDay.AC3W) / 1000;

                            allofInverterHistorDays.Add(inverterHistoryDay);
                        }
                    }
                    //sensor avg
                    logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}的Sensor Avg table所有值的平均】", powerStation.Code, dateNowDay);
                    var sensorAvgHistoryDay = await powerStationRepository.CalcSensorAvgDayDataByPowerStationId(dateNowDay, powerStation.Id);
                    logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}的Sensor Avg table所有值的平均】", powerStation.Code, dateNowDay);
                    if (sensorAvgHistoryDay != null)
                    {
                        sensorAvgHistoryDays.Add(sensorAvgHistoryDay);
                    }
                    #endregion

                }
                #endregion

                #region step3. calcPowerStations UPDATE 到 power_station 資料表
                List<string> power_station_properties = new List<string>()
                {
                    "Id",
                    "avg_kwhkwp",
                    "avg_PR",
                    "avg_irradiance"
                };

                await powerStationRepository.UpdateList(calcAvgPowerStations, power_station_properties);
                #endregion

                #region step4. 將各電站的每日的資料insert資料表
                //每日 - 電站歷史資料
                List<string> history_properties_day = new List<string>()
                {
                    "PowerStationId",
                    "TIMESTAMP",
                    "SITEID",
                    "SITETYPE",
                    "TODAYKWH",
                    "TOTALKWH",
                    "KWHKWP",
                    "PR",
                    "MP",
                    "SolarHour",
                    "MONEY",
                    "CARBON",
                    "TOTALMONEY",
                    "TOTALCARBON"
                };
                await powerStationRepository.AddPowerStationHistoryDayList(powerStationHistoryDays, history_properties_day);

                //每日 - 日照溫度歷史資料
                await powerStationRepository.AddPyrheliometerHistoryDayList(pyrheliometerHistoryDays, pyrheliometer_history_properties);

                //每日 - 逆變器歷史資料
                await powerStationRepository.AddInverterHistoryDayList(allofInverterHistorDays, inverter_history_properties);

                //每日 - sensor avg
                await powerStationRepository.AddSensorAvgHistoryDayList(sensorAvgHistoryDays, sensoravg_history_properties);

                #region step5. 歸檔電站的每月資訊
                foreach (var powerStation in powerStations)
                {
                    //電站該月份的歷史資料
                    logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}月份的歷史資料總和】", powerStation.Code, dateNowMonth);
                    var exist_history = await powerStationRepository.GetOnePowerStationHistoryByPowerStationIdAndMonth(powerStation.Id, dateNowMonth);
                    if (exist_history == null)
                    { //新增
                        var historyMonth = await powerStationRepository.ClacPowerStationHistoryMonthDataByPowerStationId(powerStation.Id, dateNowMonth);
                        var moneyandcarbonMon = await powerStationRepository.GetMoneyAndCarbonWithHistoryHour(powerStation.Id, dateNowMonth, 0);
                        var lastmoneyhistorymonth = await powerStationRepository.GetLastMoneyAndCarbonInHour(powerStation.Id, 2, "");
                        if (historyMonth != null)
                        {
                            historyMonth.Timestamp = Convert.ToDateTime(historyMonth.Timestamp).ToString("yyyy-MM-dd");
                            historyMonth.MONEY = moneyandcarbonMon.MONEY;
                            historyMonth.CARBON = moneyandcarbonMon.CARBON;
                            historyMonth.TOTALCARBON = lastmoneyhistorymonth.TOTALCARBON + moneyandcarbonMon.CARBON;
                            historyMonth.TOTALMONEY = lastmoneyhistorymonth.TOTALMONEY + moneyandcarbonMon.MONEY;

                            insertPowerStationHistoryMonths.Add(historyMonth);
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的歷史資料總和】", powerStation.Code, dateNowMonth);
                    }
                    else
                    { //修改
                        var historyMonth = await powerStationRepository.ClacPowerStationHistoryMonthDataByPowerStationId(powerStation.Id, dateNowMonth);
                        var moneyandcarbonMon = await powerStationRepository.GetMoneyAndCarbonWithHistoryHour(powerStation.Id, dateNowMonth, 0);
                        var lastmoneyhistorymonth = await powerStationRepository.GetLastMoneyAndCarbonInHour(powerStation.Id, 2, "");
                        if (historyMonth != null)
                        {
                            historyMonth.MONEY = historyMonth.MONEY + moneyandcarbonMon.MONEY;
                            historyMonth.CARBON = historyMonth.CARBON + moneyandcarbonMon.CARBON;
                            historyMonth.TOTALCARBON = lastmoneyhistorymonth.TOTALCARBON + moneyandcarbonMon.CARBON;
                            historyMonth.TOTALMONEY = lastmoneyhistorymonth.TOTALMONEY + moneyandcarbonMon.MONEY;
                            updatePowerStationHistoryMonths.Add(historyMonth);
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的歷史資料總和】", powerStation.Code, dateNowMonth);
                    }

                    //電站該月份的的日照度歷史資料
                    logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}月份的日照度歷史資料】", powerStation.Code, dateNowMonth);
                    var exist_pyrheliometer_history = await powerStationRepository.GetOnePyrheliometerHistoryByMonth(dateNowMonth, powerStation.Id);
                    if (exist_pyrheliometer_history == null)
                    { //新增
                        var pyrheliometerHistoryMonth = await powerStationRepository.CalcPyrheliometerHistoryMonthDataByPowerStationId(dateNowMonth, powerStation.Id);
                        if (pyrheliometerHistoryMonth != null)
                        {
                            pyrheliometerHistoryMonth.Timestamp = Convert.ToDateTime(pyrheliometerHistoryMonth.Timestamp).ToString("yyyy-MM-dd");
                            insertPyrheliometerHistoryMonths.Add(pyrheliometerHistoryMonth);
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的日照度歷史資料】", powerStation.Code, dateNowMonth);
                    }
                    else
                    { //修改
                        var pyrheliometerHistoryMonth = await powerStationRepository.CalcPyrheliometerHistoryMonthDataByPowerStationId(dateNowMonth, powerStation.Id);
                        if (pyrheliometerHistoryMonth != null)
                        {
                            updatePyrheliometerHistoryMonths.Add(pyrheliometerHistoryMonth);
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的日照度歷史資料】", powerStation.Code, dateNowMonth);
                    }

                    //電站該月份的的逆變器歷史資料
                    logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}月份的逆變器歷史資料】", powerStation.Code, dateNowMonth);
                    var exist_inverter_histories = await powerStationRepository.GetInverterHistoryByPowerStationIdAndMonth(dateNowMonth, powerStation.Id);
                    if (exist_inverter_histories.Count == 0)
                    { //新增
                        var inverterHistoriesMonth = await powerStationRepository.CalcInverterHistoryMonthDataByPowerStationId(dateNowMonth, powerStation.SiteDB, powerStation.Id);
                        if (inverterHistoriesMonth.Count > 0)
                        {
                            foreach (var inverterHistoryMonth in inverterHistoriesMonth)
                            {
                                inverterHistoryMonth.DC1KW = inverterHistoryMonth.DC1W / 1000;
                                inverterHistoryMonth.DC2KW = inverterHistoryMonth.DC2W / 1000;
                                inverterHistoryMonth.DC3KW = inverterHistoryMonth.DC3W / 1000;
                                inverterHistoryMonth.DC4KW = inverterHistoryMonth.DC4W / 1000;
                                inverterHistoryMonth.DC5KW = inverterHistoryMonth.DC5W / 1000;

                                inverterHistoryMonth.DCKW = (inverterHistoryMonth.DC1W + inverterHistoryMonth.DC2W + inverterHistoryMonth.DC3W + inverterHistoryMonth.DC4W + inverterHistoryMonth.DC5W) / 1000;
                                inverterHistoryMonth.ACKW = (inverterHistoryMonth.AC1W + inverterHistoryMonth.AC2W + inverterHistoryMonth.AC3W) / 1000;

                                inverterHistoryMonth.TIMESTAMP = Convert.ToDateTime(inverterHistoryMonth.TIMESTAMP).ToString("yyyy-MM-dd");
                                insertInverterHistoryMonths.Add(inverterHistoryMonth);
                            }
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的逆變器歷史資料】", powerStation.Code, dateNowMonth);
                    }
                    else
                    { //修改
                        var inverterHistoriesMonth = await powerStationRepository.CalcInverterHistoryMonthDataByPowerStationId(dateNowMonth, powerStation.SiteDB, powerStation.Id);
                        if (inverterHistoriesMonth.Count > 0)
                        {
                            foreach (var inverterHistoryMonth in inverterHistoriesMonth)
                            {
                                inverterHistoryMonth.DC1KW = inverterHistoryMonth.DC1W / 1000;
                                inverterHistoryMonth.DC2KW = inverterHistoryMonth.DC2W / 1000;
                                inverterHistoryMonth.DC3KW = inverterHistoryMonth.DC3W / 1000;
                                inverterHistoryMonth.DC4KW = inverterHistoryMonth.DC4W / 1000;
                                inverterHistoryMonth.DC5KW = inverterHistoryMonth.DC5W / 1000;

                                inverterHistoryMonth.DCKW = (inverterHistoryMonth.DC1W + inverterHistoryMonth.DC2W + inverterHistoryMonth.DC3W + inverterHistoryMonth.DC4W + inverterHistoryMonth.DC5W) / 1000;
                                inverterHistoryMonth.ACKW = (inverterHistoryMonth.AC1W + inverterHistoryMonth.AC2W + inverterHistoryMonth.AC3W) / 1000;

                                inverterHistoryMonth.TIMESTAMP = Convert.ToDateTime(inverterHistoryMonth.TIMESTAMP).ToString("yyyy-MM-dd");
                                updateInverterHistoryMonths.Add(inverterHistoryMonth);
                            }
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的逆變器歷史資料】", powerStation.Code, dateNowMonth);
                    }

                    //電站該月份的的sensoravg歷史資料
                    logger.LogInformation("【CalcAvgPowerStationJob】【開始計算電站[{0}]在{1}月份的Sensor Avg table所有值的平均資料】", powerStation.Code, dateNowMonth);
                    var exist_sensoravg_history = await powerStationRepository.GetSensorAvgHistoryByPowerStationIdAndMonth(dateNowMonth, powerStation.Id);
                    if (exist_sensoravg_history == null)
                    { //新增
                        var sensorAvgHistoryMonth = await powerStationRepository.CalcSensorAvgHistoryMonthDataByPowerStationId(dateNowMonth, powerStation.Id);
                        if (sensorAvgHistoryMonth != null)
                        {
                            sensorAvgHistoryMonth.TIMESTAMP = Convert.ToDateTime(sensorAvgHistoryMonth.TIMESTAMP).ToString("yyyy-MM-dd");
                            insertSensorAvgHistoryMonths.Add(sensorAvgHistoryMonth);
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的Sensor Avg table所有值的平均資料】", powerStation.Code, dateNowMonth);
                    }
                    else
                    { //修改
                        var sensorAvgHistoryMonth = await powerStationRepository.CalcSensorAvgHistoryMonthDataByPowerStationId(dateNowMonth, powerStation.Id);
                        if (sensorAvgHistoryMonth != null)
                        {
                            sensorAvgHistoryMonth.TIMESTAMP = Convert.ToDateTime(sensorAvgHistoryMonth.TIMESTAMP).ToString("yyyy-MM-dd");
                            updateSensorAvgHistoryMonths.Add(sensorAvgHistoryMonth);
                        }
                        logger.LogInformation("【CalcAvgPowerStationJob】【計算完成電站[{0}]在{1}月份的Sensor Avg table所有值的平均資料】", powerStation.Code, dateNowMonth);
                    }
                    #endregion
                }
                #endregion

                //每月
                List<string> history_properties_month = new List<string>()
                {
                    "PowerStationId",
                    "TIMESTAMP",
                    "SITEID",
                    "SITETYPE",
                    "MonthKWh",
                    "TOTALKWH",
                    "KWHKWP",
                    "PR",
                    "MP",
                    "SolarHour",
                    "MONEY",
                    "CARBON",
                    "TOTALMONEY",
                    "TOTALCARBON"
                };

                if (insertPowerStationHistoryMonths.Count > 0)
                {
                    await powerStationRepository.AddPowerStationHistoryMonthList(insertPowerStationHistoryMonths, history_properties_month);
                }

                if (updatePowerStationHistoryMonths.Count > 0)
                {
                    await powerStationRepository.UpdatePowerStationHistoryMonthList(updatePowerStationHistoryMonths);
                }

                #region step5. 將各電站的每月的日照度資料insert or update 各資料表

                //每月
                if (insertPyrheliometerHistoryMonths.Count > 0)
                {
                    await powerStationRepository.AddPyrheliometerHistoryMonthList(insertPyrheliometerHistoryMonths, pyrheliometer_history_properties);
                }

                if (updatePyrheliometerHistoryMonths.Count > 0)
                {
                    await powerStationRepository.UpdatePyrheliometerHistoryMonthList(updatePyrheliometerHistoryMonths);
                }
                #endregion

                #region step6. 將各電站的每月的逆變器資料insert or update 各資料表
                //每月
                if (insertInverterHistoryMonths.Count > 0)
                {
                    await powerStationRepository.AddInverterHistoryMonthList(insertInverterHistoryMonths, inverter_history_properties);
                }

                if (updateInverterHistoryMonths.Count > 0)
                {
                    await powerStationRepository.UpdateInverterHistoryMonthList(updateInverterHistoryMonths);
                }
                #endregion

                #region step6. 將各電站的每月的Sensor Avg資料insert or update 各資料表
                //每月
                if (insertSensorAvgHistoryMonths.Count > 0)
                {
                    await powerStationRepository.AddSensorAvgHistoryMonthList(insertSensorAvgHistoryMonths, sensoravg_history_properties);
                }

                if (updateSensorAvgHistoryMonths.Count > 0)
                {
                    await powerStationRepository.UpdateSensorAvgHistoryMonthList(updateSensorAvgHistoryMonths);
                }
                #endregion

            }
            catch (Exception exception)
            {
                logger.LogError("【{0}】{1}", "CalcAvgPowerStationJob", exception.Message);
            }
        }
    }
}
