Commit da03e69d authored by kdas's avatar kdas
Browse files

Added code for EMS

parent 6447eee5
Pipeline #20070 failed with stages
in 56 seconds
This diff is collapsed.
# -*- coding: utf-8 -*-
"""
Created on Sun Nov 10 12:05:52 2019
@author: kdas
"""
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
from HyDesign.sizing import HPP, read_csv_Data, issue_time, calc_DM_BAL, import_html_data, indexing, resample_smaller
import time
if __name__ == "__main__":
# =============================================================================
# # Alessandra's data
# =============================================================================
input_wind_ts_filename = './Data/power_groups.csv'
input_solar_ts_filename = './Data/aveS.csv'
input_price_ts_filename = './Data/spot_2014_2016.csv'
input_wind_power_forecast_ts_filename = './Data/DA_wind-power-grouped.csv'
input_price_forecast_ts_filename = './Data/spot_forecast_diff30h2_days.csv'
start_date = pd.to_datetime('2016-01-01 00:00')
end_date = pd.to_datetime("2016-12-31 23:59")
timeFormat_wind = "%d/%m/%Y %H:%M:%S"
timeFormat_solar = "%d/%m/%Y %H:%M"
timeFormat_price = '%Y-%m-%d %H:%M:%S'
timename = 'Time'
timeZone_wind = 'UTC'
timeZone_solar = 'Asia/Kolkata'
timeZone_price = 'UTC' #'Etc/GMT+1'
timeZone_analysis = 'UTC'
timeZone_price_forecast = 'UTC'
market_data=import_html_data(
['https://www.nordpoolgroup.com/globalassets/marketdata-excel-files/elspot-prices_'+str(year)+'_hourly_eur.xls'
for year in range(2014,2020)])
regu_data=import_html_data(
['https://www.nordpoolgroup.com/globalassets/marketdata-excel-files/regulating-prices_'+str(year)+'_hourly_eur.xls'
for year in range(2014,2020)])
#remove the first line (up and down) the header DK2 is up and DK2.1 is down
for year in range(5):
regu_data[year]=regu_data[year].iloc[1:]
#%%
hpp_grid_connection = 51
# Battery parameters
Pbmax = 34 #MW
SOCmax= 245 #MWh
SOCmin= 0 #MWh
etacha_h=0.95 #MW/MW/hour
etacha_m=0.95 #MW/MW/minute
etadis_h=0.95 #MW/MW/hour
etadis_m=0.95 #MW/MW/minute
etaleak_h=0 #MW/MWh/hour
etaleak_m=1-(1-etaleak_h)**(1/60) #MW/MWh/minute
# Hypp parameters
Pmax=51.0 #MW
Pwind=51.0 #MW
#temporary parameters
SOC_start=0.5*SOCmax #MWh
SOCgoal=0
C=0
acti=False
#%%
# inputs
# Alessandra's data
parameter_dict = {
# hpp parameters
'hpp_grid_connection': 300, # in MW
'hpp_land_area_available': 100, # in square km
'hpp_lifetime': 25, # [years]
'hpp_discount_factor': 0.07,
'hpp_BOS_soft_cost': 119940, # [Eur/MW]
'hpp_grid_connection_cost': 37074, # [Eur/MW]
# hpp wind parameters
'wind_rating_WT': 2.1,
'wind_nWT_per_string': 20,
'wind_lifetime_WT': 30,
'wind_rotor_diameter': 97, # in m
'wind_hub_height': 120, # in m
'wind_turbine_spacing': 5, # in terms of Rotor Diameter
'wind_turbine_row_spacing': 10, # in terms of Rotor Diameter
'wind_turbine_cost': 851000, # [EUR/MW]
'wind_civil_works_cost': 116986, # [Eur/MW]
'wind_fixed_onm_cost': 12805, # Wind fixed O&M cost per year [Eur/MW]
# hpp solar parameters
'solar_lifetime_PV': 30,
'solar_PV_cost': 219000, # [EUR/MW]
'solar_hardware_installation_cost': 241854, # [Eur/MW]
'solar_fixed_onm_cost': 8149, # Solar O&M cost per year [Eur/MW]
# hpp battery parameters
'battery_energy_cost': 181596, # Eur/MWh
'battery_power_cost': 64190, # Power conversion system cost[Eur/MW]
# Electric Balance of Plant, installation, commissioning cost [Eur/MW]
'battery_BOP_installation_commissioning_cost': 73360,
# Grid management control system cost[Eur/MW]
'battery_control_system_cost': 18340,
# Battery energy capacity maintenance cost [Eur/MWh] per year
'battery_energy_onm_cost': 10000,
'battery_depth_of_discharge': 0.9,
}
simulation_dict = {
'wind_as_component': 1,
'solar_as_component': 0,
'battery_as_component': 1,
}
ExampleHPP = HPP(
parameter_dict=parameter_dict,
simulation_dict=simulation_dict,
)
wind_power_t = read_csv_Data(
input_wind_ts_filename,
timename,
timeFormat_wind,
timeZone_wind,
timeZone_analysis,
)
wind_power_forecast_t = read_csv_Data(
input_wind_power_forecast_ts_filename,
timename,
timeFormat_wind,
timeZone_wind,
timeZone_analysis,
)#ExampleHPP.load_Exogenous_Data_Wind_Power_Forecast()
solar_power_t = read_csv_Data(
input_solar_ts_filename,
timename,
timeFormat_solar,
timeZone_solar,
timeZone_analysis,
)
spot_price_t = read_csv_Data(
input_price_ts_filename,
timename,
timeFormat_price,
timeZone_price,
timeZone_analysis,
)
spot_price_forecast_t = read_csv_Data(
input_price_forecast_ts_filename,
timename,
timeFormat_price,
timeZone_price_forecast,
timeZone_analysis,
)
#%%
wind_power_t = wind_power_t.loc[start_date:end_date,'DKe_wind']
wind_power_forecast_t = wind_power_forecast_t.loc[start_date:end_date,'DKe_wind']
#solar_power_t = solar_power_t.loc[start_date:end_date, 'Psolar'] / 100
spot_price_t = spot_price_t.loc[start_date:end_date]
spot_price_forecast_t=spot_price_forecast_t.loc[start_date:end_date,'DK2']
capacity_factor_wind = ExampleHPP.calculate_Capacity_Factor(
wind_power_t, 1)
# capacity_factor_solar = ExampleHPP.calculate_Capacity_Factor(
# solar_power_t, 1)
# %% -----------------------------------------------
Wind_MW=51
wind_power_t_MW = wind_power_t*Wind_MW
#Hourly data
wind_power_t_MW_hourly_resolution = wind_power_t_MW.resample("H").mean()
wind_power_forecast_t_MW=wind_power_forecast_t*Wind_MW
#%%
#power as a perfect forecast submitted every 11 o'clock
wind_power_t_MW_hourly_resolution_adjusted = issue_time(pd.DataFrame(wind_power_t_MW_hourly_resolution),11)
#forecast as submitted every 11 o'clock
wind_power_forecast_t_MW_hourly_resolution_adjusted = issue_time(pd.DataFrame(wind_power_forecast_t_MW),11)
#%%define the output frame
out=pd.DataFrame(index=['Pbid','Pgrid','SOC'])
#%%oracle best case
name='Oracle'
t0 = time.time()
out[name]=ExampleHPP.EMS(
wind_power_t_MW_hourly_resolution_adjusted,
pd.DataFrame(spot_price_t),
wind_power_t_MW,
[2,1],
SOC_start,
Pmax,
SOCmin,
SOCmax,
C,
acti,
Pbmax,
etaleak_h,
etacha_h,
etadis_h
)
t1 = time.time()
computation_time = t1-t0
print(computation_time)
#%%oracle onlyopti
name='Oracle_onlyOpti'
t0 = time.time()
out[name]=ExampleHPP.EMS(
wind_power_t_MW_hourly_resolution_adjusted,
pd.DataFrame(spot_price_t),
wind_power_t_MW,
[2,3],
SOC_start,
Pmax,
SOCmin,
SOCmax,
C,
acti,
Pbmax,
etaleak_h,
etacha_h,
etadis_h
)
t1 = time.time()
computation_time = t1-t0
print(computation_time)
#%%Oracle_woOpti
name='Oracle_woOpti'
out[name]=ExampleHPP.EMS(
wind_power_t_MW_hourly_resolution_adjusted,
pd.DataFrame(spot_price_t),
wind_power_t_MW,
[1,2],
SOC_start,
Pmax,
SOCmin,
SOCmax,
C,
acti,
Pbmax,
etaleak_h,
etacha_h,
etadis_h
)
#%%LSTM
name='LSTM'
t0 = time.time()
out[name]=ExampleHPP.EMS(
wind_power_forecast_t_MW_hourly_resolution_adjusted,
pd.DataFrame(spot_price_forecast_t),
wind_power_t_MW,
[2,1],
SOC_start,
Pmax,
SOCmin,
SOCmax,
C,
acti,
Pbmax,
etaleak_h,
etacha_h,
etadis_h
)
t1 = time.time()
computation_time = t1-t0
print(computation_time)
#%%LSTM_onlyOpti
name='LSTM_onlyOpti'
out[name]=ExampleHPP.EMS(
wind_power_forecast_t_MW_hourly_resolution_adjusted,
pd.DataFrame(spot_price_forecast_t),
wind_power_t_MW,
[2,3],
SOC_start,
Pmax,
SOCmin,
SOCmax,
C,
acti,
Pbmax,
etaleak_h,
etacha_h,
etadis_h
)
#%%
name='Oracle_woBatt'
out[name]=(wind_power_t_MW_hourly_resolution,wind_power_t_MW,None)
#%%
# name='LSTM_onlyOptishittyfor'
# out[name]=single_batt.main_opti(Pfor2,Df2,Pres,[2,3],SOC_start)
# name='monthly_ave'
# out[name]=single_batt.main_opti(Pfor2,Df2,Pres,[2,2],SOC_start)
# name='yearly_ave'
# out[name]=single_batt.main_opti(Pfor2,Df3,Pres,[2,2],SOC_start)
# print('\a')
#%%LSTM_woOPti
name='LSTM_woOPti'
out[name]=ExampleHPP.EMS(
wind_power_forecast_t_MW_hourly_resolution_adjusted,
pd.DataFrame(spot_price_forecast_t),
wind_power_t_MW,
[1,2],
SOC_start,
Pmax,
SOCmin,
SOCmax,
C,
acti,
Pbmax,
etaleak_h,
etacha_h,
etadis_h
)
#%%forecast_woBatt
name='forecast_woBatt'
out[name]=(wind_power_forecast_t_MW,wind_power_t_MW,None)
#%store out
# print('\a')
#%%
subsets=['DK2']
subsetsregu=['DK2','DK2.1']
market_data_big=indexing(market_data,subsets)
marketzone="DK2"
market_data_reduced = market_data_big.loc[start_date:end_date,marketzone]
regu_data_big=indexing(regu_data,subsetsregu)
regu_data_big_up,regu_data_big_down=regu_data_big[[subsetsregu[0]]],regu_data_big[[subsetsregu[1]]]
regu_data_big_down.columns=['DK2DOWN']
regu_data_big_up.columns=['DK2UP']
Rp=regu_data_big_up.loc[start_date:end_date,marketzone+"UP"]
Rm=regu_data_big_down.loc[start_date:end_date,marketzone+"DOWN"]
revenues=pd.DataFrame(index=['ContractedEnergy','surplus','shortage','DownCost','UpCost','RevenueTOT','RevenueSPOT','RevenueBAL','AverageDownCost','AverageUpCost'])
for name in out.columns:
revenues[name]=calc_DM_BAL(out[name].Pbid,out[name].Pgrid,market_data_reduced,Rp,Rm)
#%%
''' Plots for the report'''
normaliser=revenues.loc['RevenueTOT','Oracle_woBatt']
normaliser1=revenues.loc['RevenueTOT','forecast_woBatt']
revenueoracle=revenues.loc[['RevenueTOT'],['Oracle_woBatt','Oracle_woOpti','Oracle']]/normaliser1*100-100
revenueoracle.columns=['Without Battery','Only Balancing','Optimisation']
revenueLSTM=revenues.loc[['RevenueTOT'],['forecast_woBatt','LSTM_woOPti','LSTM']]/normaliser1*100-100
#revenueLSTM.columns=['Without Battery','Only balancing','Optimisation and balancing']
revenueLSTM.columns=['Without Battery','Only Balancing','Optimisation']
revenuetot=revenueoracle.append(revenueLSTM)
revenuetot.index=['Perfect Forecast','LSTM Forecast']
ax=(revenuetot.transpose()).plot(kind='bar',rot=1)
ax.grid(True,axis='y')
ax.set_ylabel('Added Revenue in %')
ax.set_ylim([0, 25])
rects = ax.patches
labels = [None]*6
# Make some labels.
k=0
for j in range(2):
for i in range(3):
if revenuetot.values[j,i] == 0.0:
labels[k] = ''
else:
labels[k] = str(round(revenuetot.values[j,i],1))
k=k+1
#labels = ["label%d" % i for i in range(len(rects))]
for rect, label in zip(rects, labels):
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width() / 2, height + 0.5, label, ha='center', va='bottom')
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment