# -*- coding: utf-8 -*- """ Created on Wed Nov 6 07:40:01 2019 Simulate battery operation using 3 years of trading data (volumes and prices) And linear programme for optimising operation. @author: theot """ import numpy as np import pandas as pd import os # Working directory os.chdir("XXX") # Import optimisation function from ChargeDischargeUncertainty import BatteryCycleUncertain # Input data directory input_dir = "XXXX" # Get Data data_all=pd.read_csv(input_dir+"PriceAndVolume_2010_to_2019_RCPD_N_100.csv") # Data slice data=data_all[(data_all['p_yr']>2016)].copy() # Convert dates to datetimes data['TP']=pd.to_datetime(data['TP'],format='%Y-%m-%d %H:%M:%S') data['date']=pd.to_datetime(data['date'],format='%Y-%m-%d') # Dates in data dates=np.array(data.date.dt.strftime('%Y-%m-%d').unique()) # Add values for expected prices - with uncertainty about demand df_minRCPD=data[(data.rcpd==1)].groupby(['pz','pz.name','p_yr']).X.min().reset_index() df_minRCPD['RCPDerr']=df_minRCPD.X*0.98 data=pd.merge(data,df_minRCPD[['pz','p_yr','RCPDerr']],on=['pz','p_yr'],how='left') data['E.Pt']=np.where(data.X>data.RCPDerr,(data['IC.rate']*1000)/data.rcpd_n,0) data['E.P']=data['P.e']+data['E.Pt']*2 #NB: Adjustment to transmission charge unit cost because energy prices are in $/MWh while transmission charges are $/MWhh # Given the year and region, loop over dates in dates and concatenate results capacities = np.array([1,2,5,10,20,50,100,200,300,400,500]) #List to collect results daily_cycles=[] for m, mw_val in enumerate(capacities): for d, day in enumerate(dates): if d==0: newS0_uni=0 newS0_lni=0 newS0_usi=0 newS0_lsi=0 else: newS0_uni=day_cyc_uni["Stored"].iloc[-1] newS0_lni=day_cyc_lni["Stored"].iloc[-1] newS0_usi=day_cyc_usi["Stored"].iloc[-1] newS0_lsi=day_cyc_lsi["Stored"].iloc[-1] #UNI day_data_uni = data[(data.date==day)&(data["pz.name"]=="UNI")].copy() minRCPD_uni=df_minRCPD[(df_minRCPD.p_yr==day_data_uni["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="UNI")].RCPDerr.min() minRCPDActual_uni=df_minRCPD[(df_minRCPD.p_yr==day_data_uni["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="UNI")].X.min() day_cyc_uni = BatteryCycleUncertain(df=day_data_uni,MW=mw_val,S0=newS0_uni,DC=True,minPk=minRCPD_uni,minActual=minRCPDActual_uni) day_cyc_uni['X1']=day_cyc_uni['X']-day_cyc_uni['Q'] # Grid demand with battery charging and discharging day_cyc_uni['PeakCharge']="Yes" day_cyc_uni['PZ']="UNI" day_cyc_uni['Capacity']=mw_val # Battery capacity daily_cycles.append(day_cyc_uni) #LNI day_data_lni = data[(data.date==day)&(data["pz.name"]=="LNI")].copy() minRCPD_lni=df_minRCPD[(df_minRCPD.p_yr==day_data_lni["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="LNI")].RCPDerr.min() minRCPDActual_lni=df_minRCPD[(df_minRCPD.p_yr==day_data_lni["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="LNI")].X.min() day_cyc_lni = BatteryCycleUncertain(df=day_data_lni,MW=mw_val,S0=newS0_lni,DC=True,minPk=minRCPD_lni,minActual=minRCPDActual_lni) day_cyc_lni['X1']=day_cyc_lni['X']-day_cyc_lni['Q'] # Grid demand with battery charging and discharging day_cyc_lni['PeakCharge']="Yes" day_cyc_lni['PZ']="LNI" day_cyc_lni['Capacity']=mw_val # Battery capacity daily_cycles.append(day_cyc_lni) #USI day_data_usi = data[(data.date==day)&(data["pz.name"]=="USI")].copy() minRCPD_usi=df_minRCPD[(df_minRCPD.p_yr==day_data_usi["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="USI")].RCPDerr.min() minRCPDActual_usi=df_minRCPD[(df_minRCPD.p_yr==day_data_usi["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="USI")].X.min() day_cyc_usi = BatteryCycleUncertain(df=day_data_usi,MW=mw_val,S0=newS0_usi,DC=True,minPk=minRCPD_usi,minActual=minRCPDActual_usi) day_cyc_usi['X1']=day_cyc_usi['X']-day_cyc_usi['Q'] # Grid demand with battery charging and discharging day_cyc_usi['PeakCharge']="Yes" day_cyc_usi['PZ']="USI" day_cyc_usi['Capacity']=mw_val # Battery capacity daily_cycles.append(day_cyc_usi) #LSI day_data_lsi = data[(data.date==day)&(data["pz.name"]=="LSI")].copy() minRCPD_lsi=df_minRCPD[(df_minRCPD.p_yr==day_data_lsi["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="LSI")].RCPDerr.min() minRCPDActual_lsi=df_minRCPD[(df_minRCPD.p_yr==day_data_lsi["p_yr"].iloc[0])&(df_minRCPD['pz.name']=="LSI")].X.min() day_cyc_lsi = BatteryCycleUncertain(df=day_data_lsi,MW=mw_val,S0=newS0_lsi,DC=True,minPk=minRCPD_lsi,minActual=minRCPDActual_uni) day_cyc_lsi['X1']=day_cyc_lsi['X']-day_cyc_lsi['Q'] # Grid demand with battery charging and discharging day_cyc_lsi['PeakCharge']="Yes" day_cyc_lsi['PZ']="LSI" day_cyc_lsi['Capacity']=mw_val # Battery capacity daily_cycles.append(day_cyc_lsi) print((m+(d/(len(dates))))/len(capacities)) daily_cycles = pd.concat(daily_cycles) daily_cycles.to_csv("daily_cycles_variable_MW_uncertain.csv")