honeybee-openstudio 0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yaml +88 -0
  3. data/.gitignore +33 -0
  4. data/.releaserc.json +7 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE.md +23 -0
  7. data/README.md +95 -0
  8. data/Rakefile +16 -0
  9. data/doc_templates/LICENSE.md +23 -0
  10. data/doc_templates/README.md.erb +42 -0
  11. data/doc_templates/copyright_erb.txt +32 -0
  12. data/doc_templates/copyright_js.txt +5 -0
  13. data/doc_templates/copyright_ruby.txt +30 -0
  14. data/honeybee-openstudio.gemspec +38 -0
  15. data/lib/files/Honeybee.rb +113 -0
  16. data/lib/files/honeybee_workflow.osw +48 -0
  17. data/lib/files/urbanopt_Gemfile +32 -0
  18. data/lib/from_openstudio.rb +49 -0
  19. data/lib/from_openstudio/geometry/aperture.rb +136 -0
  20. data/lib/from_openstudio/geometry/door.rb +136 -0
  21. data/lib/from_openstudio/geometry/face.rb +174 -0
  22. data/lib/from_openstudio/geometry/room.rb +121 -0
  23. data/lib/from_openstudio/geometry/shade.rb +87 -0
  24. data/lib/from_openstudio/model.rb +123 -0
  25. data/lib/from_openstudio/model_object.rb +43 -0
  26. data/lib/from_openstudio/simulation/design_day.rb +123 -0
  27. data/lib/from_openstudio/simulation/parameter_model.rb +93 -0
  28. data/lib/from_openstudio/simulation/simulation_output.rb +67 -0
  29. data/lib/honeybee.rb +93 -0
  30. data/lib/honeybee/_defaults/energy_default.json +1682 -0
  31. data/lib/honeybee/_defaults/model.json +11311 -0
  32. data/lib/honeybee/_defaults/simulation-parameter.json +973 -0
  33. data/lib/honeybee/construction/air.rb +42 -0
  34. data/lib/honeybee/construction/opaque.rb +42 -0
  35. data/lib/honeybee/construction/shade.rb +42 -0
  36. data/lib/honeybee/construction/window.rb +51 -0
  37. data/lib/honeybee/construction/windowshade.rb +43 -0
  38. data/lib/honeybee/construction_set.rb +42 -0
  39. data/lib/honeybee/extension.rb +129 -0
  40. data/lib/honeybee/geometry/aperture.rb +42 -0
  41. data/lib/honeybee/geometry/door.rb +42 -0
  42. data/lib/honeybee/geometry/face.rb +48 -0
  43. data/lib/honeybee/geometry/room.rb +56 -0
  44. data/lib/honeybee/geometry/shade.rb +42 -0
  45. data/lib/honeybee/hvac/ideal_air.rb +42 -0
  46. data/lib/honeybee/hvac/template.rb +73 -0
  47. data/lib/honeybee/load/electric_equipment.rb +42 -0
  48. data/lib/honeybee/load/gas_equipment.rb +42 -0
  49. data/lib/honeybee/load/infiltration.rb +42 -0
  50. data/lib/honeybee/load/lighting.rb +43 -0
  51. data/lib/honeybee/load/people.rb +42 -0
  52. data/lib/honeybee/load/setpoint_humidistat.rb +46 -0
  53. data/lib/honeybee/load/setpoint_thermostat.rb +46 -0
  54. data/lib/honeybee/load/ventilation.rb +42 -0
  55. data/lib/honeybee/material/opaque.rb +42 -0
  56. data/lib/honeybee/material/opaque_no_mass.rb +42 -0
  57. data/lib/honeybee/material/window_blind.rb +42 -0
  58. data/lib/honeybee/material/window_gas.rb +42 -0
  59. data/lib/honeybee/material/window_gas_custom.rb +42 -0
  60. data/lib/honeybee/material/window_gas_mixture.rb +42 -0
  61. data/lib/honeybee/material/window_glazing.rb +42 -0
  62. data/lib/honeybee/material/window_shade.rb +42 -0
  63. data/lib/honeybee/material/window_simpleglazsys.rb +42 -0
  64. data/lib/honeybee/model.rb +87 -0
  65. data/lib/honeybee/model_object.rb +108 -0
  66. data/lib/honeybee/program_type.rb +56 -0
  67. data/lib/honeybee/schedule/fixed_interval.rb +42 -0
  68. data/lib/honeybee/schedule/ruleset.rb +42 -0
  69. data/lib/honeybee/schedule/type_limit.rb +42 -0
  70. data/lib/honeybee/simulation/design_day.rb +42 -0
  71. data/lib/honeybee/simulation/parameter_model.rb +86 -0
  72. data/lib/honeybee/simulation/simulation_output.rb +42 -0
  73. data/lib/honeybee/ventcool/control.rb +42 -0
  74. data/lib/honeybee/ventcool/opening.rb +46 -0
  75. data/lib/honeybee/ventcool/simulation.rb +42 -0
  76. data/lib/measures/.gitkeep +0 -0
  77. data/lib/measures/from_honeybee_model/LICENSE.md +23 -0
  78. data/lib/measures/from_honeybee_model/README.md +32 -0
  79. data/lib/measures/from_honeybee_model/measure.rb +91 -0
  80. data/lib/measures/from_honeybee_model/measure.xml +80 -0
  81. data/lib/measures/from_honeybee_model/tests/from_honeybee_model_test.rb +126 -0
  82. data/lib/measures/from_honeybee_simulation_parameter/LICENSE.md +23 -0
  83. data/lib/measures/from_honeybee_simulation_parameter/README.md +32 -0
  84. data/lib/measures/from_honeybee_simulation_parameter/measure.rb +95 -0
  85. data/lib/measures/from_honeybee_simulation_parameter/measure.xml +86 -0
  86. data/lib/measures/from_honeybee_simulation_parameter/tests/from_honeybee_simulation_parameter_test.rb +109 -0
  87. data/lib/to_openstudio.rb +92 -0
  88. data/lib/to_openstudio/construction/air.rb +56 -0
  89. data/lib/to_openstudio/construction/opaque.rb +67 -0
  90. data/lib/to_openstudio/construction/shade.rb +99 -0
  91. data/lib/to_openstudio/construction/window.rb +70 -0
  92. data/lib/to_openstudio/construction/windowshade.rb +196 -0
  93. data/lib/to_openstudio/construction_set.rb +266 -0
  94. data/lib/to_openstudio/geometry/aperture.rb +157 -0
  95. data/lib/to_openstudio/geometry/door.rb +150 -0
  96. data/lib/to_openstudio/geometry/face.rb +178 -0
  97. data/lib/to_openstudio/geometry/room.rb +442 -0
  98. data/lib/to_openstudio/geometry/shade.rb +79 -0
  99. data/lib/to_openstudio/hvac/Model.hvac.rb +641 -0
  100. data/lib/to_openstudio/hvac/ideal_air.rb +141 -0
  101. data/lib/to_openstudio/hvac/template.rb +169 -0
  102. data/lib/to_openstudio/load/electric_equipment.rb +87 -0
  103. data/lib/to_openstudio/load/gas_equipment.rb +88 -0
  104. data/lib/to_openstudio/load/infiltration.rb +86 -0
  105. data/lib/to_openstudio/load/lighting.rb +89 -0
  106. data/lib/to_openstudio/load/people.rb +91 -0
  107. data/lib/to_openstudio/load/setpoint_humidistat.rb +66 -0
  108. data/lib/to_openstudio/load/setpoint_thermostat.rb +62 -0
  109. data/lib/to_openstudio/load/ventilation.rb +87 -0
  110. data/lib/to_openstudio/material/opaque.rb +85 -0
  111. data/lib/to_openstudio/material/opaque_no_mass.rb +85 -0
  112. data/lib/to_openstudio/material/window_blind.rb +229 -0
  113. data/lib/to_openstudio/material/window_gas.rb +67 -0
  114. data/lib/to_openstudio/material/window_gas_custom.rb +108 -0
  115. data/lib/to_openstudio/material/window_gas_mixture.rb +70 -0
  116. data/lib/to_openstudio/material/window_glazing.rb +157 -0
  117. data/lib/to_openstudio/material/window_shade.rb +151 -0
  118. data/lib/to_openstudio/material/window_simpleglazsys.rb +64 -0
  119. data/lib/to_openstudio/model.rb +497 -0
  120. data/lib/to_openstudio/model_object.rb +52 -0
  121. data/lib/to_openstudio/program_type.rb +104 -0
  122. data/lib/to_openstudio/schedule/fixed_interval.rb +105 -0
  123. data/lib/to_openstudio/schedule/ruleset.rb +164 -0
  124. data/lib/to_openstudio/schedule/type_limit.rb +76 -0
  125. data/lib/to_openstudio/simulation/design_day.rb +96 -0
  126. data/lib/to_openstudio/simulation/parameter_model.rb +243 -0
  127. data/lib/to_openstudio/ventcool/control.rb +185 -0
  128. data/lib/to_openstudio/ventcool/opening.rb +189 -0
  129. data/lib/to_openstudio/ventcool/simulation.rb +101 -0
  130. metadata +301 -0
