urbanopt-cli 0.2.1 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +10 -1
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +36 -0
- data/Gemfile +30 -26
- data/README.md +27 -14
- data/Rakefile +6 -0
- data/developer_nrel_key.rb +1 -0
- data/example_files/Gemfile +22 -33
- data/example_files/example_project.json +1 -1
- data/example_files/mappers/Baseline.rb +112 -93
- data/example_files/mappers/HighEfficiency.rb +2 -1
- data/lib/uo_cli.rb +199 -156
- data/lib/uo_cli/version.rb +2 -1
- data/uo_cli.gemspec +7 -9
- metadata +28 -31
- data/lib/change_log.rb +0 -152
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
# *********************************************************************************
|
2
3
|
# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
|
3
4
|
# contributors. All rights reserved.
|
@@ -51,7 +52,7 @@ module URBANopt
|
|
51
52
|
OpenStudio::Extension.set_measure_argument(osw, 'ReduceLightingLoadsByPercentage', '__SKIP__', false)
|
52
53
|
OpenStudio::Extension.set_measure_argument(osw, 'ReduceLightingLoadsByPercentage', 'lighting_power_reduction_percent', 10)
|
53
54
|
|
54
|
-
osw
|
55
|
+
return osw
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
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') 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") 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\
|
@@ -142,10 +190,6 @@ module URBANopt
|
|
142
190
|
mapper_files_dir = File.join(@root_dir, 'mappers')
|
143
191
|
reopt_files_dir = File.join(@root_dir, 'reopt/')
|
144
192
|
num_header_rows = 1
|
145
|
-
# FIXME: This can be cleaned up in Ruby 2.5 with Dir.children(<"foldername">)
|
146
|
-
# TODO: Better way of grabbing assumptions file than the first file in the folder
|
147
|
-
reopt_files_dir_contents_list = Dir["#{reopt_files_dir}/*"]
|
148
|
-
reopt_assumptions_filename = File.basename(reopt_files_dir_contents_list[0])
|
149
193
|
|
150
194
|
if @feature_id
|
151
195
|
feature_run_dir = File.join(run_dir, @feature_id)
|
@@ -154,7 +198,14 @@ module URBANopt
|
|
154
198
|
end
|
155
199
|
|
156
200
|
feature_file = URBANopt::GeoJSON::GeoFile.from_file(featurefile)
|
157
|
-
|
201
|
+
if @opthash.subopts[:reopt] == true || @opthash.subopts[:reopt_scenario] == true || @opthash.subopts[:reopt_feature] == true
|
202
|
+
# TODO: Better way of grabbing assumptions file than the first file in the folder
|
203
|
+
reopt_files_dir_contents_list = Dir.children(reopt_files_dir.to_s)
|
204
|
+
reopt_assumptions_filename = File.basename(reopt_files_dir_contents_list[0])
|
205
|
+
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)
|
206
|
+
else
|
207
|
+
scenario_output = URBANopt::Scenario::ScenarioCSV.new(name, @root_dir, run_dir, feature_file, mapper_files_dir, csv_file, num_header_rows)
|
208
|
+
end
|
158
209
|
scenario_output
|
159
210
|
end
|
160
211
|
|
@@ -162,7 +213,7 @@ module URBANopt
|
|
162
213
|
# params\
|
163
214
|
# +feature_file_path+:: _string_ Path to a FeatureFile
|
164
215
|
def self.create_scenario_csv_file(feature_id)
|
165
|
-
feature_file_json = JSON.parse(File.read(File.absolute_path(@
|
216
|
+
feature_file_json = JSON.parse(File.read(File.absolute_path(@opthash.subopts[:scenario_file])), symbolize_names: true)
|
166
217
|
Dir["#{@feature_path}/mappers/*.rb"].each do |mapper_file|
|
167
218
|
mapper_name = File.basename(mapper_file, File.extname(mapper_file))
|
168
219
|
scenario_file_name = if feature_id == 'SKIP'
|
@@ -171,15 +222,15 @@ module URBANopt
|
|
171
222
|
"#{mapper_name.downcase}_scenario-#{feature_id}.csv"
|
172
223
|
end
|
173
224
|
CSV.open(File.join(@feature_path, scenario_file_name), 'wb', write_headers: true,
|
174
|
-
headers: ['Feature Id', 'Feature Name', 'Mapper Class'
|
225
|
+
headers: ['Feature Id', 'Feature Name', 'Mapper Class']) do |csv|
|
175
226
|
feature_file_json[:features].each do |feature|
|
176
227
|
if feature_id == 'SKIP'
|
177
228
|
# ensure that feature is a building
|
178
229
|
if feature[:properties][:type] == 'Building'
|
179
|
-
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"
|
180
|
-
|
181
|
-
elsif feature_id == feature[:properties][:id]
|
182
|
-
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"
|
230
|
+
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
|
231
|
+
end
|
232
|
+
elsif feature_id == feature[:properties][:id]
|
233
|
+
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
|
183
234
|
elsif
|
184
235
|
# If Feature ID specified does not exist in the Feature File raise error
|
185
236
|
unless feature_file_json[:features].any? { |hash| hash[:properties][:id].include?(feature_id.to_s) }
|
@@ -191,24 +242,38 @@ module URBANopt
|
|
191
242
|
end
|
192
243
|
end
|
193
244
|
|
245
|
+
# Write new ScenarioFile with REopt column
|
246
|
+
# params \
|
247
|
+
# +existing_scenario_file+:: _string_ - Name of existing ScenarioFile
|
248
|
+
def self.create_reopt_scenario_file(existing_scenario_file)
|
249
|
+
existing_path, existing_name = File.split(File.absolute_path(existing_scenario_file))
|
250
|
+
table = CSV.read(existing_scenario_file, headers: true, col_sep: ',')
|
251
|
+
# Add another column, row by row:
|
252
|
+
table.each do |row|
|
253
|
+
row['REopt Assumptions'] = 'multiPV_assumptions.json'
|
254
|
+
end
|
255
|
+
# write new file
|
256
|
+
CSV.open(File.join(existing_path, 'REopt_scenario.csv'), 'w') do |f|
|
257
|
+
f << table.headers
|
258
|
+
table.each { |row| f << row }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
194
262
|
# Create project folder
|
195
263
|
# params\
|
196
264
|
# +dir_name+:: _string_ Name of new project folder
|
197
265
|
#
|
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.
|
266
|
+
# Includes weather for example location, a base workflow file, and mapper files to show a baseline and a high-efficiency option.
|
200
267
|
def self.create_project_folder(dir_name, empty_folder = false, overwrite_project = false)
|
201
268
|
if overwrite_project == true
|
202
269
|
if Dir.exist?(dir_name)
|
203
270
|
FileUtils.rm_rf(dir_name)
|
204
|
-
puts "Overwriting project directory: #{dir_name}\n"
|
205
271
|
end
|
206
272
|
elsif overwrite_project == false
|
207
273
|
if Dir.exist?(dir_name)
|
208
274
|
abort("\nERROR: there is already a directory here named #{dir_name}... aborting\n---\n\n")
|
209
275
|
end
|
210
276
|
end
|
211
|
-
puts "CREATING NEW URBANopt project directory: #{dir_name}\n"
|
212
277
|
Dir.mkdir dir_name
|
213
278
|
Dir.mkdir File.join(dir_name, 'mappers')
|
214
279
|
Dir.mkdir File.join(dir_name, 'weather')
|
@@ -296,93 +361,84 @@ module URBANopt
|
|
296
361
|
end
|
297
362
|
|
298
363
|
# Perform CLI actions
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
puts "
|
304
|
-
|
305
|
-
|
364
|
+
|
365
|
+
# Create new project folder
|
366
|
+
if @opthash.command == 'create' && @opthash.subopts[:project_folder] && @opthash.subopts[:empty] == false
|
367
|
+
if @opthash.subopts[:overwrite] == true
|
368
|
+
puts "\nOverwriting existing project folder: #{@opthash.subopts[:project_folder]}...\n\n"
|
369
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = false, overwrite_project = true)
|
370
|
+
elsif @opthash.subopts[:overwrite] == false
|
371
|
+
puts "\nCreating a new project folder...\n"
|
372
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = false, overwrite_project = false)
|
306
373
|
end
|
307
374
|
puts "\nAn example FeatureFile is included: 'example_project.json'. You may place your own FeatureFile alongside the example."
|
308
375
|
puts 'Weather data is provided for the example FeatureFile. Additional weather data files may be downloaded from energyplus.net/weather for free'
|
309
376
|
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"
|
310
|
-
puts "
|
311
|
-
elsif @
|
312
|
-
if @
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
create_project_folder(@
|
377
|
+
puts "We recommend using absolute paths for all commands, for cleaner output\n"
|
378
|
+
elsif @opthash.command == 'create' && @opthash.subopts[:project_folder] && @opthash.subopts[:empty] == true
|
379
|
+
if @opthash.subopts[:overwrite] == true
|
380
|
+
puts "\nOverwriting existing project folder: #{@opthash.subopts[:project_folder]} with an empty folder...\n\n"
|
381
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = true, overwrite_project = true)
|
382
|
+
elsif @opthash.subopts[:overwrite] == false
|
383
|
+
puts "\nCreating a new empty project folder...\n"
|
384
|
+
create_project_folder(@opthash.subopts[:project_folder], empty_folder = true, overwrite_project = false)
|
318
385
|
end
|
319
|
-
puts
|
386
|
+
puts "\nAdd your FeatureFile in the Project directory you just created."
|
320
387
|
puts 'Add your weather data files in the Weather folder. They may be downloaded from energyplus.net/weather for free'
|
321
388
|
puts 'Add your OpenStudio models for Features in your Feature file, if any in the osm_building folder'
|
322
|
-
puts "
|
389
|
+
puts "We recommend using absolute paths for all commands, for cleaner output\n"
|
323
390
|
end
|
324
391
|
|
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])
|
392
|
+
# Create ScenarioFile from FeatureFile
|
393
|
+
if @opthash.command == 'create' && @opthash.subopts[:scenario_file]
|
394
|
+
if @opthash.subopts[:single_feature]
|
395
|
+
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to Feature ID #{@opthash.subopts[:single_feature]}"
|
396
|
+
create_scenario_csv_file(@opthash.subopts[:single_feature])
|
333
397
|
puts "\nDone\n"
|
334
398
|
else
|
335
|
-
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to each feature from #{@feature_name}
|
399
|
+
puts "\nBuilding sample ScenarioFiles, assigning mapper classes to each feature from #{@feature_name}"
|
336
400
|
# Skip Feature ID argument if not present
|
337
401
|
create_scenario_csv_file('SKIP')
|
338
402
|
puts "\nDone\n"
|
339
403
|
end
|
340
404
|
end
|
341
405
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
406
|
+
# Create REopt ScenarioFile from existing
|
407
|
+
if @opthash.command == 'create' && @opthash.subopts[:reopt_scenario_file]
|
408
|
+
puts "\nCreating ScenarioFile with REopt functionality, extending from #{@opthash.subopts[:reopt_scenario_file]}..."
|
409
|
+
create_reopt_scenario_file(@opthash.subopts[:reopt_scenario_file])
|
410
|
+
puts "\nDone"
|
411
|
+
end
|
412
|
+
|
413
|
+
# Run simulations
|
414
|
+
if @opthash.command == 'run' && @opthash.subopts[:scenario] && @opthash.subopts[:feature]
|
415
|
+
if @opthash.subopts[:scenario].to_s.include? '-'
|
350
416
|
@scenario_folder = @scenario_file_name.split(/\W+/)[0].capitalize.to_s
|
351
417
|
@feature_id = (@feature_name.split(/\W+/)[1]).to_s
|
352
418
|
else
|
353
419
|
@scenario_folder = @scenario_file_name.split('.')[0].capitalize.to_s
|
354
420
|
end
|
355
|
-
puts "\nSimulating features of '#{@feature_name}' as directed by '#{@
|
421
|
+
puts "\nSimulating features of '#{@feature_name}' as directed by '#{@scenario_file_name}'...\n\n"
|
356
422
|
scenario_runner = URBANopt::Scenario::ScenarioRunnerOSW.new
|
357
423
|
scenario_runner.run(run_func)
|
358
424
|
puts "\nDone\n"
|
359
425
|
end
|
360
426
|
|
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")
|
367
|
-
end
|
368
|
-
if @user_input[:type].nil?
|
369
|
-
abort("\nYou must provide '-t' flag and a valid Gather type!\n" \
|
370
|
-
"Valid types include: 'default', 'reopt-scenario', 'reopt-feature', or 'opendss'\n---\n\n")
|
427
|
+
# Post-process the scenario
|
428
|
+
if @opthash.command == 'process'
|
429
|
+
if @opthash.subopts[:default] == false && @opthash.subopts[:opendss] == false && @opthash.subopts[:reopt_scenario] == false && @opthash.subopts[:reopt_feature] == false
|
430
|
+
abort("\nERROR: No valid process type entered. Must enter a valid process type\n")
|
371
431
|
end
|
372
432
|
@scenario_folder = @scenario_file_name.split('.')[0].capitalize.to_s
|
373
|
-
|
374
433
|
default_post_processor = URBANopt::Scenario::ScenarioDefaultPostProcessor.new(run_func)
|
375
434
|
scenario_report = default_post_processor.run
|
376
435
|
scenario_report.save
|
377
|
-
|
378
|
-
|
379
|
-
scenario_report.feature_reports.each(&:save_feature_report)
|
380
|
-
|
381
|
-
if @user_input[:type].to_s.casecmp('default').zero?
|
436
|
+
if @opthash.subopts[:default] == true
|
437
|
+
puts 'Post-processing URBANopt results'
|
382
438
|
puts "\nDone\n"
|
383
|
-
elsif @
|
439
|
+
elsif @opthash.subopts[:opendss] == true
|
384
440
|
puts "\nPost-processing OpenDSS results\n"
|
385
|
-
opendss_folder = File.join(@root_dir, 'run', @
|
441
|
+
opendss_folder = File.join(@root_dir, 'run', @scenario_file_name.split('.')[0], 'opendss')
|
386
442
|
if File.directory?(opendss_folder)
|
387
443
|
opendss_folder_name = File.basename(opendss_folder)
|
388
444
|
opendss_post_processor = URBANopt::Scenario::OpenDSSPostProcessor.new(scenario_report, opendss_results_dir_name = opendss_folder_name)
|
@@ -391,32 +447,23 @@ module URBANopt
|
|
391
447
|
else
|
392
448
|
abort("\nNo OpenDSS results available in folder '#{opendss_folder}'\n")
|
393
449
|
end
|
394
|
-
elsif @
|
450
|
+
elsif @opthash.subopts.to_s.include?('reopt')
|
395
451
|
scenario_base = default_post_processor.scenario_base
|
396
452
|
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(scenario_report, scenario_base.scenario_reopt_assumptions_file, scenario_base.reopt_feature_assumptions, DEVELOPER_NREL_KEY)
|
397
|
-
|
398
|
-
|
399
|
-
if @user_input[:type].to_s.casecmp('reopt-scenario').zero?
|
400
|
-
puts "\nOptimizing renewable energy for the scenario\n"
|
453
|
+
if @opthash.subopts[:reopt_scenario] == true
|
454
|
+
puts "\nPost-processing entire scenario with REopt\n"
|
401
455
|
scenario_report_scenario = reopt_post_processor.run_scenario_report(scenario_report: scenario_report, save_name: 'scenario_optimization')
|
402
456
|
puts "\nDone\n"
|
403
|
-
|
404
|
-
|
405
|
-
puts "\nOptimizing renewable energy for each feature\n"
|
457
|
+
elsif @opthash.subopts[:reopt_feature] == true
|
458
|
+
puts "\nPost-processing each building individually with REopt\n"
|
406
459
|
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')
|
407
460
|
puts "\nDone\n"
|
408
|
-
else
|
409
|
-
abort("\nError: did not use type 'reopt-scenario', 'reopt-feature'. Aborting...\n---\n\n")
|
410
461
|
end
|
411
|
-
else
|
412
|
-
abort("\nError: did not use type 'default', 'reopt-scenario', 'reopt-feature', or 'opendss'. Aborting...\n---\n\n")
|
413
462
|
end
|
414
463
|
end
|
415
464
|
|
416
|
-
|
417
|
-
|
418
|
-
abort("\nYou must provide '-s' flag and a valid path to a ScenarioFile!\n---\n\n")
|
419
|
-
end
|
465
|
+
# Delete simulations from a scenario
|
466
|
+
if @opthash.command == 'delete'
|
420
467
|
scenario_name = @scenario_file_name.split('.')[0]
|
421
468
|
scenario_path = File.absolute_path(@root_dir)
|
422
469
|
scenario_results_dir = File.join(scenario_path, 'run', scenario_name)
|
@@ -424,9 +471,5 @@ module URBANopt
|
|
424
471
|
FileUtils.rm_rf(scenario_results_dir)
|
425
472
|
puts "\nDone\n"
|
426
473
|
end
|
427
|
-
|
428
|
-
if @user_input[:version_request]
|
429
|
-
puts "\nURBANopt CLI version: #{@user_input[:version_request]}\n---\n\n"
|
430
|
-
end
|
431
474
|
end
|
432
475
|
end
|