urbanopt-reopt 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,7 @@ module URBANopt # :nodoc:
14
14
  module REopt # :nodoc:
15
15
  class ScenarioReportAdapter
16
16
  ##
17
- # ScenarioReportAdapter can convert a ScenarioReport into a \REopt Lite posts or updates a ScenarioReport and its FeatureReports from \REopt Lite response(s)
17
+ # ScenarioReportAdapter can convert a ScenarioReport into a \REopt posts or updates a ScenarioReport and its FeatureReports from \REopt response(s)
18
18
  ##
19
19
  # [*parameters:*]
20
20
  def initialize
@@ -23,26 +23,35 @@ module URBANopt # :nodoc:
23
23
  end
24
24
 
25
25
  ##
26
- # Convert a ScenarioReport into a \REopt Lite post
26
+ # Convert a ScenarioReport into a \REopt post
27
27
  #
28
28
  # [*parameters:*]
29
29
  #
30
- # * +scenario_report+ - _URBANopt::Reporting::DefaultReports::ScenarioReport_ - ScenarioReport to use in converting the +reopt_assumptions_hash+, if provided, to a \REopt Lite post. Otherwise, if the +reopt_assumptions_hash+ is nil a default post will be updated from this ScenarioReport and submitted to the \REopt Lite API.
31
- # * +reopt_assumptions_hash+ - _Hash_ - Optional. A hash formatted for submittal to the \REopt Lite API containing default values. Values will be overwritten from the ScenarioReport where available (i.e. latitude, roof_squarefeet). Missing optional parameters will be filled in with default values by the API.
30
+ # * +scenario_report+ - _URBANopt::Reporting::DefaultReports::ScenarioReport_ - ScenarioReport to use in converting the +reopt_assumptions_hash+, if provided, to a \REopt post. Otherwise, if the +reopt_assumptions_hash+ is nil a default post will be updated from this ScenarioReport and submitted to the \REopt API.
31
+ # * +reopt_assumptions_hash+ - _Hash_ - Optional. A hash formatted for submittal to the \REopt API containing default values. Values will be overwritten from the ScenarioReport where available (i.e. latitude, roof_squarefeet). Missing optional parameters will be filled in with default values by the API.
32
32
  #
33
- # [*return:*] _Hash_ - Returns hash formatted for submittal to the \REopt Lite API
33
+ # [*return:*] _Hash_ - Returns hash formatted for submittal to the \REopt API
34
34
  ##
35
35
  def reopt_json_from_scenario_report(scenario_report, reopt_assumptions_json = nil, community_photovoltaic = nil)
36
36
  name = scenario_report.name.delete ' '
37
37
  scenario_id = scenario_report.id.delete ' '
38
38
  description = "scenario_report_#{name}_#{scenario_id}"
39
39
 
40
- # Create base REpopt Lite post
41
- 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
+ # Create base REpopt post
42
41
  if !reopt_assumptions_json.nil?
43
42
  reopt_inputs = reopt_assumptions_json
44
43
  else
45
- @@logger.info('Using default REopt Lite assumptions')
44
+ @@logger.info('Using default REopt assumptions')
45
+ reopt_inputs = {
46
+ Settings:{},
47
+ Site: {},
48
+ Financial:{},
49
+ ElectricTariff: {
50
+ monthly_demand_rates: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
51
+ 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]
52
+ },
53
+ ElectricLoad: {}
54
+ }
46
55
  end
47
56
 
48
57
  # Update required info
@@ -76,26 +85,26 @@ module URBANopt # :nodoc:
76
85
  end
77
86
  end
78
87
 
79
- reopt_inputs[:Scenario][:description] = description
88
+ reopt_inputs[:description] = description
80
89
 
81
- reopt_inputs[:Scenario][:Site][:latitude] = scenario_report.location.latitude_deg
82
- reopt_inputs[:Scenario][:Site][:longitude] = scenario_report.location.longitude_deg
90
+ reopt_inputs[:Site][:latitude] = scenario_report.location.latitude_deg
91
+ reopt_inputs[:Site][:longitude] = scenario_report.location.longitude_deg
83
92
 
84
93
  # Update optional info
85
94
  # REK: attribute names should be updated
86
- if reopt_inputs[:Scenario][:Site][:roof_squarefeet].nil? && !scenario_report.program.roof_area_sqft.nil?
87
- reopt_inputs[:Scenario][:Site][:roof_squarefeet] = scenario_report.program.roof_area_sqft[:available_roof_area_sqft]
95
+ if reopt_inputs[:Site][:roof_squarefeet].nil? && !scenario_report.program.roof_area_sqft.nil?
96
+ reopt_inputs[:Site][:roof_squarefeet] = scenario_report.program.roof_area_sqft[:available_roof_area_sqft]
88
97
  end
89
98
 
90
99
  begin
91
- if reopt_inputs[:Scenario][:Site][:land_acres].nil? && !community_photovoltaic[0][:properties][:footprint_area].nil?
92
- reopt_inputs[:Scenario][:Site][:land_acres] = community_photovoltaic[0][:properties][:footprint_area] * 1.0 / 43560 # acres/sqft
100
+ if reopt_inputs[:Site][:land_acres].nil? && !community_photovoltaic[0][:properties][:footprint_area].nil?
101
+ reopt_inputs[:Site][:land_acres] = community_photovoltaic[0][:properties][:footprint_area] * 1.0 / 43560 # acres/sqft
93
102
  end
