def fetchSection1_1_2Context(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_1_1_2: mRepo = MetricsDataRepo(appDbConnStr) # get WR Unrestricted demand hourly values for this month and prev yr month wrDemVals = mRepo.getEntityMetricHourlyData('wr', 'Demand(MW)', startDt, endDt) wrPeakDemDf = pd.DataFrame(wrDemVals) wrPeakDemDf = wrPeakDemDf.pivot(index='time_stamp', columns='metric_name', values='data_value') lastYrStartDt = addMonths(startDt, -12) lastYrEndDt = addMonths(endDt, -12) # last_yr_month_name = dt.datetime.strftime(lastYrStartDt, "%b %y") wrLastYrDemVals = mRepo.getEntityMetricHourlyData('wr', 'Demand(MW)', lastYrStartDt, lastYrEndDt) wrLastYrPeakDemDf = pd.DataFrame(wrLastYrDemVals) wrLastYrPeakDemDf = wrLastYrPeakDemDf.pivot(index='time_stamp', columns='metric_name', values='data_value') wr_peak_dem = round(wrPeakDemDf['Demand(MW)'].max()) maxPeakDemDt = wrPeakDemDf['Demand(MW)'].idxmax() wr_peak_dem_time_str = "{0} Hrs on {1}".format( dt.datetime.strftime(maxPeakDemDt, "%H:%M"), dt.datetime.strftime(maxPeakDemDt, "%d-%b-%y")) wr_peak_dem_last_yr = round(wrLastYrPeakDemDf['Demand(MW)'].max()) wr_peak_dem_perc_inc = 100 * \ (wr_peak_dem - wr_peak_dem_last_yr)/wr_peak_dem_last_yr wr_peak_dem_perc_inc = round(wr_peak_dem_perc_inc, 2) wr_avg_dem = round(wrPeakDemDf['Demand(MW)'].mean()) wr_avg_dem_last_yr = round(wrLastYrPeakDemDf['Demand(MW)'].mean()) wr_avg_dem_perc_inc = round( 100 * (wr_avg_dem - wr_avg_dem_last_yr) / wr_avg_dem_last_yr, 2) secData: ISection_1_1_2 = { 'wr_peak_dem_met': wr_peak_dem, 'wr_peak_dem_time_str': wr_peak_dem_time_str, 'wr_peak_dem_perc_inc': wr_peak_dem_perc_inc, 'wr_last_year_peak_dem': wr_peak_dem_last_yr, 'wr_avg_dem': wr_avg_dem, 'wr_avg_dem_last_yr': wr_avg_dem_last_yr, 'wr_avg_dem_perc_inc': wr_avg_dem_perc_inc } return secData
def fetchSection2_1_LoadDurationCurve(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> dict: mRepo = MetricsDataRepo(appDbConnStr) currentMonthMW = mRepo.getEntityMetricHourlyData('wr','Demand(MW)', startDt , endDt) df = pd.DataFrame(currentMonthMW) currentMonthMWVals = deriveDurationVals(df['data_value'],100) pastMonthMW = mRepo.getEntityMetricHourlyData('wr','Demand(MW)',addMonths(startDt,-1) , addMonths(endDt,-1)) df = pd.DataFrame(pastMonthMW) pastMonthMWVals = deriveDurationVals(df['data_value'],100) pastYearMW = mRepo.getEntityMetricHourlyData('wr','Demand(MW)',addMonths(startDt,-12) , addMonths(endDt,-12)) df = pd.DataFrame(pastYearMW) pastYearMWVals = deriveDurationVals(df['data_value'],100) pltTitle = 'Load Duration Curve {0}, {1} & {2}'.format(startDt.strftime('%b-%y') , addMonths(startDt,-1).strftime('%b-%y') , addMonths(startDt,-12).strftime('%b-%y')) fig, ax = plt.subplots(figsize=(7.5, 4.5)) ax.set_title(pltTitle) ax.set_ylabel('Demand met (MW)') ax.set_xlabel('% of time') # ax.xaxis.set_major_locator(mdates.DayLocator(interval=2)) # ax.xaxis.set_major_formatter(mdates.DateFormatter('%d')) ax.plot( currentMonthMWVals['perc_exceeded'],currentMonthMWVals['bins'], color='red',label=dt.datetime.strftime(startDt, '%b-%y')) ax.plot( pastMonthMWVals['perc_exceeded'] , pastMonthMWVals['bins'],color='blue', label=addMonths(startDt,-1).strftime('%b-%y')) ax.plot( pastYearMWVals['perc_exceeded'] , pastYearMWVals['bins'], color='green', label=addMonths(startDt,-12).strftime('%b-%y')) ax.yaxis.grid(True) ax.xaxis.grid(True) ax.legend( loc='best', ncol=4, borderaxespad=0.) plt.xticks(np.arange(0,110,10)) ax.set_xlim(xmin=0 , xmax= 100) ax.set_ylim(ymin=35000, ymax=65000) fig.subplots_adjust(bottom=0.25, top=0.8) ax.set_facecolor("#cbffff") fig.savefig('assets/section_2_1_loadDurationCurve.png') # plt.show() # plt.close() secData: dict = {} return secData
def test_getEntityMetricHourlyData(self) -> None: """tests the function that gets hourly data of entity metric """ appDbConnStr = self.jsonConf['appDbConnStr'] mRepo = MetricsDataRepo(appDbConnStr) startDt = dt.datetime(2020, 1, 1) endDt = dt.datetime(2020, 1, 10) samples = mRepo.getEntityMetricHourlyData( "wr", "Demand(MW)", startDt, endDt) self.assertFalse(len(samples) == 0)
def fetchSection2_3_MinContext(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_2_3_2: monthDtObj = dt.datetime(startDt.year, startDt.month, 1) month_name = dt.datetime.strftime(startDt, "%b' %y") full_month_name = dt.datetime.strftime(startDt, "%B %Y") constituentinfo = getConstituentsMappings() numPages = 0 mRepo = MetricsDataRepo(appDbConnStr) # get WR Unrestricted demand hourly values for this month and prev yr month wrDemVals = mRepo.getEntityMetricHourlyData('wr', 'Demand(MW)', startDt, endDt) wrUnResDemDf = pd.DataFrame(wrDemVals) wrUnResDemDf = wrUnResDemDf.set_index('time_stamp') wr_max_unres_dem = round(wrUnResDemDf['data_value'].min()) minUnresDemDt = wrUnResDemDf['data_value'].idxmin() minDtSrtT = dt.datetime(minUnresDemDt.year, minUnresDemDt.month, minUnresDemDt.day) minDtEndT = dt.datetime(minUnresDemDt.year, minUnresDemDt.month, minUnresDemDt.day, 23) wr_min_unres_dem_time_str = "HOURLY MIN.DEMAND CURVES ON REGIONAL MINIMUM DAY {1} at {0} Hrs".format( dt.datetime.strftime(minUnresDemDt, "%H:%M"), dt.datetime.strftime(minUnresDemDt, "%d-%b-%y")) wrUnResDemDf = wrUnResDemDf[(wrUnResDemDf.index >= minDtSrtT) & (wrUnResDemDf.index <= minDtEndT)] # create a plotting area and get the figure, axes handle in return fig, ax = plt.subplots(figsize=(7.5, 2.5)) # set plot title pltTitle = "WR" ax.set_title(pltTitle) # set x and y labels ax.set_xlabel('HOUR') ax.set_ylabel('MW') ax.set_facecolor("violet") fig.patch.set_facecolor('#95d0fc') wrUnResDemDf.reset_index(inplace=True) dateList = [] times = wrUnResDemDf["time_stamp"] for col in times: dateList.append(dt.datetime.strftime(col, '%H')) wrUnResDemDf["time_stamp"] = dateList # plot data and get the line artist object in return laThisMonth, = ax.plot(wrUnResDemDf['time_stamp'], wrUnResDemDf['data_value'], color='#0000ff') # enable axis grid lines ax.yaxis.grid(True) ax.xaxis.grid(True) fig.subplots_adjust(bottom=0.25, top=0.8) fig.suptitle(wr_min_unres_dem_time_str, fontsize=10) fig.savefig('assets/section_2_3_2_{0}.png'.format(numPages)) numPages += 1 for itr in constituentinfo: if itr['entity_tag'] == 'wr': continue else: # get WR Unrestricted demand hourly values for this month and prev yr month constDemVals = mRepo.getEntityMetricHourlyData( itr['entity_tag'], 'Demand(MW)', minDtSrtT, minDtEndT) constUnResDemDf = pd.DataFrame(constDemVals) constUnResDemDf = constUnResDemDf.set_index('time_stamp') constUnResDemDf.reset_index(inplace=True) dateList = [] times = constUnResDemDf["time_stamp"] for col in times: dateList.append(dt.datetime.strftime(col, '%H')) constUnResDemDf["time_stamp"] = dateList # create a plotting area and get the figure, axes handle in return fig, ax = plt.subplots(figsize=(7.5, 2.5)) # set plot title pltTitle = itr['display_name'] ax.set_title(pltTitle) # set x and y labels ax.set_xlabel('HOUR') ax.set_ylabel('MW') laThisMonth, = ax.plot(constUnResDemDf['time_stamp'], constUnResDemDf['data_value'], color='#0000ff') # enable axis grid lines ax.yaxis.grid(True) ax.xaxis.grid(True) fig.subplots_adjust(bottom=0.25, top=0.8) ax.set_facecolor(itr['plot_c']) fig.patch.set_facecolor(itr['bac_c']) fig.savefig('assets/section_2_3_2_{0}.png'.format(numPages)) numPages += 1 sectionData = {'num_plts_sec_min_hourly': numPages} return sectionData
def fetchSection1_1_WindSolarContext( appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_1_1_wind_solar: mRepo = MetricsDataRepo(appDbConnStr) # get solar mu solarMuVals = mRepo.getEntityMetricDailyData("wr", "Solar(MU)", startDt, endDt) cgsSolarMuVals = mRepo.getEntityMetricDailyData("wr", "CGS Solar(Mus)", startDt, endDt) tot_month_solar_gen_mu = 0 for s, c in zip(solarMuVals, cgsSolarMuVals): tot_month_solar_gen_mu += s["data_value"] + c["data_value"] avg_month_solar_gen_mu = tot_month_solar_gen_mu / len(solarMuVals) # get solar mu for last year solarMuLastYrVals = mRepo.getEntityMetricDailyData("wr", "Solar(MU)", addMonths(startDt, -12), addMonths(endDt, -12)) cgsSolarMuLastYrVals = mRepo.getEntityMetricDailyData( "wr", "CGS Solar(Mus)", addMonths(startDt, -12), addMonths(endDt, -12)) tot_last_year_solar_gen_mu = 0 for s, c in zip(solarMuLastYrVals, cgsSolarMuLastYrVals): tot_last_year_solar_gen_mu += s["data_value"] + c["data_value"] tot_last_year_solar_gen_mu_perc = round( 100 * (tot_month_solar_gen_mu - tot_last_year_solar_gen_mu) / tot_last_year_solar_gen_mu, 2) tot_last_year_solar_gen_mu_perc_str = "" if tot_last_year_solar_gen_mu_perc < 0: tot_last_year_solar_gen_mu_perc_str = "reduced by {0}%".format( -1 * tot_last_year_solar_gen_mu_perc) else: tot_last_year_solar_gen_mu_perc_str = "increased by {0}%".format( tot_last_year_solar_gen_mu_perc) solarMwVals = mRepo.getEntityMetricHourlyData("wr", "Solar(MW)", startDt, endDt) maxSolarMwObj = solarMwVals[0] for v in solarMwVals: if v["data_value"] > maxSolarMwObj["data_value"]: maxSolarMwObj = v max_month_solar_gen_mw = maxSolarMwObj["data_value"] max_month_solar_gen_mw_date = '{0} at {1} hrs'.format( dt.datetime.strftime(maxSolarMwObj["time_stamp"], "%d %b %Y"), dt.datetime.strftime(maxSolarMwObj["time_stamp"], "%H:%M")) # get wind mu windMuVals = mRepo.getEntityMetricDailyData("wr", "Wind(MU)", startDt, endDt) cgsWindMuVals = mRepo.getEntityMetricDailyData("wr", "CGS Wind(Mus)", startDt, endDt) tot_month_wind_gen_mu = 0 for w, c in zip(windMuVals, cgsWindMuVals): tot_month_wind_gen_mu += w["data_value"] + c["data_value"] avg_month_wind_gen_mu = tot_month_wind_gen_mu / len(windMuVals) # get wind mu for last year windMuLastYrVals = mRepo.getEntityMetricDailyData("wr", "Wind(MU)", addMonths(startDt, -12), addMonths(endDt, -12)) cgsWindMuLastYrVals = mRepo.getEntityMetricDailyData( "wr", "CGS Wind(Mus)", addMonths(startDt, -12), addMonths(endDt, -12)) tot_last_year_wind_gen_mu = 0 for w, c in zip(windMuLastYrVals, cgsWindMuLastYrVals): tot_last_year_wind_gen_mu += w["data_value"] + c["data_value"] tot_last_year_wind_gen_mu_perc = round( 100 * (tot_month_wind_gen_mu - tot_last_year_wind_gen_mu) / tot_last_year_wind_gen_mu, 2) tot_last_year_wind_gen_mu_perc_str = "" if tot_last_year_wind_gen_mu_perc < 0: tot_last_year_wind_gen_mu_perc_str = "reduced by {0}%".format( -1 * tot_last_year_wind_gen_mu_perc) else: tot_last_year_wind_gen_mu_perc_str = "increased by {0}%".format( tot_last_year_wind_gen_mu_perc) windMwVals = mRepo.getEntityMetricHourlyData("wr", "Wind(MW)", startDt, endDt) maxWindMwObj = windMwVals[0] for v in windMwVals: if v["data_value"] > maxWindMwObj["data_value"]: maxWindMwObj = v max_month_wind_gen_mw = maxWindMwObj["data_value"] max_month_wind_gen_mw_date = '{0} at {1} hrs'.format( dt.datetime.strftime(maxWindMwObj["time_stamp"], "%d %b %Y"), dt.datetime.strftime(maxWindMwObj["time_stamp"], "%H:%M")) # create dataframe for solar and wind addition resDf = pd.DataFrame(windMwVals + solarMwVals) resDf = resDf.pivot(index="time_stamp", columns="metric_name", values="data_value") resDf["Renewable"] = resDf["Wind(MW)"] + resDf["Solar(MW)"] max_month_ren_gen_mw = resDf["Renewable"].max() maxRenDt = resDf["Renewable"].idxmax().to_pydatetime() max_month_ren_gen_mw_date = '{0} at {1} hrs'.format( dt.datetime.strftime(maxRenDt, "%d %b %Y"), dt.datetime.strftime(maxRenDt, "%H:%M")) secData: ISection_1_1_wind_solar = { 'tot_month_wind_gen_mu': round(tot_month_wind_gen_mu), 'avg_month_wind_gen_mu': round(avg_month_wind_gen_mu, 1), 'tot_last_year_wind_gen_mu_perc_str': tot_last_year_wind_gen_mu_perc_str, 'tot_last_year_wind_gen_mu': round(tot_last_year_wind_gen_mu), 'max_month_wind_gen_mw': round(max_month_wind_gen_mw), 'max_month_wind_gen_mw_date': max_month_wind_gen_mw_date, 'tot_month_solar_gen_mu': round(tot_month_solar_gen_mu), 'avg_month_solar_gen_mu': round(avg_month_solar_gen_mu, 1), 'tot_last_year_solar_gen_mu_perc_str': tot_last_year_solar_gen_mu_perc_str, 'tot_last_year_solar_gen_mu': round(tot_last_year_solar_gen_mu), 'max_month_solar_gen_mw': round(max_month_solar_gen_mw), 'max_month_solar_gen_mw_date': max_month_solar_gen_mw_date, 'max_month_ren_gen_mw': round(max_month_ren_gen_mw), 'max_month_ren_gen_mw_date': max_month_ren_gen_mw_date } return secData
def fetchSection1_4_2Context(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_1_4_2: monthName = dt.datetime.strftime(startDt, "%b %y") mRepo = MetricsDataRepo(appDbConnStr) # get WR demand hourly values for this month and prev yr month wrDemVals = mRepo.getEntityMetricHourlyData('wr', 'Demand(MW)', startDt, endDt) demVals = [x['data_value'] for x in wrDemVals] wr_max_dem = max(demVals) wrMaxDemDt = wrDemVals[demVals.index(wr_max_dem)]['time_stamp'] wr_max_dem_date_str = dt.datetime.strftime(wrMaxDemDt, "%d-%b-%y") wr_avg_dem = sum(demVals) / len(demVals) wrMaxDemTimestampStr = dt.datetime.strftime(wrMaxDemDt, "%d-%b-%y %H:%M") + " hrs" lastYrStartDt = addMonths(startDt, -12) lastYrEndDt = addMonths(endDt, -12) monthNameLastYear = dt.datetime.strftime(lastYrStartDt, "%b %y") wrLastYrDemVals = mRepo.getEntityMetricHourlyData('wr', 'Demand(MW)', lastYrStartDt, lastYrEndDt) demVals = [x['data_value'] for x in wrLastYrDemVals] wr_max_dem_last_year = max(demVals) wr_max_dem_date_str_last_year = dt.datetime.strftime( wrLastYrDemVals[demVals.index(wr_max_dem_last_year)]['time_stamp'], "%d-%b-%y") wr_avg_dem_last_year = sum(demVals) / len(demVals) wr_avg_dem_perc_change_last_year = round( 100 * (wr_avg_dem - wr_avg_dem_last_year) / wr_avg_dem_last_year, 2) wr_max_dem_perc_change_last_year = round( 100 * (wr_max_dem - wr_max_dem_last_year) / wr_max_dem_last_year, 2) prevMonthStartDt = addMonths(startDt, -1) prevMonthEndDt = addMonths(endDt, -1) prev_month_name = dt.datetime.strftime(prevMonthStartDt, "%b %y") wrPrevMonthDemVals = mRepo.getEntityMetricHourlyData( 'wr', 'Demand(MW)', prevMonthStartDt, prevMonthEndDt) demVals = [x['data_value'] for x in wrPrevMonthDemVals] wr_max_dem_prev_month = max(demVals) wr_max_dem_date_str_prev_month = dt.datetime.strftime( wrPrevMonthDemVals[demVals.index(wr_max_dem_prev_month)]['time_stamp'], "%d-%b-%y") wr_avg_dem_prev_month = sum(demVals) / len(demVals) wr_avg_dem_perc_change_prev_month = round( 100 * (wr_avg_dem - wr_avg_dem_prev_month) / wr_avg_dem_prev_month, 2) wr_max_dem_perc_change_prev_month = round( 100 * (wr_max_dem - wr_max_dem_prev_month) / wr_max_dem_prev_month, 2) # create plot image for demands of prev yr, prev month, this month pltDemObjs = [{ 'Date': convertDtToDayNum(x["time_stamp"]), 'colName': monthName, 'val': x["data_value"] } for x in wrDemVals] pltDemObjsLastYear = [{ 'Date': convertDtToDayNum(x["time_stamp"]), 'colName': monthNameLastYear, 'val': x["data_value"] } for x in wrLastYrDemVals] pltDemObjsPrevMonth = [{ 'Date': convertDtToDayNum(x["time_stamp"]), 'colName': prev_month_name, 'val': x["data_value"] } for x in wrPrevMonthDemVals] pltDataObjs = pltDemObjs + pltDemObjsLastYear + pltDemObjsPrevMonth pltDataDf = pd.DataFrame(pltDataObjs) pltDataDf = pltDataDf.pivot(index='Date', columns='colName', values='val') pltDataDf.reset_index(inplace=True) pltDataDf["Date"] = [math.floor(x) for x in pltDataDf["Date"]] pltDataDf = pltDataDf.groupby(by="Date").max() # save plot data as excel pltDataDf.to_excel("assets/plot_1_4_2.xlsx", index=True) # derive plot title pltTitle = 'Demand met {0}, {1} & {2} \n Max. {3} MW on dt. {4} \n Average Load Growth {5}{6} against last year'.format( monthName, prev_month_name, monthNameLastYear, format(round(wr_max_dem), ","), wrMaxDemTimestampStr, wr_avg_dem_perc_change_last_year, "%") # create a plotting area and get the figure, axes handle in return fig, ax = plt.subplots(figsize=(7.5, 4.5)) # set plot title ax.set_title(pltTitle) # set x and y labels ax.set_xlabel('Date') ax.set_ylabel('MW') ax.set_facecolor("#c6d9f1") fig.patch.set_facecolor('#fac090') # plot data and get the line artist object in return laThisMonth, = ax.plot(pltDataDf.index.values, pltDataDf[monthName].values, color='#ff0000') laThisMonth.set_label(monthName) laLastYear, = ax.plot(pltDataDf.index.values, pltDataDf[monthNameLastYear].values, color='#00ff00') laLastYear.set_label(monthNameLastYear) laPrevMonth, = ax.plot(pltDataDf.index.values, pltDataDf[prev_month_name].values, color='#A52A2A') laPrevMonth.set_label(prev_month_name) ax.set_xlim((1, 31), auto=True) # enable y axis grid lines ax.yaxis.grid(True) # enable legends ax.legend(bbox_to_anchor=(0.0, -0.3, 1, 0), loc='lower center', ncol=3, mode="expand", borderaxespad=0.) fig.subplots_adjust(bottom=0.25, top=0.8) fig.savefig('assets/section_1_4_2.png') secData: ISection_1_4_2 = { 'prev_month_name': prev_month_name, 'wr_max_dem': round(wr_max_dem), 'wr_max_dem_date_str': wr_max_dem_date_str, 'wr_avg_dem': round(wr_avg_dem), 'wr_max_dem_last_year': round(wr_max_dem_last_year), 'wr_max_dem_date_str_last_year': wr_max_dem_date_str_last_year, 'wr_avg_dem_last_year': round(wr_avg_dem_last_year), 'wr_avg_dem_perc_change_last_year': wr_avg_dem_perc_change_last_year, 'wr_max_dem_perc_change_last_year': wr_max_dem_perc_change_last_year, 'wr_max_dem_prev_month': round(wr_max_dem_prev_month), 'wr_max_dem_date_str_prev_month': wr_max_dem_date_str_prev_month, 'wr_avg_dem_prev_month': round(wr_avg_dem_prev_month), 'wr_avg_dem_perc_change_prev_month': wr_avg_dem_perc_change_prev_month, 'wr_max_dem_perc_change_prev_month': wr_max_dem_perc_change_prev_month } return secData
def fetchSection1_11_windPLF(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_1_11_PLFCUF: constituentsInfos = getREConstituentsMappings() mRepo = MetricsDataRepo(appDbConnStr) numOfDays = (endDt - startDt).days + 1 soFarHighestAllEntityGenVals = mRepo.getSoFarHighestAllEntityData( 'soFarHighestWindGen', addMonths(startDt, -1)) soFarHighestGenLookUp = {} for v in soFarHighestAllEntityGenVals: soFarHighestGenLookUp[v['constituent']] = { 'value': v['data_value'], 'ts': v['data_time'] } dispRows: List[IPLFCUFDataRow] = [] for cIter in range(len(constituentsInfos)): constInfo = constituentsInfos[cIter] if (math.isnan(constInfo['windCapacity'])): continue maxGenData = mRepo.getEntityMetricHourlyData(constInfo["entity_tag"], "Wind(MW)", startDt, endDt) if constInfo['entity_tag'] == 'central': windEnerConsumption = mRepo.getEntityMetricDailyData( 'wr', 'CGS Wind(Mus)', startDt, endDt) elif constInfo['entity_tag'] == 'wr': windEnerConsumption = mRepo.getEntityMetricDailyData( 'wr', "Wind(MU)", startDt, endDt) cgsWindEnerConsumption = mRepo.getEntityMetricDailyData( 'wr', 'CGS Wind(Mus)', startDt, endDt) for w, c in zip(windEnerConsumption, cgsWindEnerConsumption): w["data_value"] += c["data_value"] else: windEnerConsumption = mRepo.getEntityMetricDailyData( constInfo['entity_tag'], 'Wind(MU)', startDt, endDt) energyConsumption = mRepo.getEntityMetricDailyData( constInfo['entity_tag'], 'Consumption(MU)', startDt, endDt) maxGenDf = pd.DataFrame(maxGenData) maxGenDf = maxGenDf.pivot(index='time_stamp', columns='metric_name', values='data_value') windEnerConsumptionSum = pd.DataFrame(windEnerConsumption).groupby( 'entity_tag').sum().iloc[0]['data_value'] if (len(energyConsumption) == 0): # This is for central sector as we dont have consumption data # calculate mu from mw # df = pd.DataFrame(maxGenData) # average = df.groupby('entity_tag').mean() # windEnerConsumptionSumDf = average * 0.024 * numOfDays #To Calculate Avg MU from MW # windEnerConsumptionSum = windEnerConsumptionSumDf.iloc[0]['data_value'] EnerConsumptionSum = 0 penetrationLevel = 0 else: EnerConsumptionSum = pd.DataFrame(energyConsumption).groupby( 'entity_tag').sum().iloc[0]['data_value'] penetrationLevel = round( (windEnerConsumptionSum / EnerConsumptionSum) * 100, 2) maxWind = maxGenDf["Wind(MW)"].max() maxWindDt = maxGenDf["Wind(MW)"].idxmax() plf = (windEnerConsumptionSum * 1000) / (int(constInfo['windCapacity']) * 24 * numOfDays) cuf = maxWind * 100 / (int(constInfo['windCapacity'])) prevHighestWindObj = soFarHighestGenLookUp[constInfo["entity_tag"]] newHighestWind = maxWind newHighestWindTime = maxWindDt.to_pydatetime() if newHighestWind < prevHighestWindObj["value"]: newHighestWind = prevHighestWindObj["value"] newHighestWindTime = prevHighestWindObj["ts"] mRepo.insertSoFarHighest(constInfo['entity_tag'], "soFarHighestWindGen", startDt, newHighestWind, newHighestWindTime) # soFarHighestAllEntityGenVals = mRepo.getSoFarHighestAllEntityData( # 'soFarHighestWindGen', startDt) # soFarHighestGenLookUp = {} # for v in soFarHighestAllEntityGenVals: # soFarHighestGenLookUp[v['constituent']] = { # 'value': v['data_value'], 'ts': v['data_time']} so_far_high_gen_str = str( round(newHighestWind)) + ' on ' + dt.datetime.strftime( newHighestWindTime, '%d-%b-%Y') + ' at ' + dt.datetime.strftime( newHighestWindTime, '%H:%S') const_display_row: IPLFCUFDataRow = { 'entity': constInfo['display_name'], 'capacityMW': round(constInfo['windCapacity']), 'maxgenerationMW': round(maxWind), 'soFarHighestGenMW': so_far_high_gen_str, 'energyGeneration': round(windEnerConsumptionSum), 'energyConsumption': round(EnerConsumptionSum), 'penetration': penetrationLevel, 'plf': round(plf * 100), 'cuf': round(cuf) } dispRows.append(const_display_row) secData: ISection_1_11_PLFCUF = {"so_far_hig_win_gen_plf": dispRows} return secData
def fetchSection1_1_1Context(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_1_1_1: monthDtObj = dt.datetime(startDt.year, startDt.month, 1) month_name = dt.datetime.strftime(startDt, "%b' %y") full_month_name = dt.datetime.strftime(startDt, "%B %Y") mRepo = MetricsDataRepo(appDbConnStr) # get WR Unrestricted demand hourly values for this month and prev yr month wrDemVals = mRepo.getEntityMetricHourlyData('wr', 'Demand(MW)', startDt, endDt) wrLoadSheddingVals = mRepo.getEntityMetricHourlyData( 'wr', 'Load Shedding(MW)', startDt, endDt) wrUnResDemDf = pd.DataFrame(wrDemVals + wrLoadSheddingVals) wrUnResDemDf = wrUnResDemDf.pivot(index='time_stamp', columns='metric_name', values='data_value') wrUnResDemDf['UnresDem'] = wrUnResDemDf['Demand(MW)'] + \ wrUnResDemDf['Load Shedding(MW)'] lastYrStartDt = addMonths(startDt, -12) lastYrEndDt = addMonths(endDt, -12) last_yr_month_name = dt.datetime.strftime(lastYrStartDt, "%b %y") wrLastYrDemVals = mRepo.getEntityMetricHourlyData('wr', 'Demand(MW)', lastYrStartDt, lastYrEndDt) wrLastYrLoadSheddingVals = mRepo.getEntityMetricHourlyData( 'wr', 'Load Shedding(MW)', lastYrStartDt, lastYrEndDt) wrLastYrUnResDemDf = pd.DataFrame(wrLastYrDemVals + wrLastYrLoadSheddingVals) wrLastYrUnResDemDf = wrLastYrUnResDemDf.pivot(index='time_stamp', columns='metric_name', values='data_value') wrLastYrUnResDemDf['UnresDem'] = wrLastYrUnResDemDf['Demand(MW)'] + \ wrLastYrUnResDemDf['Load Shedding(MW)'] wr_max_unres_dem = round(wrUnResDemDf['UnresDem'].max()) maxUnresDemDt = wrUnResDemDf['UnresDem'].idxmax() wr_max_unres_dem_time_str = "{0} Hrs on {1}".format( dt.datetime.strftime(maxUnresDemDt, "%H:%M"), dt.datetime.strftime(maxUnresDemDt, "%d-%b-%y")) wr_max_unres_dem_last_yr = round(wrLastYrUnResDemDf['UnresDem'].max()) wr_max_unres_dem_perc_inc = 100 * \ (wr_max_unres_dem - wr_max_unres_dem_last_yr)/wr_max_unres_dem_last_yr wr_max_unres_dem_perc_inc = round(wr_max_unres_dem_perc_inc, 2) wr_avg_unres_dem = round(wrUnResDemDf['UnresDem'].mean()) wr_avg_unres_dem_last_yr = round(wrLastYrUnResDemDf['UnresDem'].mean()) wr_avg_unres_dem_perc_inc = round( 100 * (wr_avg_unres_dem - wr_avg_unres_dem_last_yr) / wr_avg_unres_dem_last_yr, 2) secData: ISection_1_1_1 = { 'monthDtObj': monthDtObj, 'month_name': month_name, 'full_month_name': full_month_name, 'last_yr_month_name': last_yr_month_name, 'wr_max_unres_dem': wr_max_unres_dem, 'wr_max_unres_dem_time_str': wr_max_unres_dem_time_str, 'wr_max_unres_dem_perc_inc': wr_max_unres_dem_perc_inc, 'wr_max_unres_dem_last_yr': wr_max_unres_dem_last_yr, 'wr_avg_unres_dem': wr_avg_unres_dem, 'wr_avg_unres_dem_last_yr': wr_avg_unres_dem_last_yr, 'wr_avg_unres_dem_perc_inc': wr_avg_unres_dem_perc_inc } return secData
def fetchSection1_3_bContext(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_1_3_b: constituentsInfos = getConstituentsMappings() mRepo = MetricsDataRepo(appDbConnStr) soFarHighestAllEntityReqVals = mRepo.getSoFarHighestAllEntityData( 'soFarHighestRequirement', addMonths(startDt, -1)) soFarHighestReqLookUp = {} for v in soFarHighestAllEntityReqVals: soFarHighestReqLookUp[v['constituent']] = { 'value': v['data_value'], 'ts': v['data_time'] } soFarHighestAllEntityAvailVals = mRepo.getSoFarHighestAllEntityData( 'soFarHighestAvailability', addMonths(startDt, -1)) soFarHighestAvailLookUp = {} for v in soFarHighestAllEntityAvailVals: soFarHighestAvailLookUp[v['constituent']] = { 'value': v['data_value'], 'ts': v['data_time'] } dispRows: List[ISoFarHighestDataRow] = [] for cIter in range(len(constituentsInfos)): constInfo = constituentsInfos[cIter] availData = mRepo.getEntityMetricHourlyData(constInfo["entity_tag"], "Demand(MW)", startDt, endDt) loadSheddingData = mRepo.getEntityMetricHourlyData( constInfo["entity_tag"], "Load Shedding(MW)", startDt, endDt) availReqData = availData + loadSheddingData availReqDataDf = pd.DataFrame(availReqData) availReqDataDf = availReqDataDf.pivot(index='time_stamp', columns='metric_name', values='data_value') availReqDataDf.reset_index(inplace=True) availReqDataDf["Requirement"] = availReqDataDf["Demand(MW)"] + \ availReqDataDf["Load Shedding(MW)"] maxReq = availReqDataDf["Requirement"].max() maxReqDt = availReqDataDf["time_stamp"].loc[ availReqDataDf["Requirement"].idxmax()] maxAvail = availReqDataDf["Demand(MW)"].max() maxAvailDt = availReqDataDf["time_stamp"].loc[ availReqDataDf["Demand(MW)"].idxmax()] maxShortagePerc = round(100 * (maxReq - maxAvail) / maxAvail, 2) prevHighestReqObj = soFarHighestReqLookUp[constInfo["entity_tag"]] newHighestReq = maxReq newHighestReqTime = maxReqDt.to_pydatetime() if newHighestReq < prevHighestReqObj["value"]: newHighestReq = prevHighestReqObj["value"] newHighestReqTime = prevHighestReqObj["ts"] prevHighestAvailObj = soFarHighestAvailLookUp[constInfo["entity_tag"]] newHighestAvail = maxAvail newHighestAvailTime = maxAvailDt.to_pydatetime() if newHighestAvail < prevHighestAvailObj["value"]: newHighestAvail = prevHighestAvailObj["value"] newHighestAvailTime = prevHighestAvailObj["ts"] newHighestShortagePerc = round( 100 * (newHighestReq - newHighestAvail) / newHighestAvail, 2) newHighestAvailTime = newHighestAvailTime newHighestReqTime = newHighestReqTime mRepo.insertSoFarHighest(constInfo['entity_tag'], "soFarHighestAvailability", startDt, newHighestAvail, newHighestAvailTime) mRepo.insertSoFarHighest(constInfo['entity_tag'], "soFarHighestRequirement", startDt, newHighestReq, newHighestReqTime) const_display_row: ISoFarHighestDataRow = { 'entity': constInfo['display_name'], 'peakReqMW': round(maxReq), 'peakAvailMW': round(maxAvail), 'shortage_X': maxShortagePerc, 'highestReqMW': round(newHighestReq), 'highestAvailMW': round(newHighestAvail), 'shortage_Y': newHighestShortagePerc, 'highestReqMWDateStr': 'Max on {0} at {1} hrs'.format( dt.datetime.strftime(newHighestReqTime, "%d.%m.%y"), dt.datetime.strftime(newHighestReqTime, "%H:%M")), 'highestAvailMWDateStr': 'Max on {0} at {1} hrs'.format( dt.datetime.strftime(newHighestAvailTime, "%d.%m.%y"), dt.datetime.strftime(newHighestAvailTime, "%H:%M")) } dispRows.append(const_display_row) secData: ISection_1_3_b = {"so_far_hig_req_avail": dispRows} return secData
def fetchSection1_11_LoadCurve(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime): mRepo = MetricsDataRepo(appDbConnStr) pltDataObj: list = [] totalGen = mRepo.getEntityREHourlyData('wr', startDt, endDt) df = pd.DataFrame(totalGen) max_total_gen_position = df['val'].idxmax() max_total_gen_dt = df['time_stamp'].iloc[max_total_gen_position] max_str_date = dt.datetime(max_total_gen_dt.year, max_total_gen_dt.month, max_total_gen_dt.day) totalGenOnMaxGenDay = mRepo.getEntityREHourlyData('wr', max_str_date, max_str_date) wrDemandOnMaxGenDay = mRepo.getEntityMetricHourlyData( 'wr', 'Demand(MW)', max_str_date, max_str_date) pltDataDf = pd.DataFrame() pltDataDf['hours'] = [ x['time_stamp'].hour + 1 for x in totalGenOnMaxGenDay ] pltDataDf['reGen'] = [x['val'] for x in totalGenOnMaxGenDay] pltDataDf['wrDemand'] = [x['data_value'] for x in wrDemandOnMaxGenDay] pltDataDf['netLoad'] = [ float(x['data_value']) - float(y['val']) for x, y in zip(wrDemandOnMaxGenDay, totalGenOnMaxGenDay) ] pltDataDf.to_excel("assets/plot_1_11_netloadcurve.xlsx") pltTitle = 'Net load Curve when RES (wind and Solar) Generation was max on {0} '.format( max_str_date.strftime('%d-%m-%Y')) fig, ax = plt.subplots(figsize=(7.5, 5.6)) ax.set_title(pltTitle) ax.set_ylabel('MW') ax.set_xlabel('Hour') ax.xaxis.set_major_locator(mdates.DayLocator(interval=1)) # ax.xaxis.set_major_formatter(mdates.DateFormatter('%H')) clr = ['#03a56a', '#a5033e', '#00ffff'] x = pltDataDf['hours'] y = [pltDataDf['reGen'], pltDataDf['netLoad'], pltDataDf['wrDemand']] # ax.stackplot(x, y , labels=['Wind+Solar' ,'Net Load', 'WR Demand'],baseline='sym') ax.fill_between(x, y[0], color='#3f9a3c', alpha=1, label='Wind+Solar', zorder=3) ax.fill_between(x, y[1], color='#b03b3d', alpha=1, label='Net Load', zorder=2) ax.fill_between(x, y[2], color='#5aeaeb', alpha=1, label='WR Demand', zorder=1) ax.yaxis.grid(True) ax.legend(bbox_to_anchor=(0.5, -0.2, 0.0, 0.0), loc='center', ncol=4, borderaxespad=0.) # plt.xticks(rotation=90) ax.set_xlim(xmin=1, xmax=24) fig.subplots_adjust(bottom=0.25, top=0.8) fig.savefig('assets/section_1_11_netLoadCurve.png') # plt.show() # plt.close() secData: dict = {} return secData
def fetchSection1_4_1Context(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> ISection_1_4_1: mRepo = MetricsDataRepo(appDbConnStr) # get WR demand hourly values for this month and prev yr month # Load Shedding(MW) # initialize demand rows dem_data_1_4_1: List[IDemDataRow_1_4_1] = [] constList: List[IConstituentConfig] = getConstituentsMappings() for con in constList: cTag = con["entity_tag"] cName = con["display_name"] cDemVals = mRepo.getEntityMetricHourlyData(cTag, 'Demand(MW)', startDt, endDt) cLsVals = mRepo.getEntityMetricHourlyData(cTag, 'Load Shedding(MW)', startDt, endDt) cDemDf = pd.DataFrame(cDemVals + cLsVals) cDemDf = cDemDf.pivot(index="time_stamp", columns="metric_name", values="data_value") cDemDf["Req"] = cDemDf["Demand(MW)"] + cDemDf["Load Shedding(MW)"] # get max month demand met maxDem = cDemDf["Demand(MW)"].max() maxDemDt = cDemDf["Demand(MW)"].idxmax().to_pydatetime() maxDemDateStr = dt.datetime.strftime(maxDemDt, "%d-%m-%Y") maxDemTimeStr = dt.datetime.strftime(maxDemDt, "%H:%M") freqSamples = mRepo.getRawFreq(maxDemDt, maxDemDt) freqAtMaxDem = 50 if len(freqSamples) > 0: freqAtMaxDem = freqSamples[0]["frequency"] maxReq = cDemDf["Req"].max() maxReqDt = cDemDf["Req"].idxmax() lsAtMaxReq = cDemDf["Load Shedding(MW)"].loc[maxReqDt] maxReqDateStr = dt.datetime.strftime(maxReqDt.to_pydatetime(), "%d-%m-%Y") maxReqTimeStr = dt.datetime.strftime(maxReqDt.to_pydatetime(), "%H:%M") freqSamples = mRepo.getRawFreq(maxDemDt, maxDemDt) freqAtMaxReq = 50 if len(freqSamples) > 0: freqAtMaxReq = freqSamples[0]["frequency"] freqCorrAtMaxReq = 0 # TODO find freq correction at max req demMetAtMaxReq = maxReq - lsAtMaxReq if freqAtMaxReq < 50: freqCorrAtMaxReq = 0.035 * demMetAtMaxReq * (50 - freqAtMaxReq) reqPlusFreqCorrAtMaxReq = maxReq + freqCorrAtMaxReq dem_data_1_4_1.extend([{ 'state_name': cName, 'catered': "", 'ls': "", 'freq_corr': "", 'pc': "", 'tot_dem': "", 'peak_date': "", 'peak_time': "", 'freq_at_peak': "" }, { 'state_name': "Registered", 'catered': round(maxDem), 'ls': "", 'freq_corr': "", 'pc': "", 'tot_dem': round(maxDem), 'peak_date': maxDemDateStr, 'peak_time': maxDemTimeStr, 'freq_at_peak': round(freqAtMaxDem, 3) }, { 'state_name': "Un-Restricted", 'catered': round(demMetAtMaxReq), 'ls': round(lsAtMaxReq, 1), 'freq_corr': round(freqCorrAtMaxReq, 1), 'pc': "0", 'tot_dem': round(reqPlusFreqCorrAtMaxReq), 'peak_date': maxReqDateStr, 'peak_time': maxReqTimeStr, 'freq_at_peak': round(freqAtMaxReq, 3) }]) secData: ISection_1_4_1 = {'dem_data_1_4_1': dem_data_1_4_1} return secData
def fetchSection1_11_Solar_B(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime) -> dict: constituentsInfos = getREConstituentsMappings() mRepo = MetricsDataRepo(appDbConnStr) allEntitySoFarHighest = mRepo.getSoFarHighestAllEntityData( 'soFarHighestSolarGen', startDt) wrSoFarHighest = {} for itr in range(len(allEntitySoFarHighest)): if allEntitySoFarHighest[itr]['constituent'] == 'wr': wrSoFarHighest = allEntitySoFarHighest[itr] soFarHighestDate = wrSoFarHighest['data_time'] hourlyGenerationObj = [] for cIter in range(len(constituentsInfos)): constInfo = constituentsInfos[cIter] if (math.isnan(constInfo['solarCapacity'])): continue hourlyGen = mRepo.getEntityMetricHourlyData(constInfo['entity_tag'], 'Solar(MW)', soFarHighestDate, soFarHighestDate) hourlyGenerationObj.append(hourlyGen) if (len(hourlyGenerationObj) > 0): pltDataObj: list = [] for temp in range(len(hourlyGenerationObj)): pltDataObj = pltDataObj + [{ 'Hours': x["time_stamp"].hour, 'colName': x['entity_tag'], 'val': x["data_value"] } for x in hourlyGenerationObj[temp]] pltDataDf = pd.DataFrame(pltDataObj) pltDataDf = pltDataDf.pivot(index='Hours', columns='colName', values='val') pltDataDf.reset_index(inplace=True) pltDataDf.to_excel("assets/plot_1_11_solar_2.xlsx", index=True) pltTitle = 'Highest Solar Generation on {0} '.format( soFarHighestDate.strftime('%d-%m-%y')) fig, ax = plt.subplots(figsize=(7.5, 4.5)) ax.set_title(pltTitle) ax.set_ylabel('MW') ax.set_xlabel('Hours') ax.xaxis.set_major_locator(mdates.DayLocator(interval=2)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%d')) clr = [ '#00ccff', '#ff8533', '#ff0000', '#9900ff', '#00ff88', '#3388ff' ] for col in range(len(pltDataDf.columns) - 1): ax.plot(pltDataDf['Hours'], pltDataDf[pltDataDf.columns[col + 1]], color=clr[col], label=pltDataDf.columns[col + 1]) ax.yaxis.grid(True) ax.legend(bbox_to_anchor=(0.5, -0.3, 0.0, 0.0), loc='center', ncol=4, borderaxespad=0.) # plt.xticks(rotation=90) ax.set_xlim(xmin=0, xmax=23) fig.subplots_adjust(bottom=0.25, top=0.8) fig.savefig('assets/section_1_11_solar_2.png') # plt.close() secData: dict = { 'data': wrSoFarHighest['data_value'], 'date': dt.datetime.strftime(wrSoFarHighest['data_time'], '%d.%m.%Y'), 'time': dt.datetime.strftime(wrSoFarHighest['data_time'], '%H:%M') } return secData
def fetchSection1_11_WindGenCurveContext(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime): constituentsInfos = getREConstituentsMappings() mRepo = MetricsDataRepo(appDbConnStr) hourlyGenerationObj = [] for cIter in range(len(constituentsInfos)): constInfo = constituentsInfos[cIter] if (pd.isna(constInfo['windCapacity'])): continue hourlyGen = mRepo.getEntityMetricHourlyData(constInfo['entity_tag'], 'Wind(MW)', startDt, endDt) hourlyGenerationObj.append(hourlyGen) if (len(hourlyGenerationObj) > 0): pltDataObj: list = [] for temp in range(len(hourlyGenerationObj)): pltDataObj = pltDataObj + [{ 'Hours': x["time_stamp"], 'colName': x['entity_tag'], 'val': x["data_value"] } for x in hourlyGenerationObj[temp]] pltDataDf = pd.DataFrame(pltDataObj) pltDataDf = pltDataDf.pivot(index='Hours', columns='colName', values='val') pltDataDf.reset_index(inplace=True) pltDataDf.to_excel("assets/plot_1_11_windGenCurve.xlsx", index=True) pltTitle = 'Wind Gen Curve {0} '.format(startDt.strftime('%b-%y')) fig, ax = plt.subplots(figsize=(7.5, 5.6)) ax.set_title(pltTitle) ax.set_ylabel('MW') ax.set_xlabel('Time') ax.xaxis.set_major_locator(mdates.DayLocator(interval=1)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%y %H:%M')) clr = ['#00ccff', '#ff8533', '#ff0000', '#9900ff', '#00ff88'] for col in range(1, len(pltDataDf.columns)): ax.plot(pltDataDf['Hours'], pltDataDf[pltDataDf.columns[col]], color=clr[col - 1], label=pltDataDf.columns[col]) ax.yaxis.grid(True) ax.legend(loc='best', ncol=4, borderaxespad=0.) plt.xticks(rotation=90) ax.set_xlim(xmin=startDt, xmax=endDt) fig.subplots_adjust(bottom=0.25, top=0.8) fig.savefig('assets/section_1_11_windGenCurve.png') # plt.close() secData: dict = {} return secData
def fetchSection1_11_WindSolarCombinedWR(appDbConnStr: str, startDt: dt.datetime, endDt: dt.datetime): mRepo = MetricsDataRepo(appDbConnStr) hourlyGenerationObj = [] hourlyGen = mRepo.getEntityMetricHourlyData('wr', 'Wind(MW)', startDt, endDt) hourlyGenerationObj.append(hourlyGen) hourlyGen = mRepo.getEntityMetricHourlyData('wr', 'Solar(MW)', startDt, endDt) hourlyGenerationObj.append(hourlyGen) if (len(hourlyGenerationObj) > 0): pltDataObj: list = [] for temp in range(len(hourlyGenerationObj)): pltDataObj = pltDataObj + [{ 'Hours': x["time_stamp"], 'colName': 'Total Solar' if x['metric_name'] == 'Solar(MW)' else 'Total Wind', 'val': x["data_value"] } for x in hourlyGenerationObj[temp]] pltDataDf = pd.DataFrame(pltDataObj) pltDataDf = pltDataDf.pivot(index='Hours', columns='colName', values='val') pltDataDf.reset_index(inplace=True) pltDataDf.to_excel("assets/plot_1_11_WindSolarGenCurve.xlsx", index=True) pltTitle = 'Wind Gen. & Solar Gen. curve {0} '.format( startDt.strftime('%b-%y')) fig, ax = plt.subplots(figsize=(7.5, 5.6)) ax.set_title(pltTitle) ax.set_ylabel('MW') ax.set_xlabel('Time') ax.xaxis.set_major_locator(mdates.DayLocator(interval=1)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%y %H:%M')) clr = ['#00ccff', '#ff8533'] for col in range(len(pltDataDf.columns) - 1): ax.plot(pltDataDf['Hours'], pltDataDf[pltDataDf.columns[col + 1]], color=clr[col], label=pltDataDf.columns[col + 1]) ax.yaxis.grid(True) ax.legend(loc='best', ncol=4, borderaxespad=0.) plt.xticks(rotation=90) ax.set_xlim(xmin=startDt, xmax=endDt) fig.subplots_adjust(bottom=0.25, top=0.8) fig.savefig('assets/section_1_11_WindSolarGenCurve.png') # plt.close() secData: dict = {} return secData