honeybee-openstudio 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/honeybee-openstudio.gemspec +1 -1
- data/lib/from_honeybee/_defaults/energy_default.json +1682 -0
- data/lib/from_honeybee/{_openapi → _defaults}/model.json +0 -0
- data/lib/from_honeybee/{_openapi → _defaults}/simulation-parameter.json +0 -0
- data/lib/from_honeybee/extension.rb +21 -1
- data/lib/from_honeybee/model.rb +182 -87
- data/lib/from_honeybee/simulation/extension.rb +1 -1
- metadata +5 -4
File without changes
|
File without changes
|
@@ -37,6 +37,7 @@ require 'openstudio/extension'
|
|
37
37
|
module FromHoneybee
|
38
38
|
class Extension < OpenStudio::Extension::Extension
|
39
39
|
@@schema = nil
|
40
|
+
@@standards = nil
|
40
41
|
|
41
42
|
# Override parent class
|
42
43
|
def initialize
|
@@ -49,6 +50,7 @@ module FromHoneybee
|
|
49
50
|
|
50
51
|
@instance_lock = Mutex.new
|
51
52
|
@@schema ||= schema
|
53
|
+
@@standards ||= standards
|
52
54
|
end
|
53
55
|
|
54
56
|
# Return the absolute path of the measures or nil if there is none.
|
@@ -73,7 +75,12 @@ module FromHoneybee
|
|
73
75
|
|
74
76
|
# return path to the model schema file
|
75
77
|
def schema_file
|
76
|
-
File.join(@lib_dir, 'from_honeybee', '
|
78
|
+
File.join(@lib_dir, 'from_honeybee', '_defaults', 'model.json')
|
79
|
+
end
|
80
|
+
|
81
|
+
# return path to the model standards file
|
82
|
+
def standards_file
|
83
|
+
File.join(@lib_dir, 'from_honeybee', '_defaults', 'energy_default.json')
|
77
84
|
end
|
78
85
|
|
79
86
|
# return the model schema
|
@@ -89,6 +96,19 @@ module FromHoneybee
|
|
89
96
|
@@schema
|
90
97
|
end
|
91
98
|
|
99
|
+
# return the JSON of default standards
|
100
|
+
def standards
|
101
|
+
@instance_lock.synchronize do
|
102
|
+
if @@standards.nil?
|
103
|
+
File.open(standards_file, 'r') do |f|
|
104
|
+
@@standards = JSON.parse(f.read, symbolize_names: true)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
@@standards
|
110
|
+
end
|
111
|
+
|
92
112
|
# check if the model schema is valid
|
93
113
|
def schema_valid?
|
94
114
|
if Gem.loaded_specs.has_key?("json-schema")
|
data/lib/from_honeybee/model.rb
CHANGED
@@ -95,12 +95,12 @@ module FromHoneybee
|
|
95
95
|
# initialize class variable @@extension only once
|
96
96
|
@@extension ||= Extension.new
|
97
97
|
@@schema ||= @@extension.schema
|
98
|
+
@@standards ||= @@extension.standards
|
98
99
|
|
99
100
|
@hash = hash
|
100
101
|
@type = @hash[:type]
|
101
102
|
raise 'Unknown model type' if @type.nil?
|
102
103
|
raise "Incorrect model type '#{@type}'" unless @type == 'Model'
|
103
|
-
|
104
104
|
end
|
105
105
|
|
106
106
|
# check if the model is valid
|
@@ -157,34 +157,58 @@ module FromHoneybee
|
|
157
157
|
building = @openstudio_model.getBuilding
|
158
158
|
building.setStandardsBuildingType('MediumOffice')
|
159
159
|
|
160
|
+
# initialize global hashes for various model properties
|
161
|
+
$gas_gap_hash = Hash.new # hash to track gas gaps in case they are split by shades
|
162
|
+
$air_boundary_hash = Hash.new # hash to track any air boundary constructions
|
163
|
+
$window_shade_hash = Hash.new # hash to track any window constructions with shade
|
164
|
+
$programtype_setpoint_hash = Hash.new # hash to track Setpoint objects
|
165
|
+
|
160
166
|
# create all of the non-geometric model elements
|
161
167
|
if log_report
|
162
168
|
puts 'Translating Materials'
|
163
169
|
end
|
164
|
-
|
170
|
+
if @hash[:properties][:energy][:materials]
|
171
|
+
create_materials(@hash[:properties][:energy][:materials])
|
172
|
+
end
|
165
173
|
|
166
174
|
if log_report
|
167
175
|
puts 'Translating Constructions'
|
168
176
|
end
|
169
|
-
|
177
|
+
if @hash[:properties][:energy][:constructions]
|
178
|
+
create_constructions(@hash[:properties][:energy][:constructions])
|
179
|
+
end
|
170
180
|
|
171
181
|
if log_report
|
172
182
|
puts 'Translating ConstructionSets'
|
173
183
|
end
|
174
|
-
|
175
|
-
|
184
|
+
if @hash[:properties][:energy][:construction_sets]
|
185
|
+
create_construction_sets(@hash[:properties][:energy][:construction_sets])
|
186
|
+
end
|
176
187
|
|
177
188
|
if log_report
|
178
189
|
puts 'Translating Schedules'
|
179
190
|
end
|
180
|
-
|
181
|
-
|
191
|
+
if @hash[:properties][:energy][:schedule_type_limits]
|
192
|
+
create_schedule_type_limits(@hash[:properties][:energy][:schedule_type_limits])
|
193
|
+
end
|
194
|
+
if @hash[:properties][:energy][:schedules]
|
195
|
+
create_schedules(@hash[:properties][:energy][:schedules])
|
196
|
+
end
|
182
197
|
|
183
198
|
if log_report
|
184
199
|
puts 'Translating ProgramTypes'
|
185
200
|
end
|
186
|
-
|
201
|
+
if @hash[:properties][:energy][:program_types]
|
202
|
+
create_program_types(@hash[:properties][:energy][:program_types])
|
203
|
+
end
|
204
|
+
|
205
|
+
# create the default construction set to catch any cases of unassigned constructions
|
206
|
+
if log_report
|
207
|
+
puts 'Translating Default ConstructionSet'
|
208
|
+
end
|
209
|
+
create_default_construction_set
|
187
210
|
|
211
|
+
# create the geometry and add any extra properties to it
|
188
212
|
if log_report
|
189
213
|
puts 'Translating Room Geometry'
|
190
214
|
end
|
@@ -211,103 +235,139 @@ module FromHoneybee
|
|
211
235
|
create_orphaned_doors
|
212
236
|
end
|
213
237
|
|
214
|
-
def create_materials
|
215
|
-
|
238
|
+
def create_materials(material_dicts, check_existing=false)
|
239
|
+
material_dicts.each do |material|
|
240
|
+
# check if there's already a material in the model with the identifier
|
241
|
+
add_obj = true
|
242
|
+
if check_existing
|
243
|
+
object = @openstudio_model.getMaterialByName(material[:identifier])
|
244
|
+
if object.is_initialized
|
245
|
+
add_obj = false
|
246
|
+
end
|
247
|
+
end
|
216
248
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
249
|
+
# add the material object to the Model
|
250
|
+
if add_obj
|
251
|
+
material_type = material[:type]
|
252
|
+
case material_type
|
253
|
+
when 'EnergyMaterial'
|
254
|
+
material_object = EnergyMaterial.new(material)
|
255
|
+
when 'EnergyMaterialNoMass'
|
256
|
+
material_object = EnergyMaterialNoMass.new(material)
|
257
|
+
when 'EnergyWindowMaterialGas'
|
258
|
+
material_object = EnergyWindowMaterialGas.new(material)
|
259
|
+
$gas_gap_hash[material[:identifier]] = material_object
|
260
|
+
when 'EnergyWindowMaterialGasMixture'
|
261
|
+
material_object = EnergyWindowMaterialGasMixture.new(material)
|
262
|
+
$gas_gap_hash[material[:identifier]] = material_object
|
263
|
+
when 'EnergyWindowMaterialGasCustom'
|
264
|
+
material_object = EnergyWindowMaterialGasCustom.new(material)
|
265
|
+
$gas_gap_hash[material[:identifier]] = material_object
|
266
|
+
when 'EnergyWindowMaterialSimpleGlazSys'
|
267
|
+
material_object = EnergyWindowMaterialSimpleGlazSys.new(material)
|
268
|
+
when 'EnergyWindowMaterialBlind'
|
269
|
+
material_object = EnergyWindowMaterialBlind.new(material)
|
270
|
+
when 'EnergyWindowMaterialGlazing'
|
271
|
+
material_object = EnergyWindowMaterialGlazing.new(material)
|
272
|
+
when 'EnergyWindowMaterialShade'
|
273
|
+
material_object = EnergyWindowMaterialShade.new(material)
|
274
|
+
else
|
275
|
+
raise "Unknown material type #{material_type}"
|
276
|
+
end
|
277
|
+
material_object.to_openstudio(@openstudio_model)
|
244
278
|
end
|
245
|
-
material_object.to_openstudio(@openstudio_model)
|
246
279
|
end
|
247
280
|
end
|
248
281
|
|
249
|
-
def create_constructions
|
250
|
-
|
251
|
-
|
282
|
+
def create_constructions(construction_dicts, check_existing=false)
|
283
|
+
construction_dicts.each do |construction|
|
284
|
+
# check if there's already a construction in the model with the identifier
|
285
|
+
add_obj = true
|
286
|
+
if check_existing
|
287
|
+
object = @openstudio_model.getConstructionByName(construction[:identifier])
|
288
|
+
if object.is_initialized
|
289
|
+
add_obj = false
|
290
|
+
end
|
291
|
+
end
|
252
292
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
293
|
+
# add the construction object to the Model
|
294
|
+
if add_obj
|
295
|
+
construction_type = construction[:type]
|
296
|
+
case construction_type
|
297
|
+
when 'OpaqueConstructionAbridged'
|
298
|
+
construction_object = OpaqueConstructionAbridged.new(construction)
|
299
|
+
when 'WindowConstructionAbridged'
|
300
|
+
construction_object = WindowConstructionAbridged.new(construction)
|
301
|
+
when 'WindowConstructionShadeAbridged'
|
302
|
+
construction_object = WindowConstructionShadeAbridged.new(construction)
|
303
|
+
$window_shade_hash[construction[:identifier]] = construction_object
|
304
|
+
when 'ShadeConstruction'
|
305
|
+
construction_object = ShadeConstruction.new(construction)
|
306
|
+
when 'AirBoundaryConstructionAbridged'
|
307
|
+
construction_object = AirBoundaryConstructionAbridged.new(construction)
|
308
|
+
$air_boundary_hash[construction[:identifier]] = construction
|
309
|
+
else
|
310
|
+
raise "Unknown construction type #{construction_type}."
|
311
|
+
end
|
312
|
+
construction_object.to_openstudio(@openstudio_model)
|
272
313
|
end
|
273
|
-
construction_object.to_openstudio(@openstudio_model)
|
274
314
|
end
|
275
315
|
end
|
276
316
|
|
277
|
-
def
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
317
|
+
def create_construction_sets(construction_set_dicts, check_existing=false)
|
318
|
+
construction_set_dicts.each do |construction_set|
|
319
|
+
# check if there's already a construction set in the model with the identifier
|
320
|
+
add_obj = true
|
321
|
+
if check_existing
|
322
|
+
object = @openstudio_model.getDefaultConstructionSetByName(
|
323
|
+
construction_set[:identifier])
|
324
|
+
if object.is_initialized
|
325
|
+
add_obj = false
|
326
|
+
end
|
282
327
|
end
|
283
|
-
end
|
284
|
-
end
|
285
328
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
unless construction.empty?
|
291
|
-
openstudio_construction = construction.get
|
329
|
+
# add the construction set object to the Model
|
330
|
+
if add_obj
|
331
|
+
construction_set_object = ConstructionSetAbridged.new(construction_set)
|
332
|
+
construction_set_object.to_openstudio(@openstudio_model)
|
292
333
|
end
|
293
|
-
@openstudio_model.getBuilding.setDefaultConstructionSet(openstudio_construction)
|
294
334
|
end
|
295
335
|
end
|
296
336
|
|
297
|
-
def create_schedule_type_limits
|
298
|
-
|
299
|
-
|
337
|
+
def create_schedule_type_limits(stl_dicts, check_existing=false)
|
338
|
+
stl_dicts.each do |schedule_type_limit|
|
339
|
+
# check if there's already a schedule type limit in the model with the identifier
|
340
|
+
add_obj = true
|
341
|
+
if check_existing
|
342
|
+
object = @openstudio_model.getScheduleTypeLimitsByName(
|
343
|
+
schedule_type_limit[:identifier])
|
344
|
+
if object.is_initialized
|
345
|
+
add_obj = false
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
# add the schedule type limit object to the Model
|
350
|
+
if add_obj
|
300
351
|
schedule_type_limit_object = ScheduleTypeLimit.new(schedule_type_limit)
|
301
352
|
schedule_type_limit_object.to_openstudio(@openstudio_model)
|
302
353
|
end
|
303
354
|
end
|
304
355
|
end
|
305
356
|
|
306
|
-
def create_schedules
|
307
|
-
|
308
|
-
|
309
|
-
|
357
|
+
def create_schedules(schedule_dicts, check_existing=false)
|
358
|
+
schedule_dicts.each do |schedule|
|
359
|
+
# check if there's already a schedule in the model with the identifier
|
360
|
+
add_obj = true
|
361
|
+
if check_existing
|
362
|
+
object = @openstudio_model.getScheduleByName(schedule[:identifier])
|
363
|
+
if object.is_initialized
|
364
|
+
add_obj = false
|
365
|
+
end
|
366
|
+
end
|
310
367
|
|
368
|
+
# add the schedule object to the Model
|
369
|
+
if add_obj
|
370
|
+
schedule_type = schedule[:type]
|
311
371
|
case schedule_type
|
312
372
|
when 'ScheduleRulesetAbridged'
|
313
373
|
schedule_object = ScheduleRulesetAbridged.new(schedule)
|
@@ -317,21 +377,56 @@ module FromHoneybee
|
|
317
377
|
raise("Unknown schedule type #{schedule_type}.")
|
318
378
|
end
|
319
379
|
schedule_object.to_openstudio(@openstudio_model)
|
320
|
-
|
321
380
|
end
|
322
381
|
end
|
323
382
|
end
|
324
383
|
|
325
|
-
def create_program_types
|
326
|
-
|
327
|
-
|
328
|
-
|
384
|
+
def create_program_types(program_dicts, check_existing=false)
|
385
|
+
program_dicts.each do |space_type|
|
386
|
+
# check if there's already a space type in the model with the identifier
|
387
|
+
add_obj = true
|
388
|
+
if check_existing
|
389
|
+
object = @openstudio_model.getSpaceTypeByName(space_type[:identifier])
|
390
|
+
if object.is_initialized
|
391
|
+
add_obj = false
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
# add the space type object to the Model
|
396
|
+
if add_obj
|
329
397
|
space_type_object = ProgramTypeAbridged.new(space_type)
|
330
398
|
space_type_object.to_openstudio(@openstudio_model)
|
331
399
|
end
|
332
400
|
end
|
333
401
|
end
|
334
402
|
|
403
|
+
def create_default_construction_set
|
404
|
+
# create the materials, constructions and construction set
|
405
|
+
create_materials(@@standards[:materials], true)
|
406
|
+
create_constructions(@@standards[:constructions], true)
|
407
|
+
create_construction_sets(@@standards[:construction_sets], true)
|
408
|
+
|
409
|
+
# write the fractional schedule type and always on schedule if they are not there
|
410
|
+
@@standards[:schedule_type_limits].each do |sch_type_limit|
|
411
|
+
if sch_type_limit[:identifier] == 'Fractional'
|
412
|
+
create_schedule_type_limits([sch_type_limit], true)
|
413
|
+
end
|
414
|
+
end
|
415
|
+
@@standards[:schedules].each do |schedule|
|
416
|
+
if schedule[:identifier] == 'Always On'
|
417
|
+
create_schedules([schedule], true)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
# set the default construction set to the building level of the Model
|
422
|
+
construction_id = 'Default Generic Construction Set'
|
423
|
+
construction = @openstudio_model.getDefaultConstructionSetByName(construction_id)
|
424
|
+
unless construction.empty?
|
425
|
+
os_constructionset = construction.get
|
426
|
+
@openstudio_model.getBuilding.setDefaultConstructionSet(os_constructionset)
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
335
430
|
def create_rooms
|
336
431
|
if @hash[:rooms]
|
337
432
|
$air_mxing_array = [] # list to track any air mixing between Rooms
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: honeybee-openstudio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tanushree Charan
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2020-06-
|
14
|
+
date: 2020-06-30 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -165,8 +165,9 @@ files:
|
|
165
165
|
- lib/files/honeybee_workflow.osw
|
166
166
|
- lib/files/urbanopt_Gemfile
|
167
167
|
- lib/from_honeybee.rb
|
168
|
-
- lib/from_honeybee/
|
169
|
-
- lib/from_honeybee/
|
168
|
+
- lib/from_honeybee/_defaults/energy_default.json
|
169
|
+
- lib/from_honeybee/_defaults/model.json
|
170
|
+
- lib/from_honeybee/_defaults/simulation-parameter.json
|
170
171
|
- lib/from_honeybee/construction/air.rb
|
171
172
|
- lib/from_honeybee/construction/opaque.rb
|
172
173
|
- lib/from_honeybee/construction/shade.rb
|