Class: URBANopt::REopt::REoptLiteAPI
- Inherits:
-
Object
- Object
- URBANopt::REopt::REoptLiteAPI
- Defined in:
- lib/urbanopt/reopt/reopt_lite_api.rb
Instance Method Summary collapse
-
#check_connection(data) ⇒ Object
Checks if a optimization task can be submitted to the REopt Lite API.
-
#initialize(nrel_developer_key = nil, use_localhost = false) ⇒ REoptLiteAPI
constructor
REoptLiteAPI manages submitting optimization tasks to the REopt Lite API and recieving results.
- #make_request(http, r, max_tries = 3) ⇒ Object
-
#reopt_request(reopt_input, filename) ⇒ Object
Completes a REopt Lite optimization.
-
#resilience_request(run_uuid, filename) ⇒ Object
Completes a REopt Lite optimization.
-
#uri_resilience(run_uuid) ⇒ Object
URL of the resilience statistics end point for a specific optimization task.
-
#uri_results(run_uuid) ⇒ Object
URL of the results end point for a specific optimization task.
Constructor Details
#initialize(nrel_developer_key = nil, use_localhost = false) ⇒ REoptLiteAPI
REoptLiteAPI manages submitting optimization tasks to the REopt Lite API and recieving results. Results can either be sourced from the production REopt Lite API with an API key from developer.nrel.gov, or from a version running at localhost.
- parameters:
-
use_localhost
- Bool - If this is true, requests will be sent to a version of the REopt Lite API running on localhost. Default is false, such that the production version of REopt Lite is accessed. -
nrel_developer_key
- String - API key used to access the REopt Lite APi. Required only if localhost is false. Obtain from developer.nrel.gov/signup/
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/urbanopt/reopt/reopt_lite_api.rb', line 55 def initialize(nrel_developer_key = nil, use_localhost = false) @use_localhost = use_localhost if @use_localhost @uri_submit = URI.parse('http//:127.0.0.1:8000/v1/job/') @uri_submit_outagesimjob = URI.parse('http//:127.0.0.1:8000/v1/outagesimjob/') else if [nil, '', '<insert your key here>'].include? nrel_developer_key if [nil, '', '<insert your key here>'].include? DEVELOPER_NREL_KEY raise 'A developer.nrel.gov API key is required. Please see https://developer.nrel.gov/signup/ then update the file urbanopt-reopt-gem/developer_nrel_key.rb' else nrel_developer_key = DEVELOPER_NREL_KEY end end @nrel_developer_key = nrel_developer_key @uri_submit = URI.parse("https://developer.nrel.gov/api/reopt/v1/job/?api_key=#{@nrel_developer_key}") @uri_submit_outagesimjob = URI.parse("https://developer.nrel.gov/api/reopt/v1/outagesimjob/?api_key=#{@nrel_developer_key}") # initialize @@logger @@logger ||= URBANopt::REopt.reopt_logger end end |
Instance Method Details
#check_connection(data) ⇒ Object
Checks if a optimization task can be submitted to the REopt Lite API
- parameters:
-
data
- Hash - Default REopt Lite formatted post containing at least all the required parameters.
- return:
-
Bool - Returns true if the post succeeeds. Otherwise returns false.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/urbanopt/reopt/reopt_lite_api.rb', line 134 def check_connection(data) header = { 'Content-Type' => 'application/json' } http = Net::HTTP.new(@uri_submit.host, @uri_submit.port) if !@use_localhost http.use_ssl = true end request = Net::HTTP::Post.new(@uri_submit, header) request.body = ::JSON.generate(data, allow_nan: true) # Send the request response = make_request(http, request) if !response.is_a?(Net::HTTPSuccess) @@logger.error('Check_connection Failed') raise 'Check_connection Failed' end return true end |
#make_request(http, r, max_tries = 3) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/urbanopt/reopt/reopt_lite_api.rb', line 110 def make_request(http, r, max_tries = 3) result = nil tries = 0 while tries < max_tries begin result = http.request(r) tries = 4 rescue StandardError tries += 1 end end return result end |
#reopt_request(reopt_input, filename) ⇒ Object
Completes a REopt Lite optimization. From a formatted hash, an optimization task is submitted to the API. Results are polled at 5 second interval until they are ready or an error is returned from the API. Results are written to disk.
- parameters:
-
reopt_input
- Hash - REopt Lite formatted post containing at least required parameters. -
filename
- String - Path to file that will be created containing the full REopt Lite response.
- return:
-
Bool - Returns true if the post succeeeds. Otherwise returns false.
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/urbanopt/reopt/reopt_lite_api.rb', line 241 def reopt_request(reopt_input, filename) description = reopt_input[:Scenario][:description] @@logger.info("Submitting #{description} to REopt Lite API") # Format the request header = { 'Content-Type' => 'application/json' } http = Net::HTTP.new(@uri_submit.host, @uri_submit.port) if !@use_localhost http.use_ssl = true end request = Net::HTTP::Post.new(@uri_submit, header) request.body = ::JSON.generate(reopt_input, allow_nan: true) # Send the request response = make_request(http, request) # Get UUID run_uuid = JSON.parse(response.body, allow_nan:true)['run_uuid'] if File.directory? filename if run_uuid.nil? run_uuid = 'error' end if run_uuid.downcase.include? 'error' run_uuid = "error#{SecureRandom.uuid}" end filename = File.join(filename, "#{description}_#{run_uuid}.json") @@logger.info("REopt results saved to #{filename}") end text = ::JSON.generate(response.body, allow_nan: true) if response.code != '201' File.open(filename, 'w+') do |f| f.puts(text) end @@logger.info("Cannot write - #{filename}") raise "Error in REopt optimization post - see #{filename}" end # Poll results until ready or error occurs status = 'Optimizing...' uri = uri_results(run_uuid) http = Net::HTTP.new(uri.host, uri.port) if !@use_localhost http.use_ssl = true end request = Net::HTTP::Get.new(uri.request_uri) while status == 'Optimizing...' response = make_request(http, request) data = JSON.parse(response.body, allow_nan:true) if data['outputs']['Scenario']['Site']['PV'].kind_of?(Array) pv_sizes = 0 data['outputs']['Scenario']['Site']['PV'].each do |x| pv_sizes = pv_sizes + x['size_kw'].to_f end else pv_sizes = data['outputs']['Scenario']['Site']['PV']['size_kw'] || 0 end sizes = pv_sizes + (data['outputs']['Scenario']['Site']['Storage']['size_kw'] || 0) + (data['outputs']['Scenario']['Site']['Wind']['size_kw'] || 0) + (data['outputs']['Scenario']['Site']['Generator']['size_kw'] || 0) status = data['outputs']['Scenario']['status'] sleep 5 end _max_retry = 5 _tries = 0 (check_complete = sizes == 0) && ((data['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0) > 0) while (_tries < _max_retry) && check_complete sleep 1 response = make_request(http, request) data = JSON.parse(response.body, allow_nan:true) if data['outputs']['Scenario']['Site']['PV'].kind_of?(Array) pv_sizes = 0 data['outputs']['Scenario']['Site']['PV'].each do |x| pv_sizes = pv_sizes + x['size_kw'].to_f end else pv_sizes = data['outputs']['Scenario']['Site']['PV']['size_kw'] || 0 end sizes = pv_sizes + (data['outputs']['Scenario']['Site']['Storage']['size_kw'] || 0) + (data['outputs']['Scenario']['Site']['Wind']['size_kw'] || 0) + (data['outputs']['Scenario']['Site']['Generator']['size_kw'] || 0) (check_complete = sizes == 0) && ((data['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0) > 0) _tries += 1 end data = JSON.parse(response.body) text = ::JSON.generate(data, allow_nan: true) begin File.open(filename, 'w+') do |f| f.puts(text) end rescue @@logger.info("Cannot write - #{filename}") end if status == 'optimal' return data end = data['messages']['error'] raise "Error from REopt API - #{}" end |
#resilience_request(run_uuid, filename) ⇒ Object
Completes a REopt Lite optimization. From a formatted hash, an optimization task is submitted to the API. Results are polled at 5 second interval until they are ready or an error is returned from the API. Results are written to disk.
- parameters:
-
reopt_input
- Hash - REopt Lite formatted post containing at least required parameters. -
filename
- String - Path to file that will be created containing the full REopt Lite response.
- return:
-
Bool - Returns true if the post succeeeds. Otherwise returns false.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/urbanopt/reopt/reopt_lite_api.rb', line 167 def resilience_request(run_uuid, filename) if File.directory? filename if run_uuid.nil? run_uuid = 'error' end if run_uuid.downcase.include? 'error' run_uuid = "error#{SecureRandom.uuid}" end filename = File.join(filename, "#{run_uuid}_resilience.json") @@logger.info("REopt results saved to #{filename}") end #Submit Job @@logger.info("Submitting Resilience Statistics job for #{run_uuid}") header = { 'Content-Type' => 'application/json' } http = Net::HTTP.new(@uri_submit_outagesimjob.host, @uri_submit_outagesimjob.port) if !@use_localhost http.use_ssl = true end request = Net::HTTP::Post.new(@uri_submit_outagesimjob, header) request.body = ::JSON.generate({"run_uuid" => run_uuid, "bau" => false }, allow_nan: true) submit_response = make_request(http, request) @@logger.info(submit_response.body) #Fetch Results uri = uri_resilience(run_uuid) http = Net::HTTP.new(uri.host, uri.port) if !@use_localhost http.use_ssl = true end elapsed_time = 0 max_elapsed_time = 60 request = Net::HTTP::Get.new(uri.request_uri) response = make_request(http, request) while (elapsed_time < max_elapsed_time) & (response.code == "404") response = make_request(http, request) elapsed_time += 5 sleep 5 end data = JSON.parse(response.body) text = ::JSON.generate(data, allow_nan: true) begin File.open(filename, 'w+') do |f| f.puts(text) end rescue @@logger.info("Cannot write - #{filename}") end if response.code == "200" return data end raise "Error from REopt API - #{data['Error']}" end |
#uri_resilience(run_uuid) ⇒ Object
URL of the resilience statistics end point for a specific optimization task
- parameters:
-
run_uuid
- String - Resilience statistics for a unique run_uuid obtained from the REopt Lite job submittal URL for a specific optimization task.
- return:
-
URI - Returns URI object for use in calling the REopt Lite resilience statistics endpoint for a specifc optimization task.
103 104 105 106 107 108 |
# File 'lib/urbanopt/reopt/reopt_lite_api.rb', line 103 def uri_resilience(run_uuid) # :nodoc: if @use_localhost return URI.parse("http://127.0.0.1:8000/v1/job/#{run_uuid}/resilience_stats") end return URI.parse("https://developer.nrel.gov/api/reopt/v1/job/#{run_uuid}/resilience_stats?api_key=#{@nrel_developer_key}") end |
#uri_results(run_uuid) ⇒ Object
URL of the results end point for a specific optimization task
- parameters:
-
run_uuid
- String - Unique run_uuid obtained from the REopt Lite job submittal URL for a specific optimization task.
- return:
-
URI - Returns URI object for use in calling the REopt Lite results endpoint for a specifc optimization task.
86 87 88 89 90 91 |
# File 'lib/urbanopt/reopt/reopt_lite_api.rb', line 86 def uri_results(run_uuid) # :nodoc: if @use_localhost return URI.parse("http://127.0.0.1:8000/v1/job/#{run_uuid}/results") end return URI.parse("https://developer.nrel.gov/api/reopt/v1/job/#{run_uuid}/results?api_key=#{@nrel_developer_key}") end |