honeybee-openstudio 0 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +5 -5
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +32 -33
  4. data/.releaserc.json +7 -7
  5. data/.travis.yml +41 -0
  6. data/Gemfile +18 -14
  7. data/LICENSE.md +23 -23
  8. data/README.md +95 -95
  9. data/Rakefile +21 -16
  10. data/doc_templates/LICENSE.md +23 -23
  11. data/doc_templates/copyright_erb.txt +31 -31
  12. data/doc_templates/copyright_js.txt +4 -4
  13. data/doc_templates/copyright_ruby.txt +29 -29
  14. data/honeybee-openstudio.gemspec +35 -38
  15. data/lib/files/Honeybee.rb +112 -112
  16. data/lib/files/honeybee_workflow.osw +47 -47
  17. data/lib/files/urbanopt_Gemfile +32 -32
  18. data/lib/{honeybee/_defaults → from_honeybee/_openapi}/model.json +8126 -11310
  19. data/lib/{honeybee/_defaults → from_honeybee/_openapi}/simulation-parameter.json +842 -972
  20. data/lib/{to_openstudio → from_honeybee}/construction/air.rb +65 -56
  21. data/lib/{to_openstudio → from_honeybee}/construction/opaque.rb +77 -67
  22. data/lib/{to_openstudio → from_honeybee}/construction/shade.rb +108 -99
  23. data/lib/{to_openstudio → from_honeybee}/construction/window.rb +80 -70
  24. data/lib/{to_openstudio → from_honeybee}/construction_set.rb +278 -266
  25. data/lib/{honeybee → from_honeybee}/extension.rb +109 -129
  26. data/lib/{to_openstudio → from_honeybee}/geometry/aperture.rb +167 -157
  27. data/lib/{to_openstudio → from_honeybee}/geometry/door.rb +160 -150
  28. data/lib/{to_openstudio → from_honeybee}/geometry/face.rb +163 -178
  29. data/lib/{to_openstudio → from_honeybee}/geometry/room.rb +392 -442
  30. data/lib/{to_openstudio → from_honeybee}/geometry/shade.rb +89 -79
  31. data/lib/{to_openstudio → from_honeybee}/hvac/ideal_air.rb +150 -141
  32. data/lib/{to_openstudio → from_honeybee}/load/electric_equipment.rb +96 -87
  33. data/lib/{to_openstudio → from_honeybee}/load/gas_equipment.rb +97 -88
  34. data/lib/{to_openstudio → from_honeybee}/load/infiltration.rb +94 -85
  35. data/lib/{to_openstudio → from_honeybee}/load/lighting.rb +98 -89
  36. data/lib/{to_openstudio → from_honeybee}/load/people.rb +100 -91
  37. data/lib/{to_openstudio → from_honeybee}/load/setpoint_humidistat.rb +75 -66
  38. data/lib/{to_openstudio → from_honeybee}/load/setpoint_thermostat.rb +71 -62
  39. data/lib/{to_openstudio → from_honeybee}/load/ventilation.rb +96 -87
  40. data/lib/{to_openstudio → from_honeybee}/material/opaque.rb +94 -85
  41. data/lib/{to_openstudio → from_honeybee}/material/opaque_no_mass.rb +94 -85
  42. data/lib/{to_openstudio → from_honeybee}/material/window_blind.rb +238 -229
  43. data/lib/{to_openstudio → from_honeybee}/material/window_gas.rb +76 -67
  44. data/lib/{to_openstudio → from_honeybee}/material/window_gas_custom.rb +118 -108
  45. data/lib/{to_openstudio → from_honeybee}/material/window_gas_mixture.rb +79 -70
  46. data/lib/{to_openstudio → from_honeybee}/material/window_glazing.rb +166 -157
  47. data/lib/{to_openstudio → from_honeybee}/material/window_shade.rb +160 -151
  48. data/lib/{to_openstudio → from_honeybee}/material/window_simpleglazsys.rb +73 -64
  49. data/lib/from_honeybee/model.rb +434 -0
  50. data/lib/{honeybee → from_honeybee}/model_object.rb +110 -108
  51. data/lib/{to_openstudio → from_honeybee}/program_type.rb +124 -104
  52. data/lib/{to_openstudio → from_honeybee}/schedule/fixed_interval.rb +115 -105
  53. data/lib/{to_openstudio → from_honeybee}/schedule/ruleset.rb +164 -164
  54. data/lib/{to_openstudio → from_honeybee}/schedule/type_limit.rb +88 -76
  55. data/lib/{to_openstudio/simulation/design_day.rb → from_honeybee/simulation/designday.rb} +105 -96
  56. data/lib/{honeybee/load/lighting.rb → from_honeybee/simulation/extension.rb} +46 -43
  57. data/lib/{to_openstudio/simulation/parameter_model.rb → from_honeybee/simulation/parameter.rb} +277 -243
  58. data/lib/{honeybee/simulation/design_day.rb → from_honeybee/version.rb} +34 -42
  59. data/lib/{honeybee.rb → from_honeybee.rb} +86 -93
  60. data/lib/measures/from_honeybee_model/LICENSE.md +27 -23
  61. data/lib/measures/from_honeybee_model/README.md +32 -32
  62. data/lib/measures/from_honeybee_model/measure.rb +91 -91
  63. data/lib/measures/from_honeybee_model/measure.xml +103 -80
  64. data/lib/measures/from_honeybee_model/tests/from_honeybee_model_test.rb +126 -126
  65. data/lib/measures/from_honeybee_simulation_parameter/LICENSE.md +27 -23
  66. data/lib/measures/from_honeybee_simulation_parameter/README.md +32 -32
  67. data/lib/measures/from_honeybee_simulation_parameter/measure.rb +95 -95
  68. data/lib/measures/from_honeybee_simulation_parameter/measure.xml +91 -86
  69. data/lib/measures/from_honeybee_simulation_parameter/tests/from_honeybee_simulation_parameter_test.rb +109 -109
  70. metadata +89 -147
  71. data/.github/workflows/ci.yaml +0 -88
  72. data/doc_templates/README.md.erb +0 -42
  73. data/lib/from_openstudio/geometry/aperture.rb +0 -136
  74. data/lib/from_openstudio/geometry/door.rb +0 -136
  75. data/lib/from_openstudio/geometry/face.rb +0 -174
  76. data/lib/from_openstudio/geometry/room.rb +0 -121
  77. data/lib/from_openstudio/geometry/shade.rb +0 -87
  78. data/lib/from_openstudio/model.rb +0 -123
  79. data/lib/from_openstudio/model_object.rb +0 -43
  80. data/lib/from_openstudio/simulation/design_day.rb +0 -123
  81. data/lib/from_openstudio/simulation/parameter_model.rb +0 -93
  82. data/lib/from_openstudio/simulation/simulation_output.rb +0 -67
  83. data/lib/from_openstudio.rb +0 -49
  84. data/lib/honeybee/_defaults/energy_default.json +0 -1682
  85. data/lib/honeybee/construction/air.rb +0 -42
  86. data/lib/honeybee/construction/opaque.rb +0 -42
  87. data/lib/honeybee/construction/shade.rb +0 -42
  88. data/lib/honeybee/construction/window.rb +0 -51
  89. data/lib/honeybee/construction/windowshade.rb +0 -43
  90. data/lib/honeybee/construction_set.rb +0 -42
  91. data/lib/honeybee/geometry/aperture.rb +0 -42
  92. data/lib/honeybee/geometry/door.rb +0 -42
  93. data/lib/honeybee/geometry/face.rb +0 -48
  94. data/lib/honeybee/geometry/room.rb +0 -56
  95. data/lib/honeybee/geometry/shade.rb +0 -42
  96. data/lib/honeybee/hvac/ideal_air.rb +0 -42
  97. data/lib/honeybee/hvac/template.rb +0 -73
  98. data/lib/honeybee/load/electric_equipment.rb +0 -42
  99. data/lib/honeybee/load/gas_equipment.rb +0 -42
  100. data/lib/honeybee/load/infiltration.rb +0 -42
  101. data/lib/honeybee/load/people.rb +0 -42
  102. data/lib/honeybee/load/setpoint_humidistat.rb +0 -46
  103. data/lib/honeybee/load/setpoint_thermostat.rb +0 -46
  104. data/lib/honeybee/load/ventilation.rb +0 -42
  105. data/lib/honeybee/material/opaque.rb +0 -42
  106. data/lib/honeybee/material/opaque_no_mass.rb +0 -42
  107. data/lib/honeybee/material/window_blind.rb +0 -42
  108. data/lib/honeybee/material/window_gas.rb +0 -42
  109. data/lib/honeybee/material/window_gas_custom.rb +0 -42
  110. data/lib/honeybee/material/window_gas_mixture.rb +0 -42
  111. data/lib/honeybee/material/window_glazing.rb +0 -42
  112. data/lib/honeybee/material/window_shade.rb +0 -42
  113. data/lib/honeybee/material/window_simpleglazsys.rb +0 -42
  114. data/lib/honeybee/model.rb +0 -87
  115. data/lib/honeybee/program_type.rb +0 -56
  116. data/lib/honeybee/schedule/fixed_interval.rb +0 -42
  117. data/lib/honeybee/schedule/ruleset.rb +0 -42
  118. data/lib/honeybee/schedule/type_limit.rb +0 -42
  119. data/lib/honeybee/simulation/parameter_model.rb +0 -86
  120. data/lib/honeybee/simulation/simulation_output.rb +0 -42
  121. data/lib/honeybee/ventcool/control.rb +0 -42
  122. data/lib/honeybee/ventcool/opening.rb +0 -46
  123. data/lib/honeybee/ventcool/simulation.rb +0 -42
  124. data/lib/to_openstudio/construction/windowshade.rb +0 -196
  125. data/lib/to_openstudio/hvac/Model.hvac.rb +0 -641
  126. data/lib/to_openstudio/hvac/template.rb +0 -169
  127. data/lib/to_openstudio/model.rb +0 -497
  128. data/lib/to_openstudio/model_object.rb +0 -52
  129. data/lib/to_openstudio/ventcool/control.rb +0 -185
  130. data/lib/to_openstudio/ventcool/opening.rb +0 -189
  131. data/lib/to_openstudio/ventcool/simulation.rb +0 -101
  132. data/lib/to_openstudio.rb +0 -92
