urbanopt-reopt 0.5.6 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/docs/package.json CHANGED
@@ -10,17 +10,24 @@
10
10
  },
11
11
  "author": "NREL",
12
12
  "dependencies": {
13
- "braces": "^3.0.2",
14
13
  "highlight.js": "^10.4.1",
15
14
  "json-schema-ref-parser": "^6.1.0",
16
15
  "json-schema-view-js": "git+https://git@github.com/bgschiller/json-schema-view-js.git",
17
- "serialize-javascript": "^5.0.1",
18
- "vuepress": "^1.6.0",
19
- "webpack-dev-middleware": "^3.6.0",
20
- "yargs-parser": "^18.1.1"
16
+ "webpack-dev-middleware": "^3.6.0"
21
17
  },
22
18
  "devDependencies": {
19
+ "braces": "^3.0.2",
20
+ "chokidar": ">=3.5.1",
21
+ "fsevents": ">=2.3.2",
23
22
  "gh-pages": "^2.0.1",
24
- "ini": "^2.0.0"
23
+ "ini": "^2.0.0",
24
+ "is-svg": "4.3.1",
25
+ "lodash": "^4.17.21",
26
+ "postcss": "^8.2.15",
27
+ "serialize-javascript": "^5.0.1",
28
+ "ssri": "8.0.1",
29
+ "url-parse": "^1.5.1",
30
+ "vuepress": "^1.8.2",
31
+ "yargs-parser": "^18.1.1"
25
32
  }
26
33
  }
@@ -68,7 +68,7 @@ module URBANopt # :nodoc:
68
68
  #
69
69
  # [*return:*] _Hash_ - Returns hash formatted for submittal to the \REopt Lite API
70
70
  ##
71
- def reopt_json_from_feature_report(feature_report, reopt_assumptions_hash = nil)
71
+ def reopt_json_from_feature_report(feature_report, reopt_assumptions_hash = nil, groundmount_photovoltaic = nil)
72
72
  name = feature_report.name.delete ' '
73
73
  description = "feature_report_#{name}_#{feature_report.id}"
74
74
  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 } } } }
@@ -99,15 +99,21 @@ module URBANopt # :nodoc:
99
99
  reopt_inputs[:Scenario][:Site][:longitude] = feature_report.location.longitude_deg
100
100
 
101
101
  # Parse Optional FeatureReport metrics - do not overwrite from assumptions file
102
- if reopt_inputs[:Scenario][:Site][:roof_squarefeet].nil?
103
- unless feature_report.program.roof_area_sqft.nil?
104
- reopt_inputs[:Scenario][:Site][:roof_squarefeet] = feature_report.program.roof_area_sqft[:available_roof_area_sqft]
105
- end
102
+ if reopt_inputs[:Scenario][:Site][:roof_squarefeet].nil? && !feature_report.program.roof_area_sqft.nil?
103
+ reopt_inputs[:Scenario][:Site][:roof_squarefeet] = feature_report.program.roof_area_sqft[:available_roof_area_sqft]
106
104
  end
107
105
 
108
106
  if reopt_inputs[:Scenario][:Site][:land_acres].nil?
109
- unless feature_report.program.site_area_sqft.nil?
110
- reopt_inputs[:Scenario][:Site][:land_acres] = feature_report.program.site_area_sqft * 1.0 / 43560 # acres/sqft
107
+ # Check if ground-mount PV is specified with the Feature ID and take footprint area of PV
108
+ # constrain for REopt optimization
109
+ begin
110
+ if !groundmount_photovoltaic[feature_report.id].nil?
111
+ reopt_inputs[:Scenario][:Site][:land_acres] = groundmount_photovoltaic[feature_report.id] * 1.0 / 43560 # acres/sqft
112
+ # If no ground-mount PV associated with feature use site area as constrain for REopt optimization
113
+ elsif !feature_report.program.site_area_sqft.nil?
114
+ reopt_inputs[:Scenario][:Site][:land_acres] = feature_report.program.site_area_sqft * 1.0 / 43560 # acres/sqft
115
+ end
116
+ rescue StandardError
111
117
  end