94
103
  rescue StandardError
95
104
  end
96
105
 
97
- if reopt_inputs[:Scenario][:time_steps_per_hour].nil?
98
- reopt_inputs[:Scenario][:time_steps_per_hour] = 1
106
+ if reopt_inputs[:Settings][:time_steps_per_hour].nil?
107
+ reopt_inputs[:Settings][:time_steps_per_hour] = 1
99
108
  end
100
109
 
101
110
  # Update load profile info
@@ -120,38 +129,40 @@ module URBANopt # :nodoc:
120
129
 
121
130
  # Convert load to REopt Resolution
122
131
  begin
123
- reopt_inputs[:Scenario][:Site][:LoadProfile][:loads_kw] = convert_powerflow_resolution(energy_timeseries_kw, scenario_report.timesteps_per_hour, reopt_inputs[:Scenario][:time_steps_per_hour])
132
+ reopt_inputs[:ElectricLoad][:loads_kw] = convert_powerflow_resolution(energy_timeseries_kw, scenario_report.timesteps_per_hour, reopt_inputs[:Settings][:time_steps_per_hour])
124
133
  rescue StandardError
125
- @@logger.error("Could not convert the annual electric load from a resolution of #{scenario_report.timesteps_per_hour} to #{reopt_inputs[:Scenario][:time_steps_per_hour]}")
126
- raise "Could not convert the annual electric load from a resolution of #{scenario_report.timesteps_per_hour} to #{reopt_inputs[:Scenario][:time_steps_per_hour]}"
127
- end
128
-
129
- if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps].nil?
130
- n_top_values = 100
131
- tmp1 = reopt_inputs[:Scenario][:Site][:LoadProfile][:loads_kw]
132
- tmp2 = tmp1.each_index.max_by(n_top_values * reopt_inputs[:Scenario][:time_steps_per_hour]) { |i| tmp1[i] }
133
- for i in (0...tmp2.count)
134
- tmp2[i] += 1
135
- end
136
- reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps] = tmp2
137
- end
138
-
139
- if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_charge_us_dollars_per_kw].nil?
140
- reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_charge_us_dollars_per_kw] = 0
141
- end
134
+ @@logger.error("Could not convert the annual electric load from a resolution of #{scenario_report.timesteps_per_hour} to #{reopt_inputs[:Settings][:time_steps_per_hour]}")
135
+ raise "Could not convert the annual electric load from a resolution of #{scenario_report.timesteps_per_hour} to #{reopt_inputs[:Settings][:time_steps_per_hour]}"
136
+ end
137
+
138
+ # REMOVE COINCIDENT PEAKS STUFF JUST FOR TESTING
139
+ # if reopt_inputs[:ElectricTariff][:coincident_peak_load_active_time_steps].nil?
140
+ # n_top_values = 10
141
+ # tmp1 = reopt_inputs[:ElectricLoad][:loads_kw]
142
+ # tmp2 = tmp1.each_index.max_by(n_top_values * reopt_inputs[:Settings][:time_steps_per_hour]) { |i| tmp1[i] }
143
+ # for i in (0...tmp2.count)
144
+ # tmp2[i] += 1
145
+ # end
146
+ # # this needs to be a 2D array
147
+ # reopt_inputs[:ElectricTariff][:coincident_peak_load_active_time_steps] = [tmp2]
148
+ # end
149
+
150
+ # if reopt_inputs[:ElectricTariff][:coincident_peak_load_charge_per_kw].nil?
151
+ # reopt_inputs[:ElectricTariff][:coincident_peak_load_charge_per_kw] = 0
152
+ # end
142
153
 
143
154
  return reopt_inputs
144
155
  end
145
156
 
146
157
  ##
147
- # Converts a FeatureReport list from a ScenarioReport into an array of \REopt Lite posts
158
+ # Converts a FeatureReport list from a ScenarioReport into an array of \REopt posts
148
159
  #
149
160
  # [*parameters:*]
150
161
  #
151
- # * +scenario_report+ - _URBANopt::Reporting::DefaultReports::ScenarioReport_ - ScenarioReport to use in converting FeatureReports and respecitive +reopt_assumptions_hashes+, if provided, to a \REopt Lite post. If no +reopt_assumptions_hashes+ are provided default posts will be updated from these FeatureReports and submitted to the \REopt Lite API.
152
- # * +reopt_assumptions_hashes+ - _Array_ - Optional. An array of hashes formatted for submittal to the \REopt Lite API containing default values. Values will be overwritten from the ScenarioReport where available (i.e. latitude, roof_squarefeet). Missing optional parameters will be filled in with default values by the API. The order should match the list in ScenarioReport.feature_reports.
162
+ # * +scenario_report+ - _URBANopt::Reporting::DefaultReports::ScenarioReport_ - ScenarioReport to use in converting FeatureReports and respecitive +reopt_assumptions_hashes+, if provided, to a \REopt post. If no +reopt_assumptions_hashes+ are provided default posts will be updated from these FeatureReports and submitted to the \REopt API.
163
+ # * +reopt_assumptions_hashes+ - _Array_ - Optional. An array of hashes formatted for submittal to the \REopt API containing default values. Values will be overwritten from the ScenarioReport where available (i.e. latitude, roof_squarefeet). Missing optional parameters will be filled in with default values by the API. The order should match the list in ScenarioReport.feature_reports.
153
164
  #
