# Import the necessary libraries
import numpy as np
import math as math
import csv
with open('gridwatch_2018_overq.csv','r') as f:
readerk = csv.reader(f)
listk = list(readerk)
d1 = listk[2][1]
list2 = [*zip(*listk)]
dates = list2[1]
dates[1]
from datetime import datetime, timedelta
datetime.strptime(d1," %Y-%m-%d %H:%M:%S")
datel = []
secs = []
firstdate = datetime.strptime(dates[1]," %Y-%m-%d %H:%M:%S")
#Reference date, first second of 2018
refdate = datetime(2018,1,1,0,0,0)
for x in dates:
try:
dn = datetime.strptime(x," %Y-%m-%d %H:%M:%S")
except:
print(x)
else:
datel.append(dn)
secs.append((dn-refdate).total_seconds())
import plotly.plotly as py
from plotly.graph_objs import scatter
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
layoutsk = go.Layout(yaxis=dict(automargin=True,title='Power, MW'),xaxis=dict(title='day number of 2018'))
#iplot(go.Figure(data=[{"x":np.array(secs)/86400,"y": list2[2]}],layout=layoutsk))
wind_raw = np.array(list2[7]).astype(float);
solar_raw = np.array(list2[12]).astype(float);
demand_raw = np.array(list2[2]).astype(float);
timestamp = np.array(list2[0]).astype(float)
secsa = np.array(secs)
numsecs_year = (365*86400);
numpers = math.floor(numsecs_year/300);
#Include a week before and after the year as a buffer to allow
#valid 2-week long moving averages.
buffer_pers = math.floor(7*24*3600/300);
numpers = numpers + 2*buffer_pers
secs_ev = (np.linspace(0,numpers,numpers+1)-buffer_pers)*300
#trace1 = go.Scatter(y=secsa/300)
#trace2 = go.Scatter(y=secs_ev/300)
#iplot(go.Figure(data=[trace1,trace2],layout=layoutsk))
wind = np.interp(secs_ev,secsa,wind_raw)
solar = np.interp(secs_ev,secsa,solar_raw)
demand = np.interp(secs_ev,secsa,demand_raw)
dt = 5*60
dayno = np.array(secs_ev)/86400;
firstper_val = math.floor(2*86400/300)
lastper_val = math.floor((365+7+5)*86400/300)
N_hr=math.floor(3600/dt)
wind_sm = np.convolve(wind,np.ones((N_hr,))/N_hr,mode='same')
solar_sm = np.convolve(solar,np.ones((N_hr,))/N_hr,mode='same')
times_hr = dayno[firstper_val:lastper_val:12]
solar_hr = solar_sm[firstper_val:lastper_val:12]
wind_hr = wind_sm[firstper_val:lastper_val:12]
N_day=math.floor(86400/dt)
wind_sm = np.convolve(wind,np.ones((N_day,))/N_day,mode='same')
solar_sm = np.convolve(solar,np.ones((N_day,))/N_day,mode='same')
demand_sm = np.convolve(demand,np.ones((N_day,))/N_day,mode='same')
times_day = dayno[firstper_val:lastper_val:12*24]
solar_day = solar_sm[firstper_val:lastper_val:12*24]
wind_day = wind_sm[firstper_val:lastper_val:12*24]
demand_day = demand_sm[firstper_val:lastper_val:12*24]
firstper_val = math.floor(7*86400/300)
lastper_val = math.floor((365+7)*86400/300)
N_wk=math.floor(7*86400/dt)
wind_sm = np.convolve(wind,np.ones((N_wk,))/N_wk,mode='same')
solar_sm = np.convolve(solar,np.ones((N_wk,))/N_wk,mode='same')
times_wk = dayno[firstper_val:lastper_val:12*24]
solar_wk = solar_sm[firstper_val:lastper_val:12*24]
wind_wk = wind_sm[firstper_val:lastper_val:12*24]
trace1 = go.Scatter(x=times_hr,y=wind_hr,name="wind, hourly")
trace2 = go.Scatter(x=times_hr,y=solar_hr,name="solar, hourly")
iplot(go.Figure(data=[trace1,trace2],layout=layoutsk))
trace1 = go.Scatter(x=times_day,y=wind_day,name="wind, daily")
trace2 = go.Scatter(x=times_day,y=solar_day,name="solar, daily")
iplot(go.Figure(data=[trace1,trace2],layout=layoutsk))
trace1 = go.Scatter(x=times_wk,y=wind_wk,name="wind, 7-day running mean")
trace2 = go.Scatter(x=times_wk,y=solar_wk,name="solar, 7-day running mean")
iplot(go.Figure(data=[trace1,trace2],layout=layoutsk))
solar_norm = solar_day/np.mean(solar_day)
wind_norm = wind_day/np.mean(wind_day)
demand_norm = demand_day/np.mean(demand_day)
trace1 = go.Scatter(x=times_day,y=wind_norm,name="wind, daily")
trace2 = go.Scatter(x=times_day,y=solar_norm,name="solar, daily")
trace3 = go.Scatter(x=times_day,y=0.5*(wind_norm+solar_norm),name="50/50 wind/solar, daily")
trace4 = go.Scatter(x=times_day,y=demand_norm,name="demand, daily")
iplot(go.Figure(data=[trace1,trace2,trace3,trace4],layout=layoutsk))
#Storage calculation: set up on a 'daily' basis here, so it is
#effectively assumed that there is some other short-term storage or
#demand management smoothing out demand and output on the hours-to-day scale.
#Ratio of annual renewable energy output (before curtailment) to annual demand
proportion = 1.0
#Proportion of the renewable output from wind
wind_frac = 0.7
#Proportion of the renewable output from solar
solar_frac = 1 - wind_frac
#Mean demand, daily basis
demand_mean = np.mean(demand_day)
solar_scale = proportion*demand_mean*solar_frac*solar_norm
wind_scale = proportion*demand_mean* wind_frac* wind_norm
renewmix = solar_scale + wind_scale
#Storage: 100% round-trip efficiency assumed.
#Maximum power of storage power stations in MW (for both charge and discharge)
store_maxpow = 13e3
#Number of hours of storage at full power
store_nhours = 10*24
#Amount of storage
store_MWh = store_nhours*store_maxpow
#Timestep in hours
dt = 24
#Offset to first day of 2018: data includes a 'buffer'
#of a week at each end of 2018 to allow moving averages.
firstday = 5
ndays = 365
dayssim = range(firstday,ndays+firstday-1)
store_out = renewmix*0
store_ene = renewmix*0
#Assume storage half full at start of year
store_ene[firstday] = 0.5*store_MWh
for dayno in dayssim:
rem = demand_day[dayno] - renewmix[dayno]
srem= max(min(rem,store_maxpow),-store_maxpow)
store_next = store_ene[dayno] - srem*dt
store_next = max(min(store_next,store_MWh),0)
store_out[dayno] = (store_ene[dayno] - store_next)/dt
if (dayno<ndays+firstday-1):
store_ene[dayno+1] = store_next
trace1 = go.Scatter(x=times_day[dayssim],y=renewmix[dayssim],name="70/30 wind/solar, daily")
trace2 = go.Scatter(x=times_day[dayssim],y=renewmix[dayssim]+store_out[dayssim],name="70/30 wind/solar+storage, daily")
trace3 = go.Scatter(x=times_day[dayssim],y=demand_day[dayssim],name="demand, daily")
trace4 = go.Scatter(x=times_day[dayssim],y=store_out[dayssim],name="storage output, daily")
#trace1 = go.Scatter(x=times_day,y=renewmix,name="70/30 wind/solar, daily")
iplot(go.Figure(data=[trace1,trace2,trace3,trace4],layout=layoutsk))
layoutene = go.Layout(yaxis=dict(automargin=True,title='Energy, MWh'),xaxis=dict(title='day number of 2018'))
trace4 = go.Scatter(x=times_day[dayssim],y=store_ene[dayssim],name="storage energy, daily")
iplot(go.Figure(data=[trace4],layout=layoutene))
#Proportion of total energy (daily basis) met by renewables+storage
np.mean(np.minimum(renewmix[dayssim],demand_day[dayssim]))/np.mean(demand_day[dayssim])
#Proportion of total energy (daily basis) met by renewables+storage
np.mean(np.minimum(renewmix[dayssim]+store_out[dayssim],demand_day[dayssim]))/np.mean(demand_day[dayssim])