112
118
  end
113
119
 
@@ -117,23 +123,23 @@ module URBANopt # :nodoc:
117
123
 
118
124
  # Parse Load Profile
119
125
  begin
120
- #Convert kWh values in the timeseries CSV to kW
126
+ # Convert kWh values in the timeseries CSV to kW
121
127
  col_num = feature_report.timeseries_csv.column_names.index('Electricity:Facility(kWh)')
122
128
  t = CSV.read(feature_report.timeseries_csv.path, headers: true, converters: :numeric)
123
- energy_timeseries_kw = t.by_col[col_num].map { |e| ((e * feature_report.timesteps_per_hour || 0) ) }
124
- #Fill in missing timestep values with 0 if a full year is not provided
129
+ energy_timeseries_kw = t.by_col[col_num].map { |e| ((e * feature_report.timesteps_per_hour || 0)) }
130
+ # Fill in missing timestep values with 0 if a full year is not provided
125
131
  if energy_timeseries_kw.length < (feature_report.timesteps_per_hour * 8760)
126
- start_date = Time.parse(t.by_col["Datetime"][0])
132
+ start_date = Time.parse(t.by_col['Datetime'][0])
127
133
  start_ts = (((start_date.yday * 60.0 * 60.0 * 24) + (start_date.hour * 60.0 * 60.0) + (start_date.min * 60.0) + start_date.sec) /
128
- (( 60 / feature_report.timesteps_per_hour ) * 60)).to_int
129
- end_date = Time.parse(t.by_col["Datetime"][-1])
134
+ ((60 / feature_report.timesteps_per_hour) * 60)).to_int
135
+ end_date = Time.parse(t.by_col['Datetime'][-1])
130
136
  end_ts = (((end_date.yday * 60.0 * 60.0 * 24) + (end_date.hour * 60.0 * 60.0) + (end_date.min * 60.0) + end_date.sec) /
131
- (( 60 / feature_report.timesteps_per_hour ) * 60)).to_int
132
- energy_timeseries_kw = [0.0]*(start_ts-1) + energy_timeseries_kw + [0.0]*((feature_report.timesteps_per_hour * 8760) - end_ts)
137
+ ((60 / feature_report.timesteps_per_hour) * 60)).to_int
138
+ energy_timeseries_kw = [0.0] * (start_ts - 1) + energy_timeseries_kw + [0.0] * ((feature_report.timesteps_per_hour * 8760) - end_ts)
133
139
  end
134
- #Clip to one non-leap year's worth of data
135
- energy_timeseries_kw = energy_timeseries_kw.map { |e| e ? e : 0 }[0,(feature_report.timesteps_per_hour * 8760)]
136
- #Convert from the OpenDSS resolution to the REopt Lite resolution, if necessary
140
+ # Clip to one non-leap year's worth of data
141
+ energy_timeseries_kw = energy_timeseries_kw.map { |e| e || 0 }[0, (feature_report.timesteps_per_hour * 8760)]
142
+ # Convert from the OpenDSS resolution to the REopt Lite resolution, if necessary
137
143
  rescue StandardError
138
144
  @@logger.error("Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}")
139
145
  raise "Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}"
@@ -142,8 +148,7 @@ module URBANopt # :nodoc:
142
148
  # Convert load to REopt Resolution
143
149
  begin
144
150
  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])
145
-
146
- rescue
151
+ rescue StandardError
147
152
  @@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]}")
148
153
  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]}"
149
154
  end
@@ -151,9 +156,9 @@ module URBANopt # :nodoc:
151
156
  if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps].nil?
152
157
  n_top_values = 100
153
158
  tmp1 = reopt_inputs[:Scenario][:Site][:LoadProfile][:loads_kw]
154
- tmp2 = tmp1.each_index.max_by(n_top_values*reopt_inputs[:Scenario][:time_steps_per_hour]){|i| tmp1[i]}
159
+ tmp2 = tmp1.each_index.max_by(n_top_values * reopt_inputs[:Scenario][:time_steps_per_hour]) { |i| tmp1[i] }
155
160
  for i in (0...tmp2.count)