154
- # [*return:*] _Array_ - Returns an array of hashes formatted for submittal to the \REopt Lite API in the order of the FeatureReports lited in ScenarioReport.feature_reports.
165
+ # [*return:*] _Array_ - Returns an array of hashes formatted for submittal to the \REopt API in the order of the FeatureReports lited in ScenarioReport.feature_reports.
155
166
  ##
156
167
  def reopt_jsons_from_scenario_feature_reports(scenario_report, reopt_assumptions_hashes = [])
157
168
  results = []
@@ -165,64 +176,41 @@ module URBANopt # :nodoc:
165
176
  return results
166
177
  end
167
178
 
168
- def modrow(data, idx) # :nodoc:
169
- data[$generation_timeseries_kwh_col] = $generation_timeseries_kwh[idx] || 0
170
- data[$load_col] = $load[idx] || 0
171
- data[$utility_to_load_col] = $utility_to_load[idx] || 0
172
- data[$utility_to_battery_col] = $utility_to_battery[idx] || 0
173
- data[$storage_to_load_col] = $storage_to_load[idx] || 0
174
- data[$storage_to_grid_col] = $storage_to_grid[idx] || 0
175
- data[$storage_soc_col] = $storage_soc[idx] || 0
176
- data[$generator_total_col] = $generator_total[idx] || 0
177
- data[$generator_to_battery_col] = $generator_to_battery[idx] || 0
178
- data[$generator_to_load_col] = $generator_to_load[idx] || 0
179
- data[$generator_to_grid_col] = $generator_to_grid[idx] || 0
180
- data[$pv_total_col] = $pv_total[idx] || 0
181
- data[$pv_to_battery_col] = $pv_to_battery[idx] || 0
182
- data[$pv_to_load_col] = $pv_to_load[idx] || 0
183
- data[$pv_to_grid_col] = $pv_to_grid[idx] || 0
184
- data[$wind_total_col] = $wind_total[idx] || 0
185
- data[$wind_to_battery_col] = $wind_to_battery[idx] || 0
186
- data[$wind_to_load_col] = $wind_to_load[idx] || 0
187
- data[$wind_to_grid_col] = $wind_to_grid[idx] || 0
188
- return data
189
- end
190
-
191
179
  ##
192
- # Updates a ScenarioReport from a \REopt Lite response
180
+ # Updates a ScenarioReport from a \REopt response
193
181
  #
194
182
  # [*parameters:*]
195
183
  #
196
- # * +scenario_report+ - _URBANopt::Reporting::DefaultReports::ScenarioReport_ - ScenarioReport to update from a \REopt Lite response.
197
- # * +reopt_output+ - _Hash_ - A hash response from the \REopt Lite API.
198
- # * +timeseries_csv_path+ - _String_ - Optional. The path to a file at which new timeseries data will be written. If not provided a file is created based on the run_uuid of the \REopt Lite optimization task.
184
+ # * +scenario_report+ - _URBANopt::Reporting::DefaultReports::ScenarioReport_ - ScenarioReport to update from a \REopt response.
185
+ # * +reopt_output+ - _Hash_ - A hash response from the \REopt API.
186
+ # * +timeseries_csv_path+ - _String_ - Optional. The path to a file at which new timeseries data will be written. If not provided a file is created based on the run_uuid of the \REopt optimization task.
199
187
  #
200
188
  # [*return:*] _URBANopt::Reporting::DefaultReports::ScenarioReport_ - Returns an updated ScenarioReport
201
189
  ##
202
190
  def update_scenario_report(scenario_report, reopt_output, timeseries_csv_path = nil, resilience_stats = nil)
203
- if reopt_output['outputs']['Scenario']['status'] != 'optimal'
191
+ if reopt_output['status'] != 'optimal'
204
192
  @@logger.info("Warning cannot Feature Report #{scenario_report.name} #{scenario_report.id} - REopt optimization was non-optimal")
205
193
  return scenario_report
206
194
  end
207
195
 
208
196
  # Update location
209
- scenario_report.location.latitude_deg = reopt_output['inputs']['Scenario']['Site']['latitude']
210
- scenario_report.location.longitude_deg = reopt_output['inputs']['Scenario']['Site']['longitude']
197
+ scenario_report.location.latitude_deg = reopt_output['inputs']['Site']['latitude']
198
+ scenario_report.location.longitude_deg = reopt_output['inputs']['Site']['longitude']
211
199
 
212
200
  # Update distributed generation sizing and financials