@@ -1,169 +0,0 @@
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/hvac/template'
33
-
34
- require 'to_openstudio/model_object'
35
-
36
- module Honeybee
37
- class TemplateHVAC
38
-
39
- def to_openstudio(openstudio_model, room_ids)
40
-
41
- # only load openstudio-standards when needed
42
- require 'openstudio-standards'
43
- require_relative 'Model.hvac'
44
-
45
- # get the defaults for the specific system type
46
- hvac_defaults = defaults(@hash[:type])
47
-
48
- # make the standard applier
49
- if @hash[:vintage]
50
- standard = Standard.build(@hash[:vintage])
51
- else
52
- standard = Standard.build(hvac_defaults[:vintage][:default])
53
- end
54
-
55
- # get the default equipment type
56
- if @hash[:equipment_type]
57
- equipment_type = @hash[:equipment_type]
58
- else
59
- equipment_type = hvac_defaults[:equipment_type][:default]
60
- end
61
-
62
- # get all of the thermal zones from the Model using the room identifiers
63
- zones = []
64
- room_ids.each do |room_id|
65
- zone_get = openstudio_model.getThermalZoneByName(room_id)
66
- unless zone_get.empty?
67
- os_thermal_zone = zone_get.get
68
- zones << os_thermal_zone
69
- end
70
- end
71
-
72
- # create the HVAC system and assign the display name to the air loop name if it exists
73
- os_hvac = openstudio_model.add_cbecs_hvac_system(standard, equipment_type, zones)
74
- os_air_loop = nil
75
- air_loops = openstudio_model.getAirLoopHVACs
76
- unless air_loops.length == $air_loop_count # check if any new loops were added
77
- $air_loop_count = air_loops.length
78
- os_air_loop = air_loops[-1]
79
- loop_name = os_air_loop.name
80
- unless loop_name.empty?
81
- if @hash[:display_name]
82
- os_air_loop.setName(@hash[:display_name] + ' - ' + loop_name.get)
83
- end
84
- end
85
- end
86
-
87
- # assign the economizer type if there's an air loop and the economizer is specified
88
- if @hash[:economizer_type] && @hash[:economizer_type] != 'Inferred' && os_air_loop
89
- oasys = os_air_loop.airLoopHVACOutdoorAirSystem
90
- unless oasys.empty?
91
- os_oasys = oasys.get
92
- oactrl = os_oasys.getControllerOutdoorAir
93
- oactrl.setEconomizerControlType(@hash[:economizer_type])
94
- end
95
- end
96
-
97
- # set the sensible heat recovery if there's an air loop and the heat recovery is specified
98
- if @hash[:sensible_heat_recovery] && @hash[:sensible_heat_recovery] != {:type => 'Autosize'} && os_air_loop
99
- erv = get_existing_erv(os_air_loop)
100
- unless erv
101
- erv = create_erv(openstudio_model, os_air_loop)
102
- end
103
- eff_at_max = @hash[:sensible_heat_recovery] * (0.76 / 0.81) # taken from OpenStudio defaults
104
- erv.setSensibleEffectivenessat100CoolingAirFlow(eff_at_max)
105
- erv.setSensibleEffectivenessat100HeatingAirFlow(eff_at_max)
106
- erv.setSensibleEffectivenessat75CoolingAirFlow(@hash[:sensible_heat_recovery])
107
- erv.setSensibleEffectivenessat75HeatingAirFlow(@hash[:sensible_heat_recovery])
108
- end
109
-
110
- # set the latent heat recovery if there's an air loop and the heat recovery is specified
111
- if @hash[:latent_heat_recovery] && @hash[:latent_heat_recovery] != {:type => 'Autosize'} && os_air_loop
112
- erv = get_existing_erv(os_air_loop)
113
- unless erv
114
- erv = create_erv(openstudio_model, os_air_loop)
115
- end
116
- eff_at_max = @hash[:latent_heat_recovery] * (0.68 / 0.73) # taken from OpenStudio defaults
117
- erv.setLatentEffectivenessat100CoolingAirFlow(eff_at_max)
118
- erv.setLatentEffectivenessat100HeatingAirFlow(eff_at_max)
119
- erv.setLatentEffectivenessat75CoolingAirFlow(@hash[:latent_heat_recovery])
120
- erv.setLatentEffectivenessat75HeatingAirFlow(@hash[:latent_heat_recovery])
121
- end
122
-
123
- # set all plants to non-coincident sizing to avoid simualtion control on design days
124
- openstudio_model.getPlantLoops.each do |loop|
125
- sizing = loop.sizingPlant
126
- sizing.setSizingOption('NonCoincident')
127
- end
128
-
129
- os_hvac
130
- end
131
-
132
- private
133
-
134
- def get_existing_erv(os_air_loop)
135
- # get an existing heat ecovery unit from an air loop; will be nil if there is none
136
- os_air_loop.oaComponents.each do |supply_component|
137
- if not supply_component.to_HeatExchangerAirToAirSensibleAndLatent.empty?
138
- erv = supply_component.to_HeatExchangerAirToAirSensibleAndLatent.get
139
- return erv
140
- end
141
- end
142
- nil
143
- end
144
-
145
- def create_erv(model, os_air_loop)
146
- # create a heat recovery unit with default zero efficiencies
147
- heat_ex = OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent.new(model)
148
- heat_ex.setEconomizerLockout(false)
149
- heat_ex.setName(@hash[:identifier] + '_Heat Recovery Unit')
150
- heat_ex.setSensibleEffectivenessat100CoolingAirFlow(0)
151
- heat_ex.setSensibleEffectivenessat100HeatingAirFlow(0)
152
- heat_ex.setSensibleEffectivenessat75CoolingAirFlow(0)
153
- heat_ex.setSensibleEffectivenessat75HeatingAirFlow(0)
154
- heat_ex.setLatentEffectivenessat100CoolingAirFlow(0)
155
- heat_ex.setLatentEffectivenessat100HeatingAirFlow(0)
156
- heat_ex.setLatentEffectivenessat75CoolingAirFlow(0)
157
- heat_ex.setLatentEffectivenessat75HeatingAirFlow(0)
158
-
159
- # add the heat exchanger to the air loop
160
- outdoor_node = os_air_loop.reliefAirNode
161
- unless outdoor_node.empty?
162
- os_outdoor_node = outdoor_node.get
163
- heat_ex.addToNode(os_outdoor_node)
164
- end
165
- heat_ex
166
- end
167
-
168
- end #TemplateHVAC
169
- end #Honeybee
@@ -1,497 +0,0 @@
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