urbanopt-reopt 0.10.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@ module URBANopt # :nodoc:
14
14
  module REopt # :nodoc:
15
15
  class FeatureReportAdapter
16
16
  ##
17
- # FeatureReportAdapter can convert a URBANopt::Reporting::DefaultReports::FeatureReport into a \REopt Lite posts or update a URBANopt::Reporting::DefaultReports::FeatureReport from a \REopt Lite response.
17
+ # FeatureReportAdapter can convert a URBANopt::Reporting::DefaultReports::FeatureReport into a \REopt posts or update a URBANopt::Reporting::DefaultReports::FeatureReport from a \REopt response.
18
18
  ##
19
19
  # [*parameters:*]
20
20
  ##
@@ -24,23 +24,32 @@ module URBANopt # :nodoc:
24
24
  end
25
25
 
26
26
  ##
27
- # Convert a FeatureReport into a \REopt Lite post
27
+ # Convert a FeatureReport into a \REopt post
28
28
  #
29
29
  # [*parameters:*]
30
30
  #
31
- # * +feature_report+ - _URBANopt::Reporting::DefaultReports::FeatureReport_ - FeatureReport to use in converting the optional +reopt_assumptions_hash+ to a \REopt Lite post. If a +reopt_assumptions_hash+ is not provided, a default post will be updated from this FeatureReport and submitted to the \REopt Lite API.
32
- # * +reopt_assumptions_hash+ - _Hash_ - Optional. A hash formatted for submittal to the \REopt Lite API containing default values. Values will be overwritten from the FeatureReport where available (i.e. latitude, roof_squarefeet). Missing optional parameters will be filled in with default values by the API.
31
+ # * +feature_report+ - _URBANopt::Reporting::DefaultReports::FeatureReport_ - FeatureReport to use in converting the optional +reopt_assumptions_hash+ to a \REopt post. If a +reopt_assumptions_hash+ is not provided, a default post will be updated from this FeatureReport and submitted to the \REopt API.
32
+ # * +reopt_assumptions_hash+ - _Hash_ - Optional. A hash formatted for submittal to the \REopt API containing default values. Values will be overwritten from the FeatureReport where available (i.e. latitude, roof_squarefeet). Missing optional parameters will be filled in with default values by the API.
33
33
  #
34
- # [*return:*] _Hash_ - Returns hash formatted for submittal to the \REopt Lite API
34
+ # [*return:*] _Hash_ - Returns hash formatted for submittal to the \REopt API
35
35
  ##
36
36
  def reopt_json_from_feature_report(feature_report, reopt_assumptions_hash = nil, groundmount_photovoltaic = nil)
37
37
  name = feature_report.name.delete ' '
38
38
  description = "feature_report_#{name}_#{feature_report.id}"
39
- reopt_inputs = { Scenario: { Site: { ElectricTariff: { blended_monthly_demand_charges_us_dollars_per_kw: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], blended_monthly_rates_us_dollars_per_kwh: [0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13] }, LoadProfile: {}, Wind: { max_kw: 0 } } } }
40
39
  if !reopt_assumptions_hash.nil?
41
40
  reopt_inputs = reopt_assumptions_hash
42
41
  else
