urbanopt-cli 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +10 -1
- data/CHANGELOG.md +13 -0
- data/Gemfile +28 -21
- data/example_files/Gemfile +2 -5
- data/example_files/example_project.json +1 -1
- data/example_files/mappers/Baseline.rb +111 -93
- data/example_files/mappers/HighEfficiency.rb +1 -1
- data/lib/uo_cli/version.rb +1 -1
- data/lib/uo_cli.rb +41 -39
- data/uo_cli.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45f2908aa6ed3a360029d8a474276fe27d3e1d02
|
4
|
+
data.tar.gz: a39f3810ddacfa43a0a2b36cfb5860bea5b514d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afa12d95c62d4fb01c10f4d7c79951c12fa7b85d972c41b5c1a77704d496da189c29b1e9ba5c7b21573ed614187474600136504aa3fc752fd3ef9f45fee75a08
|
7
|
+
data.tar.gz: 8acba12c2a7b36fba84f002286fa878de9577ffb9f29aae865bf5ef39fd102c458925ef3bec2e7cce5564048b266bea7e59021efe5fd669350f85a20d90fa66e
|
data/.gitignore
CHANGED
@@ -6,6 +6,11 @@
|
|
6
6
|
/pkg/
|
7
7
|
/spec/reports/
|
8
8
|
/tmp/
|
9
|
+
.DS_Store
|
10
|
+
|
11
|
+
# local dev IDE settings
|
12
|
+
.vscode/
|
13
|
+
.idea/
|
9
14
|
|
10
15
|
# rbenv virtualenv management file
|
11
16
|
.ruby-version
|
@@ -13,4 +18,8 @@
|
|
13
18
|
# rspec failure tracking
|
14
19
|
.rspec_status
|
15
20
|
|
16
|
-
|
21
|
+
# rspec test folder
|
22
|
+
spec/test_directory
|
23
|
+
|
24
|
+
Gemfile.lock
|
25
|
+
.rubocop*
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Version 0.2.3
|
4
|
+
|
5
|
+
Date Range: 04/01/20 - 04/23/20:
|
6
|
+
|
7
|
+
- Fixed [#65]( https://github.com/urbanopt/urbanopt-cli/issues/65 ), Add more tests
|
8
|
+
- Fixed [#81]( https://github.com/urbanopt/urbanopt-cli/issues/81 ), Mappers weren't updated for version 0.2
|
9
|
+
- Fixed [#83]( https://github.com/urbanopt/urbanopt-cli/issues/83 ), Recommend using absolute paths
|
10
|
+
- Fixed [#85]( https://github.com/urbanopt/urbanopt-cli/issues/85 ), reopt dependency not installed
|
11
|
+
- Fixed [#88]( https://github.com/urbanopt/urbanopt-cli/issues/88 ), Reopt tests are failing
|
12
|
+
- Fixed [#90]( https://github.com/urbanopt/urbanopt-cli/issues/90 ), Update baseline mapper
|
13
|
+
- Fixed [#92]( https://github.com/urbanopt/urbanopt-cli/issues/92 ), baseline mapper bug reading json file
|
14
|
+
|
3
15
|
## Version 0.2.2
|
16
|
+
|
4
17
|
Date Range: 3/31/20 - 3/31/20
|
5
18
|
|
6
19
|
- Fixing simplecov / json native extension dependency
|
data/Gemfile
CHANGED
@@ -6,7 +6,6 @@ gemspec
|
|
6
6
|
# simplecov has a dependency on native json gem, use fork that does not require this
|
7
7
|
gem 'certified'
|
8
8
|
gem 'simplecov', github: 'NREL/simplecov'
|
9
|
-
gem 'urbanopt-reopt', '0.2.0'
|
10
9
|
|
11
10
|
# Local gems are useful when developing and integrating the various dependencies.
|
12
11
|
# To favor the use of local gems, set the following environment variable:
|
@@ -38,23 +37,31 @@ allow_local = ENV['FAVOR_LOCAL_GEMS']
|
|
38
37
|
# gem 'openstudio-model-articulation', github: 'NREL/openstudio-model-articulation-gem', branch: 'develop'
|
39
38
|
# end
|
40
39
|
|
41
|
-
if allow_local && File.exist?('../urbanopt-scenario-gem')
|
42
|
-
|
43
|
-
elsif allow_local
|
44
|
-
|
45
|
-
else
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
if allow_local && File.exist?('../urbanopt-geojson-gem')
|
52
|
-
|
53
|
-
|
54
|
-
elsif allow_local
|
55
|
-
|
56
|
-
else
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
40
|
+
# if allow_local && File.exist?('../urbanopt-scenario-gem')
|
41
|
+
# gem 'urbanopt-scenario', path: '../urbanopt-scenario-gem'
|
42
|
+
# elsif allow_local
|
43
|
+
# gem 'urbanopt-scenario', github: 'URBANopt/urbanopt-scenario-gem', branch: 'develop'
|
44
|
+
# else
|
45
|
+
# gem 'urbanopt-scenario', '0.2.0'
|
46
|
+
# # temporary
|
47
|
+
# # gem 'urbanopt-scenario', github: 'URBANopt/urbanopt-scenario-gem', branch: 'develop'
|
48
|
+
# end
|
49
|
+
|
50
|
+
# if allow_local && File.exist?('../urbanopt-geojson-gem')
|
51
|
+
# # gem 'openstudio-extension', github: 'NREL/OpenStudio-extension-gem', branch: 'develop'
|
52
|
+
# gem 'urbanopt-geojson', path: '../urbanopt-geojson-gem'
|
53
|
+
# elsif allow_local
|
54
|
+
# gem 'urbanopt-geojson', github: 'URBANopt/urbanopt-geojson-gem', branch: 'develop'
|
55
|
+
# else
|
56
|
+
# gem 'urbanopt-geojson', '0.2.0'
|
57
|
+
# # temporary
|
58
|
+
# # gem 'urbanopt-scenario', github: 'URBANopt/urbanopt-scenario-gem', branch: 'develop'
|
59
|
+
# end
|
60
|
+
|
61
|
+
# if allow_local && File.exist?('../urbanopt-reopt-gem')
|
62
|
+
# gem 'urbanopt-reopt', path: '../urbanopt-reopt-gem'
|
63
|
+
# elsif allow_local
|
64
|
+
# gem 'urbanopt-reopt', github: 'URBANopt/urbanopt-reopt-gem', branch: 'develop'
|
65
|
+
# else
|
66
|
+
# gem 'urbanopt-reopt', '0.2.1'
|
67
|
+
# end
|
data/example_files/Gemfile
CHANGED
@@ -46,7 +46,7 @@ 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.2.
|
49
|
+
gem 'urbanopt-reopt', '0.2.1'
|
50
50
|
|
51
51
|
if allow_local && File.exist?('../urbanopt-scenario-gem')
|
52
52
|
gem 'urbanopt-scenario', path: '../urbanopt-scenario-gem'
|
@@ -54,21 +54,18 @@ elsif allow_local
|
|
54
54
|
gem 'urbanopt-scenario', github: 'URBANopt/urbanopt-scenario-gem', branch: 'develop'
|
55
55
|
else
|
56
56
|
gem 'urbanopt-scenario', '0.2.0'
|
57
|
-
# gem 'urbanopt-scenario', github: 'URBANopt/urbanopt-scenario-gem', branch: 'develop'
|
58
57
|
end
|
59
58
|
|
60
59
|
if allow_local && File.exist?('../urbanopt-geojson-gem')
|
61
|
-
# gem 'openstudio-extension', github: 'NREL/OpenStudio-extension-gem', branch: 'develop'
|
62
60
|
gem 'urbanopt-geojson', path: '../urbanopt-geojson-gem'
|
63
61
|
elsif allow_local
|
64
62
|
gem 'urbanopt-geojson', github: 'URBANopt/urbanopt-geojson-gem', branch: 'develop'
|
65
63
|
else
|
66
64
|
gem 'urbanopt-geojson', '0.2.0'
|
67
|
-
# gem 'urbanopt-geojson', github: 'URBANopt/urbanopt-geojson-gem', branch: 'develop'
|
68
65
|
end
|
69
66
|
|
70
67
|
# simplecov has an unneccesary dependency on native json gem, use fork that does not require this
|
71
68
|
gem 'simplecov', github: 'NREL/simplecov'
|
72
69
|
|
73
|
-
#
|
70
|
+
# Specify exact rack version temporarily to work with Ruby 2.2.4
|
74
71
|
gem 'rack', '2.1.2'
|
@@ -13,7 +13,7 @@
|
|
13
13
|
"cec_climate_zone": null,
|
14
14
|
"climate_zone": "6A",
|
15
15
|
"default_template": "90.1-2013",
|
16
|
-
"end_date": "2017-
|
16
|
+
"end_date": "2017-12-31T07:00:00.000Z",
|
17
17
|
"id": "53340c2c-ab20-40db-aba1-11ac607c52a7",
|
18
18
|
"import_surrounding_buildings_as_shading": null,
|
19
19
|
"name": "Site Origin",
|
@@ -67,61 +67,61 @@ module URBANopt
|
|
67
67
|
if template.include? 'DEER'
|
68
68
|
case building_type
|
69
69
|
when 'Education'
|
70
|
-
'EPr'
|
70
|
+
return 'EPr'
|
71
71
|
when 'Enclosed mall'
|
72
|
-
'RtL'
|
72
|
+
return 'RtL'
|
73
73
|
when 'Food sales'
|
74
|
-
'RSD'
|
74
|
+
return 'RSD'
|
75
75
|
when 'Food service'
|
76
|
-
'RSD'
|
76
|
+
return 'RSD'
|
77
77
|
when 'Inpatient health care'
|
78
|
-
'Nrs'
|
78
|
+
return 'Nrs'
|
79
79
|
when 'Laboratory'
|
80
|
-
'Hsp'
|
80
|
+
return 'Hsp'
|
81
81
|
when 'Lodging'
|
82
|
-
'Htl'
|
82
|
+
return 'Htl'
|
83
83
|
when 'Mixed use'
|
84
|
-
'ECC'
|
84
|
+
return 'ECC'
|
85
85
|
when 'Mobile Home'
|
86
|
-
'DMo'
|
86
|
+
return 'DMo'
|
87
87
|
when 'Multifamily (2 to 4 units)'
|
88
|
-
'MFm'
|
88
|
+
return 'MFm'
|
89
89
|
when 'Multifamily (5 or more units)'
|
90
|
-
'MFm'
|
90
|
+
return 'MFm'
|
91
91
|
when 'Nonrefrigerated warehouse'
|
92
|
-
'SUn'
|
92
|
+
return 'SUn'
|
93
93
|
when 'Nursing'
|
94
|
-
'Nrs'
|
94
|
+
return 'Nrs'
|
95
95
|
when 'Office'
|
96
96
|
if footprint_area
|
97
|
-
if footprint_area.to_f >
|
98
|
-
'OfL'
|
97
|
+
if footprint_area.to_f > 100000
|
98
|
+
return 'OfL'
|
99
99
|
else
|
100
|
-
'OfS'
|
100
|
+
return 'OfS'
|
101
101
|
end
|
102
102
|
else
|
103
103
|
raise 'footprint_area required to map office building type'
|
104
104
|
end
|
105
105
|
when 'Outpatient health care'
|
106
|
-
'Nrs'
|
106
|
+
return 'Nrs'
|
107
107
|
when 'Public assembly'
|
108
|
-
'Asm'
|
108
|
+
return 'Asm'
|
109
109
|
when 'Public order and safety'
|
110
|
-
'Asm'
|
110
|
+
return 'Asm'
|
111
111
|
when 'Refrigerated warehouse'
|
112
|
-
'WRf'
|
112
|
+
return 'WRf'
|
113
113
|
when 'Religious worship'
|
114
|
-
'Asm'
|
114
|
+
return 'Asm'
|
115
115
|
when 'Retail other than mall'
|
116
|
-
'RtS'
|
116
|
+
return 'RtS'
|
117
117
|
when 'Service'
|
118
|
-
'MLI'
|
118
|
+
return 'MLI'
|
119
119
|
when 'Single-Family'
|
120
|
-
'MFm'
|
120
|
+
return 'MFm'
|
121
121
|
when 'Strip shopping mall'
|
122
|
-
'RtL'
|
122
|
+
return 'RtL'
|
123
123
|
when 'Vacant'
|
124
|
-
'SUn'
|
124
|
+
return 'SUn'
|
125
125
|
else
|
126
126
|
raise "building type #{building_type} cannot be mapped to a DEER building type"
|
127
127
|
end
|
@@ -130,17 +130,17 @@ module URBANopt
|
|
130
130
|
# default: ASHRAE
|
131
131
|
case building_type
|
132
132
|
when 'Education'
|
133
|
-
'SecondarySchool'
|
133
|
+
return 'SecondarySchool'
|
134
134
|
when 'Enclosed mall'
|
135
|
-
'RetailStripmall'
|
135
|
+
return 'RetailStripmall'
|
136
136
|
when 'Food sales'
|
137
|
-
'FullServiceRestaurant'
|
137
|
+
return 'FullServiceRestaurant'
|
138
138
|
when 'Food service'
|
139
|
-
'FullServiceRestaurant'
|
139
|
+
return 'FullServiceRestaurant'
|
140
140
|
when 'Inpatient health care'
|
141
|
-
'Hospital'
|
141
|
+
return 'Hospital'
|
142
142
|
when 'Laboratory'
|
143
|
-
'Hospital'
|
143
|
+
return 'Hospital'
|
144
144
|
when 'Lodging'
|
145
145
|
if number_of_stories
|
146
146
|
if number_of_stories.to_i > 3
|
@@ -149,51 +149,51 @@ module URBANopt
|
|
149
149
|
return 'SmallHotel'
|
150
150
|
end
|
151
151
|
end
|
152
|
-
'LargeHotel'
|
152
|
+
return 'LargeHotel'
|
153
153
|
when 'Mixed use'
|
154
|
-
'Mixed use'
|
154
|
+
return 'Mixed use'
|
155
155
|
when 'Mobile Home'
|
156
|
-
'MidriseApartment'
|
156
|
+
return 'MidriseApartment'
|
157
157
|
when 'Multifamily (2 to 4 units)'
|
158
|
-
'MidriseApartment'
|
158
|
+
return 'MidriseApartment'
|
159
159
|
when 'Multifamily (5 or more units)'
|
160
|
-
'MidriseApartment'
|
160
|
+
return 'MidriseApartment'
|
161
161
|
when 'Nonrefrigerated warehouse'
|
162
|
-
'Warehouse'
|
162
|
+
return 'Warehouse'
|
163
163
|
when 'Nursing'
|
164
|
-
'Outpatient'
|
164
|
+
return 'Outpatient'
|
165
165
|
when 'Office'
|
166
166
|
if footprint_area
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
167
|
+
if footprint_area.to_f < 20000
|
168
|
+
value = 'SmallOffice'
|
169
|
+
elsif footprint_area.to_f > 100000
|
170
|
+
value = 'LargeOffice'
|
171
|
+
else
|
172
|
+
value = 'MediumOffice'
|
173
|
+
end
|
174
174
|
else
|
175
175
|
raise 'Floor area required to map office building type'
|
176
176
|
end
|
177
177
|
when 'Outpatient health care'
|
178
|
-
'Outpatient'
|
178
|
+
return 'Outpatient'
|
179
179
|
when 'Public assembly'
|
180
|
-
'MediumOffice'
|
180
|
+
return 'MediumOffice'
|
181
181
|
when 'Public order and safety'
|
182
|
-
'MediumOffice'
|
182
|
+
return 'MediumOffice'
|
183
183
|
when 'Refrigerated warehouse'
|
184
|
-
'Warehouse'
|
184
|
+
return 'Warehouse'
|
185
185
|
when 'Religious worship'
|
186
|
-
'MediumOffice'
|
186
|
+
return 'MediumOffice'
|
187
187
|
when 'Retail other than mall'
|
188
|
-
'RetailStandalone'
|
188
|
+
return 'RetailStandalone'
|
189
189
|
when 'Service'
|
190
|
-
'MediumOffice'
|
190
|
+
return 'MediumOffice'
|
191
191
|
when 'Single-Family'
|
192
|
-
'MidriseApartment'
|
192
|
+
return 'MidriseApartment'
|
193
193
|
when 'Strip shopping mall'
|
194
|
-
'RetailStripmall'
|
194
|
+
return 'RetailStripmall'
|
195
195
|
when 'Vacant'
|
196
|
-
'Warehouse'
|
196
|
+
return 'Warehouse'
|
197
197
|
else
|
198
198
|
raise "building type #{building_type} cannot be mapped to an ASHRAE building type"
|
199
199
|
end
|
@@ -203,38 +203,38 @@ module URBANopt
|
|
203
203
|
def lookup_template_by_year_built(template, year_built)
|
204
204
|
if template.include? 'DEER'
|
205
205
|
if year_built <= 1996
|
206
|
-
'DEER 1985'
|
206
|
+
return 'DEER 1985'
|
207
207
|
elsif year_built <= 2003
|
208
|
-
'DEER 1996'
|
208
|
+
return 'DEER 1996'
|
209
209
|
elsif year_built <= 2007
|
210
|
-
'DEER 2003'
|
210
|
+
return 'DEER 2003'
|
211
211
|
elsif year_built <= 2011
|
212
|
-
'DEER 2007'
|
212
|
+
return 'DEER 2007'
|
213
213
|
elsif year_built <= 2014
|
214
|
-
'DEER 2011'
|
214
|
+
return 'DEER 2011'
|
215
215
|
elsif year_built <= 2015
|
216
|
-
'DEER 2014'
|
216
|
+
return 'DEER 2014'
|
217
217
|
elsif year_built <= 2017
|
218
|
-
'DEER 2015'
|
218
|
+
return 'DEER 2015'
|
219
219
|
elsif year_built <= 2020
|
220
|
-
'DEER 2017'
|
220
|
+
return 'DEER 2017'
|
221
221
|
else
|
222
|
-
'DEER 2020'
|
222
|
+
return 'DEER 2020'
|
223
223
|
end
|
224
224
|
else
|
225
225
|
# ASHRAE
|
226
226
|
if year_built < 1980
|
227
|
-
'DOE Ref Pre-1980'
|
227
|
+
return 'DOE Ref Pre-1980'
|
228
228
|
elsif year_built <= 2004
|
229
|
-
'DOE Ref 1980-2004'
|
229
|
+
return 'DOE Ref 1980-2004'
|
230
230
|
elsif year_built <= 2007
|
231
|
-
'90.1-2004'
|
231
|
+
return '90.1-2004'
|
232
232
|
elsif year_built <= 2010
|
233
|
-
'90.1-2007'
|
233
|
+
return '90.1-2007'
|
234
234
|
elsif year_built <= 2013
|
235
|
-
'90.1-2010'
|
235
|
+
return '90.1-2010'
|
236
236
|
else
|
237
|
-
'90.1-2013'
|
237
|
+
return '90.1-2013'
|
238
238
|
end
|
239
239
|
end
|
240
240
|
end
|
@@ -247,7 +247,9 @@ module URBANopt
|
|
247
247
|
feature_id = feature.id
|
248
248
|
feature_type = feature.type
|
249
249
|
feature_name = feature.name
|
250
|
-
|
250
|
+
if feature_names.size == 1
|
251
|
+
feature_name = feature_names[0]
|
252
|
+
end
|
251
253
|
|
252
254
|
# deep clone of @@osw before we configure it
|
253
255
|
osw = Marshal.load(Marshal.dump(@@osw))
|
@@ -261,17 +263,17 @@ module URBANopt
|
|
261
263
|
# set_run_period
|
262
264
|
begin
|
263
265
|
timesteps_per_hour = feature.timesteps_per_hour
|
264
|
-
|
266
|
+
if timesteps_per_hour
|
265
267
|
OpenStudio::Extension.set_measure_argument(osw, 'set_run_period', 'timesteps_per_hour', timesteps_per_hour)
|
266
268
|
end
|
267
269
|
rescue StandardError
|
268
270
|
end
|
269
271
|
begin
|
270
272
|
begin_date = feature.begin_date
|
271
|
-
|
273
|
+
if begin_date
|
272
274
|
# check date-only YYYY-MM-DD
|
273
|
-
if
|
274
|
-
|
275
|
+
if begin_date.length > 10
|
276
|
+
begin_date = begin_date[0, 10]
|
275
277
|
end
|
276
278
|
OpenStudio::Extension.set_measure_argument(osw, 'set_run_period', 'begin_date', begin_date)
|
277
279
|
end
|
@@ -279,10 +281,10 @@ module URBANopt
|
|
279
281
|
end
|
280
282
|
begin
|
281
283
|
end_date = feature.end_date
|
282
|
-
|
284
|
+
if end_date
|
283
285
|
# check date-only YYYY-MM-DD
|
284
|
-
if
|
285
|
-
|
286
|
+
if end_date.length > 10
|
287
|
+
end_date = end_date[0, 10]
|
286
288
|
end
|
287
289
|
OpenStudio::Extension.set_measure_argument(osw, 'set_run_period', 'end_date', end_date)
|
288
290
|
end
|
@@ -366,11 +368,21 @@ module URBANopt
|
|
366
368
|
end
|
367
369
|
|
368
370
|
floor_height = 10
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
371
|
+
# Map system type to openstudio system types
|
372
|
+
# TODO: Map all system types
|
373
|
+
if building_hash.key?(:system_type)
|
374
|
+
system_type = building_hash[:system_type]
|
375
|
+
case system_type
|
376
|
+
when 'Fan coil district hot and chilled water'
|
377
|
+
system_type = 'Fan coil district chilled water with district hot water'
|
378
|
+
when 'Fan coil air-cooled chiller and boiler'
|
379
|
+
system_type = 'Fan coil air-cooled chiller with boiler'
|
380
|
+
when 'VAV with gas reheat'
|
381
|
+
system_type = 'VAV air-cooled chiller with gas boiler reheat'
|
382
|
+
end
|
383
|
+
else
|
384
|
+
system_type = 'Inferred'
|
385
|
+
end
|
374
386
|
|
375
387
|
def time_mapping(time)
|
376
388
|
hour = time.split(':')[0]
|
@@ -379,7 +391,7 @@ module URBANopt
|
|
379
391
|
fraction_roundup = fraction.round(2)
|
380
392
|
minute_fraction = fraction_roundup.to_s.split('.')[1]
|
381
393
|
new_time = [hour, minute_fraction].join('.')
|
382
|
-
new_time
|
394
|
+
return new_time
|
383
395
|
end
|
384
396
|
|
385
397
|
# ChangeBuildingLocation
|
@@ -390,17 +402,23 @@ module URBANopt
|
|
390
402
|
cec_found = false
|
391
403
|
begin
|
392
404
|
cec_climate_zone = feature.cec_climate_zone
|
393
|
-
|
405
|
+
if !cec_climate_zone.empty?
|
394
406
|
cec_climate_zone = 'T24-CEC' + cec_climate_zone
|
395
407
|
OpenStudio::Extension.set_measure_argument(osw, 'ChangeBuildingLocation', 'climate_zone', cec_climate_zone)
|
396
408
|
cec_found = true
|
409
|
+
# Temporary fix for CEC climate zone:
|
410
|
+
cec_modified_zone = 'CEC ' + cec_climate_zone
|
411
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_bar_from_building_type_ratios', 'climate_zone', cec_modified_zone)
|
412
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'climate_zone', cec_modified_zone, 'create_typical_building_from_model 1')
|
413
|
+
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'climate_zone', cec_modified_zone, 'create_typical_building_from_model 2')
|
414
|
+
|
397
415
|
end
|
398
416
|
rescue StandardError
|
399
417
|
end
|
400
|
-
|
418
|
+
if !cec_found
|
401
419
|
begin
|
402
420
|
climate_zone = feature.climate_zone
|
403
|
-
|
421
|
+
if !climate_zone.empty?
|
404
422
|
climate_zone = 'ASHRAE 169-2013-' + climate_zone
|
405
423
|
OpenStudio::Extension.set_measure_argument(osw, 'ChangeBuildingLocation', 'climate_zone', climate_zone)
|
406
424
|
end
|
@@ -430,7 +448,7 @@ module URBANopt
|
|
430
448
|
# set weekday start time
|
431
449
|
begin
|
432
450
|
weekday_start_time = feature.weekday_start_time
|
433
|
-
|
451
|
+
if !feature.weekday_start_time.empty?
|
434
452
|
new_weekday_start_time = time_mapping(weekday_start_time)
|
435
453
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wkdy_op_hrs_start_time', new_weekday_start_time, 'create_typical_building_from_model 1')
|
436
454
|
end
|
@@ -440,7 +458,7 @@ module URBANopt
|
|
440
458
|
# set weekday duration
|
441
459
|
begin
|
442
460
|
weekday_duration = feature.weekday_duration
|
443
|
-
|
461
|
+
if !feature.weekday_duration.empty?
|
444
462
|
new_weekday_duration = time_mapping(weekday_duration)
|
445
463
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wkdy_op_hrs_duration', new_weekday_duration, 'create_typical_building_from_model 1')
|
446
464
|
end
|
@@ -450,7 +468,7 @@ module URBANopt
|
|
450
468
|
# set weekend start time
|
451
469
|
begin
|
452
470
|
weekend_start_time = feature.weekend_start_time
|
453
|
-
|
471
|
+
if !feature.weekend_start_time.empty?
|
454
472
|
new_weekend_start_time = time_mapping(weekend_start_time)
|
455
473
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wknd_op_hrs_start_time', new_weekend_start_time, 'create_typical_building_from_model 1')
|
456
474
|
end
|
@@ -460,7 +478,7 @@ module URBANopt
|
|
460
478
|
# set weekend duration
|
461
479
|
begin
|
462
480
|
weekend_duration = feature.weekend_duration
|
463
|
-
|
481
|
+
if !feature.weekend_duration.empty?
|
464
482
|
new_weekend_duration = time_mapping(weekend_duration)
|
465
483
|
OpenStudio::Extension.set_measure_argument(osw, 'create_typical_building_from_model', 'wknd_op_hrs_duration', new_weekend_duration, 'create_typical_building_from_model 1')
|
466
484
|
end
|
@@ -546,7 +564,7 @@ module URBANopt
|
|
546
564
|
OpenStudio::Extension.set_measure_argument(osw, 'default_feature_reports', 'feature_type', feature_type)
|
547
565
|
end
|
548
566
|
|
549
|
-
osw
|
567
|
+
return osw
|
550
568
|
end
|
551
569
|
end # BaselineMapper
|
552
570
|
end # Scenario
|
@@ -51,7 +51,7 @@ module URBANopt
|
|
51
51
|
OpenStudio::Extension.set_measure_argument(osw, 'ReduceLightingLoadsByPercentage', '__SKIP__', false)
|
52
52
|
OpenStudio::Extension.set_measure_argument(osw, 'ReduceLightingLoadsByPercentage', 'lighting_power_reduction_percent', 10)
|
53
53
|
|
54
|
-
osw
|
54
|
+
return osw
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
data/lib/uo_cli/version.rb
CHANGED
data/lib/uo_cli.rb
CHANGED
@@ -46,7 +46,7 @@ module URBANopt
|
|
46
46
|
# Set up user interface
|
47
47
|
@user_input = {}
|
48
48
|
the_parser = OptionParser.new do |opts|
|
49
|
-
opts.banner = "
|
49
|
+
opts.banner = "\nUsage: uo [-peomrgdsfitv]\n" \
|
50
50
|
"\n" \
|
51
51
|
"URBANopt CLI\n" \
|
52
52
|
"First create a project folder with -p, then run additional commands as desired\n" \
|
@@ -54,60 +54,60 @@ module URBANopt
|
|
54
54
|
opts.separator ''
|
55
55
|
|
56
56
|
opts.on('-p', '--project_folder <DIR>', String, "Create project directory named <DIR> in your current folder\n" \
|
57
|
-
|
57
|
+
" Fewer warnings are presented when using full paths and the user is not inside the project folder\n\n") do |folder|
|
58
58
|
@user_input[:project_folder] = folder
|
59
59
|
end
|
60
60
|
|
61
61
|
opts.on('-e', '--empty_project_folder', String, "Use with -p argument to create an empty project folder\n" \
|
62
62
|
" Example: uo -e -p <DIR>\n" \
|
63
63
|
" Then add your own Feature file in the project directory you created,\n" \
|
64
|
-
" add Weather files in the weather folder and add OpenStudio models of Features
|
65
|
-
" in the Feature File, if any in the osm_building folder
|
66
|
-
|
64
|
+
" add Weather files in the weather folder and add OpenStudio models of Features\n" \
|
65
|
+
" in the Feature File, if any, in the osm_building folder\n" \
|
66
|
+
" Fewer warnings are presented when using full paths and the user is not inside the project folder\n\n") do
|
67
67
|
@user_input[:empty_project_folder] = 'Create empty project folder' # This text does not get displayed to the user
|
68
68
|
end
|
69
69
|
|
70
70
|
opts.on('-o', '--overwrite_project_folder', String, "Use with -p argument to overwrite existing project folder and replace with new project folder.\n" \
|
71
|
-
" Or
|
71
|
+
" Or use with -e and -p argument to overwrite existing project folder and replace with new empty project folder.\n" \
|
72
72
|
" Usage: uo -o -p <DIR>\n" \
|
73
|
-
" or
|
74
|
-
|
73
|
+
" or uo -o -e -p <DIR>\n" \
|
74
|
+
" Where <DIR> is the existing project folder\n\n") do
|
75
75
|
@user_input[:overwrite_project_folder] = 'Overwriting existing project folder' # This text does not get displayed to the user
|
76
76
|
end
|
77
77
|
|
78
78
|
opts.on('-m', '--make_scenario', String, "Create ScenarioCSV files for each MapperFile using the Feature file path. Must specify -f argument\n" \
|
79
79
|
" Example: uo -m -f example_project.json\n" \
|
80
80
|
" Or, Create Scenario CSV for each MapperFile for a single Feature from Feature File. Must specify -f and -i argument\n" \
|
81
|
-
|
81
|
+
" Example: uo -m -f example_project.json -i 1\n\n") do
|
82
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
83
|
end
|
84
84
|
|
85
85
|
opts.on('-r', '--run', String, "Run simulations. Must specify -s & -f arguments\n" \
|
86
|
-
|
86
|
+
" Example: uo -r -s baseline_scenario.csv -f example_project.json\n\n") do
|
87
87
|
@user_input[:run_scenario] = 'Run simulations' # This text does not get displayed to the user
|
88
88
|
end
|
89
89
|
|
90
90
|
opts.on('-g', '--gather', String, "group individual feature results to scenario-level results. Must specify -t, -s, & -f arguments\n" \
|
91
|
-
|
91
|
+
" Example: uo -g -t default -s baseline_scenario.csv -f example_project.json\n\n") do
|
92
92
|
@user_input[:gather] = 'Aggregate all features to a whole Scenario' # This text does not get displayed to the user
|
93
93
|
end
|
94
94
|
|
95
95
|
opts.on('-d', '--delete_scenario', String, "Delete results from scenario. Must specify -s argument\n" \
|
96
|
-
|
96
|
+
" Example: uo -d -s baseline_scenario.csv\n\n") do
|
97
97
|
@user_input[:delete_scenario] = 'Delete scenario results that were created from <SFP>' # This text does not get displayed to the user
|
98
98
|
end
|
99
99
|
|
100
|
-
opts.on('-s', '--scenario_file <SFP>', String,
|
100
|
+
opts.on('-s', '--scenario_file <SFP>', String, "Specify <SFP> (ScenarioCSV file path). Used as input for other commands\n\n") do |scenario|
|
101
101
|
@user_input[:scenario] = scenario
|
102
102
|
@root_dir, @scenario_file_name = File.split(File.absolute_path(@user_input[:scenario]))
|
103
103
|
end
|
104
104
|
|
105
|
-
opts.on('-f', '--feature_file <FFP>', String,
|
105
|
+
opts.on('-f', '--feature_file <FFP>', String, "Specify <FFP> (Feature file path). Used as input for other commands\n\n") do |feature|
|
106
106
|
@user_input[:feature] = feature
|
107
107
|
@feature_path, @feature_name = File.split(File.absolute_path(@user_input[:feature]))
|
108
108
|
end
|
109
109
|
|
110
|
-
opts.on('-i', '--feature_id <FID>', Integer,
|
110
|
+
opts.on('-i', '--feature_id <FID>', Integer, "Specify <FID> (Feature ID). Used as input for other commands\n\n") do |feature_id|
|
111
111
|
@user_input[:feature_id] = feature_id
|
112
112
|
end
|
113
113
|
|
@@ -115,11 +115,11 @@ module URBANopt
|
|
115
115
|
" default\n" \
|
116
116
|
" reopt-scenario\n" \
|
117
117
|
" reopt-feature\n" \
|
118
|
-
" opendss\n") do |type|
|
118
|
+
" opendss\n\n") do |type|
|
119
119
|
@user_input[:type] = type
|
120
120
|
end
|
121
121
|
|
122
|
-
opts.on('-v', '--version',
|
122
|
+
opts.on('-v', '--version', "Show CLI version and exit\n") do
|
123
123
|
@user_input[:version_request] = VERSION
|
124
124
|
end
|
125
125
|
end
|
@@ -176,10 +176,10 @@ module URBANopt
|
|
176
176
|
if feature_id == 'SKIP'
|
177
177
|
# ensure that feature is a building
|
178
178
|
if feature[:properties][:type] == 'Building'
|
179
|
-
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper", '
|
180
|
-
|
179
|
+
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper", 'multiPV_assumptions.json']
|
180
|
+
end
|
181
181
|
elsif feature_id == feature[:properties][:id].to_i
|
182
|
-
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper", '
|
182
|
+
csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper", 'multiPV_assumptions.json']
|
183
183
|
elsif
|
184
184
|
# If Feature ID specified does not exist in the Feature File raise error
|
185
185
|
unless feature_file_json[:features].any? { |hash| hash[:properties][:id].include?(feature_id.to_s) }
|
@@ -201,14 +201,12 @@ module URBANopt
|
|
201
201
|
if overwrite_project == true
|
202
202
|
if Dir.exist?(dir_name)
|
203
203
|
FileUtils.rm_rf(dir_name)
|
204
|
-
puts "Overwriting project directory: #{dir_name}\n"
|
205
204
|
end
|
206
205
|
elsif overwrite_project == false
|
207
206
|
if Dir.exist?(dir_name)
|
208
207
|
abort("\nERROR: there is already a directory here named #{dir_name}... aborting\n---\n\n")
|
209
208
|
end
|
210
209
|
end
|
211
|
-
puts "CREATING NEW URBANopt project directory: #{dir_name}\n"
|
212
210
|
Dir.mkdir dir_name
|
213
211
|
Dir.mkdir File.join(dir_name, 'mappers')
|
214
212
|
Dir.mkdir File.join(dir_name, 'weather')
|
@@ -298,28 +296,30 @@ module URBANopt
|
|
298
296
|
# Perform CLI actions
|
299
297
|
if @user_input[:project_folder] && @user_input[:empty_project_folder].nil?
|
300
298
|
if @user_input[:overwrite_project_folder]
|
299
|
+
puts "\nOverwriting existing project folder: #{@user_input[:project_folder]}...\n\n"
|
300
|
+
puts "Creating a new project folder...\n"
|
301
301
|
create_project_folder(@user_input[:project_folder], empty_folder = false, overwrite_project = true)
|
302
|
-
puts "\nOverwriting exiting project folder #{@user_input[:project_folder]}."
|
303
|
-
puts "Creating a new project folder.\n"
|
304
302
|
elsif @user_input[:overwrite_project_folder].nil?
|
305
303
|
create_project_folder(@user_input[:project_folder], empty_folder = false, overwrite_project = false)
|
306
304
|
end
|
307
305
|
puts "\nAn example FeatureFile is included: 'example_project.json'. You may place your own FeatureFile alongside the example."
|
308
306
|
puts 'Weather data is provided for the example FeatureFile. Additional weather data files may be downloaded from energyplus.net/weather for free'
|
309
307
|
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 "Next,
|
308
|
+
puts "Next, create ScenarioFiles using this CLI call: 'uo -m -f <FFP>'\n"
|
309
|
+
puts "We recommend using absolute paths for all commands, for cleaner output\n"
|
311
310
|
elsif @user_input[:project_folder] && @user_input[:empty_project_folder]
|
312
311
|
if @user_input[:overwrite_project_folder]
|
312
|
+
puts "\nOverwriting existing project folder: #{@user_input[:project_folder]}...\n\n"
|
313
|
+
puts "Creating a new project folder...\n\n"
|
313
314
|
create_project_folder(@user_input[:project_folder], empty_folder = true, overwrite_project = true)
|
314
|
-
puts "\nOverwriting exiting project folder #{@user_input[:project_folder]}."
|
315
|
-
puts "Creating a new project folder.\n"
|
316
315
|
elsif @user_input[:overwrite_project].nil?
|
317
316
|
create_project_folder(@user_input[:project_folder], empty_folder = true, overwrite_project = false)
|
318
317
|
end
|
319
318
|
puts 'Add your FeatureFile in the Project directory you just created.'
|
320
319
|
puts 'Add your weather data files in the Weather folder. They may be downloaded from energyplus.net/weather for free'
|
321
320
|
puts 'Add your OpenStudio models for Features in your Feature file, if any in the osm_building folder'
|
322
|
-
puts "Next,
|
321
|
+
puts "Next, create ScenarioFiles using this CLI call: 'uo -m -f <FFP>'\n"
|
322
|
+
puts "We recommend using absolute paths for all commands, for cleaner output\n"
|
323
323
|
end
|
324
324
|
|
325
325
|
if @user_input[:make_scenario_from]
|
@@ -365,10 +365,14 @@ module URBANopt
|
|
365
365
|
if @user_input[:feature].nil?
|
366
366
|
abort("\nYou must provide '-f' flag and a valid path to a FeatureFile!\n---\n\n")
|
367
367
|
end
|
368
|
-
|
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 }
|
369
372
|
abort("\nYou must provide '-t' flag and a valid Gather type!\n" \
|
370
|
-
"Valid types include:
|
373
|
+
"Valid types include: #{valid_postprocessors}\n---\n\n")
|
371
374
|
end
|
375
|
+
|
372
376
|
@scenario_folder = @scenario_file_name.split('.')[0].capitalize.to_s
|
373
377
|
|
374
378
|
default_post_processor = URBANopt::Scenario::ScenarioDefaultPostProcessor.new(run_func)
|
@@ -378,11 +382,11 @@ module URBANopt
|
|
378
382
|
# save feature reports
|
379
383
|
scenario_report.feature_reports.each(&:save_feature_report)
|
380
384
|
|
381
|
-
if @user_input[:type]
|
385
|
+
if @user_input[:type] == valid_postprocessors[0]
|
382
386
|
puts "\nDone\n"
|
383
|
-
elsif @user_input[:type]
|
387
|
+
elsif @user_input[:type] == valid_postprocessors[3]
|
384
388
|
puts "\nPost-processing OpenDSS results\n"
|
385
|
-
opendss_folder = File.join(@root_dir, 'run', @
|
389
|
+
opendss_folder = File.join(@root_dir, 'run', @scenario_file_name.split('.')[0], 'opendss')
|
386
390
|
if File.directory?(opendss_folder)
|
387
391
|
opendss_folder_name = File.basename(opendss_folder)
|
388
392
|
opendss_post_processor = URBANopt::Scenario::OpenDSSPostProcessor.new(scenario_report, opendss_results_dir_name = opendss_folder_name)
|
@@ -391,25 +395,23 @@ module URBANopt
|
|
391
395
|
else
|
392
396
|
abort("\nNo OpenDSS results available in folder '#{opendss_folder}'\n")
|
393
397
|
end
|
394
|
-
elsif @user_input[:type].to_s.
|
398
|
+
elsif @user_input[:type].to_s.include?('reopt')
|
395
399
|
scenario_base = default_post_processor.scenario_base
|
396
400
|
reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(scenario_report, scenario_base.scenario_reopt_assumptions_file, scenario_base.reopt_feature_assumptions, DEVELOPER_NREL_KEY)
|
397
401
|
|
398
402
|
# Optimize REopt outputs for the whole Scenario
|
399
|
-
if @user_input[:type]
|
403
|
+
if @user_input[:type] == valid_postprocessors[1]
|
400
404
|
puts "\nOptimizing renewable energy for the scenario\n"
|
401
405
|
scenario_report_scenario = reopt_post_processor.run_scenario_report(scenario_report: scenario_report, save_name: 'scenario_optimization')
|
402
406
|
puts "\nDone\n"
|
403
407
|
# Optimize REopt outputs for each feature individually
|
404
|
-
elsif @user_input[:type]
|
408
|
+
elsif @user_input[:type] == valid_postprocessors[2]
|
405
409
|
puts "\nOptimizing renewable energy for each feature\n"
|
406
410
|
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
411
|
puts "\nDone\n"
|
408
|
-
else
|
409
|
-
abort("\nError: did not use type 'reopt-scenario', 'reopt-feature'. Aborting...\n---\n\n")
|
410
412
|
end
|
411
413
|
else
|
412
|
-
abort("\nError: did not use
|
414
|
+
abort("\nError: did not use one of these valid types: #{valid_postprocessors} Aborting...\n---\n\n")
|
413
415
|
end
|
414
416
|
end
|
415
417
|
|
data/uo_cli.gemspec
CHANGED
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
|
37
37
|
# use specific versions of urbanopt and openstudio dependencies while under heavy development
|
38
38
|
spec.add_dependency 'urbanopt-geojson', '0.2.0'
|
39
|
+
spec.add_dependency 'urbanopt-reopt', '0.2.1'
|
39
40
|
spec.add_dependency 'urbanopt-scenario', '0.2.0'
|
40
41
|
|
41
42
|
spec.add_development_dependency 'bundler', '~> 1.17'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: urbanopt-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
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-04-
|
11
|
+
date: 2020-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: urbanopt-reopt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.2.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.2.1
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: urbanopt-scenario
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|