urbanopt-reopt 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/nightly_build.yml +36 -0
- data/CHANGELOG.md +10 -0
- data/RDOC_MAIN.md +2 -2
- data/README.md +4 -2
- data/docs/README.md +2 -2
- data/docs/package-lock.json +23 -41
- data/index.md +2 -2
- data/lib/urbanopt/reopt/reopt_lite_api.rb +20 -16
- data/lib/urbanopt/reopt/reopt_logger.rb +3 -0
- data/lib/urbanopt/reopt/reopt_post_processor.rb +5 -8
- data/lib/urbanopt/reopt/reopt_schema/reopt_input_schema.json +1 -2
- data/lib/urbanopt/reopt/scenario_report_adapter.rb +25 -28
- data/lib/urbanopt/reopt/version.rb +1 -1
- data/urbanopt-reopt.gemspec +3 -1
- metadata +33 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcab5483cee799a1e44ed9d9ecba63a8ac92c4437c62c0dd25af52b4afbc7173
|
4
|
+
data.tar.gz: 85249e213f43e34ba0b912e591de4b97f32ab8c720023a21b44fe09a8990b400
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7d8a115244f0df051d199829c00ea1b6d43f4163a5cb3dd07e4df249ba067a4d52dbf7ba20373a7d20b3ef1ed254c64c233d5812b4d094b538dad6ee9a1096c
|
7
|
+
data.tar.gz: daecf105673a8fa10a26626c6d253c5e096028e223d9cd27339b25ef5f267c771a796195cc1d72d378a15a9e4dd63fc0db14e26fd49923d66d49f06b504f7adc
|
@@ -0,0 +1,36 @@
|
|
1
|
+
name: nightly_build
|
2
|
+
|
3
|
+
on:
|
4
|
+
# push:
|
5
|
+
schedule:
|
6
|
+
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
|
7
|
+
# 5:23 am UTC (11:23pm MDT the day before) every weekday night in MDT
|
8
|
+
- cron: '23 5 * * 2-6'
|
9
|
+
|
10
|
+
env:
|
11
|
+
# This env var should enforce develop branch of all dependencies
|
12
|
+
FAVOR_LOCAL_GEMS: true
|
13
|
+
GEM_DEVELOPER_KEY: ${{ secrets.GEM_DEVELOPER_KEY }}
|
14
|
+
|
15
|
+
jobs:
|
16
|
+
weeknight-tests:
|
17
|
+
# Pinned to `ubuntu-20.04`. When ubuntu-latest adopts 22.04 it would break for us since 22 only supports Ruby 3.1
|
18
|
+
# https://github.com/ruby/setup-ruby#supported-platforms
|
19
|
+
runs-on: ubuntu-20.04
|
20
|
+
container:
|
21
|
+
image: docker://nrel/openstudio:3.4.0
|
22
|
+
steps:
|
23
|
+
- name: Checkout code
|
24
|
+
uses: actions/checkout@v3
|
25
|
+
- name: Update gems
|
26
|
+
run: |
|
27
|
+
bundle update
|
28
|
+
bundle exec certified-update
|
29
|
+
- name: Run Rspec
|
30
|
+
run: bundle exec rspec
|
31
|
+
# coveralls action docs: https://github.com/marketplace/actions/coveralls-github-action
|
32
|
+
- name: Coveralls
|
33
|
+
uses: coverallsapp/github-action@master
|
34
|
+
with:
|
35
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
36
|
+
path-to-lcov: "./coverage/lcov/urbanopt-reopt-gem.lcov"
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# URBANopt REopt Gem
|
2
2
|
|
3
|
+
## Version 0.9.0
|
4
|
+
|
5
|
+
Date Range: 05/11/22 - 12/13/22
|
6
|
+
|
7
|
+
- Update dependencies for OpenStudio 3.5.0
|
8
|
+
- Fixed [#102]( https://github.com/urbanopt/urbanopt-reopt-gem/issues/102 ), update REopt API to v2 by 10/1/2022
|
9
|
+
- Fixed [#113]( https://github.com/urbanopt/urbanopt-reopt-gem/issues/113 ), Passing test includes an output error.
|
10
|
+
- Fixed [#122]( https://github.com/urbanopt/urbanopt-reopt-gem/issues/122 ), REopt gem test review
|
11
|
+
- Fixed [#124]( https://github.com/urbanopt/urbanopt-reopt-gem/issues/124 ), Code coverage reporting
|
12
|
+
|
3
13
|
## Version 0.8.0
|
4
14
|
|
5
15
|
Date Range: 11/23/21 - 05/10/22
|
data/RDOC_MAIN.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# **URBANopt REopt Gem**
|
2
2
|
|
3
3
|
The **URBANopt™ REopt Gem** extends **URBANopt::Reporting::DefaultReports::ScenarioReport** and **URBANopt::Reporting::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
|
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/v2/](https://developer.nrel.gov/docs/energy-optimization/reopt/v2/) for more detailed information on input parameters and default assumptions.
|
5
5
|
|
6
6
|
See the [example project](https://github.com/urbanopt/urbanopt-example-reopt-project.git) for more infomation about usage of this gem.
|
7
7
|
|
@@ -83,7 +83,7 @@ Moreover, the following optimal dispatch fields are added to its timeseries CSV.
|
|
83
83
|
| ElectricityProduced:Wind:ToGrid | kWh |
|
84
84
|
```
|
85
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
|
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/v2/](https://developer.nrel.gov/docs/energy-optimization/reopt/v2/) for more detailed information on input parameters and default assumptions.
|
87
87
|
|
88
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
89
|
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# URBANopt REopt Gem
|
2
2
|
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/github/urbanopt/urbanopt-reopt-gem/badge.svg?branch=github-actions-coveralls)](https://coveralls.io/github/urbanopt/urbanopt-reopt-gem?branch=github-actions-coveralls)
|
4
|
+
|
3
5
|
The **URBANopt<sup>™</sup> REopt Gem** extends **URBANopt::Reporting::DefaultReports::ScenarioReport** and **URBANopt::Reporting::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
|
6
|
+
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/v2/](https://developer.nrel.gov/docs/energy-optimization/reopt/v2/) for more detailed information on input parameters and default assumptions.
|
5
7
|
|
6
8
|
See the [example project](https://github.com/urbanopt/urbanopt-example-geojson-reopt-project) for more infomation about usage of this gem.
|
7
9
|
|
@@ -85,7 +87,7 @@ Moreover, the following optimal dispatch fields are added to its timeseries CSV.
|
|
85
87
|
| ElectricityProduced:Wind:ToGrid | kWh |
|
86
88
|
|
87
89
|
|
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
|
90
|
+
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/v2/">https://developer.nrel.gov/docs/energy-optimization/reopt/v2/</StaticLink> for more detailed information on input parameters and default assumptions.
|
89
91
|
|
90
92
|
<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
93
|
|
data/docs/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
### <StaticLink target="\_blank" href="rdoc/">Rdocs</StaticLink>
|
4
4
|
|
5
5
|
The **URBANopt<sup>™</sup> REopt Gem** extends a **URBANopt::Reporting::DefaultReports::ScenarioReport** and **URBANopt::Reporting::DefaultReports::FeatureReport** with the ability to derive cost-optimal distributed energy resource (DER) technology sizes and annual dispatch strageties via the <StaticLink target="\_blank" href="https://reopt.nrel.gov/tool">REopt Lite</StaticLink> decision support platform.
|
6
|
-
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 <StaticLink target="\_blank" href="https://developer.nrel.gov/docs/energy-optimization/reopt
|
6
|
+
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 <StaticLink target="\_blank" href="https://developer.nrel.gov/docs/energy-optimization/reopt/v2/">https://developer.nrel.gov/docs/energy-optimization/reopt/v2/</StaticLink> for more detailed information on input parameters and default assumptions.
|
7
7
|
|
8
8
|
The REopt Gem accomplishes three basic functions (described more below in the _Functionality_ section):
|
9
9
|
|
@@ -99,7 +99,7 @@ Moreover, the following optimal dispatch fields are added to its timeseries CSV.
|
|
99
99
|
| ElectricityProduced:Wind:ToGrid | kWh |
|
100
100
|
|
101
101
|
|
102
|
-
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
|
102
|
+
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/v2/">https://developer.nrel.gov/docs/energy-optimization/reopt/v2/</StaticLink> for more detailed information on input parameters and default assumptions.
|
103
103
|
|
104
104
|
<b>Note:</b> Required attributes for a REopt run include latitude and longitude, parsed from the Feature or Scenario Report attributes. If no utility rate is specified in your assumptions, then a constant 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).
|
105
105
|
|
data/docs/package-lock.json
CHANGED
@@ -6650,13 +6650,10 @@
|
|
6650
6650
|
}
|
6651
6651
|
},
|
6652
6652
|
"node_modules/eventsource": {
|
6653
|
-
"version": "1.1.
|
6654
|
-
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.
|
6655
|
-
"integrity": "sha512-
|
6653
|
+
"version": "1.1.2",
|
6654
|
+
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz",
|
6655
|
+
"integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==",
|
6656
6656
|
"dev": true,
|
6657
|
-
"dependencies": {
|
6658
|
-
"original": "^1.0.0"
|
6659
|
-
},
|
6660
6657
|
"engines": {
|
6661
6658
|
"node": ">=0.12.0"
|
6662
6659
|
}
|
@@ -7540,7 +7537,7 @@
|
|
7540
7537
|
"node_modules/glob-parent": {
|
7541
7538
|
"version": "3.1.0",
|
7542
7539
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
7543
|
-
"integrity": "
|
7540
|
+
"integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
|
7544
7541
|
"dev": true,
|
7545
7542
|
"dependencies": {
|
7546
7543
|
"is-glob": "^3.1.0",
|
@@ -10453,15 +10450,6 @@
|
|
10453
10450
|
"webpack": "^4.0.0"
|
10454
10451
|
}
|
10455
10452
|
},
|
10456
|
-
"node_modules/original": {
|
10457
|
-
"version": "1.0.2",
|
10458
|
-
"resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
|
10459
|
-
"integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
|
10460
|
-
"dev": true,
|
10461
|
-
"dependencies": {
|
10462
|
-
"url-parse": "^1.4.3"
|
10463
|
-
}
|
10464
|
-
},
|
10465
10453
|
"node_modules/os-browserify": {
|
10466
10454
|
"version": "0.3.0",
|
10467
10455
|
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
|
@@ -14448,9 +14436,9 @@
|
|
14448
14436
|
}
|
14449
14437
|
},
|
14450
14438
|
"node_modules/terser": {
|
14451
|
-
"version": "4.8.
|
14452
|
-
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.
|
14453
|
-
"integrity": "sha512-
|
14439
|
+
"version": "4.8.1",
|
14440
|
+
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
|
14441
|
+
"integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
|
14454
14442
|
"dev": true,
|
14455
14443
|
"dependencies": {
|
14456
14444
|
"commander": "^2.20.0",
|
@@ -15682,7 +15670,10 @@
|
|
15682
15670
|
"node_modules/watchpack/chokidar2": {
|
15683
15671
|
"version": "0.0.1",
|
15684
15672
|
"dev": true,
|
15685
|
-
"optional": true
|
15673
|
+
"optional": true,
|
15674
|
+
"dependencies": {
|
15675
|
+
"chokidar": "^2.1.8"
|
15676
|
+
}
|
15686
15677
|
},
|
15687
15678
|
"node_modules/wbuf": {
|
15688
15679
|
"version": "1.7.3",
|
@@ -19823,7 +19814,10 @@
|
|
19823
19814
|
}
|
19824
19815
|
},
|
19825
19816
|
"chokidar2": {
|
19826
|
-
"version": "file:node_modules/watchpack/chokidar2"
|
19817
|
+
"version": "file:node_modules/watchpack/chokidar2",
|
19818
|
+
"requires": {
|
19819
|
+
"chokidar": "^2.1.8"
|
19820
|
+
}
|
19827
19821
|
},
|
19828
19822
|
"chownr": {
|
19829
19823
|
"version": "1.1.4",
|
@@ -21663,13 +21657,10 @@
|
|
21663
21657
|
"dev": true
|
21664
21658
|
},
|
21665
21659
|
"eventsource": {
|
21666
|
-
"version": "1.1.
|
21667
|
-
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.
|
21668
|
-
"integrity": "sha512-
|
21669
|
-
"dev": true
|
21670
|
-
"requires": {
|
21671
|
-
"original": "^1.0.0"
|
21672
|
-
}
|
21660
|
+
"version": "1.1.2",
|
21661
|
+
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz",
|
21662
|
+
"integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==",
|
21663
|
+
"dev": true
|
21673
21664
|
},
|
21674
21665
|
"evp_bytestokey": {
|
21675
21666
|
"version": "1.0.3",
|
@@ -22363,7 +22354,7 @@
|
|
22363
22354
|
"glob-parent": {
|
22364
22355
|
"version": "3.1.0",
|
22365
22356
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
22366
|
-
"integrity": "
|
22357
|
+
"integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
|
22367
22358
|
"dev": true,
|
22368
22359
|
"requires": {
|
22369
22360
|
"is-glob": "^3.1.0",
|
@@ -24673,15 +24664,6 @@
|
|
24673
24664
|
"last-call-webpack-plugin": "^3.0.0"
|
24674
24665
|
}
|
24675
24666
|
},
|
24676
|
-
"original": {
|
24677
|
-
"version": "1.0.2",
|
24678
|
-
"resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
|
24679
|
-
"integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
|
24680
|
-
"dev": true,
|
24681
|
-
"requires": {
|
24682
|
-
"url-parse": "^1.4.3"
|
24683
|
-
}
|
24684
|
-
},
|
24685
24667
|
"os-browserify": {
|
24686
24668
|
"version": "0.3.0",
|
24687
24669
|
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
|
@@ -27835,9 +27817,9 @@
|
|
27835
27817
|
"dev": true
|
27836
27818
|
},
|
27837
27819
|
"terser": {
|
27838
|
-
"version": "4.8.
|
27839
|
-
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.
|
27840
|
-
"integrity": "sha512-
|
27820
|
+
"version": "4.8.1",
|
27821
|
+
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
|
27822
|
+
"integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
|
27841
27823
|
"dev": true,
|
27842
27824
|
"requires": {
|
27843
27825
|
"commander": "^2.20.0",
|
data/index.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# **URBANopt REopt Gem**
|
2
2
|
|
3
3
|
The **URBANopt<sup>™</sup> REopt Gem** extends **URBANopt::Reporting::DefaultReports::ScenarioReport** and **URBANopt::Reporting::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
|
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/v2/](https://developer.nrel.gov/docs/energy-optimization/reopt/v2/) for more detailed information on input parameters and default assumptions.
|
5
5
|
|
6
6
|
See the [example project](https://github.com/urbanopt/urbanopt-example-reopt-project.git) for more infomation about usage of this gem.
|
7
7
|
|
@@ -83,7 +83,7 @@ Moreover, the following optimal dispatch fields are added to its timeseries CSV.
|
|
83
83
|
| ElectricityProduced:Wind:ToGrid | kWh |
|
84
84
|
```
|
85
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
|
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/v2/](https://developer.nrel.gov/docs/energy-optimization/reopt/v2/) for more detailed information on input parameters and default assumptions.
|
87
87
|
|
88
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
89
|
|
@@ -31,7 +31,6 @@
|
|
31
31
|
require 'net/https'
|
32
32
|
require 'openssl'
|
33
33
|
require 'uri'
|
34
|
-
require 'uri'
|
35
34
|
require 'json'
|
36
35
|
require 'securerandom'
|
37
36
|
require 'certified'
|
@@ -55,8 +54,8 @@ module URBANopt # :nodoc:
|
|
55
54
|
def initialize(nrel_developer_key = nil, use_localhost = false)
|
56
55
|
@use_localhost = use_localhost
|
57
56
|
if @use_localhost
|
58
|
-
@uri_submit = URI.parse('http//:127.0.0.1:8000/
|
59
|
-
@uri_submit_outagesimjob = URI.parse('http//:127.0.0.1:8000/
|
57
|
+
@uri_submit = URI.parse('http//:127.0.0.1:8000/v2/job/')
|
58
|
+
@uri_submit_outagesimjob = URI.parse('http//:127.0.0.1:8000/v2/outagesimjob/')
|
60
59
|
else
|
61
60
|
if [nil, '', '<insert your key here>'].include? nrel_developer_key
|
62
61
|
if [nil, '', '<insert your key here>'].include? DEVELOPER_NREL_KEY
|
@@ -66,8 +65,8 @@ module URBANopt # :nodoc:
|
|
66
65
|
end
|
67
66
|
end
|
68
67
|
@nrel_developer_key = nrel_developer_key
|
69
|
-
@uri_submit = URI.parse("https://developer.nrel.gov/api/reopt/
|
70
|
-
@uri_submit_outagesimjob = URI.parse("https://developer.nrel.gov/api/reopt/
|
68
|
+
@uri_submit = URI.parse("https://developer.nrel.gov/api/reopt/v2/job?api_key=#{@nrel_developer_key}")
|
69
|
+
@uri_submit_outagesimjob = URI.parse("https://developer.nrel.gov/api/reopt/v2/outagesimjob?api_key=#{@nrel_developer_key}")
|
71
70
|
# initialize @@logger
|
72
71
|
@@logger ||= URBANopt::REopt.reopt_logger
|
73
72
|
end
|
@@ -85,10 +84,10 @@ module URBANopt # :nodoc:
|
|
85
84
|
##
|
86
85
|
def uri_results(run_uuid) # :nodoc:
|
87
86
|
if @use_localhost
|
88
|
-
return URI.parse("http://127.0.0.1:8000/
|
87
|
+
return URI.parse("http://127.0.0.1:8000/v2/job/#{run_uuid}/results")
|
89
88
|
end
|
90
89
|
|
91
|
-
return URI.parse("https://developer.nrel.gov/api/reopt/
|
90
|
+
return URI.parse("https://developer.nrel.gov/api/reopt/v2/job/#{run_uuid}/results?api_key=#{@nrel_developer_key}")
|
92
91
|
end
|
93
92
|
|
94
93
|
##
|
@@ -103,26 +102,31 @@ module URBANopt # :nodoc:
|
|
103
102
|
##
|
104
103
|
def uri_resilience(run_uuid) # :nodoc:
|
105
104
|
if @use_localhost
|
106
|
-
return URI.parse("http://127.0.0.1:8000/
|
105
|
+
return URI.parse("http://127.0.0.1:8000/v2/job/#{run_uuid}/resilience_stats")
|
107
106
|
end
|
108
107
|
|
109
|
-
return URI.parse("https://developer.nrel.gov/api/reopt/
|
108
|
+
return URI.parse("https://developer.nrel.gov/api/reopt/v2/job/#{run_uuid}/resilience_stats?api_key=#{@nrel_developer_key}")
|
110
109
|
end
|
111
110
|
|
112
|
-
def make_request(http,
|
111
|
+
def make_request(http, req, max_tries = 3)
|
113
112
|
result = nil
|
114
113
|
tries = 0
|
115
114
|
while tries < max_tries
|
116
115
|
begin
|
117
|
-
result = http.request(
|
116
|
+
result = http.request(req)
|
118
117
|
# Result codes sourced from https://developer.nrel.gov/docs/errors/
|
119
118
|
if result.code == '429'
|
120
119
|
@@logger.fatal('Exceeded the REopt-Lite API limit of 300 requests per hour')
|
121
120
|
puts 'Using the URBANopt CLI to submit a Scenario optimization counts as one request per scenario'
|
122
121
|
puts 'Using the URBANopt CLI to submit a Feature optimization counts as one request per feature'
|
123
122
|
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')
|
123
|
+
elsif result.code == '404'
|
124
|
+
@@logger.info("REOpt is still calculating. We'll give it a moment and check again")
|
125
|
+
sleep 15
|
126
|
+
tries += 1
|
127
|
+
next
|
124
128
|
elsif (result.code != '201') && (result.code != '200') # Anything in the 200s is success
|
125
|
-
@@logger.
|
129
|
+
@@logger.warn("REopt-Lite has returned a '#{result.code}' status code. Visit https://developer.nrel.gov/docs/errors/ for more status code information")
|
126
130
|
# display error messages
|
127
131
|
json_res = JSON.parse(result.body, allow_nan: true)
|
128
132
|
json_res['messages'].delete('warnings') if json_res['messages']['warnings']
|
@@ -341,10 +345,10 @@ module URBANopt # :nodoc:
|
|
341
345
|
sleep 5
|
342
346
|
end
|
343
347
|
|
344
|
-
|
345
|
-
|
348
|
+
max_retry = 5
|
349
|
+
tries = 0
|
346
350
|
(check_complete = sizes == 0) && ((data['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0) > 0)
|
347
|
-
while (
|
351
|
+
while (tries < max_retry) && check_complete
|
348
352
|
sleep 3
|
349
353
|
response = make_request(http, get_request)
|
350
354
|
data = JSON.parse(response.body, allow_nan: true)
|
@@ -358,7 +362,7 @@ module URBANopt # :nodoc:
|
|
358
362
|
end
|
359
363
|
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)
|
360
364
|
(check_complete = sizes == 0) && ((data['outputs']['Scenario']['Site']['Financial']['npv_us_dollars'] || 0) > 0)
|
361
|
-
|
365
|
+
tries += 1
|
362
366
|
end
|
363
367
|
|
364
368
|
data = JSON.parse(response.body, allow_nan: true)
|
@@ -33,6 +33,9 @@ require 'logger'
|
|
33
33
|
module URBANopt
|
34
34
|
module REopt
|
35
35
|
@@reopt_logger = Logger.new($stdout)
|
36
|
+
|
37
|
+
# Set Logger::DEBUG for development
|
38
|
+
@@reopt_logger.level = Logger::WARN
|
36
39
|
##
|
37
40
|
# Definining class variable "@@logger" to log errors, info and warning messages.
|
38
41
|
def self.reopt_logger
|
@@ -83,9 +83,6 @@ module URBANopt # :nodoc:
|
|
83
83
|
@@logger.info("Created directory: #{File.join(fr.directory_name, 'reopt')}")
|
84
84
|
end
|
85
85
|
@feature_reports_reopt_default_output_files << File.join(fr.directory_name, "reopt/feature_report_#{fr.id}_reopt_run.json")
|
86
|
-
end
|
87
|
-
|
88
|
-
@scenario_report.feature_reports.each do |fr|
|
89
86
|
@feature_reports_timeseries_default_output_files << File.join(fr.directory_name, "feature_report_#{fr.id}_timeseries.csv")
|
90
87
|
end
|
91
88
|
end
|
@@ -129,13 +126,13 @@ module URBANopt # :nodoc:
|
|
129
126
|
reopt_output_file = File.join(feature_report.directory_name, 'reopt')
|
130
127
|
end
|
131
128
|
reopt_output = api.reopt_request(reopt_input, reopt_output_file)
|
132
|
-
|
129
|
+
@@logger.debug("REOpt output file: #{reopt_output_file}")
|
133
130
|
if run_resilience
|
134
131
|
run_uuid = reopt_output['outputs']['Scenario']['run_uuid']
|
135
132
|
if File.directory? reopt_output_file
|
136
133
|
resilience_stats = api.resilience_request(run_uuid, reopt_output_file)
|
137
134
|
else
|
138
|
-
resilience_stats = api.resilience_request(run_uuid, reopt_output_file.sub
|
135
|
+
resilience_stats = api.resilience_request(run_uuid, reopt_output_file.sub('.json', '_resilience.json'))
|
139
136
|
end
|
140
137
|
else
|
141
138
|
resilience_stats = nil
|
@@ -160,7 +157,7 @@ module URBANopt # :nodoc:
|
|
160
157
|
#
|
161
158
|
# [*return:*] _URBANopt::Scenario::DefaultReports::ScenarioReport_ Returns an updated ScenarioReport
|
162
159
|
def run_scenario_report(scenario_report:, reopt_assumptions_hash: nil, reopt_output_file: nil, timeseries_csv_path: nil, save_name: nil, run_resilience: true, community_photovoltaic: nil)
|
163
|
-
puts
|
160
|
+
puts 'run scenario report'
|
164
161
|
@save_assumptions_filepath = false
|
165
162
|
if !reopt_assumptions_hash.nil?
|
166
163
|
@scenario_reopt_default_assumptions_hash = reopt_assumptions_hash
|
@@ -185,7 +182,7 @@ module URBANopt # :nodoc:
|
|
185
182
|
if File.directory? @scenario_reopt_default_output_file
|
186
183
|
resilience_stats = api.resilience_request(run_uuid, @scenario_reopt_default_output_file)
|
187
184
|
else
|
188
|
-
resilience_stats = api.resilience_request(run_uuid, @scenario_reopt_default_output_file.sub
|
185
|
+
resilience_stats = api.resilience_request(run_uuid, @scenario_reopt_default_output_file.sub('.json', '_resilience.json'))
|
189
186
|
end
|
190
187
|
else
|
191
188
|
resilience_stats = nil
|
@@ -254,7 +251,7 @@ module URBANopt # :nodoc:
|
|
254
251
|
if File.directory? @feature_reports_reopt_default_output_files[idx]
|
255
252
|
resilience_stats = api.resilience_request(run_uuid, @feature_reports_reopt_default_output_files[idx])
|
256
253
|
else
|
257
|
-
resilience_stats = api.resilience_request(run_uuid, @feature_reports_reopt_default_output_files[idx].sub
|
254
|
+
resilience_stats = api.resilience_request(run_uuid, @feature_reports_reopt_default_output_files[idx].sub('.json', '_resilience.json'))
|
258
255
|
end
|
259
256
|
else
|
260
257
|
resilience_stats = nil
|
@@ -75,7 +75,7 @@ module URBANopt # :nodoc:
|
|
75
75
|
lats = []
|
76
76
|
longs = []
|
77
77
|
scenario_report.feature_reports.each do |x|
|
78
|
-
@@logger.
|
78
|
+
@@logger.debug("Latitude '#{x.location.latitude_deg}' in feature report but not in scenario report. Adding it now.")
|
79
79
|
if ![nil].include?(x.location.latitude_deg) && ![nil].include?(x.location.longitude_deg)
|
80
80
|
lats.push(x.location.latitude_deg)
|
81
81
|
longs.push(x.location.longitude_deg)
|
@@ -190,6 +190,29 @@ module URBANopt # :nodoc:
|
|
190
190
|
return results
|
191
191
|
end
|
192
192
|
|
193
|
+
def modrow(data, idx) # :nodoc:
|
194
|
+
data[$generation_timeseries_kwh_col] = $generation_timeseries_kwh[idx] || 0
|
195
|
+
data[$load_col] = $load[idx] || 0
|
196
|
+
data[$utility_to_load_col] = $utility_to_load[idx] || 0
|
197
|
+
data[$utility_to_battery_col] = $utility_to_battery[idx] || 0
|
198
|
+
data[$storage_to_load_col] = $storage_to_load[idx] || 0
|
199
|
+
data[$storage_to_grid_col] = $storage_to_grid[idx] || 0
|
200
|
+
data[$storage_soc_col] = $storage_soc[idx] || 0
|
201
|
+
data[$generator_total_col] = $generator_total[idx] || 0
|
202
|
+
data[$generator_to_battery_col] = $generator_to_battery[idx] || 0
|
203
|
+
data[$generator_to_load_col] = $generator_to_load[idx] || 0
|
204
|
+
data[$generator_to_grid_col] = $generator_to_grid[idx] || 0
|
205
|
+
data[$pv_total_col] = $pv_total[idx] || 0
|
206
|
+
data[$pv_to_battery_col] = $pv_to_battery[idx] || 0
|
207
|
+
data[$pv_to_load_col] = $pv_to_load[idx] || 0
|
208
|
+
data[$pv_to_grid_col] = $pv_to_grid[idx] || 0
|
209
|
+
data[$wind_total_col] = $wind_total[idx] || 0
|
210
|
+
data[$wind_to_battery_col] = $wind_to_battery[idx] || 0
|
211
|
+
data[$wind_to_load_col] = $wind_to_load[idx] || 0
|
212
|
+
data[$wind_to_grid_col] = $wind_to_grid[idx] || 0
|
213
|
+
return data
|
214
|
+
end
|
215
|
+
|
193
216
|
##
|
194
217
|
# Updates a ScenarioReport from a \REopt Lite response
|
195
218
|
#
|
@@ -282,9 +305,6 @@ module URBANopt # :nodoc:
|
|
282
305
|
module_type[pv['pv_name']] = pv_inputs[i]['module_type']
|
283
306
|
end
|
284
307
|
end
|
285
|
-
end
|
286
|
-
|
287
|
-
pv_outputs.each_with_index do |pv, i|
|
288
308
|
scenario_report.distributed_generation.add_tech 'solar_pv', URBANopt::Reporting::DefaultReports::SolarPV.new({ size_kw: (pv['size_kw'] || 0), id: i, location: location[pv['pv_name']], average_yearly_energy_produced_kwh: pv['average_yearly_energy_produced_kwh'], azimuth: azimuth[pv['pv_name']], tilt: tilt[pv['pv_name']], module_type: module_type[pv['pv_name']], gcr: gcr[pv['pv_name']] })
|
289
309
|
end
|
290
310
|
|
@@ -475,36 +495,13 @@ module URBANopt # :nodoc:
|
|
475
495
|
scenario_report.timeseries_csv.column_names.push('REopt:ElectricityProduced:Wind:ToGrid(kw)')
|
476
496
|
end
|
477
497
|
|
478
|
-
def modrow(x, i) # :nodoc:
|
479
|
-
x[$generation_timeseries_kwh_col] = $generation_timeseries_kwh[i] || 0
|
480
|
-
x[$load_col] = $load[i] || 0
|
481
|
-
x[$utility_to_load_col] = $utility_to_load[i] || 0
|
482
|
-
x[$utility_to_battery_col] = $utility_to_battery[i] || 0
|
483
|
-
x[$storage_to_load_col] = $storage_to_load[i] || 0
|
484
|
-
x[$storage_to_grid_col] = $storage_to_grid[i] || 0
|
485
|
-
x[$storage_soc_col] = $storage_soc[i] || 0
|
486
|
-
x[$generator_total_col] = $generator_total[i] || 0
|
487
|
-
x[$generator_to_battery_col] = $generator_to_battery[i] || 0
|
488
|
-
x[$generator_to_load_col] = $generator_to_load[i] || 0
|
489
|
-
x[$generator_to_grid_col] = $generator_to_grid[i] || 0
|
490
|
-
x[$pv_total_col] = $pv_total[i] || 0
|
491
|
-
x[$pv_to_battery_col] = $pv_to_battery[i] || 0
|
492
|
-
x[$pv_to_load_col] = $pv_to_load[i] || 0
|
493
|
-
x[$pv_to_grid_col] = $pv_to_grid[i] || 0
|
494
|
-
x[$wind_total_col] = $wind_total[i] || 0
|
495
|
-
x[$wind_to_battery_col] = $wind_to_battery[i] || 0
|
496
|
-
x[$wind_to_load_col] = $wind_to_load[i] || 0
|
497
|
-
x[$wind_to_grid_col] = $wind_to_grid[i] || 0
|
498
|
-
return x
|
499
|
-
end
|
500
|
-
|
501
498
|
old_data = CSV.open(scenario_report.timeseries_csv.path).read
|
502
499
|
start_date = Time.parse(old_data[1][0]) # Time is the end of the timestep
|
503
500
|
start_ts = (
|
504
501
|
(
|
505
502
|
((start_date.yday - 1) * 60.0 * 60.0 * 24) +
|
506
503
|
((start_date.hour - 1) * 60.0 * 60.0) +
|
507
|
-
(start_date.min * 60.0) + start_date.sec) /
|
504
|
+
(start_date.min * 60.0) + start_date.sec) / \
|
508
505
|
((60 / scenario_report.timesteps_per_hour) * 60)
|
509
506
|
).to_int
|
510
507
|
mod_data = old_data.map.with_index do |x, i|
|
data/urbanopt-reopt.gemspec
CHANGED
@@ -27,8 +27,10 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency 'bundler', '>= 2.1.0'
|
28
28
|
spec.add_development_dependency 'rake', '~> 13.0'
|
29
29
|
spec.add_development_dependency 'rspec', '~> 3.9'
|
30
|
+
spec.add_development_dependency 'simplecov', '~> 0.18.2'
|
31
|
+
spec.add_development_dependency 'simplecov-lcov', '~> 0.8.0'
|
30
32
|
|
31
33
|
spec.add_dependency 'certified', '~> 1'
|
32
34
|
spec.add_dependency 'json_pure', '~> 2'
|
33
|
-
spec.add_dependency 'urbanopt-scenario', '~> 0.
|
35
|
+
spec.add_dependency 'urbanopt-scenario', '~> 0.9.0'
|
34
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: urbanopt-reopt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.18.2
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.18.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov-lcov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.8.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.8.0
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: certified
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +114,14 @@ dependencies:
|
|
86
114
|
requirements:
|
87
115
|
- - "~>"
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
117
|
+
version: 0.9.0
|
90
118
|
type: :runtime
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
122
|
- - "~>"
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
124
|
+
version: 0.9.0
|
97
125
|
description: Classes and measures for utilizing the REopt Lite API within OpenStudio
|
98
126
|
workflows.
|
99
127
|
email:
|
@@ -105,6 +133,7 @@ files:
|
|
105
133
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
106
134
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
107
135
|
- ".github/pull_request_template.md"
|
136
|
+
- ".github/workflows/nightly_build.yml"
|
108
137
|
- ".gitignore"
|
109
138
|
- ".rakeTasks"
|
110
139
|
- ".rdoc_options"
|