213
- scenario_report.distributed_generation.annual_renewable_electricity_pct = reopt_output['outputs']['Scenario']['Site']['annual_renewable_electricity_pct'] || 0
214
- scenario_report.distributed_generation.lcc_us_dollars = reopt_output['outputs']['Scenario']['Site']['Financial']['lcc_us_dollars'] || 0
215
- scenario_report.distributed_generation.npv_us_dollars = reopt_output['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0
216
- scenario_report.distributed_generation.year_one_energy_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_energy_cost_us_dollars'] || 0
217
- scenario_report.distributed_generation.year_one_demand_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_demand_cost_us_dollars'] || 0
218
- scenario_report.distributed_generation.year_one_bill_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_bill_us_dollars'] || 0
219
- scenario_report.distributed_generation.total_energy_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_energy_cost_us_dollars'] || 0
220
- scenario_report.distributed_generation.total_demand_cost_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_demand_cost_us_dollars'] || 0
221
- scenario_report.distributed_generation.year_one_energy_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_energy_cost_bau_us_dollars'] || 0
222
- scenario_report.distributed_generation.year_one_demand_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_demand_cost_bau_us_dollars'] || 0
223
- scenario_report.distributed_generation.year_one_bill_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_bill_bau_us_dollars'] || 0
224
- scenario_report.distributed_generation.total_demand_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_demand_cost_bau_us_dollars'] || 0
225
- scenario_report.distributed_generation.total_energy_cost_bau_us_dollars = reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['total_energy_cost_bau_us_dollars'] || 0
201
+ scenario_report.distributed_generation.renewable_electricity_fraction = reopt_output['outputs']['Site']['renewable_electricity_fraction'] || 0
202
+ scenario_report.distributed_generation.lcc = reopt_output['outputs']['Financial']['lcc'] || 0
203
+ scenario_report.distributed_generation.npv = reopt_output['outputs']['Financial']['npv'] || 0
204
+ scenario_report.distributed_generation.year_one_energy_cost_before_tax = reopt_output['outputs']['ElectricTariff']['year_one_energy_cost_before_tax'] || 0
205
+ scenario_report.distributed_generation.year_one_demand_cost_before_tax = reopt_output['outputs']['ElectricTariff']['year_one_demand_cost_before_tax'] || 0
206
+ scenario_report.distributed_generation.year_one_bill_before_tax = reopt_output['outputs']['ElectricTariff']['year_one_bill_before_tax'] || 0
207
+ scenario_report.distributed_generation.lifecycle_energy_cost_after_tax = reopt_output['outputs']['ElectricTariff']['lifecycle_energy_cost_after_tax'] || 0
208
+ scenario_report.distributed_generation.lifecycle_demand_cost_after_tax = reopt_output['outputs']['ElectricTariff']['lifecycle_demand_cost_after_tax'] || 0
209
+ scenario_report.distributed_generation.year_one_energy_cost_before_tax_bau = reopt_output['outputs']['ElectricTariff']['year_one_energy_cost_before_tax_bau'] || 0
210
+ scenario_report.distributed_generation.year_one_demand_cost_before_tax_bau = reopt_output['outputs']['ElectricTariff']['year_one_demand_cost_before_tax_bau'] || 0
211
+ scenario_report.distributed_generation.year_one_bill_before_tax_bau = reopt_output['outputs']['ElectricTariff']['year_one_bill_before_tax_bau'] || 0
212
+ scenario_report.distributed_generation.lifecycle_demand_cost_after_tax_bau = reopt_output['outputs']['ElectricTariff']['lifecycle_demand_cost_after_tax_bau'] || 0
213
+ scenario_report.distributed_generation.lifecycle_energy_cost_after_tax_bau = reopt_output['outputs']['ElectricTariff']['lifecycle_energy_cost_after_tax_bau'] || 0
226
214
  if !resilience_stats.nil?
227
215
  scenario_report.distributed_generation.resilience_hours_min = resilience_stats['resilience_hours_min']
228
216
  scenario_report.distributed_generation.resilience_hours_max = resilience_stats['resilience_hours_max']
@@ -232,10 +220,10 @@ module URBANopt # :nodoc:
232
220
  scenario_report.distributed_generation.probs_of_surviving_by_hour_of_the_day = resilience_stats['probs_of_surviving_by_hour_of_the_day']
233
221
  end
234
222
 
235
- if reopt_output['outputs']['Scenario']['Site']['PV'].instance_of?(Hash)
236
- reopt_output['outputs']['Scenario']['Site']['PV'] = [reopt_output['outputs']['Scenario']['Site']['PV']]
237
- elsif reopt_output['outputs']['Scenario']['Site']['PV'].nil?
238
- reopt_output['outputs']['Scenario']['Site']['PV'] = []
223
+ if reopt_output['outputs']['PV'].is_a?(Hash)
224
+ reopt_output['outputs']['PV'] = [reopt_output['outputs']['PV']]
225
+ elsif reopt_output['outputs']['PV'].nil?
226
+ reopt_output['outputs']['PV'] = []
239
227
  end
240
228
 
241
229
  # Store the PV name and location in a hash
@@ -245,81 +233,85 @@ module URBANopt # :nodoc:
245
233
  module_type = {}
246
234
  gcr = {}
247
235
  # Check whether multi PV assumption input file is used or single PV
248
- if reopt_output['inputs']['Scenario']['Site']['PV'].is_a?(Array)
249
- reopt_output['inputs']['Scenario']['Site']['PV'].each do |pv|
250
- location[pv['pv_name']] = pv['location']
251
- azimuth[pv['pv_name']] = pv['azimuth']
252
- tilt[pv['pv_name']] = pv['tilt']
253
- module_type[pv['pv_name']] = pv['module_type']
254
- gcr[pv['pv_name']] = pv['gcr']
255
- end
256
- else
257
- location[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['location']
258
- azimuth[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['azimuth']
259
- tilt[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['tilt']
260
- module_type[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['module_type']
261
- gcr[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['gcr']
262
- end
263
- pv_inputs = reopt_output['inputs']['Scenario']['Site']['PV']
264
- if pv_inputs.is_a?(Hash)
265
- pv_inputs = [pv_inputs]
266
- end
267
- pv_outputs = reopt_output['outputs']['Scenario']['Site']['PV']
268
- if pv_outputs.is_a?(Hash)
269
- pv_outputs = [pv_outputs]
270
- end
271
- pv_outputs.each_with_index do |pv, i|
272
- if pv_inputs[i]
273
- if pv_inputs[i]['tilt']
274
- tilt[pv['pv_name']] = pv_inputs[i]['tilt']
275
- end
276
- if pv_inputs[i]['azimuth']
277
- azimuth[pv['pv_name']] = pv_inputs[i]['azimuth']
236
+ if reopt_output['inputs'].key?('PV')
237
+ if reopt_output['inputs']['PV'].is_a?(Array)
238
+ reopt_output['inputs']['PV'].each do |pv|
239
+ location[pv['name']] = pv['location']
240
+ azimuth[pv['name']] = pv['azimuth']
241
+ tilt[pv['name']] = pv['tilt']
242
+ module_type[pv['name']] = pv['module_type']
243
+ gcr[pv['name']] = pv['gcr']
278
244
  end
279
- if pv_inputs[i]['module_type']
280
- module_type[pv['pv_name']] = pv_inputs[i]['module_type']
245
+ else
246
+ location[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['location']
247
+ azimuth[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['azimuth']
248
+ tilt[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['tilt']
249
+ module_type[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['module_type']
250
+ gcr[reopt_output['inputs']['PV']['name']] = reopt_output['inputs']['PV']['gcr']
251
+ end
252
+ pv_inputs = reopt_output['inputs']['PV']
253
+ if pv_inputs.is_a?(Hash)
254
+ pv_inputs = [pv_inputs]
255
+ end
256
+ pv_outputs = reopt_output['outputs']['PV']
257
+ if pv_outputs.is_a?(Hash)
258
+ pv_outputs = [pv_outputs]
259
+ end
260
+ pv_outputs.each_with_index do |pv, i|
261
+ if pv_inputs[i]
262
+ if pv_inputs[i]['tilt']
263
+ tilt[pv['name']] = pv_inputs[i]['tilt']
264
+ end
265
+ if pv_inputs[i]['azimuth']
266
+ azimuth[pv['name']] = pv_inputs[i]['azimuth']
267
+ end
268
+ if pv_inputs[i]['module_type']
269
+ module_type[pv['name']] = pv_inputs[i]['module_type']
270
+ end
281
271
  end
272
+ scenario_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['average_yearly_energy_produced_kwh'], azimuth: azimuth[pv['name']], tilt: tilt[pv['name']], module_type: module_type[pv['name']], gcr: gcr[pv['name']] })
282
273
  end
283
- scenario_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']] })
284
274
  end
285
275
 
286
- wind = reopt_output['outputs']['Scenario']['Site']['Wind']
287
- if !wind['size_kw'].nil? && (wind['size_kw'] != 0)
276
+ if reopt_output['outputs'].key?('Wind')
277
+ wind = reopt_output['outputs']['Wind']
288
278
  # find size_class
289
279
  size_class = nil
290
- if reopt_output['inputs']['Scenario']['Site']['Wind']['size_class']
291
- size_class = reopt_output['inputs']['Scenario']['Site']['Wind']['size_class']
280
+ if reopt_output['inputs']['Wind']['size_class']
281
+ size_class = reopt_output['inputs']['Wind']['size_class']
292
282
  else
293
283
  size_class = 'commercial' # default
294
284
  end
295
285
  scenario_report.distributed_generation.add_tech 'wind', URBANopt::Reporting::DefaultReports::Wind.new({ size_kw: (wind['size_kw'] || 0), size_class: size_class, average_yearly_energy_produced_kwh: (wind['average_yearly_energy_produced_kwh'] || 0) })
296
286
  end
297
287
 
298
- generator = reopt_output['outputs']['Scenario']['Site']['Generator']
299
- if !generator['size_kw'].nil? && (generator['size_kw'] != 0)
288
+ if reopt_output['outputs'].key?('Generator')
289
+ generator = reopt_output['outputs']['Generator']
300
290
  scenario_report.distributed_generation.add_tech 'generator', URBANopt::Reporting::DefaultReports::Generator.new({ size_kw: (generator['size_kw'] || 0) })
301
291
  end
302
292
 
303
- storage = reopt_output['outputs']['Scenario']['Site']['Storage']
304
- if !storage['size_kw'].nil? && (storage['size_kw'] != 0)
293
+ if reopt_output['outputs'].key?('ElectricStorage')
294
+ storage = reopt_output['outputs']['ElectricStorage']
305
295
  scenario_report.distributed_generation.add_tech 'storage', URBANopt::Reporting::DefaultReports::Storage.new({ size_kwh: (storage['size_kwh'] || 0), size_kw: (storage['size_kw'] || 0) })
306
296
  end
307
297
 
308
- reopt_resolution = reopt_output['inputs']['Scenario']['time_steps_per_hour']
298
+ reopt_resolution = reopt_output['inputs']['Settings']['time_steps_per_hour']
309
299
  generation_timeseries_kwh = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
310
300
 
311
- reopt_output['outputs']['Scenario']['Site']['PV'].each do |pv|
312
- if (pv['size_kw'] || 0) > 0 && !pv['year_one_power_production_series_kw'].nil?
313
- generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour)]
301
+ if reopt_output['outputs'].key?('PV') && !reopt_output['outputs']['PV'].nil?
302
+ reopt_output['outputs']['PV'].each do |pv|
303
+ if (pv['size_kw'] || 0) > 0 && !pv['year_one_power_production_series_kw'].nil?
304
+ generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour)]
305
+ end
314
306
  end
315
307
  end
316
308
 
317
- 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?
318
- generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour)]
309
+ 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?
310
+ generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Wind']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour)]
319
311
  end
320
312
 
321
- 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?
322
- generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour)]
313
+ 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?
314
+ generation_timeseries_kwh += Matrix[convert_powerflow_resolution(reopt_output['outputs']['Generator']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour)]
323
315
  end