156
- tmp2[i] += 1
161
+ tmp2[i] += 1
157
162
  end
158
163
  reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps] = tmp2
159
164
  end
@@ -165,7 +170,6 @@ module URBANopt # :nodoc:
165
170
  return reopt_inputs
166
171
  end
167
172
 
168
-
169
173
  ##
170
174
  # Update a FeatureReport from a \REopt Lite response
171
175
  #
@@ -177,7 +181,7 @@ module URBANopt # :nodoc:
177
181
  #
178
182
  # [*return:*] _URBANopt::Reporting::DefaultReports::FeatureReport_ - Returns an updated FeatureReport.
179
183
  ##
180
- def update_feature_report(feature_report, reopt_output, timeseries_csv_path=nil, resilience_stats=nil)
184
+ def update_feature_report(feature_report, reopt_output, timeseries_csv_path = nil, resilience_stats = nil)
181
185
  # Check if the \REopt Lite response is valid
182
186
  if reopt_output['outputs']['Scenario']['status'] != 'optimal'
183
187
  @@logger.info("Warning cannot Feature Report #{feature_report.name} #{feature_report.id} - REopt optimization was non-optimal")
@@ -210,29 +214,40 @@ module URBANopt # :nodoc:
210
214
  feature_report.distributed_generation.probs_of_surviving_by_hour_of_the_day = resilience_stats['probs_of_surviving_by_hour_of_the_day']
211
215
  end
212
216
 
213
- if reopt_output['outputs']['Scenario']['Site']['PV'].class == Hash
217
+ if reopt_output['outputs']['Scenario']['Site']['PV'].instance_of?(Hash)
214
218
  reopt_output['outputs']['Scenario']['Site']['PV'] = [reopt_output['outputs']['Scenario']['Site']['PV']]
215
219
  elsif reopt_output['outputs']['Scenario']['Site']['PV'].nil?
216
220
  reopt_output['outputs']['Scenario']['Site']['PV'] = []
217
221
  end
218
222
 
223
+ # Store the PV name and location in a hash
224
+ location = {}
225
+ # Check whether multi PV assumption input file is used or single PV
226
+ if reopt_output['inputs']['Scenario']['Site']['PV'].is_a?(Array)
227
+ reopt_output['inputs']['Scenario']['Site']['PV'].each do |pv|
228
+ location[pv['pv_name']] = pv['location']
229
+ end
230
+ else
231
+ location[reopt_output['inputs']['Scenario']['Site']['PV']['pv_name']] = reopt_output['inputs']['Scenario']['Site']['PV']['location']
232
+ end
233
+
219
234
  reopt_output['outputs']['Scenario']['Site']['PV'].each_with_index do |pv, i|
220
- feature_report.distributed_generation.add_tech 'solar_pv', URBANopt::Reporting::DefaultReports::SolarPV.new( {size_kw: (pv['size_kw'] || 0), id: i })
235
+ 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']] })
221
236
  end
222
237
 
223
238
  wind = reopt_output['outputs']['Scenario']['Site']['Wind']
224
- if !wind['size_kw'].nil? and wind['size_kw'] != 0
225
- feature_report.distributed_generation.add_tech 'wind', URBANopt::Reporting::DefaultReports::Wind.new( {size_kw: (wind['size_kw'] || 0) })
239
+ if !wind['size_kw'].nil? && (wind['size_kw'] != 0)
240
+ feature_report.distributed_generation.add_tech 'wind', URBANopt::Reporting::DefaultReports::Wind.new({ size_kw: (wind['size_kw'] || 0) })
226
241
  end
227
242
 
228
243
  generator = reopt_output['outputs']['Scenario']['Site']['Generator']
229
- if !generator['size_kw'].nil? and generator['size_kw'] != 0
230
- feature_report.distributed_generation.add_tech 'generator', URBANopt::Reporting::DefaultReports::Generator.new( {size_kw: (generator['size_kw'] || 0) })
244
+ if !generator['size_kw'].nil? && (generator['size_kw'] != 0)
245
+ feature_report.distributed_generation.add_tech 'generator', URBANopt::Reporting::DefaultReports::Generator.new({ size_kw: (generator['size_kw'] || 0) })
231
246
  end
