urbanopt-reopt 0.6.0 → 0.6.1
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -2
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -1
- data/Rakefile +2 -2
- data/lib/urbanopt/reopt/feature_report_adapter.rb +38 -55
- data/lib/urbanopt/reopt/reopt_lite_api.rb +56 -42
- data/lib/urbanopt/reopt/reopt_logger.rb +1 -1
- data/lib/urbanopt/reopt/reopt_post_processor.rb +72 -47
- data/lib/urbanopt/reopt/scenario/reopt_scenario_csv.rb +7 -7
- data/lib/urbanopt/reopt/scenario_report_adapter.rb +46 -63
- data/lib/urbanopt/reopt/utilities.rb +106 -106
- data/lib/urbanopt/reopt/version.rb +1 -1
- data/urbanopt-reopt.gemspec +2 -5
- metadata +10 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 219ca91a5d19e9bb7e556b82795b1c6d8585ff114a315e684d90877a955f0d77
|
4
|
+
data.tar.gz: d3176067f1c7621d242285404274e932ee03cf4cef4520565321f23ca21d866b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b535f5094280f785bc86172528931011f1dba89cbc8c5b3673e6452aea093f7add85bf9b2ef94ab8db960d39c26b71c2edd7d0742f8f6ef3c405c24bcb67a745
|
7
|
+
data.tar.gz: 4052393e76b6b15077dc7b24c5654aa7dc74d69482d31fdf472c6a7ddf1c98dd1f9202b17adb3e964879a6c193450bd88843047a557ce936e4c78d1bc2c21dda
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# URBANopt REopt Gem
|
2
2
|
|
3
|
+
## Version 0.6.1
|
4
|
+
|
5
|
+
Date Range: 04/30/21 - 06/30/21:
|
6
|
+
* Fixed [#83]( https://github.com/urbanopt/urbanopt-reopt-gem/issues/83 ), reopt rate-limit error is hard to decipher
|
7
|
+
* Fixed [#84]( https://github.com/urbanopt/urbanopt-reopt-gem/pull/84 ), Api error codes
|
8
|
+
* Fixed [#86]( https://github.com/urbanopt/urbanopt-reopt-gem/pull/86 ), update rubocop configs to v4
|
9
|
+
|
3
10
|
## Version 0.6.0
|
4
11
|
Date Range: 4/16/21 - 4/29/21
|
5
12
|
|
data/Gemfile
CHANGED
@@ -53,4 +53,4 @@ allow_local = ENV['FAVOR_LOCAL_GEMS']
|
|
53
53
|
# gem 'urbanopt-geojson', github: 'URBANopt/urbanopt-geojson-gem', branch: 'develop'
|
54
54
|
# end
|
55
55
|
|
56
|
-
# gem 'urbanopt-reporting', github: 'URBANopt/urbanopt-reporting-gem', branch: 'develop'
|
56
|
+
# gem 'urbanopt-reporting', github: 'URBANopt/urbanopt-reporting-gem', branch: 'develop'
|
data/Rakefile
CHANGED
@@ -99,16 +99,12 @@ 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
|
-
|
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
|
-
if reopt_inputs[:Scenario][:Site][:land_acres].nil?
|
109
|
-
|
110
|
-
reopt_inputs[:Scenario][:Site][:land_acres] = feature_report.program.site_area_sqft * 1.0 / 43560 # acres/sqft
|
111
|
-
end
|
106
|
+
if reopt_inputs[:Scenario][:Site][:land_acres].nil? && !feature_report.program.site_area_sqft.nil?
|
107
|
+
reopt_inputs[:Scenario][:Site][:land_acres] = feature_report.program.site_area_sqft * 1.0 / 43560 # acres/sqft
|
112
108
|
end
|
113
109
|
|
114
110
|
if reopt_inputs[:Scenario][:time_steps_per_hour].nil?
|
@@ -117,23 +113,23 @@ module URBANopt # :nodoc:
|
|
117
113
|
|
118
114
|
# Parse Load Profile
|
119
115
|
begin
|
120
|
-
#Convert kWh values in the timeseries CSV to kW
|
116
|
+
# Convert kWh values in the timeseries CSV to kW
|
121
117
|
col_num = feature_report.timeseries_csv.column_names.index('Electricity:Facility(kWh)')
|
122
118
|
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
|
119
|
+
energy_timeseries_kw = t.by_col[col_num].map { |e| ((e * feature_report.timesteps_per_hour || 0)) }
|
120
|
+
# Fill in missing timestep values with 0 if a full year is not provided
|
125
121
|
if energy_timeseries_kw.length < (feature_report.timesteps_per_hour * 8760)
|
126
|
-
start_date = Time.parse(t.by_col[
|
122
|
+
start_date = Time.parse(t.by_col['Datetime'][0])
|
127
123
|
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
|
-
((
|
129
|
-
end_date = Time.parse(t.by_col[
|
124
|
+
((60 / feature_report.timesteps_per_hour) * 60)).to_int
|
125
|
+
end_date = Time.parse(t.by_col['Datetime'][-1])
|
130
126
|
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
|
-
((
|
132
|
-
energy_timeseries_kw = [0.0]*(start_ts-1) + energy_timeseries_kw + [0.0]*((feature_report.timesteps_per_hour * 8760) - end_ts)
|
127
|
+
((60 / feature_report.timesteps_per_hour) * 60)).to_int
|
128
|
+
energy_timeseries_kw = [0.0] * (start_ts - 1) + energy_timeseries_kw + [0.0] * ((feature_report.timesteps_per_hour * 8760) - end_ts)
|
133
129
|
end
|
134
|
-
#Clip to one non-leap year's worth of data
|
135
|
-
energy_timeseries_kw = energy_timeseries_kw.map { |e| e
|
136
|
-
#Convert from the OpenDSS resolution to the REopt Lite resolution, if necessary
|
130
|
+
# Clip to one non-leap year's worth of data
|
131
|
+
energy_timeseries_kw = energy_timeseries_kw.map { |e| e || 0 }[0, (feature_report.timesteps_per_hour * 8760)]
|
132
|
+
# Convert from the OpenDSS resolution to the REopt Lite resolution, if necessary
|
137
133
|
rescue StandardError
|
138
134
|
@@logger.error("Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}")
|
139
135
|
raise "Could not parse the annual electric load from the timeseries csv - #{feature_report.timeseries_csv.path}"
|
@@ -142,8 +138,7 @@ module URBANopt # :nodoc:
|
|
142
138
|
# Convert load to REopt Resolution
|
143
139
|
begin
|
144
140
|
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
|
141
|
+
rescue StandardError
|
147
142
|
@@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
143
|
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
144
|
end
|
@@ -151,9 +146,9 @@ module URBANopt # :nodoc:
|
|
151
146
|
if reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps].nil?
|
152
147
|
n_top_values = 100
|
153
148
|
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]}
|
149
|
+
tmp2 = tmp1.each_index.max_by(n_top_values * reopt_inputs[:Scenario][:time_steps_per_hour]) { |i| tmp1[i] }
|
155
150
|
for i in (0...tmp2.count)
|
156
|
-
|
151
|
+
tmp2[i] += 1
|
157
152
|
end
|
158
153
|
reopt_inputs[:Scenario][:Site][:ElectricTariff][:coincident_peak_load_active_timesteps] = tmp2
|
159
154
|
end
|
@@ -165,7 +160,6 @@ module URBANopt # :nodoc:
|
|
165
160
|
return reopt_inputs
|
166
161
|
end
|
167
162
|
|
168
|
-
|
169
163
|
##
|
170
164
|
# Update a FeatureReport from a \REopt Lite response
|
171
165
|
#
|
@@ -177,7 +171,7 @@ module URBANopt # :nodoc:
|
|
177
171
|
#
|
178
172
|
# [*return:*] _URBANopt::Reporting::DefaultReports::FeatureReport_ - Returns an updated FeatureReport.
|
179
173
|
##
|
180
|
-
def update_feature_report(feature_report, reopt_output, timeseries_csv_path=nil, resilience_stats=nil)
|
174
|
+
def update_feature_report(feature_report, reopt_output, timeseries_csv_path = nil, resilience_stats = nil)
|
181
175
|
# Check if the \REopt Lite response is valid
|
182
176
|
if reopt_output['outputs']['Scenario']['status'] != 'optimal'
|
183
177
|
@@logger.info("Warning cannot Feature Report #{feature_report.name} #{feature_report.id} - REopt optimization was non-optimal")
|
@@ -210,29 +204,29 @@ module URBANopt # :nodoc:
|
|
210
204
|
feature_report.distributed_generation.probs_of_surviving_by_hour_of_the_day = resilience_stats['probs_of_surviving_by_hour_of_the_day']
|
211
205
|
end
|
212
206
|
|
213
|
-
if reopt_output['outputs']['Scenario']['Site']['PV'].
|
207
|
+
if reopt_output['outputs']['Scenario']['Site']['PV'].instance_of?(Hash)
|
214
208
|
reopt_output['outputs']['Scenario']['Site']['PV'] = [reopt_output['outputs']['Scenario']['Site']['PV']]
|
215
209
|
elsif reopt_output['outputs']['Scenario']['Site']['PV'].nil?
|
216
210
|
reopt_output['outputs']['Scenario']['Site']['PV'] = []
|
217
211
|
end
|
218
212
|
|
219
213
|
reopt_output['outputs']['Scenario']['Site']['PV'].each_with_index do |pv, i|
|
220
|
-
feature_report.distributed_generation.add_tech 'solar_pv',
|
214
|
+
feature_report.distributed_generation.add_tech 'solar_pv', URBANopt::Reporting::DefaultReports::SolarPV.new({ size_kw: (pv['size_kw'] || 0), id: i })
|
221
215
|
end
|
222
216
|
|
223
217
|
wind = reopt_output['outputs']['Scenario']['Site']['Wind']
|
224
|
-
if !wind['size_kw'].nil?
|
225
|
-
feature_report.distributed_generation.add_tech 'wind',
|
218
|
+
if !wind['size_kw'].nil? && (wind['size_kw'] != 0)
|
219
|
+
feature_report.distributed_generation.add_tech 'wind', URBANopt::Reporting::DefaultReports::Wind.new({ size_kw: (wind['size_kw'] || 0) })
|
226
220
|
end
|
227
221
|
|
228
222
|
generator = reopt_output['outputs']['Scenario']['Site']['Generator']
|
229
|
-
if !generator['size_kw'].nil?
|
230
|
-
feature_report.distributed_generation.add_tech 'generator',
|
223
|
+
if !generator['size_kw'].nil? && (generator['size_kw'] != 0)
|
224
|
+
feature_report.distributed_generation.add_tech 'generator', URBANopt::Reporting::DefaultReports::Generator.new({ size_kw: (generator['size_kw'] || 0) })
|
231
225
|
end
|
232
226
|
|
233
227
|
storage = reopt_output['outputs']['Scenario']['Site']['Storage']
|
234
|
-
if !storage['size_kw'].nil?
|
235
|
-
feature_report.distributed_generation.add_tech 'storage',
|
228
|
+
if !storage['size_kw'].nil? && (storage['size_kw'] != 0)
|
229
|
+
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
230
|
end
|
237
231
|
|
238
232
|
generation_timeseries_kwh = Matrix[[0] * (8760 * feature_report.timesteps_per_hour)]
|
@@ -240,28 +234,18 @@ module URBANopt # :nodoc:
|
|
240
234
|
|
241
235
|
unless reopt_output['outputs']['Scenario']['Site']['PV'].nil?
|
242
236
|
reopt_output['outputs']['Scenario']['Site']['PV'].each do |pv|
|
243
|
-
if (pv['size_kw'] || 0) > 0
|
244
|
-
|
245
|
-
generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
|
246
|
-
end
|
237
|
+
if (pv['size_kw'] || 0) > 0 && !pv['year_one_power_production_series_kw'].nil?
|
238
|
+
generation_timeseries_kwh += Matrix[convert_powerflow_resolution(pv['year_one_power_production_series_kw'], reopt_resolution, feature_report.timesteps_per_hour)]
|
247
239
|
end
|
248
|
-
|
240
|
+
end
|
249
241
|
end
|
250
242
|
|
251
|
-
|
252
|
-
|
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
|
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
245
|
end
|
258
246
|
|
259
|
-
|
260
|
-
|
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
|
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)]
|
265
249
|
end
|
266
250
|
|
267
251
|
$generation_timeseries_kwh = generation_timeseries_kwh.to_a[0] || [0] * (8760 * feature_report.timesteps_per_hour)
|
@@ -359,7 +343,6 @@ module URBANopt # :nodoc:
|
|
359
343
|
feature_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:PV:ToLoad(kw)')
|
360
344
|
end
|
361
345
|
|
362
|
-
|
363
346
|
$pv_to_grid_col = feature_report.timeseries_csv.column_names.index('REopt:ElectricityProduced:PV:ToGrid(kw)')
|
364
347
|
if $pv_to_grid_col.nil?
|
365
348
|
$pv_to_grid_col = feature_report.timeseries_csv.column_names.length
|
@@ -441,14 +424,14 @@ module URBANopt # :nodoc:
|
|
441
424
|
start_ts = (
|
442
425
|
(
|
443
426
|
((start_date.yday - 1) * 60.0 * 60.0 * 24) +
|
444
|
-
((
|
445
|
-
(start_date.min * 60.0) + start_date.sec
|
446
|
-
((
|
427
|
+
((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)
|
447
430
|
).to_int
|
448
431
|
|
449
432
|
mod_data = old_data.map.with_index do |x, i|
|
450
433
|
if i > 0
|
451
|
-
modrow(x, start_ts + i -1)
|
434
|
+
modrow(x, start_ts + i - 1)
|
452
435
|
else
|
453
436
|
x
|
454
437
|
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,20 @@ module URBANopt # :nodoc:
|
|
122
124
|
tries = 0
|
123
125
|
while tries < max_tries
|
124
126
|
begin
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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')
|
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
|
+
end
|
137
|
+
tries = 4
|
138
|
+
rescue StandardError
|
139
|
+
tries += 1
|
140
|
+
end
|
130
141
|
end
|
131
142
|
return result
|
132
143
|
end
|
@@ -148,11 +159,11 @@ module URBANopt # :nodoc:
|
|
148
159
|
http.use_ssl = true
|
149
160
|
end
|
150
161
|
|
151
|
-
|
152
|
-
|
162
|
+
post_request = Net::HTTP::Post.new(@uri_submit, header)
|
163
|
+
post_request.body = ::JSON.generate(data, allow_nan: true)
|
153
164
|
|
154
165
|
# Send the request
|
155
|
-
response = make_request(http,
|
166
|
+
response = make_request(http, post_request)
|
156
167
|
|
157
168
|
if !response.is_a?(Net::HTTPSuccess)
|
158
169
|
@@logger.error('Check_connection Failed')
|
@@ -175,7 +186,6 @@ module URBANopt # :nodoc:
|
|
175
186
|
# [*return:*] _Bool_ - Returns true if the post succeeeds. Otherwise returns false.
|
176
187
|
##
|
177
188
|
def resilience_request(run_uuid, filename)
|
178
|
-
|
179
189
|
if File.directory? filename
|
180
190
|
if run_uuid.nil?
|
181
191
|
run_uuid = 'error'
|
@@ -187,33 +197,38 @@ module URBANopt # :nodoc:
|
|
187
197
|
@@logger.info("REopt results saved to #{filename}")
|
188
198
|
end
|
189
199
|
|
190
|
-
#Submit Job
|
200
|
+
# Submit Job
|
191
201
|
@@logger.info("Submitting Resilience Statistics job for #{run_uuid}")
|
192
202
|
header = { 'Content-Type' => 'application/json' }
|
193
203
|
http = Net::HTTP.new(@uri_submit_outagesimjob.host, @uri_submit_outagesimjob.port)
|
194
204
|
if !@use_localhost
|
195
205
|
http.use_ssl = true
|
196
206
|
end
|
197
|
-
|
198
|
-
|
199
|
-
submit_response = make_request(http,
|
200
|
-
@@logger.
|
207
|
+
post_request = Net::HTTP::Post.new(@uri_submit_outagesimjob, header)
|
208
|
+
post_request.body = ::JSON.generate({ 'run_uuid' => run_uuid, 'bau' => false }, allow_nan: true)
|
209
|
+
submit_response = make_request(http, post_request)
|
210
|
+
@@logger.debug(submit_response.body)
|
201
211
|
|
202
|
-
#Fetch Results
|
212
|
+
# Fetch Results
|
203
213
|
uri = uri_resilience(run_uuid)
|
204
214
|
http = Net::HTTP.new(uri.host, uri.port)
|
205
215
|
if !@use_localhost
|
206
216
|
http.use_ssl = true
|
207
217
|
end
|
208
218
|
|
219
|
+
# Wait a few seconds for the REopt database to update before GETing results
|
220
|
+
sleep 5
|
221
|
+
get_request = Net::HTTP::Get.new(uri.request_uri)
|
222
|
+
response = make_request(http, get_request)
|
223
|
+
|
224
|
+
# Set a limit on retries when 404s are returned from REopt API
|
209
225
|
elapsed_time = 0
|
210
226
|
max_elapsed_time = 60 * 5
|
211
227
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
response = make_request(http, request)
|
228
|
+
# If database still hasn't updated, wait a little longer and try again
|
229
|
+
while (elapsed_time < max_elapsed_time) & (response.code == '404')
|
230
|
+
response = make_request(http, get_request)
|
231
|
+
@@logger.warn('GET request was too fast for REOpt-Lite API. Retrying...')
|
217
232
|
elapsed_time += 5
|
218
233
|
sleep 5
|
219
234
|
end
|
@@ -224,17 +239,16 @@ module URBANopt # :nodoc:
|
|
224
239
|
File.open(filename, 'w+') do |f|
|
225
240
|
f.puts(text)
|
226
241
|
end
|
227
|
-
rescue
|
228
|
-
@@logger.
|
242
|
+
rescue StandardError
|
243
|
+
@@logger.error("Cannot write - #{filename}")
|
229
244
|
end
|
230
245
|
|
231
|
-
if response.code ==
|
246
|
+
if response.code == '200'
|
232
247
|
return data
|
233
248
|
end
|
234
249
|
|
235
|
-
@@logger.
|
250
|
+
@@logger.error("Error from REopt API - #{data['Error']}")
|
236
251
|
return {}
|
237
|
-
|
238
252
|
end
|
239
253
|
|
240
254
|
##
|
@@ -261,14 +275,14 @@ module URBANopt # :nodoc:
|
|
261
275
|
if !@use_localhost
|
262
276
|
http.use_ssl = true
|
263
277
|
end
|
264
|
-
|
265
|
-
|
278
|
+
post_request = Net::HTTP::Post.new(@uri_submit, header)
|
279
|
+
post_request.body = ::JSON.generate(reopt_input, allow_nan: true)
|
266
280
|
|
267
281
|
# Send the request
|
268
|
-
response = make_request(http,
|
282
|
+
response = make_request(http, post_request)
|
269
283
|
|
270
284
|
# Get UUID
|
271
|
-
run_uuid = JSON.parse(response.body, allow_nan:true)['run_uuid']
|
285
|
+
run_uuid = JSON.parse(response.body, allow_nan: true)['run_uuid']
|
272
286
|
|
273
287
|
if File.directory? filename
|
274
288
|
if run_uuid.nil?
|
@@ -286,7 +300,7 @@ module URBANopt # :nodoc:
|
|
286
300
|
File.open(filename, 'w+') do |f|
|
287
301
|
f.puts(text)
|
288
302
|
end
|
289
|
-
@@logger.
|
303
|
+
@@logger.error("Cannot write - #{filename}")
|
290
304
|
raise "Error in REopt optimization post - see #{filename}"
|
291
305
|
end
|
292
306
|
|
@@ -298,17 +312,17 @@ module URBANopt # :nodoc:
|
|
298
312
|
http.use_ssl = true
|
299
313
|
end
|
300
314
|
|
301
|
-
|
315
|
+
get_request = Net::HTTP::Get.new(uri.request_uri)
|
302
316
|
|
303
317
|
while status == 'Optimizing...'
|
304
|
-
response = make_request(http,
|
318
|
+
response = make_request(http, get_request)
|
305
319
|
|
306
|
-
data = JSON.parse(response.body, allow_nan:true)
|
320
|
+
data = JSON.parse(response.body, allow_nan: true)
|
307
321
|
|
308
|
-
if data['outputs']['Scenario']['Site']['PV'].
|
322
|
+
if data['outputs']['Scenario']['Site']['PV'].is_a?(Array)
|
309
323
|
pv_sizes = 0
|
310
324
|
data['outputs']['Scenario']['Site']['PV'].each do |x|
|
311
|
-
pv_sizes
|
325
|
+
pv_sizes += x['size_kw'].to_f
|
312
326
|
end
|
313
327
|
else
|
314
328
|
pv_sizes = data['outputs']['Scenario']['Site']['PV']['size_kw'] || 0
|
@@ -323,13 +337,13 @@ module URBANopt # :nodoc:
|
|
323
337
|
_tries = 0
|
324
338
|
(check_complete = sizes == 0) && ((data['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0) > 0)
|
325
339
|
while (_tries < _max_retry) && check_complete
|
326
|
-
sleep
|
327
|
-
response = make_request(http,
|
328
|
-
data = JSON.parse(response.body, allow_nan:true)
|
329
|
-
if data['outputs']['Scenario']['Site']['PV'].
|
340
|
+
sleep 3
|
341
|
+
response = make_request(http, get_request)
|
342
|
+
data = JSON.parse(response.body, allow_nan: true)
|
343
|
+
if data['outputs']['Scenario']['Site']['PV'].is_a?(Array)
|
330
344
|
pv_sizes = 0
|
331
345
|
data['outputs']['Scenario']['Site']['PV'].each do |x|
|
332
|
-
pv_sizes
|
346
|
+
pv_sizes += x['size_kw'].to_f
|
333
347
|
end
|
334
348
|
else
|
335
349
|
pv_sizes = data['outputs']['Scenario']['Site']['PV']['size_kw'] || 0
|
@@ -345,8 +359,8 @@ module URBANopt # :nodoc:
|
|
345
359
|
File.open(filename, 'w+') do |f|
|
346
360
|
f.puts(text)
|
347
361
|
end
|
348
|
-
rescue
|
349
|
-
@@logger.
|
362
|
+
rescue StandardError
|
363
|
+
@@logger.error("Cannot write - #{filename}")
|
350
364
|
end
|
351
365
|
|
352
366
|
if status == 'optimal'
|