43
- @@logger.info('Using default REopt Lite assumptions')
42
+ @@logger.info('Using default REopt assumptions')
43
+ reopt_inputs = {
44
+ Settings:{},
45
+ Site: {},
46
+ Financial:{},
47
+ ElectricTariff: {
48
+ monthly_demand_rates: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
49
+ monthly_energy_rates: [0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
50
+ },
51
+ ElectricLoad: {}
52
+ }
44
53
  end
45
54
 
46
55
  # Check FeatureReport has required data
@@ -57,33 +66,33 @@ module URBANopt # :nodoc:
57
66
  end
58
67
  end
59
68
 
60
- reopt_inputs[:Scenario][:description] = description
69
+ reopt_inputs[:description] = description
61
70
 
62
71
  # Parse Location
63
- reopt_inputs[:Scenario][:Site][:latitude] = feature_report.location.latitude_deg
64
- reopt_inputs[:Scenario][:Site][:longitude] = feature_report.location.longitude_deg
72
+ reopt_inputs[:Site][:latitude] = feature_report.location.latitude_deg
73
+ reopt_inputs[:Site][:longitude] = feature_report.location.longitude_deg
65
74
 
66
75
  # Parse Optional FeatureReport metrics - do not overwrite from assumptions file
67
- if reopt_inputs[:Scenario][:Site][:roof_squarefeet].nil? && !feature_report.program.roof_area_sqft.nil?
68
- reopt_inputs[:Scenario][:Site][:roof_squarefeet] = feature_report.program.roof_area_sqft[:available_roof_area_sqft]
76
+ if reopt_inputs[:Site][:roof_squarefeet].nil? && !feature_report.program.roof_area_sqft.nil?
77
+ reopt_inputs[:Site][:roof_squarefeet] = feature_report.program.roof_area_sqft[:available_roof_area_sqft]
69
78
  end
70
79
 
71
- if reopt_inputs[:Scenario][:Site][:land_acres].nil?
80
+ if reopt_inputs[:Site][:land_acres].nil?
72
81
  # Check if ground-mount PV is specified with the Feature ID and take footprint area of PV
73
82
  # constrain for REopt optimization
74
83
  begin
75
84
  if !groundmount_photovoltaic[feature_report.id].nil?
76
- reopt_inputs[:Scenario][:Site][:land_acres] = groundmount_photovoltaic[feature_report.id] * 1.0 / 43560 # acres/sqft
85
+ reopt_inputs[:Site][:land_acres] = groundmount_photovoltaic[feature_report.id] * 1.0 / 43560 # acres/sqft
77
86
  # If no ground-mount PV associated with feature use site area as constrain for REopt optimization
78
87
  elsif !feature_report.program.site_area_sqft.nil?
79
- reopt_inputs[:Scenario][:Site][:land_acres] = feature_report.program.site_area_sqft * 1.0 / 43560 # acres/sqft
88
+ reopt_inputs[:Site][:land_acres] = feature_report.program.site_area_sqft * 1.0 / 43560 # acres/sqft
80
89
  end
81
90
  rescue StandardError
82
91
  end
83
92
  end
84
93
 
85
- if reopt_inputs[:Scenario][:time_steps_per_hour].nil?
86
- reopt_inputs[:Scenario][:time_steps_per_hour] = 1
94
+ if reopt_inputs[:Settings][:time_steps_per_hour].nil?
95
+ reopt_inputs[:Settings][:time_steps_per_hour] = 1
87
96
  end
88
97
 
89
98
  # Parse Load Profile
@@ -104,7 +113,7 @@ module URBANopt # :nodoc:
104
113
  end
105
114
  # Clip to one non-leap year's worth of data
106
115
  energy_timeseries_kw = energy_timeseries_kw.map { |e| e || 0 }[0, (feature_report.timesteps_per_hour * 8760)]
107
- # Convert from the OpenDSS resolution to the REopt Lite resolution, if necessary
116
+ # Convert from the OpenDSS resolution to the REopt resolution, if necessary
108
117
  rescue StandardError
109
118
  @@logger.error("Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}")
110
119
  raise "Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}"
@@ -112,65 +121,68 @@ module URBANopt # :nodoc:
112
121
 
113
122
  # Convert load to REopt Resolution
114
123
  begin
115
- reopt_inputs[:Scenario][:Site][:LoadProfile][:loads_kw] = convert_powerflow_resolution(energy_timeseries_kw, feature_report.timesteps_per_hour, reopt_inputs[:Scenario][:time_steps_per_hour])
124
+ reopt_inputs[:ElectricLoad][:loads_kw] = convert_powerflow_resolution(energy_timeseries_kw, feature_report.timesteps_per_hour, reopt_inputs[:Settings][:time_steps_per_hour])
116
125
  rescue StandardError
117
- @@logger.error("Could not convert the annual electric load from a resolution of #{feature_report.timesteps_per_hour} to #{reopt_inputs[:Scenario][:time_steps_per_hour]}")
118
- raise "Could not convert the annual electric load from a resolution of #{feature_report.timesteps_per_hour} to #{reopt_inputs[:Scenario][:time_steps_per_hour]}"
119
- end
120
-
121
- if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps].nil?
122
- n_top_values = 100
123
- tmp1 = reopt_inputs[:Scenario][:Site][:LoadProfile][:loads_kw]
124
- tmp2 = tmp1.each_index.max_by(n_top_values * reopt_inputs[:Scenario][:time_steps_per_hour]) { |i| tmp1[i] }
125
- for i in (0...tmp2.count)
126
- tmp2[i] += 1
127
- end
128
- reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps] = tmp2
129
- end
130
-
131
- if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_charge_us_dollars_per_kw].nil?
132
- reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_charge_us_dollars_per_kw] = 0
133
- end
126
+ @@logger.error("Could not convert the annual electric load from a resolution of #{feature_report.timesteps_per_hour} to #{reopt_inputs[:Settings][:time_steps_per_hour]}")
127
+ raise "Could not convert the annual electric load from a resolution of #{feature_report.timesteps_per_hour} to #{reopt_inputs[:Settings][:time_steps_per_hour]}"
128
+ end
129
+
130
+ # TODO: Restore coincident_peak stuff here and in Scenario Report adapter
131
+ # if reopt_inputs[:ElectricTariff][:coincident_peak_load_active_time_steps].nil?
132
+ # n_top_values = 100
133
+ # tmp1 = reopt_inputs[:ElectricLoad][:loads_kw]
134
+ # tmp2 = tmp1.each_index.max_by(n_top_values * reopt_inputs[:Settings][:time_steps_per_hour]) { |i| tmp1[i] }
135
+ # for i in (0...tmp2.count)
136
+ # tmp2[i] += 1
137
+ # end
138
+ # # this needs to be a 2D array
139
+ # reopt_inputs[:ElectricTariff][:coincident_peak_load_active_time_steps] = [tmp2]
140
+ # end
141
+
142
+ # if reopt_inputs[:ElectricTariff][:coincident_peak_load_charge_per_kw].nil?
143
+ # reopt_inputs[:ElectricTariff][:coincident_peak_load_charge_per_kw] = 0
144
+ # end
134
145
 