324
316
 
325
317
  $generation_timeseries_kwh = generation_timeseries_kwh.to_a[0] || [0] * (8760 * scenario_report.timesteps_per_hour)
@@ -329,145 +321,188 @@ module URBANopt # :nodoc:
329
321
  scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Total(kw)')
330
322
  end
331
323
 
332
- $load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['LoadProfile']['year_one_electric_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
324
+ $load = convert_powerflow_resolution(reopt_output['outputs']['ElectricLoad']['year_one_electric_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
333
325
  $load_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Load:Total(kw)')
334
326
  if $load_col.nil?
335
327
  $load_col = scenario_report.timeseries_csv.column_names.length
336
328
  scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Load:Total(kw)')
337
329
  end
338
330
 
339
- $utility_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
331
+ $utility_to_load = convert_powerflow_resolution(reopt_output['outputs']['ElectricUtility']['electric_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
340
332
  $utility_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToLoad(kw)')
341
333
  if $utility_to_load_col.nil?
342
334
  $utility_to_load_col = scenario_report.timeseries_csv.column_names.length
343
335
  scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToLoad(kw)')
344
336
  end
345
337
 
346
- $utility_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['ElectricTariff']['year_one_to_battery_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
347
- $utility_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToBattery(kw)')
348
- if $utility_to_battery_col.nil?
349
- $utility_to_battery_col = scenario_report.timeseries_csv.column_names.length
350
- scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToBattery(kw)')
351
- end
338
+ if !storage.nil?
339
+ $utility_to_battery = convert_powerflow_resolution(reopt_output['outputs']['ElectricUtility']['electric_to_storage_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
340
+ $utility_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Grid:ToBattery(kw)')
341
+ if $utility_to_battery_col.nil?
342
+ $utility_to_battery_col = scenario_report.timeseries_csv.column_names.length
343
+ scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Grid:ToBattery(kw)')
344
+ end
352
345
 
353
- $storage_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
354
- $storage_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToLoad(kw)')
355
- if $storage_to_load_col.nil?
356
- $storage_to_load_col = scenario_report.timeseries_csv.column_names.length
357
- scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToLoad(kw)')
358
- end
346
+ $storage_to_load = convert_powerflow_resolution(reopt_output['outputs']['ElectricStorage']['storage_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
347
+ $storage_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToLoad(kw)')
348
+ if $storage_to_load_col.nil?
349
+ $storage_to_load_col = scenario_report.timeseries_csv.column_names.length
350
+ scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToLoad(kw)')
351
+ end
359
352
 
360
- $storage_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
361
- $storage_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToGrid(kw)')
362
- if $storage_to_grid_col.nil?
363
- $storage_to_grid_col = scenario_report.timeseries_csv.column_names.length
364
- scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToGrid(kw)')
365
- end
353
+ $storage_to_grid = convert_powerflow_resolution(reopt_output['outputs']['ElectricStorage']['electric_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
354
+ $storage_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:ToGrid(kw)')
355
+ if $storage_to_grid_col.nil?
356
+ $storage_to_grid_col = scenario_report.timeseries_csv.column_names.length
357
+ scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:ToGrid(kw)')
358
+ end
366
359
 
367
- $storage_soc = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Storage']['year_one_soc_series_pct'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
368
- $storage_soc_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:StateOfCharge(pct)')
369
- if $storage_soc_col.nil?
370
- $storage_soc_col = scenario_report.timeseries_csv.column_names.length
371
- scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:StateOfCharge(pct)')
360
+ $storage_soc = convert_powerflow_resolution(reopt_output['outputs']['ElectricStorage']['soc_series_fraction'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
361
+ $storage_soc_col = scenario_report.timeseries_csv.column_names.index('REopt:Electricity:Storage:StateOfCharge(pct)')
362
+ if $storage_soc_col.nil?
363
+ $storage_soc_col = scenario_report.timeseries_csv.column_names.length
364
+ scenario_report.timeseries_csv.column_names.push('REopt:Electricity:Storage:StateOfCharge(pct)')
365
+ end
372
366
  end
373
367
 
374
- $generator_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
375
- $generator_total_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:Total(kw)')
376
- if $generator_total_col.nil?
377
- $generator_total_col = scenario_report.timeseries_csv.column_names.length
378
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:Total(kw)')
379
- end
368
+ if !generator.nil?
369
+ # $generator_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
370
+ $generator_total_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:Total(kw)')
371
+ if $generator_total_col.nil?
372
+ $generator_total_col = scenario_report.timeseries_csv.column_names.length
373
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:Total(kw)')
374
+ end
380
375
 
381
- $generator_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_battery_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
382
- $generator_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToBattery(kw)')
383
- if $generator_to_battery_col.nil?
384
- $generator_to_battery_col = scenario_report.timeseries_csv.column_names.length
385
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToBattery(kw)')
386
- end
376
+ if !storage.nil?
377
+ $generator_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Generator']['electric_to_storage_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
378
+ $generator_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToBattery(kw)')
379
+ if $generator_to_battery_col.nil?
380
+ $generator_to_battery_col = scenario_report.timeseries_csv.column_names.length
381
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToBattery(kw)')
382
+ end
383
+ end
387
384
 
388
- $generator_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
389
- $generator_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToLoad(kw)')
390
- if $generator_to_load_col.nil?
391
- $generator_to_load_col = scenario_report.timeseries_csv.column_names.length
392
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToLoad(kw)')
393
- end
385
+ $generator_to_load = convert_powerflow_resolution(reopt_output['outputs']['Generator']['electric_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
386
+ $generator_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToLoad(kw)')
387
+ if $generator_to_load_col.nil?
388
+ $generator_to_load_col = scenario_report.timeseries_csv.column_names.length
389
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToLoad(kw)')
390
+ end
394
391
 
395
- $generator_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
396
- $generator_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToGrid(kw)')
397
- if $generator_to_grid_col.nil?
398
- $generator_to_grid_col = scenario_report.timeseries_csv.column_names.length
399
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToGrid(kw)')
392
+ $generator_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Generator']['electric_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
393
+ $generator_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Generator:ToGrid(kw)')
394
+ if $generator_to_grid_col.nil?
395
+ $generator_to_grid_col = scenario_report.timeseries_csv.column_names.length
396
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Generator:ToGrid(kw)')
397
+ end
400
398
  end
401
399
 
402
- $pv_total_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:Total(kw)')
403
- if $pv_total_col.nil?
404
- $pv_total_col = scenario_report.timeseries_csv.column_names.length
405
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:Total(kw)')
406
- end
400
+ if reopt_output['outputs'].key?('PV') && !reopt_output['outputs']['PV'].nil?
401
+ $pv_total_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:Total(kw)')
402
+ if $pv_total_col.nil?
403
+ $pv_total_col = scenario_report.timeseries_csv.column_names.length
404
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:Total(kw)')
405
+ end
407
406
 
408
- $pv_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToBattery(kw)')
409
- if $pv_to_battery_col.nil?
410
- $pv_to_battery_col = scenario_report.timeseries_csv.column_names.length
411
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToBattery(kw)')
412
- end
407
+ if !storage.nil?
408
+ $pv_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToBattery(kw)')
409
+ if $pv_to_battery_col.nil?
410
+ $pv_to_battery_col = scenario_report.timeseries_csv.column_names.length
411
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToBattery(kw)')
412
+ end
413
+ end
413
414
 
414
- $pv_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToLoad(kw)')
415
- if $pv_to_load_col.nil?
416
- $pv_to_load_col = scenario_report.timeseries_csv.column_names.length
417
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToLoad(kw)')
418
- end
415
+ $pv_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToLoad(kw)')
416
+ if $pv_to_load_col.nil?
417
+ $pv_to_load_col = scenario_report.timeseries_csv.column_names.length
418
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToLoad(kw)')
419
+ end
419
420
 
420
- $pv_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToGrid(kw)')
421
- if $pv_to_grid_col.nil?
422
- $pv_to_grid_col = scenario_report.timeseries_csv.column_names.length
423
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToGrid(kw)')
424
- end
421
+ $pv_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToGrid(kw)')
422
+ if $pv_to_grid_col.nil?
423
+ $pv_to_grid_col = scenario_report.timeseries_csv.column_names.length
424
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToGrid(kw)')
425
+ end
425
426
 
426
- $pv_total = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
427
- $pv_to_battery = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
428
- $pv_to_load = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
429
- $pv_to_grid = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
430
-
431
- reopt_output['outputs']['Scenario']['Site']['PV'].each_with_index do |pv, i|
432
- if (pv['size_kw'] || 0) > 0
433
- $pv_total += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
434
- $pv_to_battery += Matrix[convert_powerflow_resolution(pv['year_one_to_battery_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
435
- $pv_to_load += Matrix[convert_powerflow_resolution(pv['year_one_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
436
- $pv_to_grid += Matrix[convert_powerflow_resolution(pv['year_one_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
427
+ $pv_total = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
428
+ if !storage.nil?
429
+ $pv_to_battery = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
430
+ end
431
+ $pv_to_load = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
432
+ $pv_to_grid = Matrix[[0] * (8760 * scenario_report.timesteps_per_hour)]
433
+
434
+ reopt_output['outputs']['PV'].each_with_index do |pv, i|
435
+ if (pv['size_kw'] || 0) > 0
436
+ # $pv_total += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
437
+ if !storage.nil?
438
+ $pv_to_battery += Matrix[convert_powerflow_resolution(pv['electric_to_storage_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
439
+ end
440
+ $pv_to_load += Matrix[convert_powerflow_resolution(pv['electric_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
441
+ $pv_to_grid += Matrix[convert_powerflow_resolution(pv['electric_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)]
442
+ end
437
443
  end
444
+
445
+ $pv_total = $pv_total.to_a[0]
446
+ if !storage.nil?
447
+ $pv_to_battery = $pv_to_battery.to_a[0]
448
+ end
449
+ $pv_to_load = $pv_to_load.to_a[0]
450
+ $pv_to_grid = $pv_to_grid.to_a[0]
438
451
  end
439
452
 
440
- $pv_total = $pv_total.to_a[0]
441
- $pv_to_battery = $pv_to_battery.to_a[0]
442
- $pv_to_load = $pv_to_load.to_a[0]
443
- $pv_to_grid = $pv_to_grid.to_a[0]
453
+ if !wind.nil?
454
+ # $wind_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
455
+ $wind_total_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:Total(kw)')
456
+ if $wind_total_col.nil?
457
+ $wind_total_col = scenario_report.timeseries_csv.column_names.length
458
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:Total(kw)')
459
+ end
444
460
 
445
- $wind_total = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
446
- $wind_total_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:Total(kw)')
447
- if $wind_total_col.nil?
448
- $wind_total_col = scenario_report.timeseries_csv.column_names.length
449
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:Total(kw)')
450
- end
461
+ if !storage.nil?
462
+ $wind_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Wind']['electric_to_storage_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
463
+ $wind_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToBattery(kw)')
464
+ if $wind_to_battery_col.nil?
465
+ $wind_to_battery_col = scenario_report.timeseries_csv.column_names.length
466
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToBattery(kw)')
467
+ end
468
+ end
451
469
 
452
- $wind_to_battery = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_battery_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
453
- $wind_to_battery_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToBattery(kw)')
454
- if $wind_to_battery_col.nil?
455
- $wind_to_battery_col = scenario_report.timeseries_csv.column_names.length
456
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToBattery(kw)')
457
- end
470
+ $wind_to_load = convert_powerflow_resolution(reopt_output['outputs']['Wind']['electric_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
471
+ $wind_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToLoad(kw)')
472
+ if $wind_to_load_col.nil?
473
+ $wind_to_load_col = scenario_report.timeseries_csv.column_names.length
474
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToLoad(kw)')
475
+ end
458
476
 
459
- $wind_to_load = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_load_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
460
- $wind_to_load_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToLoad(kw)')
461
- if $wind_to_load_col.nil?
462
- $wind_to_load_col = scenario_report.timeseries_csv.column_names.length
463
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToLoad(kw)')
477
+ $wind_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Wind']['electric_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
478
+ $wind_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToGrid(kw)')
479
+ if $wind_to_grid_col.nil?
480
+ $wind_to_grid_col = scenario_report.timeseries_csv.column_names.length
481
+ scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToGrid(kw)')
482
+ end
464
483
  end
465
484
 
466
- $wind_to_grid = convert_powerflow_resolution(reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_to_grid_series_kw'], reopt_resolution, scenario_report.timesteps_per_hour) || [0] * (8760 * scenario_report.timesteps_per_hour)
467
- $wind_to_grid_col = scenario_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:Wind:ToGrid(kw)')
468
- if $wind_to_grid_col.nil?
469
- $wind_to_grid_col = scenario_report.timeseries_csv.column_names.length
470
- scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToGrid(kw)')
485
+ def modrow(data, idx) # :nodoc:
486
+ data[$generation_timeseries_kwh_col] = $generation_timeseries_kwh[idx] || 0
487
+ data[$load_col] = $load[idx] || 0
488
+ data[$utility_to_load_col] = $utility_to_load[idx] || 0
489
+ data[$utility_to_battery_col] = $utility_to_battery[idx] || 0 if defined?(storage)
490
+ data[$storage_to_load_col] = $storage_to_load[idx] || 0 if defined?(storage)
491
+ data[$storage_to_grid_col] = $storage_to_grid[idx] || 0 if defined?(storage)
492
+ data[$storage_soc_col] = $storage_soc[idx] || 0 if defined?(storage)
493
+ data[$generator_total_col] = $generator_total[idx] || 0 if defined?(generator)
494
+ data[$generator_to_battery_col] = $generator_to_battery[idx] || 0 if (defined?(generator) && defined?(storage))
495
+ data[$generator_to_load_col] = $generator_to_load[idx] || 0 if defined?(generator)
496
+ data[$generator_to_grid_col] = $generator_to_grid[idx] || 0 if defined?(generator)
497
+ data[$pv_total_col] = $pv_total[idx] || 0
498
+ data[$pv_to_battery_col] = $pv_to_battery[idx] || 0 if defined?(storage)
499
+ data[$pv_to_load_col] = $pv_to_load[idx] || 0
500
+ data[$pv_to_grid_col] = $pv_to_grid[idx] || 0
501
+ data[$wind_total_col] = $wind_total[idx] || 0 if defined?(wind)
502
+ data[$wind_to_battery_col] = $wind_to_battery[idx] || 0 if (defined?(wind) && defined?(storage))
503
+ data[$wind_to_load_col] = $wind_to_load[idx] || 0 if defined?(wind)
504
+ data[$wind_to_grid_col] = $wind_to_grid[idx] || 0 if defined?(wind)
505
+ return data
471
506
  end
472
507
 
473
508
  old_data = CSV.open(scenario_report.timeseries_csv.path).read