honeybee-openstudio 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.
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