@@ -0,0 +1,64 @@
1
+ # *******************************************************************************
2
+ # Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
3
+ # Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # (1) Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # (3) Neither the name of the copyright holder nor the names of any contributors
16
+ # may be used to endorse or promote products derived from this software without
17
+ # specific prior written permission from the respective party.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
23
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
24
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ # *******************************************************************************
31
+
32
+ require 'honeybee/material/window_simpleglazsys'
33
+
34
+ require 'to_openstudio/model_object'
35
+
36
+ module Honeybee
37
+ class EnergyWindowMaterialSimpleGlazSys
38
+
39
+ def find_existing_openstudio_object(openstudio_model)
40
+ object = openstudio_model.getSimpleGlazingByName(@hash[:identifier])
41
+ return object.get if object.is_initialized
42
+ nil
43
+ end
44
+
45
+ def to_openstudio(openstudio_model)
46
+ # create simple glazing openstudio object
47
+ os_simple_glazing = OpenStudio::Model::SimpleGlazing.new(openstudio_model)
48
+ os_simple_glazing.setName(@hash[:identifier])
49
+ os_simple_glazing.setUFactor(@hash[:u_factor])
50
+ os_simple_glazing.setSolarHeatGainCoefficient(@hash[:shgc])
51
+
52
+ # assign visible transmittance
53
+ if @hash[:vt]
54
+ os_simple_glazing.setVisibleTransmittance(@hash[:vt])
55
+ else
56
+ os_simple_glazing.setVisibleTransmittance(defaults[:vt][:default])
57
+ end
58
+
59
+ os_simple_glazing
60
+ end
61
+
62
+
63
+ end # EnergyWindowMaterialSimpleGlazSys
64
+ end # Honeybee
@@ -0,0 +1,497 @@
1
+ # *******************************************************************************
2
+ # Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
3
+ # Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # (1) Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # (2) Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # (3) Neither the name of the copyright holder nor the names of any contributors
16
+ # may be used to endorse or promote products derived from this software without
17
+ # specific prior written permission from the respective party.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
23
+ # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
24
+ # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ # *******************************************************************************
31
+
32
+ require 'honeybee/model'
33
+
34
+ require 'openstudio'
35
+
36
+ module Honeybee
37
+ class Model
38
+
39
+ attr_reader :openstudio_model
40
+
41
+ # convert to openstudio model, clears errors and warnings
42
+ def to_openstudio_model(openstudio_model=nil, log_report=true)
43
+ @errors = []
44
+ @warnings = []
45
+
46
+ if log_report
47
+ puts 'Starting Model translation from Honeybee to OpenStudio'
48
+ end
49
+
50
+ @openstudio_model = if openstudio_model
51
+ openstudio_model
52
+ else
53
+ OpenStudio::Model::Model.new
54
+ end
55
+
56
+ # create all openstudio objects in the model
57
+ create_openstudio_objects(log_report)
58
+
59
+ if log_report
60
+ puts 'Done with Model translation!'
61
+ end
62
+
63
+ @openstudio_model
64
+ end
65
+
66
+ private
67
+
68
+ # create OpenStudio objects in the OpenStudio model
69
+ def create_openstudio_objects(log_report=true)
70
+ # assign a standards building type so that David's measures can run
71
+ building = @openstudio_model.getBuilding
72
+ building.setStandardsBuildingType('MediumOffice')
73
+
74
+ # initialize a global variable for whether the AFN is used instead of simple ventilation
75
+ $use_simple_vent = true
76
+ if @hash[:properties][:energy][:ventilation_simulation_control]
77
+ vent_sim_control = @hash[:properties][:energy][:ventilation_simulation_control]
78
+ if vent_sim_control[:vent_control_type] && vent_sim_control[:vent_control_type] != 'SingleZone'
79
+ $use_simple_vent = false
80
+ vsim_cntrl = VentilationSimulationControl.new(vent_sim_control)
81
+ $afn_reference_crack = vsim_cntrl.to_openstudio(@openstudio_model)
82
+ end
83
+ end
84
+
85
+ # initialize global hashes for various model properties
86
+ $gas_gap_hash = Hash.new # hash to track gas gaps in case they are split by shades
87
+ $air_boundary_hash = Hash.new # hash to track any air boundary constructions
88
+ $window_shade_hash = Hash.new # hash to track any window constructions with shade
89
+ $programtype_setpoint_hash = Hash.new # hash to track Setpoint objects
90
+ $interior_afn_srf_hash = Hash.new # track whether an adjacent surface is already in the AFN
91
+
92
+ # create all of the non-geometric model elements
93
+ if log_report # schedules are used by all other objects and come first
94
+ puts 'Translating Schedules'
95
+ end
96
+ if @hash[:properties][:energy][:schedule_type_limits]
97
+ create_schedule_type_limits(@hash[:properties][:energy][:schedule_type_limits])
98
+ end
99
+ if @hash[:properties][:energy][:schedules]
100
+ create_schedules(@hash[:properties][:energy][:schedules])
101
+ end
102
+
103
+ if log_report
104
+ puts 'Translating Materials'
105
+ end
106
+ if @hash[:properties][:energy][:materials]
107
+ create_materials(@hash[:properties][:energy][:materials])
108
+ end
109
+
110
+ if log_report
111
+ puts 'Translating Constructions'
112
+ end
113
+ if @hash[:properties][:energy][:constructions]
114
+ create_constructions(@hash[:properties][:energy][:constructions])
115
+ end
116
+
117
+ if log_report
118
+ puts 'Translating ConstructionSets'
119
+ end
120
+ if @hash[:properties][:energy][:construction_sets]
121
+ create_construction_sets(@hash[:properties][:energy][:construction_sets])
122
+ end
123
+
124
+ if log_report
125
+ puts 'Translating ProgramTypes'
126
+ end
127
+ if @hash[:properties][:energy][:program_types]
128
+ create_program_types(@hash[:properties][:energy][:program_types])
129
+ end
130
+
131
+ # create the default construction set to catch any cases of unassigned constructions
132
+ if log_report
133
+ puts 'Translating Default ConstructionSet'
134
+ end
135
+ create_default_construction_set
136
+
137
+ # create the geometry and add any extra properties to it
138
+ if log_report
139
+ puts 'Translating Room Geometry'
140
+ end
141
+ create_rooms
142
+
143
+ unless $window_shade_hash.empty?
144
+ if log_report
145
+ puts 'Translating Window Shading Control'
146
+ end
147
+ create_shading_control
148
+ end
149
+
150
+ if log_report
151
+ puts 'Translating HVAC Systems'
152
+ end
153
+ create_hvacs
154
+
155
+ if log_report
156
+ puts 'Translating Context Shade Geometry'
157
+ end
158
+ create_orphaned_shades
159
+ create_orphaned_faces
160
+ create_orphaned_apertures
161
+ create_orphaned_doors
162
+ end
163
+
164
+ def create_materials(material_dicts, check_existing=false)
165
+ material_dicts.each do |material|
166
+ # check if there's already a material in the model with the identifier
167
+ add_obj = true
168
+ if check_existing
169
+ object = @openstudio_model.getMaterialByName(material[:identifier])
170
+ if object.is_initialized
171
+ add_obj = false
172
+ end
173
+ end
174
+
175
+ # add the material object to the Model
176
+ if add_obj
177
+ material_type = material[:type]
178
+ case material_type
179
+ when 'EnergyMaterial'
180
+ material_object = EnergyMaterial.new(material)
181
+ when 'EnergyMaterialNoMass'
182
+ material_object = EnergyMaterialNoMass.new(material)
183
+ when 'EnergyWindowMaterialGas'
184
+ material_object = EnergyWindowMaterialGas.new(material)
185
+ $gas_gap_hash[material[:identifier]] = material_object
186
+ when 'EnergyWindowMaterialGasMixture'
187
+ material_object = EnergyWindowMaterialGasMixture.new(material)
188
+ $gas_gap_hash[material[:identifier]] = material_object
189
+ when 'EnergyWindowMaterialGasCustom'
190
+ material_object = EnergyWindowMaterialGasCustom.new(material)
191
+ $gas_gap_hash[material[:identifier]] = material_object
192
+ when 'EnergyWindowMaterialSimpleGlazSys'
193
+ material_object = EnergyWindowMaterialSimpleGlazSys.new(material)
194
+ when 'EnergyWindowMaterialBlind'
195
+ material_object = EnergyWindowMaterialBlind.new(material)
196
+ when 'EnergyWindowMaterialGlazing'
197
+ material_object = EnergyWindowMaterialGlazing.new(material)
198
+ when 'EnergyWindowMaterialShade'
199
+ material_object = EnergyWindowMaterialShade.new(material)
200
+ else
201
+ raise "Unknown material type #{material_type}"
202
+ end
203
+ material_object.to_openstudio(@openstudio_model)
204
+ end
205
+ end
206
+ end
207
+
208
+ def create_constructions(construction_dicts, check_existing=false)
209
+ construction_dicts.each do |construction|
210
+ # check if there's already a construction in the model with the identifier
211
+ add_obj = true
212
+ if check_existing
213
+ object = @openstudio_model.getConstructionByName(construction[:identifier])
214
+ if object.is_initialized
215
+ add_obj = false
216
+ end
217
+ end
218
+
219
+ # add the construction object to the Model
220
+ if add_obj
221
+ construction_type = construction[:type]
222
+ case construction_type
223
+ when 'OpaqueConstructionAbridged'
224
+ construction_object = OpaqueConstructionAbridged.new(construction)
225
+ when 'WindowConstructionAbridged'
226
+ construction_object = WindowConstructionAbridged.new(construction)
227
+ when 'WindowConstructionShadeAbridged'
228
+ construction_object = WindowConstructionShadeAbridged.new(construction)
229
+ $window_shade_hash[construction[:identifier]] = construction_object
230
+ when 'ShadeConstruction'
231
+ construction_object = ShadeConstruction.new(construction)
232
+ when 'AirBoundaryConstructionAbridged'
233
+ construction_object = AirBoundaryConstructionAbridged.new(construction)
234
+ $air_boundary_hash[construction[:identifier]] = construction
235
+ else
236
+ raise "Unknown construction type #{construction_type}."
237
+ end
238
+ construction_object.to_openstudio(@openstudio_model)
239
+ end
240
+ end
241
+ end
242
+
243
+ def create_construction_sets(construction_set_dicts, check_existing=false)
244
+ construction_set_dicts.each do |construction_set|
245
+ # check if there's already a construction set in the model with the identifier
246
+ add_obj = true
247
+ if check_existing
248
+ object = @openstudio_model.getDefaultConstructionSetByName(
249
+ construction_set[:identifier])
250
+ if object.is_initialized
251
+ add_obj = false
252
+ end
253
+ end
254
+
255
+ # add the construction set object to the Model
256
+ if add_obj
257
+ construction_set_object = ConstructionSetAbridged.new(construction_set)
258
+ construction_set_object.to_openstudio(@openstudio_model)
259
+ end
260
+ end
261
+ end
262
+
263
+ def create_schedule_type_limits(stl_dicts, check_existing=false)
264
+ stl_dicts.each do |schedule_type_limit|
265
+ # check if there's already a schedule type limit in the model with the identifier
266
+ add_obj = true
267
+ if check_existing
268
+ object = @openstudio_model.getScheduleTypeLimitsByName(
269
+ schedule_type_limit[:identifier])
270
+ if object.is_initialized
271
+ add_obj = false
272
+ end
273
+ end
274
+
275
+ # add the schedule type limit object to the Model
276
+ if add_obj
277
+ schedule_type_limit_object = ScheduleTypeLimit.new(schedule_type_limit)
278
+ schedule_type_limit_object.to_openstudio(@openstudio_model)
279
+ end
280
+ end
281
+ end
282
+
283
+ def create_schedules(schedule_dicts, check_existing=false)
284
+ schedule_dicts.each do |schedule|
285
+ # check if there's already a schedule in the model with the identifier
286
+ add_obj = true
287
+ if check_existing
288
+ object = @openstudio_model.getScheduleByName(schedule[:identifier])
289
+ if object.is_initialized
290
+ add_obj = false
291
+ end
292
+ end
293
+
294
+ # add the schedule object to the Model
295
+ if add_obj
296
+ schedule_type = schedule[:type]
297
+ case schedule_type
298
+ when 'ScheduleRulesetAbridged'
299
+ schedule_object = ScheduleRulesetAbridged.new(schedule)
300
+ when 'ScheduleFixedIntervalAbridged'
301
+ schedule_object = ScheduleFixedIntervalAbridged.new(schedule)
302
+ else
303
+ raise("Unknown schedule type #{schedule_type}.")
304
+ end
305
+ schedule_object.to_openstudio(@openstudio_model)
306
+ end
307
+ end
308
+ end
309
+
310
+ def create_program_types(program_dicts, check_existing=false)
311
+ program_dicts.each do |space_type|
312
+ # check if there's already a space type in the model with the identifier
313
+ add_obj = true
314
+ if check_existing
315
+ object = @openstudio_model.getSpaceTypeByName(space_type[:identifier])
316
+ if object.is_initialized
317
+ add_obj = false
318
+ end
319
+ end
320
+
321
+ # add the space type object to the Model
322
+ if add_obj
323
+ space_type_object = ProgramTypeAbridged.new(space_type)
324
+ space_type_object.to_openstudio(@openstudio_model)
325
+ end
326
+ end
327
+ end
328
+
329
+ def create_default_construction_set
330
+ # create the materials, constructions and construction set
331
+ create_materials(@@standards[:materials], true)
332
+ create_constructions(@@standards[:constructions], true)
333
+ create_construction_sets(@@standards[:construction_sets], true)
334
+
335
+ # write the fractional schedule type and always on schedule if they are not there
336
+ @@standards[:schedule_type_limits].each do |sch_type_limit|
337
+ if sch_type_limit[:identifier] == 'Fractional'
338
+ create_schedule_type_limits([sch_type_limit], true)
339
+ end
340
+ end
341
+ @@standards[:schedules].each do |schedule|
342
+ if schedule[:identifier] == 'Always On'
343
+ create_schedules([schedule], true)
344
+ end
345
+ end
346
+
347
+ # set the default construction set to the building level of the Model
348
+ construction_id = 'Default Generic Construction Set'
349
+ construction = @openstudio_model.getDefaultConstructionSetByName(construction_id)
350
+ unless construction.empty?
351
+ os_constructionset = construction.get
352
+ @openstudio_model.getBuilding.setDefaultConstructionSet(os_constructionset)
353
+ end
354
+ end
355
+
356
+ def create_rooms
357
+ if @hash[:rooms]
358
+ $air_mxing_array = [] # list to track any air mixing between Rooms
359
+
360
+ @hash[:rooms].each do |room|
361
+ room_object = Room.new(room)
362
+ openstudio_room = room_object.to_openstudio(@openstudio_model)
363
+
364
+ # for rooms with setpoint objects definied in the ProgramType, make a new thermostat
365
+ if room[:properties][:energy][:program_type] && !room[:properties][:energy][:setpoint]
366
+ thermal_zone = openstudio_room.thermalZone()
367
+ unless thermal_zone.empty?
368
+ thermal_zone_object = thermal_zone.get
369
+ program_type_id = room[:properties][:energy][:program_type]
370
+ setpoint_hash = $programtype_setpoint_hash[program_type_id]
371
+ if not setpoint_hash.nil? # program type has no setpoint
372
+ thermostat_object = SetpointThermostat.new(setpoint_hash)
373
+ openstudio_thermostat = thermostat_object.to_openstudio(@openstudio_model)
374
+ thermal_zone_object.setThermostatSetpointDualSetpoint(openstudio_thermostat)
375
+ if setpoint_hash[:humidifying_schedule] or setpoint_hash[:dehumidifying_schedule]
376
+ humidistat_object = ZoneControlHumidistat.new(setpoint_hash)
377
+ openstudio_humidistat = humidistat_object.to_openstudio(@openstudio_model)
378
+ thermal_zone_object.setZoneControlHumidistat(openstudio_humidistat)
379
+ end
380
+ end
381
+ end
382
+ end
383
+ end
384
+
385
+ # create mixing objects between Rooms
386
+ $air_mxing_array.each do |air_mix_props|
387
+ zone_mixing = OpenStudio::Model::ZoneMixing.new(air_mix_props[0])
388
+ zone_mixing.setDesignFlowRate(air_mix_props[1])
389
+ flow_sch_ref = @openstudio_model.getScheduleByName(air_mix_props[2])
390
+ unless flow_sch_ref.empty?
391
+ flow_sched = flow_sch_ref.get
392
+ zone_mixing.setSchedule(flow_sched)
393
+ end
394
+ source_zone_ref = @openstudio_model.getThermalZoneByName(air_mix_props[3])
395
+ unless source_zone_ref.empty?
396
+ source_zone = source_zone_ref.get
397
+ zone_mixing.setSourceZone(source_zone)
398
+ end
399
+ end
400
+ end
401
+ end
402
+
403
+ def create_shading_control
404
+ # assign any shading control objects to windows with shades
405
+ # this is run as a separate step once all logic about construction sets is in place
406
+ sub_faces = @openstudio_model.getSubSurfaces()
407
+ sub_faces.each do |sub_face|
408
+ constr_ref = sub_face.construction
409
+ unless constr_ref.empty?
410
+ constr = constr_ref.get
411
+ constr_name_ref = constr.name
412
+ unless constr_name_ref.empty?
413
+ constr_name = constr_name_ref.get
414
+ unless $window_shade_hash[constr_name].nil?
415
+ window_shd_constr = $window_shade_hash[constr_name]
416
+ os_shd_control = window_shd_constr.to_openstudio_shading_control(@openstudio_model)
417
+ sub_face.setShadingControl(os_shd_control)
418
+ end
419
+ end
420
+ end
421
+ end
422
+ end
423
+
424
+ def create_hvacs
425
+ if @hash[:properties][:energy][:hvacs]
426
+ $air_loop_count = 0 # track the total number of air loops in the model
427
+ # gather all of the hashes of the HVACs
428
+ hvac_hashes = Hash.new
429
+ @hash[:properties][:energy][:hvacs].each do |hvac|
430
+ hvac_hashes[hvac[:identifier]] = hvac
431
+ hvac_hashes[hvac[:identifier]]['rooms'] = []
432
+ end
433
+ # loop through the rooms and track which are assigned to each HVAC
434
+ if @hash[:rooms]
435
+ @hash[:rooms].each do |room|
436
+ if room[:properties][:energy][:hvac]
437
+ hvac_hashes[room[:properties][:energy][:hvac]]['rooms'] << room[:identifier]
438
+ end
439
+ end
440
+ end
441
+
442
+ hvac_hashes.each_value do |hvac|
443
+ system_type = hvac[:type]
444
+ if system_type == 'IdealAirSystemAbridged'
445
+ ideal_air_system = IdealAirSystemAbridged.new(hvac)
446
+ hvac['rooms'].each do |room_id|
447
+ os_ideal_air = ideal_air_system.to_openstudio(@openstudio_model)
448
+ # enforce a strict naming system for each zone so results can be matched
449
+ os_ideal_air.setName(room_id + ' Ideal Loads Air System')
450
+ zone_get = @openstudio_model.getThermalZoneByName(room_id)
451
+ unless zone_get.empty?
452
+ os_thermal_zone = zone_get.get
453
+ os_ideal_air.addToThermalZone(os_thermal_zone)
454
+ end
455
+ end
456
+ elsif TemplateHVAC.types.include?(system_type)
457
+ template_system = TemplateHVAC.new(hvac)
458
+ os_template_system = template_system.to_openstudio(@openstudio_model, hvac['rooms'])
459
+ end
460
+ end
461
+ end
462
+ end
463
+
464
+ def create_orphaned_shades
465
+ if @hash[:orphaned_shades]
466
+ shading_surface_group = OpenStudio::Model::ShadingSurfaceGroup.new(@openstudio_model)
467
+ shading_surface_group.setShadingSurfaceType('Building')
468
+ @hash[:orphaned_shades].each do |shade|
469
+ shade_object = Shade.new(shade)
470
+ openstudio_shade = shade_object.to_openstudio(@openstudio_model)
471
+ openstudio_shade.setShadingSurfaceGroup(shading_surface_group)
472
+ end
473
+ end
474
+ end
475
+
476
+ def create_orphaned_faces
477
+ if @hash[:orphaned_faces]
478
+ raise "Orphaned Faces are not translatable to OpenStudio."
479
+ end
480
+ end
481
+
482
+ def create_orphaned_apertures
483
+ if @hash[:orphaned_apertures]
484
+ raise "Orphaned Apertures are not translatable to OpenStudio."
485
+ end
486
+ end
487
+
488
+ def create_orphaned_doors
489
+ if @hash[:orphaned_doors]
490
+ raise "Orphaned Doors are not translatable to OpenStudio."
491
+ end
492
+ end
493
+
494
+ #TODO: create runlog for errors.
495
+
496
+ end # Model
497
+ end # Honeybee