232
247
 
233
248
  storage = reopt_output['outputs']['Scenario']['Site']['Storage']
234
- if !storage['size_kw'].nil? and storage['size_kw'] != 0
235
- feature_report.distributed_generation.add_tech 'storage', URBANopt::Reporting::DefaultReports::Storage.new( {size_kwh: (storage['size_kwh'] || 0), size_kw: (storage['size_kw'] || 0) })
249
+ if !storage['size_kw'].nil? && (storage['size_kw'] != 0)
250
+ feature_report.distributed_generation.add_tech 'storage', URBANopt::Reporting::DefaultReports::Storage.new({ size_kwh: (storage['size_kwh'] || 0), size_kw: (storage['size_kw'] || 0) })
236
251
  end
237
252
 
238
253
  generation_timeseries_kwh = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
@@ -240,28 +255,18 @@ module URBANopt # :nodoc:
240
255
 
241
256
  unless reopt_output['outputs']['Scenario']['Site']['PV'].nil?
242
257
  reopt_output['outputs']['Scenario']['Site']['PV'].each do |pv|
243
- if (pv['size_kw'] || 0) > 0
244
- if !pv['year_one_power_production_series_kw'].nil?
245
- generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
246
- end
258
+ if (pv['size_kw'] || 0) > 0 && !pv['year_one_power_production_series_kw'].nil?
259
+ generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
247
260
  end
248
- end
261
+ end
249
262
  end
250
263
 
251
- unless reopt_output['outputs']['Scenario']['Site']['Wind'].nil?
252
- if (reopt_output['outputs']['Scenario']['Site']['Wind']['size_kw'] || 0) > 0
253
- if !reopt_output['outputs']['Scenario']['Site']['Wind']['year_one_power_production_series_kw'].nil?
254
- 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)]
255
- end
256
- end
264
+ 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?
265
+ 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
266
  end
258
267
 
259
- unless reopt_output['outputs']['Scenario']['Site']['Generator'].nil?
260
- if (reopt_output['outputs']['Scenario']['Site']['Generator']['size_kw'] || 0) > 0
261
- if !reopt_output['outputs']['Scenario']['Site']['Generator']['year_one_power_production_series_kw'].nil?
262
- 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)]
263
- end
264
- end
268
+ 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?
269
+ 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)]
265
270
  end
266
271
 
267
272
  $generation_timeseries_kwh = generation_timeseries_kwh.to_a[0] || [0] * (8760 * feature_report.timesteps_per_hour)
@@ -359,7 +364,6 @@ module URBANopt # :nodoc:
359
364
  feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToLoad(kw)')
360
365
  end
361
366
 
362
-
363
367
  $pv_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToGrid(kw)')
364
368
  if $pv_to_grid_col.nil?
365
369
  $pv_to_grid_col = feature_report.timeseries_csv.column_names.length
@@ -441,14 +445,14 @@ module URBANopt # :nodoc:
441
445
  start_ts = (
442
446
  (
443
447
  ((start_date.yday - 1) * 60.0 * 60.0 * 24) +
444
- (((start_date.hour) - 1) * 60.0 * 60.0) +
445
- (start_date.min * 60.0) + start_date.sec ) /
446
- (( 60 / feature_report.timesteps_per_hour ) * 60)
448
+ ((start_date.hour - 1) * 60.0 * 60.0) +
449
+ (start_date.min * 60.0) + start_date.sec) /
450
+ ((60 / feature_report.timesteps_per_hour) * 60)
447
451
  ).to_int
448
452
 
449
453
  mod_data = old_data.map.with_index do |x, i|
450
454
  if i > 0
451
- modrow(x, start_ts + i -1)
455
+ modrow(x, start_ts + i - 1)
452
456
  else
453
457
  x
454
458
  end
@@ -97,6 +97,7 @@ module URBANopt # :nodoc:
97
97
  if @use_localhost
98
98
  return URI.parse("http://127.0.0.1:8000/v1/job/#{run_uuid}/results")
