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,96 @@
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/simulation/design_day'
33
+
34
+ require 'to_openstudio/model_object'
35
+
36
+ module Honeybee
37
+ class DesignDay
38
+
39
+ def find_existing_openstudio_object(openstudio_model)
40
+ object = openstudio_model.getDesignDayByName(@hash[:name])
41
+ return object.get if object.is_initialized
42
+ nil
43
+ end
44
+
45
+ def to_openstudio(openstudio_model)
46
+ # create the DesignDay object
47
+ os_des_day = OpenStudio::Model::DesignDay.new(openstudio_model)
48
+ os_des_day.setName(@hash[:name])
49
+ os_des_day.setDayType(@hash[:day_type])
50
+
51
+ # set the DryBulbCondition properties
52
+ os_des_day.setMaximumDryBulbTemperature(@hash[:dry_bulb_condition][:dry_bulb_max])
53
+ os_des_day.setDailyDryBulbTemperatureRange(@hash[:dry_bulb_condition][:dry_bulb_range])
54
+
55
+ # set the HumidityCondition properties
56
+ os_des_day.setHumidityIndicatingType(@hash[:humidity_condition][:humidity_type])
57
+ os_des_day.setHumidityIndicatingConditionsAtMaximumDryBulb(@hash[:humidity_condition][:humidity_value])
58
+ if @hash[:humidity_condition][:barometric_pressure]
59
+ os_des_day.setBarometricPressure(@hash[:humidity_condition][:barometric_pressure])
60
+ end
61
+ if @hash[:humidity_condition][:rain]
62
+ os_des_day.setRainIndicator(@hash[:humidity_condition][:rain])
63
+ end
64
+ if @hash[:humidity_condition][:snow_on_ground]
65
+ os_des_day.setSnowIndicator(@hash[:humidity_condition][:snow_on_ground])
66
+ end
67
+
68
+ # set the WindCondition properties
69
+ os_des_day.setWindSpeed(@hash[:wind_condition][:wind_speed])
70
+ if @hash[:wind_condition][:wind_direction]
71
+ os_des_day.setWindDirection(@hash[:wind_condition][:wind_direction])
72
+ end
73
+
74
+ # set the SkyCondition properties
75
+ os_des_day.setMonth(@hash[:sky_condition][:date][0])
76
+ os_des_day.setDayOfMonth(@hash[:sky_condition][:date][1])
77
+ os_des_day.setSolarModelIndicator(@hash[:sky_condition][:type])
78
+ if @hash[:sky_condition][:daylight_savings]
79
+ os_des_day.setDaylightSavingTimeIndicator(@hash[:sky_condition][:daylight_savings])
80
+ end
81
+
82
+ # ASHRAEClearSky SkyCondition
83
+ if @hash[:sky_condition][:type] == "ASHRAEClearSky"
84
+ os_des_day.setSkyClearness(@hash[:sky_condition][:clearness])
85
+ end
86
+
87
+ # ASHRAETau SkyCondition
88
+ if @hash[:sky_condition][:type] == "ASHRAETau"
89
+ os_des_day.setAshraeTaub(@hash[:sky_condition][:tau_b])
90
+ os_des_day.setAshraeTaud(@hash[:sky_condition][:tau_d])
91
+ end
92
+
93
+ os_des_day
94
+ end
95
+ end # DesignDay
96
+ end # Honeybee
@@ -0,0 +1,243 @@
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/simulation/parameter_model'
33
+
34
+ require 'openstudio'
35
+
36
+ module Honeybee
37
+ class SimulationParameter
38
+
39
+ # convert to openstudio model, clears errors and warnings
40
+ def to_openstudio_model(openstudio_model=nil, log_report=false)
41
+ @errors = []
42
+ @warnings = []
43
+
44
+ if log_report
45
+ puts 'Starting SimulationParameter translation from Honeybee to OpenStudio'
46
+ end
47
+ @openstudio_model = if openstudio_model
48
+ openstudio_model
49
+ else
50
+ OpenStudio::Model::Model.new
51
+ end
52
+
53
+ create_openstudio_objects
54
+
55
+ if log_report
56
+ puts 'Done with SimulationParameter translation!'
57
+ end
58
+
59
+ @openstudio_model
60
+ end
61
+
62
+ def create_openstudio_objects
63
+ # get the defaults for each sub-object
64
+ simct_defaults = defaults[:SimulationControl][:properties]
65
+ shdw_defaults = defaults[:ShadowCalculation][:properties]
66
+ siz_defaults = defaults[:SizingParameter][:properties]
67
+ out_defaults = defaults[:SimulationOutput][:properties]
68
+ runper_defaults = defaults[:RunPeriod][:properties]
69
+ simpar_defaults = defaults[:SimulationParameter][:properties]
70
+
71
+ # set defaults for the Model's SimulationControl object
72
+ os_sim_control = @openstudio_model.getSimulationControl
73
+ os_sim_control.setDoZoneSizingCalculation(simct_defaults[:do_zone_sizing][:default])
74
+ os_sim_control.setDoSystemSizingCalculation(simct_defaults[:do_system_sizing][:default])
75
+ os_sim_control.setDoPlantSizingCalculation(simct_defaults[:do_plant_sizing][:default])
76
+ os_sim_control.setRunSimulationforWeatherFileRunPeriods(simct_defaults[:run_for_run_periods][:default])
77
+ os_sim_control.setRunSimulationforSizingPeriods(simct_defaults[:run_for_sizing_periods][:default])
78
+ os_sim_control.setSolarDistribution(shdw_defaults[:solar_distribution][:default])
79
+
80
+ # override any SimulationControl defaults with lodaded JSON
81
+ if @hash[:simulation_control]
82
+ unless @hash[:simulation_control][:do_zone_sizing].nil?
83
+ os_sim_control.setDoZoneSizingCalculation(@hash[:simulation_control][:do_zone_sizing])
84
+ end
85
+ unless @hash[:simulation_control][:do_system_sizing].nil?
86
+ os_sim_control.setDoSystemSizingCalculation(@hash[:simulation_control][:do_system_sizing])
87
+ end
88
+ unless @hash[:simulation_control][:do_plant_sizing].nil?
89
+ os_sim_control.setDoPlantSizingCalculation(@hash[:simulation_control][:do_plant_sizing])
90
+ end
91
+ unless @hash[:simulation_control][:run_for_run_periods].nil?
92
+ os_sim_control.setRunSimulationforWeatherFileRunPeriods(@hash[:simulation_control][:run_for_run_periods])
93
+ end
94
+ unless @hash[:simulation_control][:run_for_sizing_periods].nil?
95
+ os_sim_control.setRunSimulationforSizingPeriods(@hash[:simulation_control][:run_for_sizing_periods])
96
+ end
97
+ end
98
+
99
+ # set defaults for the Model's ShadowCalculation object
100
+ os_shadow_calc = @openstudio_model.getShadowCalculation
101
+ os_shadow_calc.setShadingCalculationMethod(
102
+ shdw_defaults[:calculation_method][:default])
103
+ os_shadow_calc.setShadingCalculationUpdateFrequencyMethod(
104
+ shdw_defaults[:calculation_update_method][:default])
105
+ os_shadow_calc.setShadingCalculationUpdateFrequency(
106
+ shdw_defaults[:calculation_frequency][:default])
107
+ os_shadow_calc.setMaximumFiguresInShadowOverlapCalculations(
108
+ shdw_defaults[:maximum_figures][:default])
109
+
110
+ # override any ShadowCalculation defaults with lodaded JSON
111
+ if @hash[:shadow_calculation]
112
+ if @hash[:shadow_calculation][:calculation_method]
113
+ os_shadow_calc.setShadingCalculationMethod(
114
+ @hash[:shadow_calculation][:calculation_method])
115
+ end
116
+ if @hash[:shadow_calculation][:calculation_update_method]
117
+ os_shadow_calc.setShadingCalculationUpdateFrequencyMethod(
118
+ @hash[:shadow_calculation][:calculation_update_method])
119
+ end
120
+ if @hash[:shadow_calculation][:calculation_frequency]
121
+ os_shadow_calc.setShadingCalculationUpdateFrequency(
122
+ @hash[:shadow_calculation][:calculation_frequency])
123
+ end
124
+ if @hash[:shadow_calculation][:maximum_figures]
125
+ os_shadow_calc.setMaximumFiguresInShadowOverlapCalculations(
126
+ @hash[:shadow_calculation][:maximum_figures])
127
+ end
128
+ if @hash[:shadow_calculation][:solar_distribution]
129
+ os_sim_control.setSolarDistribution(
130
+ @hash[:shadow_calculation][:solar_distribution])
131
+ end
132
+ end
133
+
134
+ # set defaults for the Model's SizingParameter object
135
+ os_sizing_par = @openstudio_model.getSizingParameters
136
+ os_sizing_par.setHeatingSizingFactor(siz_defaults[:heating_factor][:default])
137
+ os_sizing_par.setCoolingSizingFactor(siz_defaults[:cooling_factor][:default])
138
+
139
+ # override any SizingParameter defaults with lodaded JSON
140
+ if @hash[:sizing_parameter]
141
+ if @hash[:sizing_parameter][:heating_factor]
142
+ os_sizing_par.setHeatingSizingFactor(@hash[:sizing_parameter][:heating_factor])
143
+ end
144
+ if @hash[:sizing_parameter][:cooling_factor]
145
+ os_sizing_par.setCoolingSizingFactor(@hash[:sizing_parameter][:cooling_factor])
146
+ end
147
+ # set any design days
148
+ if @hash[:sizing_parameter][:design_days]
149
+ @hash[:sizing_parameter][:design_days].each do |des_day|
150
+ des_day_object = DesignDay.new(des_day)
151
+ os_des_day = des_day_object.to_openstudio(@openstudio_model)
152
+ end
153
+ end
154
+ end
155
+
156
+ # set Outputs for the simulation
157
+ if @hash[:output]
158
+ if @hash[:output][:outputs]
159
+ @hash[:output][:outputs].each do |output|
160
+ os_output = OpenStudio::Model::OutputVariable.new(output, @openstudio_model)
161
+ if @hash[:output][:reporting_frequency]
162
+ os_output.setReportingFrequency(@hash[:output][:reporting_frequency])
163
+ else
164
+ os_output.setReportingFrequency(out_defaults[:reporting_frequency][:default])
165
+ end
166
+ end
167
+ end
168
+ if @hash[:output][:summary_reports]
169
+ os_report = @openstudio_model.getOutputTableSummaryReports
170
+ @hash[:output][:summary_reports].each do |report|
171
+ os_report.addSummaryReport(report)
172
+ end
173
+ end
174
+ end
175
+
176
+ # set defaults for the year description
177
+ year_description = @openstudio_model.getYearDescription
178
+ year_description.setDayofWeekforStartDay(runper_defaults[:start_day_of_week][:default])
179
+
180
+ # set up the simulation RunPeriod
181
+ if @hash[:run_period]
182
+ # set the leap year
183
+ if @hash[:run_period][:leap_year]
184
+ year_description.setIsLeapYear(@hash[:run_period][:leap_year])
185
+ end
186
+
187
+ # set the start day of the week
188
+ if @hash[:run_period][:start_day_of_week]
189
+ year_description.setDayofWeekforStartDay(@hash[:run_period][:start_day_of_week])
190
+ end
191
+
192
+ # set the run preiod start and end dates
193
+ openstudio_runperiod = @openstudio_model.getRunPeriod
194
+ openstudio_runperiod.setBeginMonth(@hash[:run_period][:start_date][0])
195
+ openstudio_runperiod.setBeginDayOfMonth(@hash[:run_period][:start_date][1])
196
+ openstudio_runperiod.setEndMonth(@hash[:run_period][:end_date][0])
197
+ openstudio_runperiod.setEndDayOfMonth(@hash[:run_period][:end_date][1])
198
+
199
+ # set the daylight savings time
200
+ if @hash[:run_period][:daylight_saving_time]
201
+ os_dl_saving = @openstudio_model.getRunPeriodControlDaylightSavingTime
202
+ os_dl_saving.setStartDate(
203
+ OpenStudio::MonthOfYear.new(@hash[:run_period][:daylight_saving_time][:start_date][0]),
204
+ @hash[:run_period][:daylight_saving_time][:start_date][1])
205
+ os_dl_saving.setEndDate(
206
+ OpenStudio::MonthOfYear.new(@hash[:run_period][:daylight_saving_time][:end_date][0]),
207
+ @hash[:run_period][:daylight_saving_time][:end_date][1])
208
+ end
209
+
210
+ # Set the holidays
211
+ if @hash[:run_period][:holidays]
212
+ @hash[:run_period][:holidays].each do |hol|
213
+ os_hol = OpenStudio::Model::RunPeriodControlSpecialDays.new(
214
+ OpenStudio::MonthOfYear.new(hol[0]), hol[1], @openstudio_model)
215
+ os_hol.setDuration(1)
216
+ os_hol.setSpecialDayType('Holiday')
217
+ end
218
+ end
219
+ end
220
+
221
+ # set the simulation timestep
222
+ os_timestep = @openstudio_model.getTimestep
223
+ if @hash[:timestep]
224
+ os_timestep.setNumberOfTimestepsPerHour(@hash[:timestep])
225
+ else
226
+ os_timestep.setNumberOfTimestepsPerHour(simpar_defaults[:timestep][:default])
227
+ end
228
+
229
+ # assign the north
230
+ if @hash[:north_angle]
231
+ @openstudio_model.getBuilding.setNorthAxis(-@hash[:north_angle])
232
+ end
233
+
234
+ # assign the terrain
235
+ os_site = @openstudio_model.getSite
236
+ os_site.setTerrain(simpar_defaults[:terrain_type][:default])
237
+ if @hash[:terrain_type]
238
+ os_site.setTerrain(@hash[:terrain_type])
239
+ end
240
+ end
241
+
242
+ end #SimulationParameter
243
+ end #Honeybee
@@ -0,0 +1,185 @@
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/ventcool/opening'
33
+
34
+ require 'to_openstudio/model_object'
35
+
36
+ module Honeybee
37
+ class VentilationControlAbridged
38
+ @@outdoor_node = nil
39
+ @@program_manager = nil
40
+ @@sensor_count = 1
41
+ @@actuator_count = 1
42
+ @@program_count = 1
43
+
44
+ def get_outdoor_node(openstudio_model)
45
+ # get the EMS sensor for the outdoor node if it exists or generate it if it doesn't
46
+ if @@outdoor_node.nil?
47
+ out_var = OpenStudio::Model::OutputVariable.new(
48
+ 'Site Outdoor Air Drybulb Temperature', openstudio_model)
49
+ out_var.setReportingFrequency('Timestep')
50
+ out_var.setKeyValue('Environment')
51
+ @@outdoor_node = OpenStudio::Model::EnergyManagementSystemSensor.new(
52
+ openstudio_model, out_var)
53
+ @@outdoor_node.setName('Outdoor_Sensor')
54
+ end
55
+ @@outdoor_node
56
+ end
57
+
58
+ def get_program_manager(openstudio_model)
59
+ # get the EMS Program Manager for all window opening if it exists or generate it if it doesn't
60
+ if @@program_manager.nil?
61
+ @@program_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(
62
+ openstudio_model)
63
+ @@program_manager.setName('Temperature_Controlled_Window_Opening')
64
+ @@program_manager.setCallingPoint('BeginTimestepBeforePredictor')
65
+ end
66
+ @@program_manager
67
+ end
68
+
69
+ def replace_ems_special_characters(ems_variable_name)
70
+ # remove special characters from an name to be used as an EMS variable
71
+ new_name = ems_variable_name.to_s
72
+ new_name.gsub!(/[^A-Za-z]/, '')
73
+ new_name
74
+ end
75
+
76
+ def to_openstudio(openstudio_model, parent_zone, vent_opening_surfaces, vent_opening_factors)
77
+ # Get the outdoor temperature sensor and the room air temperature sensor
78
+ out_air_temp = get_outdoor_node(openstudio_model)
79
+ in_var = OpenStudio::Model::OutputVariable.new('Zone Air Temperature', openstudio_model)
80
+ in_var.setReportingFrequency('Timestep')
81
+ zone_name = parent_zone.name
82
+ os_zone_name = 'Indoor'
83
+ unless zone_name.empty?
84
+ os_zone_name = zone_name.get
85
+ in_var.setKeyValue(os_zone_name)
86
+ end
87
+ in_air_temp = OpenStudio::Model::EnergyManagementSystemSensor.new(openstudio_model, in_var)
88
+ in_sensor_name = replace_ems_special_characters(os_zone_name) + '_Sensor' + @@sensor_count.to_s
89
+ @@sensor_count = @@sensor_count + 1
90
+ in_air_temp.setName(in_sensor_name)
91
+
92
+ # set up a schedule sensor if there's a schedule specified
93
+ if @hash[:schedule]
94
+ vent_sch = openstudio_model.getScheduleByName(@hash[:schedule])
95
+ unless vent_sch.empty? # schedule not specified
96
+ sch_var = OpenStudio::Model::OutputVariable.new('Schedule Value', openstudio_model)
97
+ sch_var.setReportingFrequency('Timestep')
98
+ sch_var.setKeyValue(@hash[:schedule])
99
+ sch_sens = OpenStudio::Model::EnergyManagementSystemSensor.new(openstudio_model, sch_var)
100
+ sch_sensor_name = replace_ems_special_characters(os_zone_name) + '_Sensor' + @@sensor_count.to_s
101
+ @@sensor_count = @@sensor_count + 1
102
+ sch_sens.setName(sch_sensor_name)
103
+ end
104
+ end
105
+
106
+ # create the actuators for each of the operaable windows
107
+ actuator_names = []
108
+ vent_opening_surfaces.each do |vent_srf|
109
+ window_act = OpenStudio::Model::EnergyManagementSystemActuator.new(
110
+ vent_srf, 'AirFlow Network Window/Door Opening', 'Venting Opening Factor')
111
+ vent_srf_name = vent_srf.name
112
+ unless vent_srf_name.empty?
113
+ act_name = replace_ems_special_characters(vent_srf_name.get) + \
114
+ '_OpenFactor' + @@actuator_count.to_s
115
+ @@actuator_count = @@actuator_count + 1
116
+ window_act.setName(act_name)
117
+ actuator_names << act_name
118
+ end
119
+ end
120
+
121
+ # create the first line of the EMS Program to open each window according to the control logic
122
+ logic_statements = []
123
+ # check the minimum indoor tempertaure for ventilation
124
+ min_in = @hash[:min_indoor_temperature]
125
+ if min_in && min_in != defaults[:min_indoor_temperature][:default]
126
+ logic_statements << '(' + in_sensor_name + ' > ' + min_in.to_s + ')'
127
+ end
128
+ # check the maximum indoor tempertaure for ventilation
129
+ max_in = @hash[:max_indoor_temperature]
130
+ if max_in && max_in != defaults[:max_indoor_temperature][:default]
131
+ logic_statements << '(' + in_sensor_name + ' < ' + max_in.to_s + ')'
132
+ end
133
+ # check the minimum outdoor tempertaure for ventilation
134
+ min_out = @hash[:min_outdoor_temperature]
135
+ if min_out && min_out != defaults[:min_outdoor_temperature][:default]
136
+ logic_statements << '(Outdoor_Sensor > ' + min_out.to_s + ')'
137
+ end
138
+ # check the maximum outdoor tempertaure for ventilation
139
+ max_out = @hash[:max_outdoor_temperature]
140
+ if max_out && max_out != defaults[:max_outdoor_temperature][:default]
141
+ logic_statements << '(Outdoor_Sensor < ' + max_out.to_s + ')'
142
+ end
143
+ # check the delta tempertaure for ventilation
144
+ delta_in_out = @hash[:delta_temperature]
145
+ if delta_in_out && delta_in_out != defaults[:delta_temperature][:default]
146
+ logic_statements << '((' + in_sensor_name + ' - Outdoor_Sensor) > ' + delta_in_out.to_s + ')'
147
+ end
148
+ # check the schedule for ventilation
149
+ if sch_sensor_name
150
+ logic_statements << '(' + sch_sensor_name + ' > 0)'
151
+ end
152
+ # create the complete logic statement for opening windows
153
+ if logic_statements.empty?
154
+ complete_logic = 'IF (Outdoor_Sensor < 100)' # no logic has been provided; always open windows
155
+ else
156
+ complete_logic = 'IF ' + logic_statements.join(' && ')
157
+ end
158
+
159
+ # initialize the program and add the complete logic
160
+ ems_program = OpenStudio::Model::EnergyManagementSystemProgram.new(openstudio_model)
161
+ prog_name = replace_ems_special_characters(os_zone_name) + '_WindowOpening' + @@program_count.to_s
162
+ @@program_count = @@program_count + 1
163
+ ems_program.setName(prog_name)
164
+ ems_program.addLine(complete_logic)
165
+
166
+ # loop through each of the actuators and open each window
167
+ actuator_names.zip(vent_opening_factors).each do |act_name, open_factor|
168
+ ems_program.addLine('SET ' + act_name + ' = ' + open_factor.to_s)
169
+ end
170
+ # loop through each of the actuators and close each window
171
+ ems_program.addLine('ELSE')
172
+ actuator_names.each do |act_name|
173
+ ems_program.addLine('SET ' + act_name + ' = 0')
174
+ end
175
+ ems_program.addLine('ENDIF')
176
+
177
+ # add the program object the the global program manager for all window opening
178
+ prog_manager = get_program_manager(openstudio_model)
179
+ prog_manager.addProgram(ems_program)
180
+
181
+ ems_program
182
+ end
183
+
184
+ end #VentilationControl
185
+ end #Honeybee