135
146
  return reopt_inputs
136
147
  end
137
148
 
138
149
  ##
139
- # Update a FeatureReport from a \REopt Lite response
150
+ # Update a FeatureReport from a \REopt response
140
151
  #
141
152
  # [*parameters:*]
142
153
  #
143
- # * +feature_report+ - _URBANopt::Reporting::DefaultReports::FeatureReport_ - FeatureReport to update from a \REopt Lite reponse hash.
144
- # * +reopt_output+ - _Hash_ - A reponse hash from the \REopt Lite API to use in overwriting FeatureReport technology sizes, costs and dispatch strategies.
145
- # * +timeseries_csv_path+ - _String_ - Optional. The path to a file at which a new timeseries CSV will be written. If not provided a file is created based on the run_uuid of the \REopt Lite optimization task.
154
+ # * +feature_report+ - _URBANopt::Reporting::DefaultReports::FeatureReport_ - FeatureReport to update from a \REopt reponse hash.
155
+ # * +reopt_output+ - _Hash_ - A reponse hash from the \REopt API to use in overwriting FeatureReport technology sizes, costs and dispatch strategies.
156
+ # * +timeseries_csv_path+ - _String_ - Optional. The path to a file at which a new timeseries CSV will be written. If not provided a file is created based on the run_uuid of the \REopt optimization task.
146
157
  #
147
158
  # [*return:*] _URBANopt::Reporting::DefaultReports::FeatureReport_ - Returns an updated FeatureReport.
148
159
  ##
149
160
  def update_feature_report(feature_report, reopt_output, timeseries_csv_path = nil, resilience_stats = nil)
150
- # Check if the \REopt Lite response is valid
151
- if reopt_output['outputs']['Scenario']['status'] != 'optimal'
152
- @@logger.info("Warning cannot Feature Report #{feature_report.name} #{feature_report.id} - REopt optimization was non-optimal")
161
+
162
+ # Check if the \REopt response is valid
163
+ if reopt_output['status'] != 'optimal'
164
+ @@logger.error("ERROR cannot update Feature Report #{feature_report.name} #{feature_report.id} - REopt optimization was non-optimal")
153
165
  return feature_report
154
166
  end
155
167
 
156
168
  # Update location
157
- feature_report.location.latitude_deg = reopt_output['inputs']['Scenario']['Site']['latitude']
158
- feature_report.location.longitude_deg = reopt_output['inputs']['Scenario']['Site']['longitude']
169
+ feature_report.location.latitude_deg = reopt_output['inputs']['Site']['latitude']
170
+ feature_report.location.longitude_deg = reopt_output['inputs']['Site']['longitude']
159
171
 
160
172
  # Update distributed generation sizing and financials
