urbanopt-cli 0.6.0 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|