urbanopt-cli 0.6.0 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +2 -2
- data/CHANGELOG.md +38 -0
- data/CMakeLists.txt +13 -13
- data/FindOpenStudioSDK.cmake +11 -6
- data/Gemfile +11 -5
- data/example_files/Gemfile +6 -3
- data/example_files/base_workflow_res.osw +10 -0
- data/example_files/example_project_combined.json +13 -3
- data/example_files/example_project_with_PV.json +751 -0
- data/example_files/example_project_with_streets.json +826 -0
- data/example_files/mappers/Baseline.rb +69 -14
- data/example_files/mappers/CreateBar.rb +31 -1
- data/example_files/mappers/FlexibleHotWater.rb +69 -0
- data/example_files/mappers/Floorspace.rb +31 -1
- data/example_files/mappers/HighEfficiency.rb +20 -8
- data/example_files/mappers/HighEfficiencyCreateBar.rb +3 -2
- data/example_files/mappers/HighEfficiencyFloorspace.rb +3 -2
- data/example_files/mappers/base_workflow.osw +5 -0
- data/example_files/mappers/createbar_workflow.osw +3 -1
- data/example_files/mappers/floorspace_workflow.osw +2 -1
- data/example_files/osm_building/7.osm +0 -307
- data/example_files/osm_building/8.osm +0 -419
- data/example_files/osm_building/9.osm +0 -664
- data/example_files/reopt/base_assumptions.json +3 -3
- data/example_files/reopt/multiPV_assumptions.json +2 -2
- data/example_files/resources/hpxml-measures/Gemfile +1 -1
- data/example_files/resources/hpxml-measures/Gemfile.lock +6 -25
- data/example_files/visualization/input_visualization_feature.html +15 -16
- data/example_files/visualization/input_visualization_scenario.html +16 -11
- data/lib/uo_cli/version.rb +1 -1
- data/lib/uo_cli.rb +158 -26
- data/scripts/setup-env-gitbash.sh +4 -4
- data/scripts/setup-env-unix.sh +4 -4
- data/scripts/setup-env.bat +3 -3
- data/scripts/setup-env.ps1 +3 -3
- data/uo_cli.gemspec +8 -5
- metadata +59 -14
@@ -22,8 +22,8 @@
|
|
22
22
|
"net_metering_limit_kw": 0,
|
23
23
|
"interconnection_limit_kw": 100000000.0,
|
24
24
|
"blended_monthly_demand_charges_us_dollars_per_kw": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
25
|
-
"blended_monthly_rates_us_dollars_per_kwh": [0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
|
26
|
-
|
25
|
+
"blended_monthly_rates_us_dollars_per_kwh": [0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
|
26
|
+
},
|
27
27
|
"Wind": {
|
28
28
|
"min_kw": 0,
|
29
29
|
"max_kw": 0,
|
@@ -77,7 +77,7 @@
|
|
77
77
|
"losses": 0.14,
|
78
78
|
"array_type": 1,
|
79
79
|
"module_type": 0,
|
80
|
-
"gcr": 0.
|
80
|
+
"gcr": 0.99,
|
81
81
|
"dc_ac_ratio": 1.2,
|
82
82
|
"inv_eff": 0.96,
|
83
83
|
"radius": 0,
|
@@ -77,7 +77,7 @@
|
|
77
77
|
"losses": 0.14,
|
78
78
|
"array_type": 1,
|
79
79
|
"module_type": 0,
|
80
|
-
"gcr": 0.
|
80
|
+
"gcr": 0.99,
|
81
81
|
"dc_ac_ratio": 1.2,
|
82
82
|
"inv_eff": 0.96,
|
83
83
|
"radius": 0,
|
@@ -113,7 +113,7 @@
|
|
113
113
|
"losses": 0.14,
|
114
114
|
"array_type": 0,
|
115
115
|
"module_type": 0,
|
116
|
-
"gcr": 0.
|
116
|
+
"gcr": 0.99,
|
117
117
|
"dc_ac_ratio": 1.2,
|
118
118
|
"inv_eff": 0.96,
|
119
119
|
"radius": 0,
|
@@ -4,27 +4,17 @@ GEM
|
|
4
4
|
ansi (1.5.0)
|
5
5
|
ast (2.4.2)
|
6
6
|
builder (3.2.4)
|
7
|
-
|
8
|
-
builder (>= 2.1.2)
|
9
|
-
ci_reporter_minitest (1.0.0)
|
10
|
-
ci_reporter (~> 2.0)
|
11
|
-
minitest (~> 5.0)
|
12
|
-
codecov (0.2.12)
|
13
|
-
json
|
14
|
-
simplecov
|
15
|
-
docile (1.3.5)
|
16
|
-
json (2.5.1)
|
17
|
-
mini_portile2 (2.5.0)
|
7
|
+
mini_portile2 (2.6.1)
|
18
8
|
minitest (5.14.4)
|
19
9
|
minitest-reporters (1.4.3)
|
20
10
|
ansi
|
21
11
|
builder
|
22
12
|
minitest (>= 5.0)
|
23
13
|
ruby-progressbar
|
24
|
-
nokogiri (1.
|
25
|
-
mini_portile2 (~> 2.
|
14
|
+
nokogiri (1.12.5)
|
15
|
+
mini_portile2 (~> 2.6.1)
|
26
16
|
racc (~> 1.4)
|
27
|
-
nokogiri (1.
|
17
|
+
nokogiri (1.12.5-x64-mingw32)
|
28
18
|
racc (~> 1.4)
|
29
19
|
oga (3.3)
|
30
20
|
ast
|
@@ -38,28 +28,19 @@ GEM
|
|
38
28
|
ruby-progressbar (1.11.0)
|
39
29
|
schematron-nokogiri (0.0.3)
|
40
30
|
nokogiri (~> 1.6)
|
41
|
-
simplecov (0.21.2)
|
42
|
-
docile (~> 1.1)
|
43
|
-
simplecov-html (~> 0.11)
|
44
|
-
simplecov_json_formatter (~> 0.1)
|
45
|
-
simplecov-html (0.12.3)
|
46
|
-
simplecov_json_formatter (0.1.2)
|
47
31
|
|
48
32
|
PLATFORMS
|
49
33
|
ruby
|
50
34
|
x64-mingw32
|
51
35
|
|
52
36
|
DEPENDENCIES
|
53
|
-
ci_reporter_minitest (~> 1.0.0)
|
54
|
-
codecov (= 0.2.12)
|
55
37
|
minitest (~> 5.9)
|
56
38
|
minitest-reporters
|
57
|
-
nokogiri (~> 1.
|
39
|
+
nokogiri (~> 1.12)
|
58
40
|
oga
|
59
41
|
parallel
|
60
42
|
rake
|
61
43
|
schematron-nokogiri
|
62
|
-
simplecov
|
63
44
|
|
64
45
|
BUNDLED WITH
|
65
|
-
2.2.11
|
46
|
+
2.2.11
|
@@ -383,10 +383,13 @@
|
|
383
383
|
|
384
384
|
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
385
385
|
|
386
|
-
var datasets = ['Electricity:Facility', 'ElectricityProduced:
|
386
|
+
var datasets = ['Electricity:Facility', 'REopt:ElectricityProduced:Total', 'NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
|
387
387
|
|
388
388
|
var endUseKeys = ['Heating:Electricity', 'Cooling:Electricity', 'InteriorLights:Electricity', 'ExteriorLights:Electricity', 'ExteriorEquipment:Electricity', 'InteriorEquipment:Electricity', 'Fans:Electricity', 'Pumps:Electricity', 'HeatRejection:Electricity', 'WaterSystems:Electricity'];
|
389
389
|
|
390
|
+
var kbtu_datasets = ['NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
|
391
|
+
var changeToKbtu = false;
|
392
|
+
|
390
393
|
|
391
394
|
var applicableEndUseKeys = [];
|
392
395
|
|
@@ -449,8 +452,7 @@
|
|
449
452
|
|
450
453
|
// monthly fuel use
|
451
454
|
$scope.monthlyFuelChartData[feature.name] = [];
|
452
|
-
|
453
|
-
var kbtu_datasets = ['NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
|
455
|
+
|
454
456
|
// first iterate through all kbtu datasets to see if you'll need to change to kBtu units
|
455
457
|
_.forEach(kbtu_datasets, function (kbtu_dataset) {
|
456
458
|
var values = feature.monthly_values[kbtu_dataset];
|
@@ -481,7 +483,7 @@
|
|
481
483
|
datasetUnit = 'Electricity:Facility(kWh)';
|
482
484
|
}
|
483
485
|
}
|
484
|
-
} else if (dataset == 'ElectricityProduced:
|
486
|
+
} else if (dataset == 'REopt:ElectricityProduced:Total') {
|
485
487
|
// first check if there is data to include
|
486
488
|
if (!(values.every(item => item === 0))) {
|
487
489
|
if (changeToKbtu) {
|
@@ -530,29 +532,26 @@
|
|
530
532
|
// monthly net use
|
531
533
|
if(feature['complete_simulation'] == true){
|
532
534
|
$scope.monthlyNetChartData[feature.name] = [];
|
533
|
-
var
|
534
|
-
var changeToKbtu = false;
|
535
|
-
if (!(values.every(item => item === 0))) {
|
536
|
-
changeToKbtu = true
|
537
|
-
}
|
535
|
+
var unit = ' (kWh)'
|
538
536
|
if (changeToKbtu){
|
539
|
-
|
540
|
-
}
|
541
|
-
else {
|
542
|
-
var unit = ' (kWh)'
|
537
|
+
unit = ' (kBtu)'
|
543
538
|
}
|
544
539
|
|
545
540
|
$scope.annualNetChartData[feature.name] = 0;
|
546
541
|
$scope.monthlyNetChartData[feature.name].push({
|
547
542
|
key: 'Net Energy Use' + unit,
|
548
543
|
values: _.map(months, function (month, i) {
|
544
|
+
var value = 0;
|
549
545
|
if (changeToKbtu){
|
550
|
-
|
546
|
+
value = feature.monthly_values['Electricity:Facility'][i]*3.41 - feature.monthly_values['REopt:ElectricityProduced:Total'][i]*3.41;
|
547
|
+
_.forEach(kbtu_datasets, function(ds){
|
548
|
+
value += feature.monthly_values[ds][i];
|
549
|
+
});
|
551
550
|
}
|
552
551
|
else {
|
553
|
-
|
552
|
+
value = feature.monthly_values['Electricity:Facility'][i] - feature.monthly_values['REopt:ElectricityProduced:Total'][i]; //Values are in kWh
|
554
553
|
}
|
555
|
-
|
554
|
+
|
556
555
|
$scope.annualNetChartData[feature.name] += value;
|
557
556
|
// global
|
558
557
|
monthlyNetYMin = _.min([monthlyNetYMin, value]);
|
@@ -373,10 +373,13 @@
|
|
373
373
|
|
374
374
|
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
375
375
|
|
376
|
-
var datasets = ['Electricity:Facility', 'ElectricityProduced:
|
376
|
+
var datasets = ['Electricity:Facility', 'REopt:ElectricityProduced:Total', 'NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
|
377
377
|
|
378
378
|
var endUseKeys = ['Heating:Electricity', 'Cooling:Electricity', 'InteriorLights:Electricity', 'ExteriorLights:Electricity', 'InteriorEquipment:Electricity', 'ExteriorEquipment:Electricity', 'Fans:Electricity', 'Pumps:Electricity', 'HeatRejection:Electricity', 'WaterSystems:Electricity'];
|
379
379
|
|
380
|
+
var kbtu_datasets = ['NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
|
381
|
+
var changeToKbtu = false;
|
382
|
+
|
380
383
|
var applicableEndUseKeys = [];
|
381
384
|
|
382
385
|
$scope.monthlyFuelChartData = {};
|
@@ -422,8 +425,7 @@
|
|
422
425
|
|
423
426
|
// monthly fuel use
|
424
427
|
$scope.monthlyFuelChartData[scenario.name] = [];
|
425
|
-
|
426
|
-
var kbtu_datasets = ['NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
|
428
|
+
|
427
429
|
// first iterate through all kbtu datasets to see if you'll need to change to kBtu units
|
428
430
|
_.forEach(kbtu_datasets, function (kbtu_dataset) {
|
429
431
|
var values = scenario.monthly_values[kbtu_dataset];
|
@@ -454,7 +456,7 @@
|
|
454
456
|
datasetUnit = 'Electricity:Facility(kWh)';
|
455
457
|
}
|
456
458
|
}
|
457
|
-
} else if (dataset == 'ElectricityProduced:
|
459
|
+
} else if (dataset == 'REopt:ElectricityProduced:Total') {
|
458
460
|
// first check if there is data to include
|
459
461
|
if (!(values.every(item => item === 0))) {
|
460
462
|
if (changeToKbtu) {
|
@@ -502,24 +504,27 @@
|
|
502
504
|
if (!(values.every(item => item === 0))) {
|
503
505
|
changeToKbtu = true
|
504
506
|
}
|
507
|
+
var unit = ' (kWh)'
|
505
508
|
if (changeToKbtu){
|
506
|
-
|
507
|
-
}
|
508
|
-
else {
|
509
|
-
var unit = ' (kWh)'
|
509
|
+
unit = ' (kBtu)'
|
510
510
|
}
|
511
511
|
|
512
512
|
$scope.annualNetChartData[scenario.name] = 0;
|
513
513
|
$scope.monthlyNetChartData[scenario.name].push({
|
514
514
|
key: 'Net Energy Use' + unit,
|
515
515
|
values: _.map(months, function (month, i) {
|
516
|
+
var value = 0;
|
516
517
|
if (changeToKbtu){
|
517
|
-
|
518
|
+
value = scenario.monthly_values['Electricity:Facility'][i]*3.41 - scenario.monthly_values['REopt:ElectricityProduced:Total'][i]*3.41 + scenario.monthly_values['NaturalGas:Facility'][i]; //Values are in kBtu
|
519
|
+
|
520
|
+
_.forEach(kbtu_datasets, function(ds){
|
521
|
+
value += scenario.monthly_values[ds][i];
|
522
|
+
});
|
518
523
|
}
|
519
524
|
else {
|
520
|
-
|
525
|
+
value = scenario.monthly_values['Electricity:Facility'][i] - scenario.monthly_values['REopt:ElectricityProduced:Total'][i]; //Values are in kWh
|
521
526
|
}
|
522
|
-
value;
|
527
|
+
// value;
|
523
528
|
$scope.annualNetChartData[scenario.name] += value;
|
524
529
|
monthlyNetYMin = _.min([monthlyNetYMin, value]);
|
525
530
|
monthlyNetYMax = _.max([monthlyNetYMax, value]);
|
data/lib/uo_cli/version.rb
CHANGED
data/lib/uo_cli.rb
CHANGED
@@ -46,6 +46,7 @@ require 'urbanopt/geojson'
|
|
46
46
|
require 'urbanopt/scenario'
|
47
47
|
require 'urbanopt/reopt'
|
48
48
|
require 'urbanopt/reopt_scenario'
|
49
|
+
require 'urbanopt/rnm'
|
49
50
|
require 'csv'
|
50
51
|
require 'fileutils'
|
51
52
|
require 'json'
|
@@ -59,10 +60,11 @@ module URBANopt
|
|
59
60
|
COMMAND_MAP = {
|
60
61
|
'create' => 'Make new things - project directory or files',
|
61
62
|
'run' => 'Use files in your directory to simulate district energy use',
|
62
|
-
'opendss' => 'Run OpenDSS simulation',
|
63
63
|
'process' => 'Post-process URBANopt simulations for additional insights',
|
64
64
|
'visualize' => 'Visualize and compare results for features and scenarios',
|
65
65
|
'validate' => 'Validate results with custom rules',
|
66
|
+
'opendss' => 'Run OpenDSS simulation',
|
67
|
+
'rnm' => 'Run RNM simulation',
|
66
68
|
'delete' => 'Delete simulations for a specified scenario',
|
67
69
|
'des_params' => 'Make a DES system parameters config file',
|
68
70
|
'des_create' => 'Create a Modelica model',
|
@@ -106,9 +108,6 @@ module URBANopt
|
|
106
108
|
"Add additional tags to specify the method for creating geometry, or use the default urban geometry creation method to create building geometry from geojson coordinates with core and perimeter zoning\n" \
|
107
109
|
'Example: uo create --project-folder urbanopt_example_project', type: String, short: :p
|
108
110
|
|
109
|
-
opt :electric, "\nCreate default project with FeatureFile containing electrical network\n" \
|
110
|
-
"Example: uo create --project-folder urbanopt_example_project --electric", short: :l
|
111
|
-
|
112
111
|
opt :create_bar, "\nCreate building geometry and add space types using the create bar from building type ratios measure\n" \
|
113
112
|
"Refer to https://docs.urbanopt.net/ for more details about the workflow\n" \
|
114
113
|
"Used with --project-folder\n" \
|
@@ -123,6 +122,15 @@ module URBANopt
|
|
123
122
|
"This functionality has not been exhaustively tested and currently supports the Single-Family Detached building type and the Baseline Scenario only\n" \
|
124
123
|
"Used with --project-folder\n" \
|
125
124
|
"Example: uo create --project-folder urbanopt_example_project --combined\n", short: :d
|
125
|
+
|
126
|
+
opt :electric, "\nCreate default project with FeatureFile containing electrical network, used for OpenDSS analysis\n" \
|
127
|
+
"Example: uo create --project-folder urbanopt_example_project --electric", short: :l
|
128
|
+
|
129
|
+
opt :streets, "\nCreate default project wiht FeatureFile containing streets, used for RNM analysis\n" \
|
130
|
+
"Example: uo create --project-folder urbanopt_example_project --streets", short: :t
|
131
|
+
|
132
|
+
opt :photovoltaic, "\nCreate default project with FeatureFile containing community photovoltaic for the district and ground-mount photovoltaic associated with buildings, used for REopt analysis \n" \
|
133
|
+
"Example: uo create --project-folder urbanopt_example_project --photovoltaic", short: :v
|
126
134
|
|
127
135
|
opt :empty, "\nUse with --project-folder argument to create an empty project folder\n" \
|
128
136
|
"Then add your own Feature file in the project directory you created,\n" \
|
@@ -173,11 +181,11 @@ module URBANopt
|
|
173
181
|
|
174
182
|
opt :scenario, "\nRun OpenDSS simulations for <scenario>\n" \
|
175
183
|
"Requires --feature also be specified\n" \
|
176
|
-
'Example: uo opendss --scenario baseline_scenario-2.csv --feature example_project.json', default: 'baseline_scenario.csv', short: :s
|
184
|
+
'Example: uo opendss --scenario baseline_scenario-2.csv --feature example_project.json', default: 'baseline_scenario.csv', required: true, short: :s
|
177
185
|
|
178
186
|
opt :feature, "\nRun OpenDSS simulations according to <featurefile>\n" \
|
179
187
|
"Requires --scenario also be specified\n" \
|
180
|
-
'Example: uo opendss --scenario baseline_scenario.csv --feature example_project.json', default: 'example_project_with_electric_network.json', short: :f
|
188
|
+
'Example: uo opendss --scenario baseline_scenario.csv --feature example_project.json', default: 'example_project_with_electric_network.json', required: true, short: :f
|
181
189
|
|
182
190
|
opt :equipment, "\nRun OpenDSS simulations using <equipmentfile>. If not specified, the electrical_database.json from urbanopt-ditto-reader will be used.\n" \
|
183
191
|
'Example: uo opendss --scenario baseline_scenario.csv --feature example_project.json', type: String, short: :e
|
@@ -204,6 +212,33 @@ module URBANopt
|
|
204
212
|
end
|
205
213
|
end
|
206
214
|
|
215
|
+
# Define RNM commands
|
216
|
+
def opt_rnm
|
217
|
+
@subopts = Optimist.options do
|
218
|
+
banner "\nURBANopt #{@command}:\n\n"
|
219
|
+
|
220
|
+
opt :scenario, "\nRun RNM simulation for <scenario>. Scenario must be run and post-processed prior to calling the rnm command.\n" \
|
221
|
+
"Requires --feature also be specified\n" \
|
222
|
+
'Example: uo rnm --scenario baseline_scenario-2.csv --feature example_project.json', default: 'baseline_scenario.csv', required: true, short: :s
|
223
|
+
|
224
|
+
opt :feature, "\nRun RNM simulation according to <featurefile>\n" \
|
225
|
+
"Requires --scenario also be specified\n" \
|
226
|
+
'Example: uo rnm --scenario baseline_scenario.csv --feature example_project.json', default: 'example_project_with_streets.json', required: true, short: :f
|
227
|
+
|
228
|
+
opt :reopt, "\nInclude processed REopt optimization results in the simulation.\n" \
|
229
|
+
"Example: uo rnm --scenario baseline_scenario.csv --feature example_project.json --reopt", short: :r
|
230
|
+
|
231
|
+
opt :extended_catalog, "\nUse this option to specify the extended electrical catalog path.\n" \
|
232
|
+
"If this option is not included, the default catalog will be used", type: String, short: :c
|
233
|
+
|
234
|
+
opt :average_peak_catalog, "\nUse this option to specify the average peak catalog path.\n" \
|
235
|
+
"If this option is not included, the default catalog will be used", type: String, short: :a
|
236
|
+
|
237
|
+
opt :opendss, "\n If this option is specified, an OpenDSS-compatible electrical database will be created \n" \
|
238
|
+
"Example: uo rnm --scenario baseline_scenario.csv --feature example_project_with_streets.json --opendss", short: :o
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
207
242
|
# Define post-processing commands
|
208
243
|
def opt_process
|
209
244
|
@subopts = Optimist.options do
|
@@ -219,10 +254,16 @@ module URBANopt
|
|
219
254
|
opt :reopt_feature, "\nOptimize for each building individually with REopt\n" \
|
220
255
|
'Example: uo process --reopt-feature'
|
221
256
|
|
257
|
+
opt :reopt_resilience, "\nInclude resilience reporting in REopt optimization\n" \
|
258
|
+
'Example: uo process --reopt-scenario --reopt-resilience'
|
259
|
+
|
260
|
+
opt :reopt_keep_existing, "\nKeep existing reopt feature optimizations instead of rerunning them to avoid rate limit issues.\n" \
|
261
|
+
'Example: uo process --reopt-feature --reopt-keep-existing', short: :k
|
262
|
+
|
222
263
|
opt :with_database, "\nInclude a sql database output of post-processed results\n" \
|
223
264
|
'Example: uo process --default --with-database'
|
224
265
|
|
225
|
-
opt :reopt_scenario_assumptions_file, "\nPath to the scenario REopt assumptions JSON file you want to use. Use with the --reopt-scenario post-processor
|
266
|
+
opt :reopt_scenario_assumptions_file, "\nPath to the scenario REopt assumptions JSON file you want to use. Use with the --reopt-scenario post-processor.\n" \
|
226
267
|
"If not specified, the reopt/base_assumptions.json file will be used", type: String, short: :a
|
227
268
|
|
228
269
|
opt :scenario, "\nSelect which scenario to optimize", default: 'baseline_scenario.csv', required: true, short: :s
|
@@ -344,7 +385,7 @@ module URBANopt
|
|
344
385
|
@scenario_name = File.basename(@scenario_file_name, File.extname(@scenario_file_name))
|
345
386
|
end
|
346
387
|
|
347
|
-
# Simulate energy usage as defined by ScenarioCSV
|
388
|
+
# Simulate energy usage as defined by ScenarioCSV
|
348
389
|
def self.run_func
|
349
390
|
run_dir = File.join(@root_dir, 'run', @scenario_name.downcase)
|
350
391
|
csv_file = File.join(@root_dir, @scenario_file_name)
|
@@ -493,11 +534,15 @@ module URBANopt
|
|
493
534
|
|
494
535
|
if @opthash.subopts[:electric] == true
|
495
536
|
FileUtils.cp(File.join(path_item, 'example_project_with_electric_network.json'), dir_name)
|
537
|
+
elsif @opthash.subopts[:streets] == true
|
538
|
+
FileUtils.cp(File.join(path_item, 'example_project_with_streets.json'), dir_name)
|
539
|
+
elsif @opthash.subopts[:photovoltaic] == true
|
540
|
+
FileUtils.cp(File.join(path_item, 'example_project_with_PV.json'), dir_name)
|
496
541
|
end
|
497
542
|
|
498
543
|
if @opthash.subopts[:floorspace] == false
|
499
544
|
|
500
|
-
if @opthash.subopts[:electric] != true
|
545
|
+
if @opthash.subopts[:electric] != true && @opthash.subopts[:streets] != true && @opthash.subopts[:photovoltaic] != true
|
501
546
|
# copy feature file
|
502
547
|
FileUtils.cp(File.join(path_item, 'example_project.json'), dir_name)
|
503
548
|
end
|
@@ -514,6 +559,7 @@ module URBANopt
|
|
514
559
|
FileUtils.cp(File.join(path_item, 'mappers/HighEfficiency.rb'), File.join(dir_name, 'mappers'))
|
515
560
|
FileUtils.cp(File.join(path_item, 'mappers/ThermalStorage.rb'), File.join(dir_name, 'mappers'))
|
516
561
|
FileUtils.cp(File.join(path_item, 'mappers/EvCharging.rb'), File.join(dir_name, 'mappers'))
|
562
|
+
FileUtils.cp(File.join(path_item, 'mappers/FlexibleHotWater.rb'), File.join(dir_name, 'mappers'))
|
517
563
|
|
518
564
|
# copy osw file
|
519
565
|
FileUtils.cp(File.join(path_item, 'mappers/base_workflow.osw'), File.join(dir_name, 'mappers'))
|
@@ -728,6 +774,7 @@ module URBANopt
|
|
728
774
|
puts "\nDone\n"
|
729
775
|
end
|
730
776
|
|
777
|
+
# Run OpenDSS simulation
|
731
778
|
if @opthash.command == 'opendss'
|
732
779
|
|
733
780
|
# first check python
|
@@ -797,11 +844,45 @@ module URBANopt
|
|
797
844
|
begin
|
798
845
|
system(ditto_cli_root + ditto_cli_addition)
|
799
846
|
rescue FileNotFoundError
|
800
|
-
abort("\nMust post-process results before running
|
801
|
-
"Once
|
847
|
+
abort("\nMust post-process results before running OpenDSS. We recommend 'process --default'." \
|
848
|
+
"Once OpenDSS is run, you may then 'process --opendss'")
|
802
849
|
end
|
803
850
|
end
|
804
851
|
|
852
|
+
# Run RNM Simulation
|
853
|
+
if @opthash.command == 'rnm'
|
854
|
+
|
855
|
+
run_dir = File.join(@root_dir, 'run', @scenario_name.downcase)
|
856
|
+
# check if project has been post-processed appropriately
|
857
|
+
if !File.exist?(File.join(run_dir, 'default_scenario_report.json'))
|
858
|
+
abort("\nYou must first post-process the scenario before running RNM. We recommend 'process --default'.")
|
859
|
+
end
|
860
|
+
|
861
|
+
puts 'Preparing RNM inputs'
|
862
|
+
# prep arguments
|
863
|
+
reopt = @opthash.subopts[:reopt] ? true : false
|
864
|
+
opendss_catalog = @opthash.subopts[:opendss] ? true : false
|
865
|
+
|
866
|
+
# if paths below are nil, default paths will be used
|
867
|
+
extended_catalog_path = @opthash.subopts[:extended_catalog] ? @opthash.subopts[:extended_catalog] : nil
|
868
|
+
average_peak_catalog_path = @opthash.subopts[:average_peak_catalog] ? @opthash.subopts[:average_peak_catalog] : nil
|
869
|
+
|
870
|
+
# create inputs, run sim and get results
|
871
|
+
begin
|
872
|
+
runner = URBANopt::RNM::Runner.new(@scenario_name, run_dir, @opthash.subopts[:scenario], @opthash.subopts[:feature], extended_catalog_path:extended_catalog_path, average_peak_catalog_path:average_peak_catalog_path, reopt:reopt, opendss_catalog:opendss_catalog)
|
873
|
+
runner.create_simulation_files
|
874
|
+
runner.run
|
875
|
+
runner.post_process
|
876
|
+
rescue => error
|
877
|
+
abort("\nError: #{error.message}")
|
878
|
+
end
|
879
|
+
|
880
|
+
# TODO: aggregate back into scenario reports and geojson file
|
881
|
+
puts "\nRNM Results saved to: #{File.join(run_dir, 'rnm-us', 'results')}"
|
882
|
+
puts "\nDone\n"
|
883
|
+
|
884
|
+
end
|
885
|
+
|
805
886
|
# Post-process the scenario
|
806
887
|
if @opthash.command == 'process'
|
807
888
|
if @opthash.subopts[:default] == false && @opthash.subopts[:opendss] == false && @opthash.subopts[:reopt_scenario] == false && @opthash.subopts[:reopt_feature] == false
|
@@ -829,7 +910,7 @@ module URBANopt
|
|
829
910
|
results << { "process_type": 'default', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
|
830
911
|
elsif @opthash.subopts[:opendss] == true
|
831
912
|
puts "\nPost-processing OpenDSS results\n"
|
832
|
-
opendss_folder = File.join(@root_dir, 'run', @scenario_name, 'opendss')
|
913
|
+
opendss_folder = File.join(@root_dir, 'run', @scenario_name.downcase, 'opendss')
|
833
914
|
if File.directory?(opendss_folder)
|
834
915
|
opendss_folder_name = File.basename(opendss_folder)
|
835
916
|
opendss_post_processor = URBANopt::Scenario::OpenDSSPostProcessor.new(scenario_report, opendss_results_dir_name = opendss_folder_name)
|
@@ -848,15 +929,58 @@ module URBANopt
|
|
848
929
|
scenario_assumptions = File.expand_path(@opthash.subopts[:reopt_scenario_assumptions_file]).to_s
|
849
930
|
end
|
850
931
|
puts "\nRunning the REopt Scenario post-processor with scenario assumptions file: #{scenario_assumptions}\n"
|
851
|
-
|
932
|
+
# Add community photovoltaic if present in the Feature File
|
933
|
+
community_photovoltaic = []
|
934
|
+
feature_file = JSON.parse(File.read(File.expand_path(@opthash.subopts[:feature])), symbolize_names: true)
|
935
|
+
feature_file[:features].each do |feature|
|
936
|
+
begin
|
937
|
+
if feature[:properties][:district_system_type]
|
938
|
+
if feature[:properties][:district_system_type] == 'Community Photovoltaic'
|
939
|
+
community_photovoltaic << feature
|
940
|
+
end
|
941
|
+
end
|
942
|
+
rescue
|
943
|
+
end
|
944
|
+
end
|
945
|
+
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(
|
946
|
+
scenario_report,
|
947
|
+
scenario_assumptions,
|
948
|
+
scenario_base.reopt_feature_assumptions,
|
949
|
+
DEVELOPER_NREL_KEY,false
|
950
|
+
)
|
852
951
|
if @opthash.subopts[:reopt_scenario] == true
|
853
952
|
puts "\nPost-processing entire scenario with REopt\n"
|
854
|
-
scenario_report_scenario = reopt_post_processor.run_scenario_report(
|
953
|
+
scenario_report_scenario = reopt_post_processor.run_scenario_report(
|
954
|
+
scenario_report: scenario_report,
|
955
|
+
save_name: 'scenario_optimization',
|
956
|
+
run_resilience: @opthash.subopts[:reopt_resilience],
|
957
|
+
community_photovoltaic: community_photovoltaic
|
958
|
+
)
|
855
959
|
results << { "process_type": 'reopt_scenario', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
|
856
960
|
puts "\nDone\n"
|
857
961
|
elsif @opthash.subopts[:reopt_feature] == true
|
858
962
|
puts "\nPost-processing each building individually with REopt\n"
|
859
|
-
|
963
|
+
# Add groundmount photovoltaic if present in the Feature File
|
964
|
+
groundmount_photovoltaic = {}
|
965
|
+
feature_file = JSON.parse(File.read(File.expand_path(@opthash.subopts[:feature])), symbolize_names: true)
|
966
|
+
feature_file[:features].each do |feature|
|
967
|
+
begin
|
968
|
+
if feature[:properties][:district_system_type]
|
969
|
+
if feature[:properties][:district_system_type] == 'Ground Mount Photovoltaic'
|
970
|
+
groundmount_photovoltaic[feature[:properties][:associated_building_id]] = feature[:properties][:footprint_area]
|
971
|
+
end
|
972
|
+
end
|
973
|
+
rescue
|
974
|
+
end
|
975
|
+
end
|
976
|
+
scenario_report_features = reopt_post_processor.run_scenario_report_features(
|
977
|
+
scenario_report: scenario_report,
|
978
|
+
save_names_feature_reports: ['feature_optimization'] * scenario_report.feature_reports.length,
|
979
|
+
save_name_scenario_report: 'feature_optimization',
|
980
|
+
run_resilience: @opthash.subopts[:reopt_resilience],
|
981
|
+
keep_existing_output: @opthash.subopts[:reopt_keep_existing],
|
982
|
+
groundmount_photovoltaic: groundmount_photovoltaic
|
983
|
+
)
|
860
984
|
results << { "process_type": 'reopt_feature', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
|
861
985
|
puts "\nDone\n"
|
862
986
|
end
|
@@ -881,11 +1005,16 @@ module URBANopt
|
|
881
1005
|
scenario_folders = []
|
882
1006
|
scenario_report_exists = false
|
883
1007
|
Dir.glob(File.join(run_dir, '/*_scenario')) do |scenario_folder|
|
884
|
-
scenario_report = File.join(scenario_folder, '
|
885
|
-
if
|
886
|
-
|
1008
|
+
scenario_report = File.join(scenario_folder, 'scenario_optimization.csv')
|
1009
|
+
# Check if Scenario Optimization REopt file exists and add that
|
1010
|
+
if File.exist?(File.join(scenario_folder, 'scenario_optimization.csv'))
|
1011
|
+
scenario_folders << File.join(scenario_folder, 'scenario_optimization.csv')
|
887
1012
|
scenario_report_exists = true
|
888
|
-
|
1013
|
+
# Check if Default Feature Report exists and add that
|
1014
|
+
elsif File.exist?(File.join(scenario_folder, 'default_scenario_report.csv'))
|
1015
|
+
scenario_folders << File.join(scenario_folder, 'default_scenario_report.csv')
|
1016
|
+
scenario_report_exists = true
|
1017
|
+
elsif
|
889
1018
|
puts "\nERROR: Default reports not created for #{scenario_folder}. Please use 'process --default' to create default post processing reports for all scenarios first. Visualization not generated for #{scenario_folder}.\n"
|
890
1019
|
end
|
891
1020
|
end
|
@@ -921,11 +1050,14 @@ module URBANopt
|
|
921
1050
|
feature_folders = []
|
922
1051
|
# loop through building feature ids from scenario csv
|
923
1052
|
csv['Feature Id'].each do |feature|
|
924
|
-
|
925
|
-
if File.exist?(
|
1053
|
+
# Check if Feature Optimization REopt file exists and add that
|
1054
|
+
if File.exist?(File.join(run_dir, feature, 'feature_reports/feature_optimization.csv'))
|
926
1055
|
feature_report_exists = true
|
927
|
-
feature_folders << File.join(run_dir, feature)
|
928
|
-
|
1056
|
+
feature_folders << File.join(run_dir, feature, 'feature_reports/feature_optimization.csv')
|
1057
|
+
elsif File.exist?(File.join(run_dir, feature, 'feature_reports/default_feature_report.csv'))
|
1058
|
+
feature_report_exists = true
|
1059
|
+
feature_folders << File.join(run_dir, feature, 'feature_reports/default_feature_report.csv')
|
1060
|
+
elsif
|
929
1061
|
puts "\nERROR: Default reports not created for #{feature}. Please use 'process --default' to create default post processing reports for all features first. Visualization not generated for #{feature}.\n"
|
930
1062
|
end
|
931
1063
|
end
|
@@ -944,7 +1076,7 @@ module URBANopt
|
|
944
1076
|
end
|
945
1077
|
end
|
946
1078
|
end
|
947
|
-
html_out_path = File.join(@root_dir, 'run', @scenario_name, 'feature_comparison.html')
|
1079
|
+
html_out_path = File.join(@root_dir, 'run', @scenario_name.downcase, 'feature_comparison.html')
|
948
1080
|
FileUtils.cp(html_in_path, html_out_path)
|
949
1081
|
puts "\nDone\n"
|
950
1082
|
end
|
@@ -966,8 +1098,8 @@ module URBANopt
|
|
966
1098
|
feature_ids = CSV.read(@opthash.subopts[:scenario], headers: true)
|
967
1099
|
feature_list = []
|
968
1100
|
feature_ids['Feature Id'].each do |feature|
|
969
|
-
if Dir.exist?(File.join(@root_dir, 'run', @scenario_name, feature))
|
970
|
-
feature_list << File.join(@root_dir, 'run', @scenario_name, feature)
|
1101
|
+
if Dir.exist?(File.join(@root_dir, 'run', @scenario_name.downcase, feature))
|
1102
|
+
feature_list << File.join(@root_dir, 'run', @scenario_name.downcase, feature)
|
971
1103
|
else
|
972
1104
|
puts "Warning: did not find a directory for FeatureID: #{feature} ...skipping"
|
973
1105
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/bin/bash
|
1
|
+
#!/bin/bash
|
2
2
|
# This is a simple setup script that generates an enviroment file that
|
3
3
|
# is used to setup the ruby enviroment to run the urbanopt-cli tool.
|
4
4
|
# To use, just run this script in bash (e.g. ./setup-env.sh)
|
@@ -8,9 +8,9 @@
|
|
8
8
|
|
9
9
|
BASE_DIR_NAME=$(dirname `which $0`)
|
10
10
|
|
11
|
-
GEM_HOME=${BASE_DIR_NAME}/gems/ruby/2.
|
12
|
-
GEM_PATH=${BASE_DIR_NAME}/gems/ruby/2.
|
13
|
-
PATH=${BASE_DIR_NAME}/ruby/bin:${BASE_DIR_NAME}/gems/ruby/2.
|
11
|
+
GEM_HOME=${BASE_DIR_NAME}/gems/ruby/2.7.0
|
12
|
+
GEM_PATH=${BASE_DIR_NAME}/gems/ruby/2.7.0
|
13
|
+
PATH=${BASE_DIR_NAME}/ruby/bin:${BASE_DIR_NAME}/gems/ruby/2.7.0/bin:$PATH
|
14
14
|
RUBYLIB=${BASE_DIR_NAME}/OpenStudio/Ruby
|
15
15
|
RUBY_DLL_PATH=${BASE_DIR_NAME}/OpenStudio/Ruby
|
16
16
|
|
data/scripts/setup-env-unix.sh
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/bin/bash
|
1
|
+
#!/bin/bash
|
2
2
|
# This is a simple setup script that generates an enviroment file that
|
3
3
|
# is used to setup the ruby enviroment to run the urbanopt-cli tool.
|
4
4
|
# To use, just run this script in bash (e.g. ./setup-env.sh)
|
@@ -7,9 +7,9 @@
|
|
7
7
|
|
8
8
|
BASE_DIR_NAME="$(cd "$(dirname "$0")" && pwd)"
|
9
9
|
|
10
|
-
GEM_HOME=${BASE_DIR_NAME}/gems/ruby/2.
|
11
|
-
GEM_PATH=${BASE_DIR_NAME}/gems/ruby/2.
|
12
|
-
PATH=${BASE_DIR_NAME}/ruby/bin:${BASE_DIR_NAME}/gems/ruby/2.
|
10
|
+
GEM_HOME=${BASE_DIR_NAME}/gems/ruby/2.7.0
|
11
|
+
GEM_PATH=${BASE_DIR_NAME}/gems/ruby/2.7.0
|
12
|
+
PATH=${BASE_DIR_NAME}/ruby/bin:${BASE_DIR_NAME}/gems/ruby/2.7.0/bin:$PATH
|
13
13
|
RUBYLIB=${BASE_DIR_NAME}/OpenStudio/Ruby
|
14
14
|
RUBY_DLL_PATH=${BASE_DIR_NAME}/OpenStudio/Ruby
|
15
15
|
|
data/scripts/setup-env.bat
CHANGED
@@ -3,9 +3,9 @@ IF "%HOMEPATH%"=="" exit /B
|
|
3
3
|
|
4
4
|
SET BASE_DIR_NAME=%~d0%~p0
|
5
5
|
|
6
|
-
SET GEM_HOME=%BASE_DIR_NAME%\gems\ruby\2.
|
7
|
-
SET GEM_PATH=%BASE_DIR_NAME%\gems\ruby\2.
|
8
|
-
SET PATH=%BASE_DIR_NAME%\ruby\bin;%BASE_DIR_NAME%\gems\ruby\2.
|
6
|
+
SET GEM_HOME=%BASE_DIR_NAME%\gems\ruby\2.7.0
|
7
|
+
SET GEM_PATH=%BASE_DIR_NAME%\gems\ruby\2.7.0
|
8
|
+
SET PATH=%BASE_DIR_NAME%\ruby\bin;%BASE_DIR_NAME%\gems\ruby\2.7.0\bin;%PATH%
|
9
9
|
SET RUBYLIB=%BASE_DIR_NAME%\OpenStudio\Ruby
|
10
10
|
SET RUBY_DLL_PATH=%BASE_DIR_NAME%\OpenStudio\Ruby
|
11
11
|
|