161
- feature_report.distributed_generation.annual_renewable_electricity_pct = reopt_output['outputs']['Scenario']['Site']['annual_renewable_electricity_pct'] || 0
162
- feature_report.distributed_generation.lcc_us_dollars = reopt_output['outputs']['Scenario']['Site']['Financial']['lcc_us_dollars'] || 0
163
- feature_report.distributed_generation.npv_us_dollars = reopt_output['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0
164
- feature_report.distributed_generation.year_one_energy_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_energy_cost_us_dollars'] || 0
165
- feature_report.distributed_generation.year_one_demand_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_demand_cost_us_dollars'] || 0
166
- feature_report.distributed_generation.year_one_bill_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_bill_us_dollars'] || 0
167
- feature_report.distributed_generation.total_energy_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_energy_cost_us_dollars'] || 0
168
- feature_report.distributed_generation.total_demand_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_demand_cost_us_dollars'] || 0
169
- feature_report.distributed_generation.year_one_energy_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_energy_cost_bau_us_dollars'] || 0
170
- feature_report.distributed_generation.year_one_demand_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_demand_cost_bau_us_dollars'] || 0
171
- feature_report.distributed_generation.year_one_bill_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_bill_bau_us_dollars'] || 0
172
- feature_report.distributed_generation.total_demand_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_demand_cost_bau_us_dollars'] || 0
173
- feature_report.distributed_generation.total_energy_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_energy_cost_bau_us_dollars'] || 0
173
+ feature_report.distributed_generation.renewable_electricity_fraction = reopt_output['outputs']['Site']['renewable_electricity_fraction'] || 0
174
+ feature_report.distributed_generation.lcc = reopt_output['outputs']['Financial']['lcc'] || 0
175
+ feature_report.distributed_generation.npv = reopt_output['outputs']['Financial']['npv'] || 0
176
+ feature_report.distributed_generation.year_one_energy_cost_before_tax = reopt_output['outputs']['ElectricTariff']['year_one_energy_cost_before_tax'] || 0
177
+ feature_report.distributed_generation.year_one_demand_cost_before_tax = reopt_output['outputs']['ElectricTariff']['year_one_demand_cost_before_tax'] || 0
178
+ feature_report.distributed_generation.year_one_bill_before_tax = reopt_output['outputs']['ElectricTariff']['year_one_bill_before_tax'] || 0
179
+ feature_report.distributed_generation.lifecycle_energy_cost_after_tax = reopt_output['outputs']['ElectricTariff']['lifecycle_energy_cost_after_tax'] || 0
180
+ feature_report.distributed_generation.lifecycle_demand_cost_after_tax = reopt_output['outputs']['ElectricTariff']['lifecycle_demand_cost_after_tax'] || 0
181
+ feature_report.distributed_generation.year_one_energy_cost_before_tax_bau = reopt_output['outputs']['ElectricTariff']['year_one_energy_cost_before_tax_bau'] || 0
182
+ feature_report.distributed_generation.year_one_demand_cost_before_tax_bau = reopt_output['outputs']['ElectricTariff']['year_one_demand_cost_before_tax_bau'] || 0
183
+ feature_report.distributed_generation.year_one_bill_before_tax_bau = reopt_output['outputs']['ElectricTariff']['year_one_bill_before_tax_bau'] || 0
184
+ feature_report.distributed_generation.lifecycle_demand_cost_after_tax_bau = reopt_output['outputs']['ElectricTariff']['lifecycle_demand_cost_after_tax_bau'] || 0
185
+ feature_report.distributed_generation.lifecycle_energy_cost_after_tax_bau = reopt_output['outputs']['ElectricTariff']['lifecycle_energy_cost_after_tax_bau'] || 0
174
186
  if !resilience_stats.nil?
175
187
  feature_report.distributed_generation.resilience_hours_min = resilience_stats['resilience_hours_min']
176
188
  feature_report.distributed_generation.resilience_hours_max = resilience_stats['resilience_hours_max']
@@ -180,10 +192,10 @@ module URBANopt # :nodoc:
180
192
  feature_report.distributed_generation.probs_of_surviving_by_hour_of_the_day = resilience_stats['probs_of_surviving_by_hour_of_the_day']
181
193
  end
182
194
 
183
- if reopt_output['outputs']['Scenario']['Site']['PV'].instance_of?(Hash)
184
- reopt_output['outputs']['Scenario']['Site']['PV'] = [reopt_output['outputs']['Scenario']['Site']['PV']]
185
- elsif reopt_output['outputs']['Scenario']['Site']['PV'].nil?
186
- reopt_output['outputs']['Scenario']['Site']['PV'] = []
195
+ if reopt_output['outputs']['PV'].is_a?(Hash)
196
+ reopt_output['outputs']['PV'] = [reopt_output['outputs']['PV']]
197
+ elsif reopt_output['outputs']['PV'].nil?
198
+ reopt_output['outputs']['PV'] = []
187
199
  end
188
200
 
189
201
  # Store the PV name and location in a hash
@@ -194,58 +206,60 @@ module URBANopt # :nodoc:
194
206
  gcr = {}
195
207
 
196
208
  # Check whether multi PV assumption input file is used or single PV
197
- if reopt_output['inputs']['Scenario']['Site']['PV'].is_a?(Array)
198
- reopt_output['inputs']['Scenario']['Site']['PV'].each do |pv|
199
- location[pv['pv_name']] = pv['location']
200
- azimuth[pv['pv_name']] = pv['azimuth']
201
- tilt[pv['pv_name']] = pv['tilt']
202
- module_type[pv['pv_name']] = pv['module_type']
203
- gcr[pv['pv_name']] = pv['gcr']
209
+ if reopt_output['inputs'].key?('PV')
210
+ if reopt_output['inputs']['PV'].is_a?(Array)
211
+ reopt_output['inputs']['PV'].each do |pv|
212
+ location[pv['name']] = pv['location']
213
+ azimuth[pv['name']] = pv['azimuth']
214
+ tilt[pv['name']] = pv['tilt']
215
+ module_type[pv['name']] = pv['module_type']
216
+ gcr[pv['name']] = pv['gcr']
217
+ end
218
+ else
219
+ location[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['location']
220
+ azimuth[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['azimuth']
221
+ tilt[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['tilt']
222
+ module_type[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['module_type']
223
+ gcr[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['gcr']
204
224
  end
205
- else
206
- location[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['location']
207
- azimuth[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['azimuth']
208
- tilt[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['tilt']
209
- module_type[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['module_type']
210
- gcr[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['gcr']
211
- end
212
225
 
213
- reopt_output['outputs']['Scenario']['Site']['PV'].each_with_index do |pv, i|
214
- feature_report.distributed_generation.add_tech 'solar_pv', URBANopt::Reporting::DefaultReports::SolarPV.new({ size_kw: (pv['size_kw'] || 0), id: i, location: location[pv['pv_name']], average_yearly_energy_produced_kwh: pv['average_yearly_energy_produced_kwh'], azimuth: azimuth[pv['pv_name']], tilt: tilt[pv['pv_name']], module_type: module_type[pv['pv_name']], gcr: gcr[pv['pv_name']] })
226
+ reopt_output['outputs']['PV'].each_with_index do |pv, i|
227
+ feature_report.distributed_generation.add_tech 'solar_pv', URBANopt::Reporting::DefaultReports::SolarPV.new({ size_kw: (pv['size_kw'] || 0), id: i, location: location[pv['name']], average_yearly_energy_produced_kwh: pv['annual_energy_produced_kwh'], azimuth: azimuth[pv['name']], tilt: tilt[pv['name']], module_type: module_type[pv['name']], gcr: gcr[pv['name']] })
228
+ end
215
229
  end
216
230
 
217
- wind = reopt_output['outputs']['Scenario']['Site']['Wind']
218
- if !wind['size_kw'].nil? && (wind['size_kw'] != 0)
231
+ if reopt_output['outputs'].key?('Wind')
232
+ wind = reopt_output['outputs']['Wind']
219
233
  feature_report.distributed_generation.add_tech 'wind', URBANopt::Reporting::DefaultReports::Wind.new({ size_kw: (wind['size_kw'] || 0) })
220
234
  end
221
235
 
222
- generator = reopt_output['outputs']['Scenario']['Site']['Generator']
223
- if !generator['size_kw'].nil? && (generator['size_kw'] != 0)
236
+ if reopt_output['outputs'].key?('Generator')
237
+ generator = reopt_output['outputs']['Generator']
224
238
  feature_report.distributed_generation.add_tech 'generator', URBANopt::Reporting::DefaultReports::Generator.new({ size_kw: (generator['size_kw'] || 0) })
225
239
  end
226
240
 
227
- storage = reopt_output['outputs']['Scenario']['Site']['Storage']
228
- if !storage['size_kw'].nil? && (storage['size_kw'] != 0)
241
+ if reopt_output['outputs'].key?('ElectricStorage')
242
+ storage = reopt_output['outputs']['ElectricStorage']
229
243
  feature_report.distributed_generation.add_tech 'storage', URBANopt::Reporting::DefaultReports::Storage.new({ size_kwh: (storage['size_kwh'] || 0), size_kw: (storage['size_kw'] || 0) })
230
244
  end
231
245
 
232
246
  generation_timeseries_kwh = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
233
- reopt_resolution = reopt_output['inputs']['Scenario']['time_steps_per_hour']
247
+ reopt_resolution = reopt_output['inputs']['Settings']['time_steps_per_hour']
234
248
 
235
- unless reopt_output['outputs']['Scenario']['Site']['PV'].nil?
236
- reopt_output['outputs']['Scenario']['Site']['PV'].each do |pv|
249
+ if reopt_output['outputs'].key?('PV') && !reopt_output['outputs']['PV'].nil?
250
+ reopt_output['outputs']['PV'].each do |pv|
237
251
  if (pv['size_kw'] || 0) > 0 && !pv['year_one_power_production_series_kw'].nil?
238
252
  generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
239
253
  end
240
254
  end
241
255
  end
242
256
 
243
- if !reopt_output['outputs']['Scenario']['Site']['Wind'].nil? && ((reopt_output['outputs']['Scenario']['Site']['Wind']['size_kw'] || 0) > 0) && !reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'].nil?
244
- generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
257
+ if reopt_output['outputs'].key?('Wind') && !reopt_output['outputs']['Wind'].nil? && ((reopt_output['outputs']['Wind']['size_kw'] || 0) > 0) && !reopt_output['outputs']['Wind']['year_one_power_production_series_kw'].nil?
258
+ generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Wind']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
245
259
  end
246
260
 
247
- if !reopt_output['outputs']['Scenario']['Site']['Generator'].nil? && ((reopt_output['outputs']['Scenario']['Site']['Generator']['size_kw'] || 0) > 0) && !reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'].nil?
248
- generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
261
+ if reopt_output['outputs'].key?('Generator') && !reopt_output['outputs']['Generator'].nil? && ((reopt_output['outputs']['Generator']['size_kw'] || 0) > 0) && !reopt_output['outputs']['Generator']['year_one_power_production_series_kw'].nil?
262
+ generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Generator']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
249
263
  end
250
264
 
251
265
  $generation_timeseries_kwh = generation_timeseries_kwh.to_a[0] || [0] * (8760 * feature_report.timesteps_per_hour)
@@ -255,167 +269,187 @@ module URBANopt # :nodoc:
255
269
  feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Total(kw)')
256
270
  end
257
271
 
258
- $load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['LoadProfile']['year_one_electric_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
272
+ $load = convert_powerflow_resolution(reopt_output['outputs']['ElectricLoad']['load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
259
273
  $load_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Load:Total(kw)')
260
274
  if $load_col.nil?
261
275
  $load_col = feature_report.timeseries_csv.column_names.length
262
276
  feature_report.timeseries_csv.column_names.push('REopt:Electricity:Load:Total(kw)')
263
277
  end
264
278
 
265
- $utility_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
279
+ $utility_to_load = convert_powerflow_resolution(reopt_output['outputs']['ElectricUtility']['electric_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
266
280
  $utility_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToLoad(kw)')
267
281
  if $utility_to_load_col.nil?
268
282
  $utility_to_load_col = feature_report.timeseries_csv.column_names.length
269
283
  feature_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToLoad(kw)')
270
284
  end
271
285
 
272
- $utility_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
273
- $utility_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToBattery(kw)')
274
- if $utility_to_battery_col.nil?
275
- $utility_to_battery_col = feature_report.timeseries_csv.column_names.length
276
- feature_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToBattery(kw)')
277
- end
286
+ if !storage.nil?
287
+ $utility_to_battery = convert_powerflow_resolution(reopt_output['outputs']['ElectricUtility']['electric_to_storage_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
288
+ $utility_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToBattery(kw)')
289
+ if $utility_to_battery_col.nil?
290
+ $utility_to_battery_col = feature_report.timeseries_csv.column_names.length
291
+ feature_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToBattery(kw)')
292
+ end
278
293
 
279
- $storage_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
280
- $storage_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToLoad(kw)')
281
- if $storage_to_load_col.nil?
282
- $storage_to_load_col = feature_report.timeseries_csv.column_names.length
283
- feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToLoad(kw)')
284
- end
294
+ $storage_to_load = convert_powerflow_resolution(reopt_output['outputs']['ElectricStorage']['storage_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
295
+ $storage_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToLoad(kw)')
296
+ if $storage_to_load_col.nil?
297
+ $storage_to_load_col = feature_report.timeseries_csv.column_names.length
298
+ feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToLoad(kw)')
299
+ end
285
300
 
286
- $storage_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
287
- $storage_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToGrid(kw)')
288
- if $storage_to_grid_col.nil?
289
- $storage_to_grid_col = feature_report.timeseries_csv.column_names.length
290
- feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToGrid(kw)')
291
- end
301
+ $storage_to_grid = convert_powerflow_resolution(reopt_output['outputs']['ElectricStorage']['electric_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
302
+ $storage_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToGrid(kw)')
303
+ if $storage_to_grid_col.nil?
304
+ $storage_to_grid_col = feature_report.timeseries_csv.column_names.length
305
+ feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToGrid(kw)')
306
+ end
292
307
 
293
- $storage_soc = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_soc_series_pct'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
294
- $storage_soc_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:StateOfCharge(pct)')
295
- if $storage_soc_col.nil?
296
- $storage_soc_col = feature_report.timeseries_csv.column_names.length
297
- feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:StateOfCharge(pct)')
308
+ $storage_soc = convert_powerflow_resolution(reopt_output['outputs']['ElectricStorage']['soc_series_fraction'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
309
+ $storage_soc_col = feature_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:StateOfCharge(pct)')
310
+ if $storage_soc_col.nil?
311
+ $storage_soc_col = feature_report.timeseries_csv.column_names.length
312
+ feature_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:StateOfCharge(pct)')
313
+ end
298
314
  end
299
315
 
300
- $generator_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
301
- $generator_total_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:Total(kw)')
302
- if $generator_total_col.nil?
303
- $generator_total_col = feature_report.timeseries_csv.column_names.length
304
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:Total(kw)')
305
- end
316
+ if !generator.nil?
317
+ # $generator_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
318
+ $generator_total_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:Total(kw)')
319
+ if $generator_total_col.nil?
320
+ $generator_total_col = feature_report.timeseries_csv.column_names.length
321
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:Total(kw)')
322
+ end
306
323
 
307
- $generator_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
308
- $generator_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToBattery(kw)')
309
- if $generator_to_battery_col.nil?
310
- $generator_to_battery_col = feature_report.timeseries_csv.column_names.length
311
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToBattery(kw)')
312
- end
324
+ if !storage.nil?
325
+ $generator_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Generator']['electric_to_storage_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
326
+ $generator_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToBattery(kw)')
327
+ if $generator_to_battery_col.nil?
328
+ $generator_to_battery_col = feature_report.timeseries_csv.column_names.length
329
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToBattery(kw)')
330
+ end
331
+ end
313
332
 
314
- $generator_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
315
- $generator_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToLoad(kw)')
316
- if $generator_to_load_col.nil?
317
- $generator_to_load_col = feature_report.timeseries_csv.column_names.length
318
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToLoad(kw)')
319
- end
333
+ $generator_to_load = convert_powerflow_resolution(reopt_output['outputs']['Generator']['electric_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
334
+ $generator_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToLoad(kw)')
335
+ if $generator_to_load_col.nil?
336
+ $generator_to_load_col = feature_report.timeseries_csv.column_names.length
337
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToLoad(kw)')
338
+ end
320
339
 
321
- $generator_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
322
- $generator_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToGrid(kw)')
323
- if $generator_to_grid_col.nil?
324
- $generator_to_grid_col = feature_report.timeseries_csv.column_names.length
325
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToGrid(kw)')
340
+ $generator_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Generator']['electric_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
341
+ $generator_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToGrid(kw)')
342
+ if $generator_to_grid_col.nil?
343
+ $generator_to_grid_col = feature_report.timeseries_csv.column_names.length
344
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToGrid(kw)')
345
+ end
326
346
  end
327
347
 
328
- $pv_total_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:Total(kw)')
329
- if $pv_total_col.nil?
330
- $pv_total_col = feature_report.timeseries_csv.column_names.length
331
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:Total(kw)')
332
- end
348
+ if reopt_output['outputs'].key?('PV') && !reopt_output['outputs']['PV'].nil?
349
+ $pv_total_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:Total(kw)')
350
+ if $pv_total_col.nil?
351
+ $pv_total_col = feature_report.timeseries_csv.column_names.length
352
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:Total(kw)')
353
+ end
333
354
 
334
- $pv_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToBattery(kw)')
335
- if $pv_to_battery_col.nil?
336
- $pv_to_battery_col = feature_report.timeseries_csv.column_names.length
337
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToBattery(kw)')
338
- end
355
+ if !storage.nil?
356
+ $pv_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToBattery(kw)')
357
+ if $pv_to_battery_col.nil?
358
+ $pv_to_battery_col = feature_report.timeseries_csv.column_names.length
359
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToBattery(kw)')
360
+ end
361
+ end
339
362
 
340
- $pv_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToLoad(kw)')
341
- if $pv_to_load_col.nil?
342
- $pv_to_load_col = feature_report.timeseries_csv.column_names.length
343
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToLoad(kw)')
344
- end
363
+ $pv_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToLoad(kw)')
364
+ if $pv_to_load_col.nil?
365
+ $pv_to_load_col = feature_report.timeseries_csv.column_names.length
366
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToLoad(kw)')
367
+ end
345
368
 
346
- $pv_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToGrid(kw)')
347
- if $pv_to_grid_col.nil?
348
- $pv_to_grid_col = feature_report.timeseries_csv.column_names.length
349
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToGrid(kw)')
350
- end
369
+ $pv_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToGrid(kw)')
370
+ if $pv_to_grid_col.nil?
371
+ $pv_to_grid_col = feature_report.timeseries_csv.column_names.length
372
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToGrid(kw)')
373
+ end
351
374
 
352
- $pv_total = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
353
- $pv_to_battery = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
354
- $pv_to_load = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
355
- $pv_to_grid = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
356
-
357
- reopt_output['outputs']['Scenario']['Site']['PV'].each_with_index do |pv, i|
358
- if (pv['size_kw'] || 0) > 0
359
- $pv_total += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
360
- $pv_to_battery += Matrix[convert_powerflow_resolution(pv['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
361
- $pv_to_load += Matrix[convert_powerflow_resolution(pv['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
362
- $pv_to_grid += Matrix[convert_powerflow_resolution(pv['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
375
+ $pv_total = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
376
+ if !storage.nil?
377
+ $pv_to_battery = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
378
+ end
379
+ $pv_to_load = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
380
+ $pv_to_grid = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
381
+
382
+ reopt_output['outputs']['PV'].each_with_index do |pv, i|
383
+ if (pv['size_kw'] || 0) > 0
384
+ # $pv_total += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
385
+ if !storage.nil?
386
+ $pv_to_battery += Matrix[convert_powerflow_resolution(pv['electric_to_storage_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
387
+ end
388
+ $pv_to_load += Matrix[convert_powerflow_resolution(pv['electric_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
389
+ $pv_to_grid += Matrix[convert_powerflow_resolution(pv['electric_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)]
390
+ end
363
391
  end
364
- end
365
392
 
366
- $pv_total = $pv_total.to_a[0]
367
- $pv_to_battery = $pv_to_battery.to_a[0]
368
- $pv_to_load = $pv_to_load.to_a[0]
369
- $pv_to_grid = $pv_to_grid.to_a[0]
393
+ $pv_total = $pv_total.to_a[0]
394
+ if !storage.nil?
395
+ $pv_to_battery = $pv_to_battery.to_a[0]
396
+ end
397
+ $pv_to_load = $pv_to_load.to_a[0]
398
+ $pv_to_grid = $pv_to_grid.to_a[0]
399
+ end
370
400
 
371
- $wind_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
401
+ # $wind_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
372
402
  $wind_total_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:Total(kw)')
373
403
  if $wind_total_col.nil?
374
404
  $wind_total_col = feature_report.timeseries_csv.column_names.length
375
405
  feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:Total(kw)')
376
406
  end
377
407
 
378
- $wind_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_battery_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
379
- $wind_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToBattery(kw)')
380
- if $wind_to_battery_col.nil?
381
- $wind_to_battery_col = feature_report.timeseries_csv.column_names.length
382
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToBattery(kw)')
383
- end
408
+ if !wind.nil?
409
+ if !storage.nil?
410
+ $wind_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Wind']['electric_to_storage_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
411
+ $wind_to_battery_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToBattery(kw)')
412
+ if $wind_to_battery_col.nil?
413
+ $wind_to_battery_col = feature_report.timeseries_csv.column_names.length
414
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToBattery(kw)')
415
+ end
416
+ end
384
417
 
385
- $wind_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
386
- $wind_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToLoad(kw)')
387
- if $wind_to_load_col.nil?
388
- $wind_to_load_col = feature_report.timeseries_csv.column_names.length
389
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToLoad(kw)')
390
- end
418
+ $wind_to_load = convert_powerflow_resolution(reopt_output['outputs']['Wind']['electric_to_load_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
419
+ $wind_to_load_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToLoad(kw)')
420
+ if $wind_to_load_col.nil?
421
+ $wind_to_load_col = feature_report.timeseries_csv.column_names.length
422
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToLoad(kw)')
423
+ end
391
424
 
392
- $wind_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
393
- $wind_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToGrid(kw)')
394
- if $wind_to_grid_col.nil?
395
- $wind_to_grid_col = feature_report.timeseries_csv.column_names.length
396
- feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToGrid(kw)')
425
+ $wind_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Wind']['electric_to_grid_series_kw'], reopt_resolution, feature_report.timesteps_per_hour) || [0] * (8760 * feature_report.timesteps_per_hour)
426
+ $wind_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToGrid(kw)')
427
+ if $wind_to_grid_col.nil?
428
+ $wind_to_grid_col = feature_report.timeseries_csv.column_names.length
429
+ feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToGrid(kw)')
430
+ end
397
431
  end
398
432
 
399
433
  def modrow(x, i) # :nodoc:
400
434
  x[$generation_timeseries_kwh_col] = $generation_timeseries_kwh[i] || 0
401
435
  x[$load_col] = $load[i] || 0
402
436
  x[$utility_to_load_col] = $utility_to_load[i] || 0
403
- x[$utility_to_battery_col] = $utility_to_battery[i] || 0
404
- x[$storage_to_load_col] = $storage_to_load[i] || 0
405
- x[$storage_to_grid_col] = $storage_to_grid[i] || 0
406
- x[$storage_soc_col] = $storage_soc[i] || 0
407
- x[$generator_total_col] = $generator_total[i] || 0
408
- x[$generator_to_battery_col] = $generator_to_battery[i] || 0
409
- x[$generator_to_load_col] = $generator_to_load[i] || 0
410
- x[$generator_to_grid_col] = $generator_to_grid[i] || 0
437
+ x[$utility_to_battery_col] = $utility_to_battery[i] || 0 if defined?(storage)
438
+ x[$storage_to_load_col] = $storage_to_load[i] || 0 if defined?(storage)
439
+ x[$storage_to_grid_col] = $storage_to_grid[i] || 0 if defined?(storage)
440
+ x[$storage_soc_col] = $storage_soc[i] || 0 if defined?(storage)
441
+ x[$generator_total_col] = $generator_total[i] || 0 if defined?(generator)
442
+ x[$generator_to_battery_col] = $generator_to_battery[i] || 0 if (defined?(generator) && defined?(storage))
443
+ x[$generator_to_load_col] = $generator_to_load[i] || 0 if defined?(generator)
444
+ x[$generator_to_grid_col] = $generator_to_grid[i] || 0 if defined?(generator)
411
445
  x[$pv_total_col] = $pv_total[i] || 0
412
- x[$pv_to_battery_col] = $pv_to_battery[i] || 0
446
+ x[$pv_to_battery_col] = $pv_to_battery[i] || 0 if defined?(storage)
413
447
  x[$pv_to_load_col] = $pv_to_load[i] || 0
414
448
  x[$pv_to_grid_col] = $pv_to_grid[i] || 0
415
- x[$wind_total_col] = $wind_total[i] || 0
416
- x[$wind_to_battery_col] = $wind_to_battery[i] || 0
417
- x[$wind_to_load_col] = $wind_to_load[i] || 0
418
- x[$wind_to_grid_col] = $wind_to_grid[i] || 0
449
+ x[$wind_total_col] = $wind_total[i] || 0 if defined?(wind)
450
+ x[$wind_to_battery_col] = $wind_to_battery[i] || 0 if (defined?(wind) && defined?(storage))
451
+ x[$wind_to_load_col] = $wind_to_load[i] || 0 if defined?(wind)
452
+ x[$wind_to_grid_col] = $wind_to_grid[i] || 0 if defined?(wind)
419
453
  return x
420
454
  end
421
455
 
@@ -425,8 +459,7 @@ module URBANopt # :nodoc:
425
459
  (
426
460
  ((start_date.yday - 1) * 60.0 * 60.0 * 24) +
427
461
  ((start_date.hour - 1) * 60.0 * 60.0) +
428
- (start_date.min * 60.0) + start_date.sec) /
429
- ((60 / feature_report.timesteps_per_hour) * 60)
462
+ (start_date.min * 60.0) + start_date.sec) / ((60 / feature_report.timesteps_per_hour) * 60)
430
463
  ).to_int
431
464
 
432
465
  mod_data = old_data.map.with_index do |x, i|