honeybee-openstudio 2.2.0 → 2.3.0
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/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
|