# Full descriptions of these models can be found in the docstrings for each module. #TOU_pricing.py contains functions that determine the season, period (peak, off-peak, intermediate), #and cost of electricity for each hour of a timestampd dataframe containing hourly residential #electricity consumption. import TOU_pricing #storage_logic.py contains functions that implement a control algorithm for the purchase of electricity #based on available storage and period of the day (peak, off-peak). import storage_logic #calculations.py contains functions which return key metrics for analyzing the model output. import calculations import pandas as pd import numpy as np import time # Reload modules during development reload(TOU_pricing) reload(storage_logic) reload(calculations) def inverter_efficiency(direction): if direction == 'charging': eff = .85 elif direction == 'discharging': eff = .85 return eff def battery_efficiency(direction): if direction == 'charging': eff = .85 elif direction == 'discharging': eff = .85 return eff battery_sizes = [1., 2., 5., 7.5, 10., 15., 20., 25., 30.] max_dod = .2 R_output = TOU_pricing.main('R',False) R_annual_cost = np.sum(R_output['USAGE'] * R_output['cost']) print R_annual_cost save_results = False t0 = time.time() for i, bat_size in enumerate(battery_sizes): system_param = { 'Inverter Cost' : 1500., # ballpark 'Storage Cost' : 200. / 1.2, # cost per kilowatt-hour based on link above 'Storage Size' : bat_size, # storage size in kilowatt-hours 'Max Charge Rate' : bat_size / 8., 'Max DOD' : max_dod, # DOD 'Bat Depleted' : max_dod * bat_size, 'Inverter Efficiency' : inverter_efficiency, 'Battery Efficiency' : battery_efficiency, } results = storage_logic.main(TOU_pricing.main('EV', False), system_param) filename = 'results/storage_size/output_%s_kWh.csv'%bat_size if save_results == True: results.to_csv(filename) metrics = calculations.calc_metrics(results, system_param) if i == 0: all_metrics = pd.DataFrame(index=battery_sizes, columns=metrics.keys()) all_metrics['Total kWh Purchased'][bat_size] = metrics['Total kWh Purchased'] all_metrics['% Purchased During Peak'][bat_size] = metrics['% Purchased During Peak'] all_metrics['% Purchased During Off-Peak'][bat_size] = metrics['% Purchased During Off-Peak'] all_metrics['Hours on Battery Only'][bat_size] = metrics['Hours on Battery Only'] all_metrics['% Peak Demand Battery'][bat_size] = metrics['% Peak Demand Battery'] all_metrics['Hours Battery Full'][bat_size] = metrics['Hours Battery Full'] all_metrics['Hours Battery Depleted'][bat_size] = metrics['Hours Battery Depleted'] all_metrics['Annual System Eff'][bat_size] = metrics['Annual System Eff'] all_metrics['Annual Var Cost'][bat_size] = metrics['Annual Var Cost'] all_metrics['Initial Cost'][bat_size] = metrics['Initial Cost'] all_metrics['Peak kWh Shaved'][bat_size] = metrics['Peak kWh Shaved'] all_metrics['% Peak kWh Shaved'][bat_size] = metrics['% Peak kWh Shaved'] all_metrics['PBP'][bat_size] = metrics['PBP'] all_metrics['Annual Savings'][bat_size] = metrics['Annual Savings'] all_metrics['% Annual Cost Savings'][bat_size] = metrics['% Annual Cost Savings'] if save_results == True: all_metrics.to_csv('results/storage_size/all_metrics_storage_size.csv') t1 = time.time() print 'Time for model run:',round(t1-t0,1),'s' # We now have a Pandas DataFrame containing metrics that describe the system performance # indexed by battery size. all_metrics.head() save_fig = True a = 6. fig = plt.figure(figsize=[1.3*a,a]) ax = subplot(111) # turn off square border around plot ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.spines["right"].set_visible(False) ax.spines["left"].set_visible(False) # ensure only ticks on bottom and left, not top and right (unnecessary) #ax.get_xaxis().tick_bottom() #ax.get_yaxis().tick_left() all_metrics['PBP'].plot(grid='off',color='#FF3300',linewidth=2,marker='.',markersize=14) title('Payback Period in Years',fontsize=16) xlabel('Storage Size (kWh)',fontsize=14) xticks(fontsize=14) yticks(fontsize=14) # turn off tick marks plt.tick_params(axis="both", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="on") ylabel('Years',fontsize=14) if save_fig == True: fig.savefig('results/storage_size/PBP.png',bbox_inches='tight') save_fig = True a = 6. fig = plt.figure(figsize=[1.3*a,a]) ax1 = plt.subplot(111) # Ticks ticks_left = np.array(range(10,30,2))/100. ticks_right_ymin = min(ticks_left) * R_annual_cost ticks_right_ymax = max(ticks_left) * R_annual_cost ticks_right = np.array(range(80,200,20)) # turn off square border around plot ax1.spines["top"].set_visible(False) ax1.spines["bottom"].set_visible(False) ax1.spines["right"].set_visible(False) ax1.spines["left"].set_visible(False) title('Annual Electricity Bill Cost Savings',fontsize=16) xlabel('Storage Size (kWh)',fontsize=14) xticks(fontsize=14) ax1.plot(all_metrics.index, all_metrics['% Annual Cost Savings'],color='#FF3300',linewidth=2,marker='.',markersize=14) ax1.set_ylabel('% Annual Savings', fontsize=14) ax2 = ax1.twinx() ax2.set_ylim(min(all_metrics['Annual Savings']), max(all_metrics['Annual Savings'])) ax2.set_yticklabels(ticks_right, fontsize=14) ax2.set_ylabel('Annual Savings (USD)', fontsize=14) # turn off ticks ax1.tick_params(axis="both", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="on",labelsize=14) ax2.tick_params(axis="y", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="off",labelsize=14) if save_fig == True: fig.savefig('results/storage_size/cost_savings.png',bbox_inches='tight') save_fig = True a = 6. fig = plt.figure(figsize=[1.3*a,a]) ax1 = plt.subplot(111) # Ticks ticks_right = np.array(range(0,2000,200)) # turn off square border around plot ax1.spines["top"].set_visible(False) ax1.spines["bottom"].set_visible(False) ax1.spines["right"].set_visible(False) ax1.spines["left"].set_visible(False) title('Demand Shaved From Peak Hours',fontsize=16) xlabel('Storage Size (kWh)',fontsize=14) xticks(fontsize=14) ax1.plot(all_metrics.index, all_metrics['% Peak kWh Shaved'],color='#FF3300',linewidth=2,marker='.',markersize=14) ax1.set_ylabel('% Peak Demand Shaved', fontsize=14) ax1.set_ylim(0,1.1) ax2 = ax1.twinx() ax2.set_yticks(ticks_right) ax2.set_yticklabels(ticks_right, fontsize=14) ax2.set_ylim(0,1.1*max(all_metrics['Peak kWh Shaved'])) ax2.set_ylabel('Peak Demand Shaved (kWh)', fontsize=14) # turn off ticks ax1.tick_params(axis="both", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="on",labelsize=14) ax2.tick_params(axis="y", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="off",labelsize=14) if save_fig == True: fig.savefig('results/storage_size/peak_shaved_stor_cap.png',bbox_inches='tight') save_fig = True a = 6. fig = plt.figure(figsize=[1.3*a,a]) ax1 = plt.subplot(111) # Ticks ticks_right = np.array(range(0,2000,200)) # turn off square border around plot ax1.spines["top"].set_visible(False) ax1.spines["bottom"].set_visible(False) ax1.spines["right"].set_visible(False) ax1.spines["left"].set_visible(False) title('Annual System Efficiency',fontsize=16) xlabel('Storage Size (kWh)',fontsize=14) xticks(fontsize=14) ax1.plot(all_metrics.index, all_metrics['Total kWh Purchased'],color='#FF3300',linewidth=2,marker='.',markersize=14) ax1.set_ylabel('Total kWh Purchased', fontsize=14, color='#FF3300') #ax1.set_ylim(0,1.1) ax2 = ax1.twinx() ax2.plot(all_metrics.index, all_metrics['Annual System Eff'],color='#00CCFF',linewidth=2,marker='.',markersize=14) #ax2.set_yticks([0,.25,.5,1]) #ax2.set_yticklabels(, fontsize=14) ax2.set_ylim(0,1) ax2.set_ylabel('System Efficiency', fontsize=14, color='#00CCFF') # turn off ticks ax1.tick_params(axis="both", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="on",labelsize=14) ax2.tick_params(axis="y", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="off",labelsize=14) if save_fig == True: fig.savefig('results/storage_size/sys_eff_stor_cap.png',bbox_inches='tight')