99
99
  end
100
+
100
101
  return URI.parse("https://developer.nrel.gov/api/reopt/v1/job/#{run_uuid}/results?api_key=#{@nrel_developer_key}")
101
102
  end
102
103
 
@@ -114,6 +115,7 @@ module URBANopt # :nodoc:
114
115
  if @use_localhost
115
116
  return URI.parse("http://127.0.0.1:8000/v1/job/#{run_uuid}/resilience_stats")
116
117
  end
118
+
117
119
  return URI.parse("https://developer.nrel.gov/api/reopt/v1/job/#{run_uuid}/resilience_stats?api_key=#{@nrel_developer_key}")
118
120
  end
119
121
 
@@ -122,11 +124,34 @@ module URBANopt # :nodoc:
122
124
  tries = 0
123
125
  while tries < max_tries
124
126
  begin
125
- result = http.request(r)
126
- tries = 4
127
- rescue StandardError
128
- tries += 1
129
- end
127
+ result = http.request(r)
128
+ # Result codes sourced from https://developer.nrel.gov/docs/errors/
129
+ if result.code == '429'
130
+ @@logger.fatal('Exceeded the REopt-Lite API limit of 300 requests per hour')
131
+ puts 'Using the URBANopt CLI to submit a Scenario optimization counts as one request per scenario'
132
+ puts 'Using the URBANopt CLI to submit a Feature optimization counts as one request per feature'
133
+ abort('Please wait and try again once the time period has elapsed. The URBANopt CLI flag --reopt-keep-existing can be used to resume the optimization')
134
+ elsif (result.code != '201') && (result.code != '200') # Anything in the 200s is success
135
+ @@logger.debug("REopt-Lite has returned a '#{result.code}' status code. Visit https://developer.nrel.gov/docs/errors/ for more status code information")
136
+ # display error messages
137
+ json_res = JSON.parse(result.body, allow_nan: true)
138
+ json_res['messages'].delete('warnings') if json_res['messages']['warnings']
139
+ json_res['messages'].delete('Deprecations') if json_res['messages']['Deprecations']
140
+ if json_res['messages']
141
+ @@logger.error("MESSAGES: #{json_res['messages']}")
142
+ end
143
+ end
144
+ tries = max_tries
145
+ rescue StandardError => e
146
+ @@logger.debug("error from REopt lite API: #{e}")
147
+ if tries + 1 < max_tries
148
+ @@logger.debug('trying again...')
149
+ else
150
+ @@logger.debug('max tries reached!')
151
+ return
152
+ end
153
+ tries += 1
154
+ end
130
155
  end
131
156
  return result
132
157
  end
@@ -148,11 +173,11 @@ module URBANopt # :nodoc:
148
173
  http.use_ssl = true
149
174
  end
150
175
 
151
- request = Net::HTTP::Post.new(@uri_submit, header)
152
- request.body = ::JSON.generate(data, allow_nan: true)
176
+ post_request = Net::HTTP::Post.new(@uri_submit, header)
177
+ post_request.body = ::JSON.generate(data, allow_nan: true)
153
178
 
154
179
  # Send the request
155
- response = make_request(http, request)
180
+ response = make_request(http, post_request)
156
181
 
157
182
  if !response.is_a?(Net::HTTPSuccess)
158
183
  @@logger.error('Check_connection Failed')
@@ -175,7 +200,6 @@ module URBANopt # :nodoc:
175
200
  # [*return:*] _Bool_ - Returns true if the post succeeeds. Otherwise returns false.
176
201
  ##
177
202
  def resilience_request(run_uuid, filename)
178
-
179
203
  if File.directory? filename
180
204
  if run_uuid.nil?
181
205
  run_uuid = 'error'
@@ -187,54 +211,59 @@ module URBANopt # :nodoc:
187
211
  @@logger.info("REopt results saved to #{filename}")
188
212
  end
189
213
 
190
- #Submit Job
214
+ # Submit Job
191
215
  @@logger.info("Submitting Resilience Statistics job for #{run_uuid}")
192
216
  header = { 'Content-Type' => 'application/json' }
