urbanopt-reopt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.rakeTasks +7 -0
- data/.rdoc_options +37 -0
- data/.rspec +3 -0
- data/.rubocop.yml +9 -0
- data/.travis.yml +22 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +67 -0
- data/Jenkinsfile +10 -0
- data/LICENSE.md +27 -0
- data/RDOC_MAIN.md +176 -0
- data/README.md +177 -0
- data/Rakefile +30 -0
- data/deploy_docs.sh +5 -0
- data/developer_nrel_key.rb +31 -0
- data/doc_templates/LICENSE.md +27 -0
- data/doc_templates/README.md.erb +42 -0
- data/doc_templates/copyright_erb.txt +31 -0
- data/doc_templates/copyright_js.txt +4 -0
- data/doc_templates/copyright_ruby.txt +29 -0
- data/docs/.gitignore +3 -0
- data/docs/.vuepress/components/InnerJsonSchema.vue +78 -0
- data/docs/.vuepress/components/JsonSchema.vue +12 -0
- data/docs/.vuepress/components/ReoptInputSchema.vue +12 -0
- data/docs/.vuepress/components/ReoptOutputSchema.vue +12 -0
- data/docs/.vuepress/components/StaticLink.vue +8 -0
- data/docs/.vuepress/config.js +16 -0
- data/docs/.vuepress/highlight.js +8 -0
- data/docs/.vuepress/public/custom_rdoc_styles.css +58 -0
- data/docs/.vuepress/utils.js +17 -0
- data/docs/README.md +196 -0
- data/docs/package-lock.json +254 -0
- data/docs/package.json +22 -0
- data/docs/schemas/reopt-input-schema.md +57 -0
- data/docs/schemas/reopt-output-schema.md +66 -0
- data/index.html +1 -0
- data/index.md +176 -0
- data/lib/files/.gitkeep +0 -0
- data/lib/urbanopt/reopt/extension.rb +44 -0
- data/lib/urbanopt/reopt/feature_report_adapter.rb +364 -0
- data/lib/urbanopt/reopt/reopt_lite_api.rb +230 -0
- data/lib/urbanopt/reopt/reopt_logger.rb +42 -0
- data/lib/urbanopt/reopt/reopt_post_processor.rb +245 -0
- data/lib/urbanopt/reopt/reopt_schema/reopt_input_schema.json +1111 -0
- data/lib/urbanopt/reopt/reopt_schema/reopt_output_schema.json +538 -0
- data/lib/urbanopt/reopt/scenario/reopt_scenario_csv.rb +115 -0
- data/lib/urbanopt/reopt/scenario_report_adapter.rb +404 -0
- data/lib/urbanopt/reopt/version.rb +35 -0
- data/lib/urbanopt/reopt.rb +36 -0
- data/lib/urbanopt/reopt_scenario.rb +31 -0
- data/lib/urbanopt-reopt.rb +31 -0
- data/urbanopt-reopt.gemspec +33 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ee9ebcdfb84f8014a57ba10b922de59989801a03
|
4
|
+
data.tar.gz: f382a27f0219f10d01b20d09b2cfdd41d48cd223
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0edee439c2cc7bff0cc349de7511ab20c163c3ba803a0dbb4bca4291a6a6439aa2737e5c91077ea10316d23c32a80d5ed37dbe4138c0d992c7b08baddfe7db68
|
7
|
+
data.tar.gz: 28026ba4c576ece08adb4a1084eb64e36ce533400c5b2b66ab0b8290fa8de76c39b8d0aaa5afe7591463db93fd23392144f32167e97fd72ab32b8ef5783bdaf7
|
data/.gitignore
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/.ruby-version
|
4
|
+
/Gemfile.lock
|
5
|
+
/gems
|
6
|
+
/_yardoc/
|
7
|
+
/coverage/
|
8
|
+
/doc/
|
9
|
+
/pkg/
|
10
|
+
/spec/reports/
|
11
|
+
/spec/test/
|
12
|
+
/tmp/
|
13
|
+
/test/
|
14
|
+
/lib/measures/test_results
|
15
|
+
/lib/measures/.rubocop*
|
16
|
+
developer_nrel_key.rb
|
17
|
+
# rspec failure tracking
|
18
|
+
.rspec_status
|
19
|
+
|
20
|
+
# Ignore IDE files
|
21
|
+
/.idea
|
22
|
+
*.rubocop-http*
|
23
|
+
|
24
|
+
# measures tests
|
25
|
+
lib/measures/.rubocop.yml
|
26
|
+
lib/measures/test_results/*
|
27
|
+
lib/measures/*/tests/output/*
|
data/.rakeTasks
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Settings><!--This file was automatically generated by Ruby plugin.
|
3
|
+
You are allowed to:
|
4
|
+
1. Remove rake task
|
5
|
+
2. Add existing rake tasks
|
6
|
+
To add existing rake tasks automatically delete this file and reload the project.
|
7
|
+
--><RakeGroup description="" fullCmd="" taskId="rake" /></Settings>
|
data/.rdoc_options
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
--- !ruby/object:RDoc::Options
|
2
|
+
encoding: UTF-8
|
3
|
+
static_path: []
|
4
|
+
rdoc_include:
|
5
|
+
- lib
|
6
|
+
charset: UTF-8
|
7
|
+
exclude:
|
8
|
+
- doc_templates
|
9
|
+
- docs
|
10
|
+
- lib/measures
|
11
|
+
- node_modules
|
12
|
+
- spec
|
13
|
+
- test
|
14
|
+
- Gemfile
|
15
|
+
- Gemfile.lock
|
16
|
+
- Jenkinsfile
|
17
|
+
- LICENSE.md
|
18
|
+
- README.md
|
19
|
+
- Rakefile
|
20
|
+
- urbanopt-scenario-gem.gemspec
|
21
|
+
- JSON
|
22
|
+
- Object
|
23
|
+
hyperlink_all: false
|
24
|
+
line_numbers: false
|
25
|
+
locale:
|
26
|
+
locale_dir: locale
|
27
|
+
locale_name:
|
28
|
+
main_page: RDOC_MAIN.md
|
29
|
+
markup: markdown
|
30
|
+
output_decoration: true
|
31
|
+
op_dir: ./docs/.vuepress/public/rdoc
|
32
|
+
show_hash: false
|
33
|
+
tab_width: 8
|
34
|
+
template_stylesheets: ["./docs/.vuepress/public/custom_rdoc_styles.css"]
|
35
|
+
title:
|
36
|
+
visibility: :protected
|
37
|
+
webcvs:
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
sudo: false
|
3
|
+
language: ruby
|
4
|
+
#cache: bundler
|
5
|
+
rvm:
|
6
|
+
- 2.2.4
|
7
|
+
matrix:
|
8
|
+
include:
|
9
|
+
- env: OPENSTUDIO_VERSION=2.7.0 && OPENSTUDIO_SHA=544f363db5 && RUBYLIB=/usr/local/openstudio-2.7.0/Ruby:/usr/Ruby
|
10
|
+
before_install:
|
11
|
+
- gem install bundler -v '1.17'
|
12
|
+
- gem install bundler -v '~> 1.17'
|
13
|
+
install:
|
14
|
+
- bundle install
|
15
|
+
before_script:
|
16
|
+
- curl -sLO https://raw.githubusercontent.com/NREL/OpenStudio-server/develop/docker/deployment/scripts/install_openstudio.sh
|
17
|
+
- chmod +x install_openstudio.sh
|
18
|
+
- sudo ./install_openstudio.sh $OPENSTUDIO_VERSION $OPENSTUDIO_SHA
|
19
|
+
- sudo ./install_openstudio.sh $OPENSTUDIO_VERSION $OPENSTUDIO_SHA
|
20
|
+
script:
|
21
|
+
- bundle exec rake
|
22
|
+
- bundle exec rake
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in urbanopt-scenario-gem.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
# Local gems are useful when developing and integrating the various dependencies.
|
7
|
+
# To favor the use of local gems, set the following environment variable:
|
8
|
+
# Mac: export FAVOR_LOCAL_GEMS=1
|
9
|
+
# Windows: set FAVOR_LOCAL_GEMS=1
|
10
|
+
# Note that if allow_local is true, but the gem is not found locally, then it will
|
11
|
+
# checkout the latest version (develop) from github.
|
12
|
+
allow_local = ENV['FAVOR_LOCAL_GEMS']
|
13
|
+
|
14
|
+
# Uncomment the extension, common measures, core gems if you need to test local development versions. Otherwise
|
15
|
+
# these are included in the model articulation and urbanopt gems
|
16
|
+
#
|
17
|
+
# if allow_local && File.exist?('../OpenStudio-extension-gem')
|
18
|
+
# gem 'openstudio-extension', path: '../OpenStudio-extension-gem'
|
19
|
+
# elsif allow_local
|
20
|
+
# gem 'openstudio-extension', github: 'NREL/OpenStudio-extension-gem', branch: 'develop'
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# if allow_local && File.exist?('../openstudio-common-measures-gem')
|
24
|
+
# gem 'openstudio-common-measures', path: '../openstudio-common-measures-gem'
|
25
|
+
# elsif allow_local
|
26
|
+
# gem 'openstudio-common-measures', github: 'NREL/openstudio-common-measures-gem', branch: 'develop'
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# if allow_local && File.exist?('../urbanopt-core-gem')
|
30
|
+
# gem 'urbanopt-core', path: '../urbanopt-core-gem'
|
31
|
+
# elsif allow_local
|
32
|
+
# gem 'urbanopt-core', github: 'URBANopt/urbanopt-core-gem', branch: 'develop'
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# if allow_local && File.exist?('../openstudio-model-articulation-gem')
|
36
|
+
# # gem 'openstudio-model-articulation', github: 'NREL/openstudio-model-articulation-gem', branch: 'develop'
|
37
|
+
# gem 'openstudio-model-articulation', path: '../openstudio-model-articulation-gem'
|
38
|
+
# elsif allow_local
|
39
|
+
# gem 'openstudio-model-articulation', github: 'NREL/openstudio-model-articulation-gem', branch: 'develop'
|
40
|
+
# else
|
41
|
+
# gem 'openstudio-model-articulation', '0.1.0'
|
42
|
+
# end
|
43
|
+
|
44
|
+
if allow_local && File.exist?('../urbanopt-scenario-gem')
|
45
|
+
gem 'urbanopt-scenario', path: '../urbanopt-scenario-gem'
|
46
|
+
elsif allow_local
|
47
|
+
gem 'urbanopt-scenario', github: 'URBANopt/urbanopt-scenario-gem', branch: 'post_process'
|
48
|
+
else
|
49
|
+
gem 'urbanopt-scenario', '0.1.1'
|
50
|
+
end
|
51
|
+
|
52
|
+
if allow_local && File.exists?('../urbanopt-geojson-gem')
|
53
|
+
# gem 'openstudio-extension', github: 'NREL/OpenStudio-extension-gem', branch: 'develop'
|
54
|
+
gem 'urbanopt-geojson', path: '../urbanopt-geojson-gem'
|
55
|
+
elsif allow_local
|
56
|
+
gem 'urbanopt-geojson', github: 'URBANopt/urbanopt-geojson-gem', branch: 'develop'
|
57
|
+
else
|
58
|
+
gem 'urbanopt-geojson', '0.1.0'
|
59
|
+
end
|
60
|
+
|
61
|
+
# simplecov has an unnecessary dependency on native json gem, use fork that does not require this
|
62
|
+
gem 'simplecov', github: 'NREL/simplecov'
|
63
|
+
|
64
|
+
# Support requests in windows
|
65
|
+
gem 'certified'
|
66
|
+
|
67
|
+
gem 'rdoc', '4.3.0'
|
data/Jenkinsfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
//Jenkins pipelines are stored in shared libaries. Please see: https://github.com/tijcolem/nrel_cbci_jenkins_libs
|
2
|
+
|
3
|
+
@Library('cbci_shared_libs') _
|
4
|
+
|
5
|
+
// Build for PR to develop branch only.
|
6
|
+
if ((env.CHANGE_ID) && (env.CHANGE_TARGET) ) { // check if set
|
7
|
+
|
8
|
+
urbanopt_reopt_gem()
|
9
|
+
|
10
|
+
}
|
data/LICENSE.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
OpenStudio(R), Copyright (c) 2008-2018, Alliance for Sustainable Energy, LLC. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted
|
4
|
+
provided that the following conditions are met:
|
5
|
+
|
6
|
+
(1) Redistributions of source code must retain the above copyright notice, this list of conditions
|
7
|
+
and the following disclaimer.
|
8
|
+
|
9
|
+
(2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
10
|
+
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
(3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse
|
13
|
+
or promote products derived from this software without specific prior written permission from the
|
14
|
+
respective party.
|
15
|
+
|
16
|
+
(4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other
|
17
|
+
derivative works may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar
|
18
|
+
designation without specific prior written permission from Alliance for Sustainable Energy, LLC.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
21
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES GOVERNMENT,
|
23
|
+
OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
25
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
26
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/RDOC_MAIN.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# **URBANopt REopt Gem**
|
2
|
+
|
3
|
+
The **URBANopt REopt Gem** extends **URBANopt::Scenario::DefaultReports::ScenarioReport** and **URBANopt::Scenario::DefaultReports::FeatureReport** with the ability to derive cost-optimal distributed energy resource (DER) technology sizes and annual dispatch strageties via the [REopt Lite](https://reopt.nrel.gov/tool) decision support platform.
|
4
|
+
REopt Lite is a technoeconomic model which leverages mixed integer linear programming to identify the cost-optimal sizing of solar PV, Wind, Storage and/or diesel generation given an electric load profile, a utility rate tariff and other technoeconomic parameters. See [https://developer.nrel.gov/docs/energy-optimization/reopt-v1/](https://developer.nrel.gov/docs/energy-optimization/reopt-v1/) for more detailed information on input parameters and default assumptions.
|
5
|
+
|
6
|
+
See the [example project](https://github.com/urbanopt/urbanopt-example-reopt-project.git) for more infomation about usage of this gem.
|
7
|
+
|
8
|
+
<b>Note:</b> This module requires an API Key from the [NREL Developer Network](https://developer.nrel.gov/)
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
See [https://docs.urbanopt.net/installation/installation.html](https://docs.urbanopt.net/installation/installation.html) for instructions on prerequiste software, including:
|
13
|
+
- Ruby 2.2.6
|
14
|
+
- Bundler 1.17.0
|
15
|
+
- OpenStudio 2.8.1
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'urbanopt-reopt'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle install
|
26
|
+
$ bundle update
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install 'urbanopt-reopt'
|
31
|
+
|
32
|
+
## Functionality
|
33
|
+
|
34
|
+
This gem is used to call the REopt Lite API on a Scenario Report or Feature Report to update the object's Distributed Generation attributes (including system financial and sizing metrics) as shown in an example below:
|
35
|
+
|
36
|
+
```
|
37
|
+
"distributed_generation": {
|
38
|
+
"lcc_us_dollars": 100000000.0,
|
39
|
+
"npv_us_dollars": 10000000.0,
|
40
|
+
"year_one_energy_cost_us_dollars": 7000000.0,
|
41
|
+
"year_one_demand_cost_us_dollars": 3000000.0,
|
42
|
+
"year_one_bill_us_dollars": 10000000.0,
|
43
|
+
"total_energy_cost_us_dollars": 70000000.0,
|
44
|
+
"solar_pv": {
|
45
|
+
"size_kw": 30000.0
|
46
|
+
},
|
47
|
+
"wind": {
|
48
|
+
"size_kw": 0.0
|
49
|
+
},
|
50
|
+
"generator": {
|
51
|
+
"size_kw": 0.0
|
52
|
+
},
|
53
|
+
"storage": {
|
54
|
+
"size_kw": 2000.0,
|
55
|
+
"size_kwh": 5000.0
|
56
|
+
}
|
57
|
+
}
|
58
|
+
```
|
59
|
+
|
60
|
+
Moreover, the following optimal dispatch fields are added to its timeseries CSV. Where no system component is recommended the dispatch will be all zero (i.e. if no solar PV is recommended ElectricityProduced:PV:Total will be always be zero)
|
61
|
+
|
62
|
+
```
|
63
|
+
| output | unit |
|
64
|
+
| -----------------------------------------| ------- |
|
65
|
+
| ElectricityProduced:Total | kWh |
|
66
|
+
| Electricity:Load:Total | kWh |
|
67
|
+
| Electricity:Grid:ToLoad | kWh |
|
68
|
+
| Electricity:Grid:ToBattery | kWh |
|
69
|
+
| Electricity:Storage:ToLoad | kWh |
|
70
|
+
| Electricity:Storage:ToGrid | kWh |
|
71
|
+
| Electricity:Storage:StateOfCharge | kWh |
|
72
|
+
| ElectricityProduced:Generator:Total | kWh |
|
73
|
+
| ElectricityProduced:Generator:ToBattery | kWh |
|
74
|
+
| ElectricityProduced:Generator:ToLoad | kWh |
|
75
|
+
| ElectricityProduced:Generator:ToGrid | kWh |
|
76
|
+
| ElectricityProduced:PV:Total | kWh |
|
77
|
+
| ElectricityProduced:PV:ToBattery | kWh |
|
78
|
+
| ElectricityProduced:PV:ToLoad | kWh |
|
79
|
+
| ElectricityProduced:PV:ToGrid | kWh |
|
80
|
+
| ElectricityProduced:Wind:Total | kWh |
|
81
|
+
| ElectricityProduced:Wind:ToBattery | kWh |
|
82
|
+
| ElectricityProduced:Wind:ToLoad | kWh |
|
83
|
+
| ElectricityProduced:Wind:ToGrid | kWh |
|
84
|
+
```
|
85
|
+
|
86
|
+
The REopt Lite has default values for all non-required input parameters that are used unless the user specifies custom assumptions. See [https://developer.nrel.gov/docs/energy-optimization/reopt-v1/](https://developer.nrel.gov/docs/energy-optimization/reopt-v1/) for more detailed information on input parameters and default assumptions.
|
87
|
+
|
88
|
+
<b>Note:</b> Required attributes for a REopt run include latitude and longitude. If no utility rate is specified in your REopt Lite assumption settings, then a constant default rate of $0.13 is assumed without demand charges. Also, by default, only solar PV and storage are considered in the analysis (i.e. Wind and Generators are excluded from consideration).
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
## Getting Started
|
93
|
+
|
94
|
+
The code below shows how to run the REopt API on a single Feature Report hash using this gem:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
require 'urbanopt/reopt'
|
98
|
+
#Load a Feature Report Hash
|
99
|
+
feature_reports_hash = {} # <insert a Feature Report hash here>
|
100
|
+
|
101
|
+
#Create a Feature Report
|
102
|
+
feature_report = URBANopt::Scenario::DefaultReports::FeatureReport.new(feature_reports_hash)
|
103
|
+
|
104
|
+
#Specify a file name where REopt Lite results will be written in JSON format
|
105
|
+
reopt_output_file = File.join(feature_report.directory_name, 'feature_report_reopt_run1.json')
|
106
|
+
|
107
|
+
#Specify a file name where the new timeseries CSV will be written after REopt Lite has determined cost optimal dispatch
|
108
|
+
timeseries_output_file = File.join(feature_report.directory_name, 'feature_report_timeseries1.csv')
|
109
|
+
|
110
|
+
#Specify non-default REopt Lite assumptions, saved in JSON format, to be used in calling the API
|
111
|
+
reopt_assumptions_file = File.join(File.dirname(__FILE__), '../files/reopt_assumptions_basic.json')
|
112
|
+
|
113
|
+
#Create a REopt Lite Post Processor to call the API, note you will need a Developer.nrel.gov API key in this step
|
114
|
+
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(nil, nil, nil, DEVELOPER_NREL_KEY)
|
115
|
+
|
116
|
+
#Call REopt Lite with the post processor to update the feature's distributed generation attributes and timeseries CSV.
|
117
|
+
updated_feature_report = reopt_post_processor.run_feature_report(feature_report,reopt_assumptions_file,reopt_output_file,timeseries_output_file)
|
118
|
+
|
119
|
+
```
|
120
|
+
|
121
|
+
More commonly, this gem can be used to run REopt a collection of features stored in a Scenario Report as show here:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
require 'urbanopt/reopt'
|
125
|
+
#Create a Scenario Report
|
126
|
+
scenario_report = URBANopt::Scenario::DefaultReports::ScenarioReport.new({:directory_name => File.join(File.dirname(__FILE__), '../run/example_scenario'), :timeseries_csv => {:path => File.join(File.dirname(__FILE__), '../run/example_scenario/timeseries.csv') }})
|
127
|
+
|
128
|
+
#Load Feature Reports into the Scenario Report
|
129
|
+
(1..2).each do |i|
|
130
|
+
feature_reports_path = File.join(File.dirname(__FILE__), "../run/example_scenario/#{i}/010_default_feature_reports/default_feature_reports.json")
|
131
|
+
|
132
|
+
feature_reports_hash = nil
|
133
|
+
File.open(feature_reports_path, 'r') do |file|
|
134
|
+
feature_reports_hash = JSON.parse(file.read, symbolize_names: true)
|
135
|
+
end
|
136
|
+
|
137
|
+
feature_report = URBANopt::Scenario::DefaultReports::FeatureReport.new(feature_reports_hash)
|
138
|
+
|
139
|
+
feature_report_dir = File.join(File.dirname(__FILE__), "../run/example_scenario/#{i}")
|
140
|
+
feature_report.directory_name = feature_report_dir
|
141
|
+
|
142
|
+
scenario_report.add_feature_report(feature_report)
|
143
|
+
end
|
144
|
+
|
145
|
+
#Specify non-default REopt Lite assumptions, saved in JSON format, to be used in calling the API
|
146
|
+
reopt_assumptions_file = File.join(File.dirname(__FILE__), '../files/reopt_assumptions_basic.json')
|
147
|
+
|
148
|
+
#Create a REopt Lite Post Processor to call the API, note you will need a Developer.nrel.gov API key in this step
|
149
|
+
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(scenario_report, reopt_assumptions_file, nil, DEVELOPER_NREL_KEY)
|
150
|
+
|
151
|
+
#Call REopt Lite with the post processor once on the sceanrio's aggregated load to update the scenario's distributed generation attributes and timeseries CSV.
|
152
|
+
updated_scenario_report = reopt_post_processor.run_scenario_report(scenario_report)
|
153
|
+
|
154
|
+
```
|
155
|
+
|
156
|
+
## Testing
|
157
|
+
|
158
|
+
First, check out the repository (i.e. git clone this repo).
|
159
|
+
|
160
|
+
Next, obtain a developer.nrel.gov API key from the [NREL Developer Network](https://developer.nrel.gov/]). Copy and paste your key in to the _developer_nrel_key_._rb_ file then save the file:
|
161
|
+
|
162
|
+
DEVELOPER_NREL_KEY = '<insert your key here>'
|
163
|
+
|
164
|
+
Finally, execute:
|
165
|
+
|
166
|
+
$ bundle install
|
167
|
+
$ bundle update
|
168
|
+
$ bundle exec rake
|
169
|
+
|
170
|
+
|
171
|
+
## Releasing
|
172
|
+
|
173
|
+
* Update change log
|
174
|
+
* Update version in `/lib/urbanopt/reopt/version.rb`
|
175
|
+
* Merge down to master
|
176
|
+
* run `rake release` from master
|
data/README.md
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
# URBANopt REopt Gem
|
2
|
+
|
3
|
+
The **URBANopt REopt Gem** extends **URBANopt::Scenario::DefaultReports::ScenarioReport** and **URBANopt::Scenario::DefaultReports::FeatureReport** with the ability to derive cost-optimal distributed energy resource (DER) technology sizes and annual dispatch strageties via the [REopt Lite](https://reopt.nrel.gov/tool) decision support platform.
|
4
|
+
REopt Lite is a technoeconomic model which leverages mixed integer linear programming to identify the cost-optimal sizing of solar PV, Wind, Storage and/or diesel generation given an electric load profile, a utility rate tariff and other technoeconomic parameters. See [https://developer.nrel.gov/docs/energy-optimization/reopt-v1/](https://developer.nrel.gov/docs/energy-optimization/reopt-v1/) for more detailed information on input parameters and default assumptions.
|
5
|
+
|
6
|
+
See the [example project](https://github.com/urbanopt/urbanopt-example-geojson-reopt-project) for more infomation about usage of this gem.
|
7
|
+
|
8
|
+
<b>Note:</b> this module requires an API Key from the
|
9
|
+
[NREL Developer Network](https://developer.nrel.gov/)
|
10
|
+
|
11
|
+
[RDoc Documentation](https://urbanopt.github.io/urbanopt-reopt-gem/)
|
12
|
+
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
See [https://docs.urbanopt.net/installation/installation.html](https://docs.urbanopt.net/installation/installation.html) for instructions on prerequiste software, including:
|
17
|
+
- Ruby 2.2.6
|
18
|
+
- Bundler 1.17.0
|
19
|
+
- OpenStudio 2.8.1
|
20
|
+
|
21
|
+
Add this line to your application's Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'urbanopt-reopt'
|
25
|
+
```
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
|
29
|
+
$ bundle install
|
30
|
+
$ bundle update
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install 'urbanopt-reopt'
|
35
|
+
|
36
|
+
## Functionality
|
37
|
+
|
38
|
+
This gem is used to call the REopt Lite API on a Scenario Report or Feature Report to update the object's Distributed Generation attributes (including system financial and sizing metrics) as shown in an example below:
|
39
|
+
```
|
40
|
+
"distributed_generation": {
|
41
|
+
"lcc_us_dollars": 100000000.0,
|
42
|
+
"npv_us_dollars": 10000000.0,
|
43
|
+
"year_one_energy_cost_us_dollars": 7000000.0,
|
44
|
+
"year_one_demand_cost_us_dollars": 3000000.0,
|
45
|
+
"year_one_bill_us_dollars": 10000000.0,
|
46
|
+
"total_energy_cost_us_dollars": 70000000.0,
|
47
|
+
"solar_pv": {
|
48
|
+
"size_kw": 30000.0
|
49
|
+
},
|
50
|
+
"wind": {
|
51
|
+
"size_kw": 0.0
|
52
|
+
},
|
53
|
+
"generator": {
|
54
|
+
"size_kw": 0.0
|
55
|
+
},
|
56
|
+
"storage": {
|
57
|
+
"size_kw": 2000.0,
|
58
|
+
"size_kwh": 5000.0
|
59
|
+
}
|
60
|
+
}
|
61
|
+
```
|
62
|
+
|
63
|
+
Moreover, the following optimal dispatch fields are added to its timeseries CSV. Where no system component is recommended the dispatch will be all zero (i.e. if no solar PV is recommended ElectricityProduced:PV:Total will be always be zero)
|
64
|
+
|
65
|
+
| output | unit |
|
66
|
+
| -----------------------------------------| ------- |
|
67
|
+
| ElectricityProduced:Total | kWh |
|
68
|
+
| Electricity:Load:Total | kWh |
|
69
|
+
| Electricity:Grid:ToLoad | kWh |
|
70
|
+
| Electricity:Grid:ToBattery | kWh |
|
71
|
+
| Electricity:Storage:ToLoad | kWh |
|
72
|
+
| Electricity:Storage:ToGrid | kWh |
|
73
|
+
| Electricity:Storage:StateOfCharge | kWh |
|
74
|
+
| ElectricityProduced:Generator:Total | kWh |
|
75
|
+
| ElectricityProduced:Generator:ToBattery | kWh |
|
76
|
+
| ElectricityProduced:Generator:ToLoad | kWh |
|
77
|
+
| ElectricityProduced:Generator:ToGrid | kWh |
|
78
|
+
| ElectricityProduced:PV:Total | kWh |
|
79
|
+
| ElectricityProduced:PV:ToBattery | kWh |
|
80
|
+
| ElectricityProduced:PV:ToLoad | kWh |
|
81
|
+
| ElectricityProduced:PV:ToGrid | kWh |
|
82
|
+
| ElectricityProduced:Wind:Total | kWh |
|
83
|
+
| ElectricityProduced:Wind:ToBattery | kWh |
|
84
|
+
| ElectricityProduced:Wind:ToLoad | kWh |
|
85
|
+
| ElectricityProduced:Wind:ToGrid | kWh |
|
86
|
+
|
87
|
+
|
88
|
+
The REopt Lite has default values for all non-required input parameters that are used unless the user specifies custom assumptions. See <StaticLink target="\_blank" href="https://developer.nrel.gov/docs/energy-optimization/reopt-v1/">https://developer.nrel.gov/docs/energy-optimization/reopt-v1/</StaticLink> for more detailed information on input parameters and default assumptions.
|
89
|
+
|
90
|
+
<b>Note:</b> Required attributes for a REopt run include latitude and longitude. If no utility rate is specified in your REopt Lite assumption settings, then a constant default rate of $0.13 is assumed without demand charges. Also, by default, only solar PV and storage are considered in the analysis (i.e. Wind and Generators are excluded from consideration).
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
## Getting Started
|
95
|
+
|
96
|
+
The code below shows how to run the REopt API on a single Feature Report hash using this gem:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
require 'urbanopt/reopt'
|
100
|
+
#Load a Feature Report Hash
|
101
|
+
feature_reports_hash = {} # <insert a Feature Report hash here>
|
102
|
+
|
103
|
+
#Create a Feature Report
|
104
|
+
feature_report = URBANopt::Scenario::DefaultReports::FeatureReport.new(feature_reports_hash)
|
105
|
+
|
106
|
+
#Specify a file name where REopt Lite results will be written in JSON format
|
107
|
+
reopt_output_file = File.join(feature_report.directory_name, 'feature_report_reopt_run1.json')
|
108
|
+
|
109
|
+
#Specify a file name where the new timeseries CSV will be written after REopt Lite has determined cost optimal dispatch
|
110
|
+
timeseries_output_file = File.join(feature_report.directory_name, 'feature_report_timeseries1.csv')
|
111
|
+
|
112
|
+
#Specify non-default REopt Lite assumptions, saved in JSON format, to be used in calling the API
|
113
|
+
reopt_assumptions_file = File.join(File.dirname(__FILE__), '../files/reopt_assumptions_basic.json')
|
114
|
+
|
115
|
+
#Create a REopt Lite Post Processor to call the API, note you will need a Developer.nrel.gov API key in this step
|
116
|
+
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(nil, nil, nil, DEVELOPER_NREL_KEY)
|
117
|
+
|
118
|
+
#Call REopt Lite with the post processor to update the feature's distributed generation attributes and timeseries CSV.
|
119
|
+
updated_feature_report = reopt_post_processor.run_feature_report(feature_report,reopt_assumptions_file,reopt_output_file,timeseries_output_file)
|
120
|
+
|
121
|
+
```
|
122
|
+
|
123
|
+
More commonly, this gem can be used to run REopt a collection of features stored in a Scenario Report as show here:
|
124
|
+
```ruby
|
125
|
+
require 'urbanopt/reopt'
|
126
|
+
#Create a Scenario Report
|
127
|
+
scenario_report = URBANopt::Scenario::DefaultReports::ScenarioReport.new({:directory_name => File.join(File.dirname(__FILE__), '../run/example_scenario'), :timeseries_csv => {:path => File.join(File.dirname(__FILE__), '../run/example_scenario/timeseries.csv') }})
|
128
|
+
|
129
|
+
#Load Feature Reports into the Scenario Report
|
130
|
+
(1..2).each do |i|
|
131
|
+
feature_reports_path = File.join(File.dirname(__FILE__), "../run/example_scenario/#{i}/010_default_feature_reports/default_feature_reports.json")
|
132
|
+
|
133
|
+
feature_reports_hash = nil
|
134
|
+
File.open(feature_reports_path, 'r') do |file|
|
135
|
+
feature_reports_hash = JSON.parse(file.read, symbolize_names: true)
|
136
|
+
end
|
137
|
+
|
138
|
+
feature_report = URBANopt::Scenario::DefaultReports::FeatureReport.new(feature_reports_hash)
|
139
|
+
|
140
|
+
feature_report_dir = File.join(File.dirname(__FILE__), "../run/example_scenario/#{i}")
|
141
|
+
feature_report.directory_name = feature_report_dir
|
142
|
+
|
143
|
+
scenario_report.add_feature_report(feature_report)
|
144
|
+
end
|
145
|
+
|
146
|
+
#Specify non-default REopt Lite assumptions, saved in JSON format, to be used in calling the API
|
147
|
+
reopt_assumptions_file = File.join(File.dirname(__FILE__), '../files/reopt_assumptions_basic.json')
|
148
|
+
|
149
|
+
#Create a REopt Lite Post Processor to call the API, note you will need a Developer.nrel.gov API key in this step
|
150
|
+
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(scenario_report, reopt_assumptions_file, nil, DEVELOPER_NREL_KEY)
|
151
|
+
|
152
|
+
#Call REopt Lite with the post processor once on the sceanrio's aggregated load to update the scenario's distributed generation attributes and timeseries CSV.
|
153
|
+
updated_scenario_report = reopt_post_processor.run_scenario_report(scenario_report)
|
154
|
+
|
155
|
+
```
|
156
|
+
|
157
|
+
## Testing
|
158
|
+
|
159
|
+
First, check out the repository (i.e. git clone this repo).
|
160
|
+
|
161
|
+
Next, obtain a developer.nrel.gov API key from the [NREL Developer Network](https://developer.nrel.gov/]). Copy and paste your key in to the _developer_nrel_key_._rb_ file then save the file:
|
162
|
+
|
163
|
+
DEVELOPER_NREL_KEY = '<insert your key here>'
|
164
|
+
|
165
|
+
Finally, execute:
|
166
|
+
|
167
|
+
$ bundle install
|
168
|
+
$ bundle update
|
169
|
+
$ bundle exec rake
|
170
|
+
|
171
|
+
|
172
|
+
## Releasing
|
173
|
+
|
174
|
+
* Update change log
|
175
|
+
* Update version in `/lib/urbanopt/reopt/version.rb`
|
176
|
+
* Merge down to master
|
177
|
+
* run `rake release` from master
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
require 'rubocop/rake_task'
|
7
|
+
RuboCop::RakeTask.new
|
8
|
+
|
9
|
+
# Load in the rake tasks from the base openstudio-extension gem
|
10
|
+
require 'openstudio/extension/rake_task'
|
11
|
+
require 'urbanopt/reopt/extension'
|
12
|
+
os_extension = OpenStudio::Extension::RakeTask.new
|
13
|
+
os_extension.set_extension_class(URBANopt::REopt::Extension)
|
14
|
+
|
15
|
+
desc 'CLI OpenSSL test'
|
16
|
+
task :cli_openssl_test do
|
17
|
+
runner = OpenStudio::Extension::Runner.new(URBANopt::REopt::Extension.new.root_dir)
|
18
|
+
|
19
|
+
cli = OpenStudio.getOpenStudioCLI
|
20
|
+
the_call = "#{cli} --verbose --bundle '#{runner.gemfile_path}' --bundle_path '#{runner.bundle_install_path}' ./spec/cli_openssl_test.rb"
|
21
|
+
|
22
|
+
puts 'SYSTEM CALL:'
|
23
|
+
puts the_call
|
24
|
+
STDOUT.flush
|
25
|
+
result = runner.run_command(the_call)
|
26
|
+
puts "DONE, result = #{result}"
|
27
|
+
STDOUT.flush
|
28
|
+
end
|
29
|
+
|
30
|
+
task default: :spec
|
data/deploy_docs.sh
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# *********************************************************************************
|
2
|
+
# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
|
3
|
+
# contributors. All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
# are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# Redistributions of source code must retain the above copyright notice, this list
|
9
|
+
# of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer in the documentation and/or other
|
13
|
+
# materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without specific
|
17
|
+
# prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
20
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
21
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
22
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
23
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
24
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
26
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
27
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
28
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
# *********************************************************************************
|
30
|
+
|
31
|
+
DEVELOPER_NREL_KEY = (ENV['GEM_DEVELOPER_KEY'] || '< your key here https://developer.nrel.gov/signup >')
|