urbanopt-cli 0.2.3 → 0.3.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.ruby-version +1 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -5
- data/README.md +27 -14
- data/example_files/Gemfile +4 -10
- data/lib/uo_cli/version.rb +1 -1
- data/lib/uo_cli.rb +194 -151
- data/uo_cli.gemspec +8 -8
- metadata +22 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 300f91ac0998cd778f0cc3a1e250920ef9b4c522170b259b6d670353bb49bd78
|
4
|
+
data.tar.gz: fc8c993cc405be6a972d9e3126bce4df1b4ee983a9797df3a638829190e7f9d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebd6d8338f24f1f1a90dbe790971e9e76ae2fe6017f8536a062b60daf4954aa11d574b13fee67a62469376007dd8d2e902d26f98bc3bd21fe86eae4340813a2d
|
7
|
+
data.tar.gz: 5e3ec3f318c88138869b4001f0ac3b01f1b584904c411036399c65ca07886d62e3027945bca86c5702bf571150cd86a63bceaea13c2c41c826bdabbd6593d63f
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.1
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
|
-
# Specify
|
3
|
+
# Specify dependencies in uo_cli.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
# simplecov has a dependency on native json gem, use fork that does not require this
|
7
|
-
gem 'certified'
|
8
|
-
gem 'simplecov', github: 'NREL/simplecov'
|
9
|
-
|
10
6
|
# Local gems are useful when developing and integrating the various dependencies.
|
11
7
|
# To favor the use of local gems, set the following environment variable:
|
12
8
|
# Mac: export FAVOR_LOCAL_GEMS=1
|
data/README.md
CHANGED
@@ -27,48 +27,61 @@ gem install urbanopt-cli
|
|
27
27
|
For help text in your terminal, type:
|
28
28
|
|
29
29
|
```terminal
|
30
|
-
uo
|
30
|
+
uo --help
|
31
31
|
```
|
32
32
|
|
33
33
|
Create a project folder:
|
34
34
|
|
35
35
|
```terminal
|
36
|
-
uo -
|
36
|
+
uo create --project-folder <FOLDERNAME>
|
37
37
|
```
|
38
38
|
|
39
39
|
Overwrite an existing project folder:
|
40
40
|
|
41
41
|
```terminal
|
42
|
-
uo
|
42
|
+
uo create --overwrite --project-folder <FOLDERNAME>
|
43
43
|
```
|
44
44
|
|
45
45
|
Create an empty project folder without the example files:
|
46
46
|
|
47
47
|
```terminal
|
48
|
-
uo
|
48
|
+
uo create --empty --project-folder <FOLDERNAME>
|
49
|
+
```
|
50
|
+
|
51
|
+
Create ScenarioFiles from a FeatureFile using MapperFiles:
|
52
|
+
|
53
|
+
```terminal
|
54
|
+
uo create --scenario-file <FEATUREFILE>
|
55
|
+
```
|
49
56
|
|
50
|
-
|
57
|
+
Create a ScenarioFile using only a specific FEATURE_ID from a FEATUREFILE:
|
51
58
|
|
52
59
|
```terminal
|
53
|
-
uo
|
60
|
+
uo create --scenario-file <FEATUREFILE> --single-feature <FEATURE_ID>
|
54
61
|
```
|
55
62
|
|
56
|
-
|
63
|
+
Create a REopt ScenarioFile from an existing ScenarioFile:
|
57
64
|
|
58
65
|
```terminal
|
59
|
-
uo
|
66
|
+
uo create --reopt-scenario-file baseline_scenario.csv
|
60
67
|
```
|
61
68
|
|
62
69
|
Run URBANopt energy simulations for each feature in your scenario:
|
63
70
|
|
64
71
|
```terminal
|
65
|
-
uo
|
72
|
+
uo run --scenario <SCENARIOFILE> --feature <FEATUREFILE>
|
73
|
+
```
|
74
|
+
|
75
|
+
Run URBANopt energy simulations for each feature in your scenario, with REopt functionality included:
|
76
|
+
|
77
|
+
```terminal
|
78
|
+
uo run --reopt --scenario <SCENARIOFILE> --feature <FEATUREFILE>
|
66
79
|
```
|
67
80
|
|
68
|
-
|
81
|
+
Post-process simulations for a full scenario:
|
69
82
|
|
70
83
|
```terminal
|
71
|
-
uo
|
84
|
+
uo process --<TYPE> --scenario <SCENARIOFILE> --feature <FEATUREFILE>
|
72
85
|
```
|
73
86
|
|
74
87
|
- Valid `TYPE`s are: `default`, `opendss`, `reopt-scenario`, `reopt-feature`
|
@@ -76,15 +89,15 @@ uo -g -t <TYPE> -s <SCENARIOFILE> -f <FEATUREFILE>
|
|
76
89
|
Delete a scenario you have already run:
|
77
90
|
|
78
91
|
```terminal
|
79
|
-
uo
|
92
|
+
uo delete --scenario <SCENARIOFILE>
|
80
93
|
```
|
81
94
|
|
82
95
|
Installed CLI version:
|
83
96
|
|
84
97
|
```terminal
|
85
|
-
uo
|
98
|
+
uo --version
|
86
99
|
```
|
87
100
|
|
88
101
|
## Development
|
89
102
|
|
90
|
-
To install this gem onto your local machine, clone this repo and run `bundle exec rake install`. If you make changes to this repo, update the version number in `lib/version.rb` in your first commit. When ready to release,
|
103
|
+
To install this gem onto your local machine, clone this repo and run `bundle exec rake install`. If you make changes to this repo, update the version number in `lib/version.rb` in your first commit. When ready to release, [follow the documentation](https://docs.urbanopt.net/developer_resources/release_instructions.html).
|
data/example_files/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
|
-
ruby '2.
|
3
|
+
ruby '~> 2.5.0'
|
4
4
|
|
5
5
|
# Local gems are useful when developing and integrating the various dependencies.
|
6
6
|
# To favor the use of local gems, set the following environment variable:
|
@@ -46,14 +46,14 @@ allow_local = ENV['FAVOR_LOCAL_GEMS']
|
|
46
46
|
# gem 'openstudio-model-articulation', '0.1.0'
|
47
47
|
# end
|
48
48
|
|
49
|
-
gem 'urbanopt-reopt', '0.
|
49
|
+
gem 'urbanopt-reopt', '0.3.0.pre1'
|
50
50
|
|
51
51
|
if allow_local && File.exist?('../urbanopt-scenario-gem')
|
52
52
|
gem 'urbanopt-scenario', path: '../urbanopt-scenario-gem'
|
53
53
|
elsif allow_local
|
54
54
|
gem 'urbanopt-scenario', github: 'URBANopt/urbanopt-scenario-gem', branch: 'develop'
|
55
55
|
else
|
56
|
-
gem 'urbanopt-scenario', '0.
|
56
|
+
gem 'urbanopt-scenario', '0.3.0.pre1'
|
57
57
|
end
|
58
58
|
|
59
59
|
if allow_local && File.exist?('../urbanopt-geojson-gem')
|
@@ -61,11 +61,5 @@ if allow_local && File.exist?('../urbanopt-geojson-gem')
|
|
61
61
|
elsif allow_local
|
62
62
|
gem 'urbanopt-geojson', github: 'URBANopt/urbanopt-geojson-gem', branch: 'develop'
|
63
63
|
else
|
64
|
-
gem 'urbanopt-geojson', '0.
|
64
|
+
gem 'urbanopt-geojson', '0.3.0.pre1'
|
65
65
|
end
|
66
|
-
|
67
|
-
# simplecov has an unneccesary dependency on native json gem, use fork that does not require this
|
68
|
-
gem 'simplecov', github: 'NREL/simplecov'
|
69
|
-
|
70
|
-
# Specify exact rack version temporarily to work with Ruby 2.2.4
|
71
|
-
gem 'rack', '2.1.2'
|
data/lib/uo_cli/version.rb
CHANGED
data/lib/uo_cli.rb
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
# *********************************************************************************
|
32
32
|
|
33
33
|
require 'uo_cli/version'
|
34
|
-
require '
|
34
|
+
require 'optimist'
|
35
35
|
require 'urbanopt/geojson'
|
36
36
|
require 'urbanopt/scenario'
|
37
37
|
require 'urbanopt/reopt'
|
@@ -43,91 +43,139 @@ require_relative '../developer_nrel_key'
|
|
43
43
|
|
44
44
|
module URBANopt
|
45
45
|
module CLI
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
46
|
+
class UrbanOptCLI
|
47
|
+
COMMAND_MAP = {
|
48
|
+
'create' => 'Make new things - project directory or files',
|
49
|
+
'run' => 'Use files in your directory to simulate district energy use',
|
50
|
+
'process' => 'Post-process URBANopt simulations for additional insights',
|
51
|
+
'delete' => 'Delete simulations for a specified scenario'
|
52
|
+
}.freeze
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
@subopts = nil
|
56
|
+
@command = nil
|
57
|
+
@mainopts = Optimist.options do
|
58
|
+
version VERSION
|
59
|
+
banner "\nURBANopt CLI version: #{version}"
|
60
|
+
banner "\nUsage:"
|
61
|
+
banner " uo [options] [<command> [suboptions]]\n \n"
|
62
|
+
banner 'Options:'
|
63
|
+
opt :version, 'Print version and exit' ## add this here or it goes to bottom of help
|
64
|
+
opt :help, 'Show this help message' ## add this here or it goes to bottom of help
|
65
|
+
# opt :no_pager, "Disable paging"
|
66
|
+
stop_on COMMAND_MAP.keys
|
67
|
+
banner "\nCommands:"
|
68
|
+
COMMAND_MAP.each { |cmd, desc| banner format(' %-10s %s', cmd, desc) }
|
69
|
+
banner "\nFor help with a specific command: uo <command> --help"
|
70
|
+
banner "\nAdditional config options can be set with the 'runner.conf' file inside your project folder"
|
71
|
+
banner 'Fewer warnings are presented when using full paths and the user is not inside the project folder'
|
72
|
+
end
|
73
|
+
return if ARGV.empty?
|
74
|
+
@command = ARGV.shift
|
75
|
+
send("opt_#{@command}") ## dispatch to command handling method
|
59
76
|
end
|
60
77
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
"
|
66
|
-
|
67
|
-
|
78
|
+
# Define creation commands
|
79
|
+
def opt_create
|
80
|
+
cmd = @command
|
81
|
+
@subopts = Optimist.options do
|
82
|
+
banner "\nURBANopt #{cmd}:\n \n"
|
83
|
+
|
84
|
+
opt :project_folder, "\nCreate project directory in your current folder. Name the directory\n" \
|
85
|
+
'Example: uo create --project urbanopt_example_project', type: String
|
86
|
+
|
87
|
+
opt :empty, "\nUse with --project-folder argument to create an empty project folder\n" \
|
88
|
+
"Then add your own Feature file in the project directory you created,\n" \
|
89
|
+
"add Weather files in the weather folder and add OpenStudio models of Features\n" \
|
90
|
+
"in the Feature File, if any, in the osm_building folder\n" \
|
91
|
+
"Example: uo create --empty --project-folder urbanopt_example_project\n" \
|
92
|
+
|
93
|
+
opt :overwrite, "\nUse with --project-folder argument to overwrite existing project folder and replace with new project folder.\n" \
|
94
|
+
"May be combined with --empty as well to overwrite existing project folder and replace with new empty project folder.\n" \
|
95
|
+
'Example: uo create --overwrite --empty --project-folder urbanopt_project_folder_I_want_destroyed'
|
96
|
+
|
97
|
+
opt :scenario_file, "\nAutomatically create a ScenarioFile containing the features in FeatureFile for each scenario\n" \
|
98
|
+
"Provide the FeatureFile used to create the ScenarioFile\n" \
|
99
|
+
'Example: uo create --scenario-file example_project.json', type: String
|
100
|
+
|
101
|
+
opt :single_feature, "\nCreate a ScenarioFile with only a single feature\n" \
|
102
|
+
"Use the FeatureID from your FeatureFile\n" \
|
103
|
+
"Requires 'scenario-file' also be specified, to say which FeatureFile will create the ScenarioFile\n" \
|
104
|
+
'Example: uo create --single-feature 2 --scenario-file example_project.json', type: String
|
105
|
+
|
106
|
+
opt :reopt_scenario_file, "\nCreate a ScenarioFile that includes a column defining the REopt assumptions file\n" \
|
107
|
+
"Specify the existing ScenarioFile that you want to extend with REopt functionality\n" \
|
108
|
+
'Example: uo create --reopt-scenario-file baseline_scenario.csv', type: String
|
109
|
+
end
|
68
110
|
end
|
69
111
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
"
|
75
|
-
@user_input[:overwrite_project_folder] = 'Overwriting existing project folder' # This text does not get displayed to the user
|
76
|
-
end
|
112
|
+
# Define running commands
|
113
|
+
def opt_run
|
114
|
+
cmd = @command
|
115
|
+
@subopts = Optimist.options do
|
116
|
+
banner "\nURBANopt #{cmd}:\n \n"
|
77
117
|
|
78
|
-
|
79
|
-
" Example: uo -m -f example_project.json\n" \
|
80
|
-
" Or, Create Scenario CSV for each MapperFile for a single Feature from Feature File. Must specify -f and -i argument\n" \
|
81
|
-
" Example: uo -m -f example_project.json -i 1\n\n") do
|
82
|
-
@user_input[:make_scenario_from] = "Create scenario files from FeatureFiles or for single Feature according to the MapperFiles in the 'mappers' directory" # This text does not get displayed to the user
|
83
|
-
end
|
118
|
+
opt :reopt, "\nSimulate with additional REopt functionality. Must do this before post-processing with REopt"
|
84
119
|
|
85
|
-
|
86
|
-
"
|
87
|
-
|
88
|
-
end
|
120
|
+
opt :scenario, "\nRun URBANopt simulations for <scenario>\n" \
|
121
|
+
"Requires --feature also be specified\n" \
|
122
|
+
'Example: uo run --scenario baseline_scenario-2.csv --feature example_project.jsonn', default: 'baseline_scenario.csv', required: true
|
89
123
|
|
90
|
-
|
91
|
-
"
|
92
|
-
|
124
|
+
opt :feature, "\nRun URBANopt simulations according to <featurefile>\n" \
|
125
|
+
"Requires --scenario also be specified\n" \
|
126
|
+
'Example: uo run --scenario baseline_scenario.csv --feature example_project.json', default: 'example_project.json', required: true
|
127
|
+
end
|
93
128
|
end
|
94
129
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
130
|
+
# Define post-processing commands
|
131
|
+
def opt_process
|
132
|
+
cmd = @command
|
133
|
+
@subopts = Optimist.options do
|
134
|
+
banner "\nURBANopt #{cmd}:\n \n"
|
99
135
|
|
100
|
-
|
101
|
-
@user_input[:scenario] = scenario
|
102
|
-
@root_dir, @scenario_file_name = File.split(File.absolute_path(@user_input[:scenario]))
|
103
|
-
end
|
136
|
+
opt :default, "\nStandard post-processing for your scenario"
|
104
137
|
|
105
|
-
|
106
|
-
@user_input[:feature] = feature
|
107
|
-
@feature_path, @feature_name = File.split(File.absolute_path(@user_input[:feature]))
|
108
|
-
end
|
138
|
+
opt :opendss, "\nPost-process with OpenDSS"
|
109
139
|
|
110
|
-
|
111
|
-
|
112
|
-
|
140
|
+
opt :reopt_scenario, "\nOptimize for entire scenario with REopt\n" \
|
141
|
+
'Example: uo process --reopt-scenario'
|
142
|
+
|
143
|
+
opt :reopt_feature, "\nOptimize for each building individually with REopt\n" \
|
144
|
+
'Example: uo process --reopt-feature'
|
113
145
|
|
114
|
-
|
115
|
-
|
116
|
-
"
|
117
|
-
|
118
|
-
" opendss\n\n") do |type|
|
119
|
-
@user_input[:type] = type
|
146
|
+
opt :scenario, "\nSelect which scenario to optimize", default: 'baseline_scenario.csv', required: true
|
147
|
+
|
148
|
+
opt :feature, "\nSelect which FeatureFile to use", default: 'example_project.json', required: true
|
149
|
+
end
|
120
150
|
end
|
121
151
|
|
122
|
-
|
123
|
-
|
152
|
+
def opt_delete
|
153
|
+
cmd = @command
|
154
|
+
@subopts = Optimist.options do
|
155
|
+
banner "\nURBANopt #{cmd}:\n \n"
|
156
|
+
|
157
|
+
opt :scenario, "\nDelete simulation files for this scenario", default: 'baseline_scenario.csv', required: true
|
158
|
+
end
|
124
159
|
end
|
160
|
+
|
161
|
+
attr_reader :mainopts, :command, :subopts
|
125
162
|
end
|
126
163
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
164
|
+
# Initialize the CLI class
|
165
|
+
@opthash = UrbanOptCLI.new
|
166
|
+
|
167
|
+
# Pull out feature and scenario filenames and paths
|
168
|
+
if @opthash.subopts[:scenario_file]
|
169
|
+
@feature_path, @feature_name = File.split(File.absolute_path(@opthash.subopts[:scenario_file]))
|
170
|
+
end
|
171
|
+
# FIXME: Can this be combined with the above block? This isn't very DRY
|
172
|
+
# One solution would be changing scenario_file to feature.
|
173
|
+
# Would that be confusing when creating a ScenarioFile from the FeatureFile?
|
174
|
+
if @opthash.subopts[:feature]
|
175
|
+
@feature_path, @feature_name = File.split(File.absolute_path(@opthash.subopts[:feature]))
|
176
|
+
end
|
177
|
+
if @opthash.subopts[:scenario]
|
178
|
+
@root_dir, @scenario_file_name = File.split(File.absolute_path(@opthash.subopts[:scenario]))
|
131
179
|
end
|
132
180
|
|
133
181
|
# Simulate energy usage as defined by ScenarioCSV\
|
@@ -154,7 +202,11 @@ module URBANopt
|
|
154
202
|
end
|
155
203
|
|
156
204
|
feature_file = URBANopt::GeoJSON::GeoFile.from_file(featurefile)
|
157
|
-
|
205
|
+
if @opthash.subopts[:reopt] == true || @opthash.subopts[:reopt_scenario] == true || @opthash.subopts[:reopt_feature] == true
|
206
|
+
scenario_output = URBANopt::Scenario::REoptScenarioCSV.new(name, @root_dir, run_dir, feature_file, mapper_files_dir, csv_file, num_header_rows, reopt_files_dir, reopt_assumptions_filename)
|
207
|
+
else
|
208
|
+
scenario_output = URBANopt::Scenario::ScenarioCSV.new(name, @root_dir, run_dir, feature_file, mapper_files_dir, csv_file, num_header_rows)
|
209
|
+
end
|
158
210
|
scenario_output
|
159
211
|
end
|
160
212
|
|
@@ -162,7 +214,7 @@ module URBANopt
|
|
162
214
|
# params\
|
163
215
|
# +feature_file_path+:: _string_ Path to a FeatureFile
|
164
216
|
def self.create_scenario_csv_file(feature_id)
|
165
|
-
feature_file_json = JSON.parse(File.read(File.absolute_path(@
|
217
|
+
feature_file_json = JSON.parse(File.read(File.absolute_path(@opthash.subopts[:scenario_file])), symbolize_names: true)
|
166
218
|
Dir["#{@feature_path}/mappers/*.rb"].each do |mapper_file|
|
167
219
|
mapper_name = File.basename(mapper_file, File.extname(mapper_file))
|
168
220
|
scenario_file_name = if feature_id == 'SKIP'
|
@@ -171,15 +223,15 @@ module URBANopt
|
|
171
223
|
"#{mapper_name.downcase}_scenario-#{feature_id}.csv"
|
172
224
|
end
|
173
225
|
CSV.open(File.join(@feature_path, scenario_file_name), 'wb', write_headers: true,
|
174
|
-
headers: ['Feature Id', 'Feature Name', 'Mapper Class'
|
226
|
+
headers: ['Feature Id', 'Feature Name', 'Mapper Class']) do |csv|
|
175
227
|
feature_file_json[:features].each do |feature|
|
176
228
|
if feature_id == 'SKIP'
|
177
229
|
# ensure that feature is a building
|
178
230
|
if feature[:properties][:type] == 'Building'
|
179
|
-
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"
|
231
|
+
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
|
180
232
|
end
|
181
|
-
elsif feature_id == feature[:properties][:id]
|
182
|
-
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"
|
233
|
+
elsif feature_id == feature[:properties][:id]
|
234
|
+
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
|
183
235
|
elsif
|
184
236
|
# If Feature ID specified does not exist in the Feature File raise error
|
185
237
|
unless feature_file_json[:features].any? { |hash| hash[:properties][:id].include?(feature_id.to_s) }
|
@@ -191,12 +243,28 @@ module URBANopt
|
|
191
243
|
end
|
192
244
|
end
|
193
245
|
|
246
|
+
# Write new ScenarioFile with REopt column
|
247
|
+
# params \
|
248
|
+
# +existing_scenario_file+:: _string_ - Name of existing ScenarioFile
|
249
|
+
def self.create_reopt_scenario_file(existing_scenario_file)
|
250
|
+
existing_path, existing_name = File.split(File.absolute_path(existing_scenario_file))
|
251
|
+
table = CSV.read(existing_scenario_file, headers: true, col_sep: ',')
|
252
|
+
# Add another column, row by row:
|
253
|
+
table.each do |row|
|
254
|
+
row['REopt Assumptions'] = 'multiPV_assumptions.json'
|
255
|
+
end
|
256
|
+
# write new file
|
257
|
+
CSV.open(File.join(existing_path, 'REopt_scenario.csv'), 'w') do |f|
|
258
|
+
f << table.headers
|
259
|
+
table.each { |row| f << row }
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
194
263
|
# Create project folder
|
195
264
|
# params\
|
196
265
|
# +dir_name+:: _string_ Name of new project folder
|
197
266
|
#
|
198
|
-
#
|
199
|
-
# Includes weather for UO's example location, a base workflow file, and mapper files to show a baseline and a high-efficiency option.
|
267
|
+
# Includes weather for example location, a base workflow file, and mapper files to show a baseline and a high-efficiency option.
|
200
268
|
def self.create_project_folder(dir_name, empty_folder = false, overwrite_project = false)
|
201
269
|
if overwrite_project == true
|
202
270
|
if Dir.exist?(dir_name)
|
@@ -219,7 +287,8 @@ module URBANopt
|
|
219
287
|
|
220
288
|
config_file = 'https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/runner.conf'
|
221
289
|
example_feature_file = 'https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/example_project.json'
|
222
|
-
|
290
|
+
# FIXME: Gemfile is TEMPORARILY pointint to branch. Restore to master before merging to master.
|
291
|
+
example_gem_file = 'https://raw.githubusercontent.com/urbanopt/urbanopt-cli/openstudio-3.x/example_files/Gemfile'
|
223
292
|
remote_weather_files = [
|
224
293
|
'https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.epw',
|
225
294
|
'https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.ddy',
|
@@ -294,97 +363,82 @@ module URBANopt
|
|
294
363
|
end
|
295
364
|
|
296
365
|
# Perform CLI actions
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
366
|
+
|
367
|
+
# Create new project folder
|
368
|
+
if @opthash.command == 'create' && @opthash.subopts[:project_folder] && @opthash.subopts[:empty] == false
|
369
|
+
if @opthash.subopts[:overwrite] == true
|
370
|
+
puts "\nOverwriting existing project folder: #{@opthash.subopts[:project_folder]}...\n\n"
|
371
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = false, overwrite_project = true)
|
372
|
+
elsif @opthash.subopts[:overwrite] == false
|
373
|
+
puts "\nCreating a new project folder...\n"
|
374
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = false, overwrite_project = false)
|
304
375
|
end
|
305
376
|
puts "\nAn example FeatureFile is included: 'example_project.json'. You may place your own FeatureFile alongside the example."
|
306
377
|
puts 'Weather data is provided for the example FeatureFile. Additional weather data files may be downloaded from energyplus.net/weather for free'
|
307
378
|
puts "If you use additional weather files, ensure they are added to the 'weather' directory. You will need to configure your mapper file and your osw file to use the desired weather file"
|
308
|
-
puts "Next, create ScenarioFiles using this CLI call: 'uo -m -f <FFP>'\n"
|
309
379
|
puts "We recommend using absolute paths for all commands, for cleaner output\n"
|
310
|
-
elsif @
|
311
|
-
if @
|
312
|
-
puts "\nOverwriting existing project folder: #{@
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
create_project_folder(@
|
380
|
+
elsif @opthash.command == 'create' && @opthash.subopts[:project_folder] && @opthash.subopts[:empty] == true
|
381
|
+
if @opthash.subopts[:overwrite] == true
|
382
|
+
puts "\nOverwriting existing project folder: #{@opthash.subopts[:project_folder]} with an empty folder...\n\n"
|
383
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = true, overwrite_project = true)
|
384
|
+
elsif @opthash.subopts[:overwrite] == false
|
385
|
+
puts "\nCreating a new empty project folder...\n"
|
386
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = true, overwrite_project = false)
|
317
387
|
end
|
318
|
-
puts
|
388
|
+
puts "\nAdd your FeatureFile in the Project directory you just created."
|
319
389
|
puts 'Add your weather data files in the Weather folder. They may be downloaded from energyplus.net/weather for free'
|
320
390
|
puts 'Add your OpenStudio models for Features in your Feature file, if any in the osm_building folder'
|
321
|
-
puts "Next, create ScenarioFiles using this CLI call: 'uo -m -f <FFP>'\n"
|
322
391
|
puts "We recommend using absolute paths for all commands, for cleaner output\n"
|
323
392
|
end
|
324
393
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
if @user_input[:feature_id]
|
331
|
-
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to Feature ID #{@user_input[:feature_id]}..."
|
332
|
-
create_scenario_csv_file(@user_input[:feature_id])
|
394
|
+
# Create ScenarioFile from FeatureFile
|
395
|
+
if @opthash.command == 'create' && @opthash.subopts[:scenario_file]
|
396
|
+
if @opthash.subopts[:single_feature]
|
397
|
+
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to Feature ID #{@opthash.subopts[:single_feature]}"
|
398
|
+
create_scenario_csv_file(@opthash.subopts[:single_feature])
|
333
399
|
puts "\nDone\n"
|
334
400
|
else
|
335
|
-
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to each feature from #{@feature_name}
|
401
|
+
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to each feature from #{@feature_name}"
|
336
402
|
# Skip Feature ID argument if not present
|
337
403
|
create_scenario_csv_file('SKIP')
|
338
404
|
puts "\nDone\n"
|
339
405
|
end
|
340
406
|
end
|
341
407
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
408
|
+
# Create REopt ScenarioFile from existing
|
409
|
+
if @opthash.command == 'create' && @opthash.subopts[:reopt_scenario_file]
|
410
|
+
puts "\nCreating ScenarioFile with REopt functionality, extending from #{@opthash.subopts[:reopt_scenario_file]}..."
|
411
|
+
create_reopt_scenario_file(@opthash.subopts[:reopt_scenario_file])
|
412
|
+
puts "\nDone"
|
413
|
+
end
|
414
|
+
|
415
|
+
# Run simulations
|
416
|
+
if @opthash.command == 'run' && @opthash.subopts[:scenario] && @opthash.subopts[:feature]
|
417
|
+
if @opthash.subopts[:scenario].to_s.include? '-'
|
350
418
|
@scenario_folder = @scenario_file_name.split(/\W+/)[0].capitalize.to_s
|
351
419
|
@feature_id = (@feature_name.split(/\W+/)[1]).to_s
|
352
420
|
else
|
353
421
|
@scenario_folder = @scenario_file_name.split('.')[0].capitalize.to_s
|
354
422
|
end
|
355
|
-
puts "\nSimulating features of '#{@feature_name}' as directed by '#{@
|
423
|
+
puts "\nSimulating features of '#{@feature_name}' as directed by '#{@scenario_file_name}'...\n\n"
|
356
424
|
scenario_runner = URBANopt::Scenario::ScenarioRunnerOSW.new
|
357
425
|
scenario_runner.run(run_func)
|
358
426
|
puts "\nDone\n"
|
359
427
|
end
|
360
428
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
if @user_input[:feature].nil?
|
366
|
-
abort("\nYou must provide '-f' flag and a valid path to a FeatureFile!\n---\n\n")
|
429
|
+
# Post-process the scenario
|
430
|
+
if @opthash.command == 'process'
|
431
|
+
if @opthash.subopts[:default] == false && @opthash.subopts[:opendss] == false && @opthash.subopts[:reopt_scenario] == false && @opthash.subopts[:reopt_feature] == false
|
432
|
+
abort("\nERROR: No valid process type entered. Must enter a valid process type\n")
|
367
433
|
end
|
368
|
-
|
369
|
-
valid_postprocessors = ['default', 'reopt-scenario', 'reopt-feature', 'opendss']
|
370
|
-
# Abort if <type> is nil or not in valid list
|
371
|
-
if @user_input[:type].nil? || valid_postprocessors.none? { |needle| @user_input[:type].include? needle }
|
372
|
-
abort("\nYou must provide '-t' flag and a valid Gather type!\n" \
|
373
|
-
"Valid types include: #{valid_postprocessors}\n---\n\n")
|
374
|
-
end
|
375
|
-
|
376
434
|
@scenario_folder = @scenario_file_name.split('.')[0].capitalize.to_s
|
377
|
-
|
378
435
|
default_post_processor = URBANopt::Scenario::ScenarioDefaultPostProcessor.new(run_func)
|
379
436
|
scenario_report = default_post_processor.run
|
380
437
|
scenario_report.save
|
381
|
-
|
382
|
-
|
383
|
-
scenario_report.feature_reports.each(&:save_feature_report)
|
384
|
-
|
385
|
-
if @user_input[:type] == valid_postprocessors[0]
|
438
|
+
if @opthash.subopts[:default] == true
|
439
|
+
puts 'Post-processing URBANopt results'
|
386
440
|
puts "\nDone\n"
|
387
|
-
elsif @
|
441
|
+
elsif @opthash.subopts[:opendss] == true
|
388
442
|
puts "\nPost-processing OpenDSS results\n"
|
389
443
|
opendss_folder = File.join(@root_dir, 'run', @scenario_file_name.split('.')[0], 'opendss')
|
390
444
|
if File.directory?(opendss_folder)
|
@@ -395,30 +449,23 @@ module URBANopt
|
|
395
449
|
else
|
396
450
|
abort("\nNo OpenDSS results available in folder '#{opendss_folder}'\n")
|
397
451
|
end
|
398
|
-
elsif @
|
452
|
+
elsif @opthash.subopts.to_s.include?('reopt')
|
399
453
|
scenario_base = default_post_processor.scenario_base
|
400
454
|
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(scenario_report, scenario_base.scenario_reopt_assumptions_file, scenario_base.reopt_feature_assumptions, DEVELOPER_NREL_KEY)
|
401
|
-
|
402
|
-
|
403
|
-
if @user_input[:type] == valid_postprocessors[1]
|
404
|
-
puts "\nOptimizing renewable energy for the scenario\n"
|
455
|
+
if @opthash.subopts[:reopt_scenario] == true
|
456
|
+
puts "\nPost-processing entire scenario with REopt\n"
|
405
457
|
scenario_report_scenario = reopt_post_processor.run_scenario_report(scenario_report: scenario_report, save_name: 'scenario_optimization')
|
406
458
|
puts "\nDone\n"
|
407
|
-
|
408
|
-
|
409
|
-
puts "\nOptimizing renewable energy for each feature\n"
|
459
|
+
elsif @opthash.subopts[:reopt_feature] == true
|
460
|
+
puts "\nPost-processing each building individually with REopt\n"
|
410
461
|
scenario_report_features = reopt_post_processor.run_scenario_report_features(scenario_report: scenario_report, save_names_feature_reports: ['feature_optimization'] * scenario_report.feature_reports.length, save_name_scenario_report: 'feature_optimization')
|
411
462
|
puts "\nDone\n"
|
412
463
|
end
|
413
|
-
else
|
414
|
-
abort("\nError: did not use one of these valid types: #{valid_postprocessors} Aborting...\n---\n\n")
|
415
464
|
end
|
416
465
|
end
|
417
466
|
|
418
|
-
|
419
|
-
|
420
|
-
abort("\nYou must provide '-s' flag and a valid path to a ScenarioFile!\n---\n\n")
|
421
|
-
end
|
467
|
+
# Delete simulations from a scenario
|
468
|
+
if @opthash.command == 'delete'
|
422
469
|
scenario_name = @scenario_file_name.split('.')[0]
|
423
470
|
scenario_path = File.absolute_path(@root_dir)
|
424
471
|
scenario_results_dir = File.join(scenario_path, 'run', scenario_name)
|
@@ -426,9 +473,5 @@ module URBANopt
|
|
426
473
|
FileUtils.rm_rf(scenario_results_dir)
|
427
474
|
puts "\nDone\n"
|
428
475
|
end
|
429
|
-
|
430
|
-
if @user_input[:version_request]
|
431
|
-
puts "\nURBANopt CLI version: #{@user_input[:version_request]}\n---\n\n"
|
432
|
-
end
|
433
476
|
end
|
434
477
|
end
|
data/uo_cli.gemspec
CHANGED
@@ -29,19 +29,19 @@ Gem::Specification.new do |spec|
|
|
29
29
|
# spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
30
|
spec.executables = ['uo']
|
31
31
|
spec.require_paths = ['lib']
|
32
|
-
spec.required_ruby_version = '~> 2.
|
32
|
+
spec.required_ruby_version = '~> 2.5.0'
|
33
33
|
|
34
34
|
# use specific versions of these dependencies while using Ruby 2.2
|
35
|
-
spec.add_development_dependency 'rack', '2.1.2'
|
35
|
+
#spec.add_development_dependency 'rack', '2.1.2'
|
36
36
|
|
37
37
|
# use specific versions of urbanopt and openstudio dependencies while under heavy development
|
38
|
-
spec.add_dependency '
|
39
|
-
spec.add_dependency 'urbanopt-
|
40
|
-
spec.add_dependency 'urbanopt-
|
38
|
+
spec.add_dependency 'optimist'
|
39
|
+
spec.add_dependency 'urbanopt-geojson', '0.3.0.pre1'
|
40
|
+
spec.add_dependency 'urbanopt-reopt', '0.3.0.pre1'
|
41
|
+
spec.add_dependency 'urbanopt-scenario', '0.3.0.pre1'
|
41
42
|
|
42
|
-
spec.add_development_dependency 'bundler', '~> 1
|
43
|
-
spec.add_development_dependency '
|
44
|
-
spec.add_development_dependency 'rake', '~> 12.3'
|
43
|
+
spec.add_development_dependency 'bundler', '~> 2.1'
|
44
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
45
45
|
spec.add_development_dependency 'rspec', '~> 3.7'
|
46
46
|
spec.add_development_dependency 'rubocop', '~> 0.54.0'
|
47
47
|
end
|
metadata
CHANGED
@@ -1,113 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: urbanopt-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Moore
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: optimist
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
type: :
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: urbanopt-geojson
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.3.0.pre1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.3.0.pre1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: urbanopt-reopt
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 0.3.0.pre1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 0.3.0.pre1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: urbanopt-scenario
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.3.0.pre1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 0.3.0.pre1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '1
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.17'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: github_api
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0.18'
|
75
|
+
version: '2.1'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
80
|
- - "~>"
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
82
|
+
version: '2.1'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rake
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
89
|
+
version: '13.0'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
94
|
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
96
|
+
version: '13.0'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: rspec
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,15 +179,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
193
179
|
requirements:
|
194
180
|
- - "~>"
|
195
181
|
- !ruby/object:Gem::Version
|
196
|
-
version: 2.
|
182
|
+
version: 2.5.0
|
197
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
184
|
requirements:
|
199
|
-
- - "
|
185
|
+
- - ">"
|
200
186
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
187
|
+
version: 1.3.1
|
202
188
|
requirements: []
|
203
|
-
|
204
|
-
rubygems_version: 2.4.5.1
|
189
|
+
rubygems_version: 3.1.2
|
205
190
|
signing_key:
|
206
191
|
specification_version: 4
|
207
192
|
summary: URBANopt CLI
|