193
217
  http = Net::HTTP.new(@uri_submit_outagesimjob.host, @uri_submit_outagesimjob.port)
194
218
  if !@use_localhost
195
219
  http.use_ssl = true
196
220
  end
197
- request = Net::HTTP::Post.new(@uri_submit_outagesimjob, header)
198
- request.body = ::JSON.generate({"run_uuid" => run_uuid, "bau" => false }, allow_nan: true)
199
- submit_response = make_request(http, request)
200
- @@logger.info(submit_response.body)
221
+ post_request = Net::HTTP::Post.new(@uri_submit_outagesimjob, header)
222
+ post_request.body = ::JSON.generate({ 'run_uuid' => run_uuid, 'bau' => false }, allow_nan: true)
223
+ submit_response = make_request(http, post_request)
224
+ @@logger.debug(submit_response.body)
201
225
 
202
- #Fetch Results
226
+ # Fetch Results
203
227
  uri = uri_resilience(run_uuid)
204
228
  http = Net::HTTP.new(uri.host, uri.port)
205
229
  if !@use_localhost
206
230
  http.use_ssl = true
207
231
  end
208
232
 
233
+ # Wait a few seconds for the REopt database to update before GETing results
234
+ sleep 5
235
+ get_request = Net::HTTP::Get.new(uri.request_uri)
236
+ response = make_request(http, get_request, 8)
237
+
238
+ # Set a limit on retries when 404s are returned from REopt API
209
239
  elapsed_time = 0
210
240
  max_elapsed_time = 60 * 5
211
241
 
212
- request = Net::HTTP::Get.new(uri.request_uri)
213
- response = make_request(http, request)
214
-
215
- while (elapsed_time < max_elapsed_time) & (response.code == "404")
216
- response = make_request(http, request)
242
+ # If database still hasn't updated, wait a little longer and try again
243
+ while (elapsed_time < max_elapsed_time) & (response.code == '404')
244
+ response = make_request(http, get_request)
245
+ @@logger.warn('GET request was too fast for REOpt-Lite API. Retrying...')
217
246
  elapsed_time += 5
218
247
  sleep 5
219
248
  end
220
249
 
221
- data = JSON.parse(response.body)
222
- text = ::JSON.generate(data, allow_nan: true)
250
+ data = JSON.parse(response.body, allow_nan: true)
251
+ text = JSON.pretty_generate(data)
223
252
  begin
224
253
  File.open(filename, 'w+') do |f|
225
254
  f.puts(text)
226
255
  end
227
- rescue
228
- @@logger.info("Cannot write - #{filename}")
256
+ rescue StandardError => e
257
+ @@logger.error("Cannot write - #{filename}")
258
+ @@logger.error("ERROR: #{e}")
229
259
  end
230
260
 
231
- if response.code == "200"
261
+ if response.code == '200'
232
262
  return data
233
263
  end
234
264
 
235
- @@logger.info("Error from REopt API - #{data['Error']}")
265
+ @@logger.error("Error from REopt API - #{data['Error']}")
236
266
  return {}
237
-
238
267
  end
239
268
 
240
269
  ##
@@ -261,14 +290,18 @@ module URBANopt # :nodoc:
261
290
  if !@use_localhost
262
291
  http.use_ssl = true
263
292
  end
264
- request = Net::HTTP::Post.new(@uri_submit, header)
265
- request.body = ::JSON.generate(reopt_input, allow_nan: true)
293
+ post_request = Net::HTTP::Post.new(@uri_submit, header)
294
+ post_request.body = ::JSON.generate(reopt_input, allow_nan: true)
266
295
 
267
296
  # Send the request
268
- response = make_request(http, request)
297
+ response = make_request(http, post_request)
298
+ if !response.is_a?(Net::HTTPSuccess)
299
+ @@logger.error('make_request Failed')
300
+ raise 'Check_connection Failed'
301
+ end
269
302
 
270
303
  # Get UUID
271
- run_uuid = JSON.parse(response.body, allow_nan:true)['run_uuid']
304
+ run_uuid = JSON.parse(response.body, allow_nan: true)['run_uuid']
272
305
 
273
306
  if File.directory? filename
274
307
  if run_uuid.nil?
@@ -281,12 +314,11 @@ module URBANopt # :nodoc:
281
314
  @@logger.info("REopt results saved to #{filename}")
282
315
  end
283
316
 
284
- text = ::JSON.generate(response.body, allow_nan: true)
317
+ text = JSON.parse(response.body, allow_nan: true)
285
318
  if response.code != '201'
286
319
  File.open(filename, 'w+') do |f|
287
- f.puts(text)
320
+ f.puts(JSON.pretty_generate(text))
288
321
  end
289
- @@logger.info("Cannot write - #{filename}")
290
322
  raise "Error in REopt optimization post - see #{filename}"
291
323
  end
292
324
 
@@ -298,17 +330,17 @@ module URBANopt # :nodoc:
298
330
  http.use_ssl = true
299
331
  end
300
332
 
301
- request = Net::HTTP::Get.new(uri.request_uri)
333
+ get_request = Net::HTTP::Get.new(uri.request_uri)
302
334
 
303
335
  while status == 'Optimizing...'
304
- response = make_request(http, request)
336
+ response = make_request(http, get_request)
305
337
 
306
- data = JSON.parse(response.body, allow_nan:true)
338
+ data = JSON.parse(response.body, allow_nan: true)
307
339
 
308
- if data['outputs']['Scenario']['Site']['PV'].kind_of?(Array)
340
+ if data['outputs']['Scenario']['Site']['PV'].is_a?(Array)
309
341
  pv_sizes = 0
310
342
  data['outputs']['Scenario']['Site']['PV'].each do |x|
311
- pv_sizes = pv_sizes + x['size_kw'].to_f
343
+ pv_sizes += x['size_kw'].to_f
312
344
  end
313
345
  else
314
346
  pv_sizes = data['outputs']['Scenario']['Site']['PV']['size_kw'] || 0
@@ -323,13 +355,13 @@ module URBANopt # :nodoc:
323
355
  _tries = 0
324
356
  (check_complete = sizes == 0) && ((data['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0) > 0)
325
357
  while (_tries < _max_retry) && check_complete
326
- sleep 1
327
- response = make_request(http, request)
328
- data = JSON.parse(response.body, allow_nan:true)
329
- if data['outputs']['Scenario']['Site']['PV'].kind_of?(Array)
358
+ sleep 3
359
+ response = make_request(http, get_request)
360
+ data = JSON.parse(response.body, allow_nan: true)
361
+ if data['outputs']['Scenario']['Site']['PV'].is_a?(Array)
330
362
  pv_sizes = 0
331
363
  data['outputs']['Scenario']['Site']['PV'].each do |x|
332
- pv_sizes = pv_sizes + x['size_kw'].to_f
364
+ pv_sizes += x['size_kw'].to_f
333
365
  end
334
366
  else
335
367
  pv_sizes = data['outputs']['Scenario']['Site']['PV']['size_kw'] || 0
@@ -339,14 +371,14 @@ module URBANopt # :nodoc:
339
371
  _tries += 1
340
372
  end
341
373
 
342
- data = JSON.parse(response.body)
343
- text = ::JSON.generate(data, allow_nan: true)
374
+ data = JSON.parse(response.body, allow_nan: true)
375
+ text = JSON.pretty_generate(data)
344
376
  begin
345
377
  File.open(filename, 'w+') do |f|
346
378
  f.puts(text)
347
379
  end
348
- rescue
349
- @@logger.info("Cannot write - #{filename}")
380
+ rescue StandardError
381
+ @@logger.error("Cannot write - #{filename}")
350
382
  end
351
383
 
352
384
  if status == 'optimal'
@@ -42,7 +42,7 @@ require 'logger'
42
42
 
43
43
  module URBANopt
44
44
  module REopt
45
- @@reopt_logger = Logger.new(STDOUT)
45
+ @@reopt_logger = Logger.new($stdout)
46
46
  ##
47
47
  # Definining class variable "@@logger" to log errors, info and warning messages.
48
48
  def self.reopt_logger