openstudio-ee 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/Rakefile +2 -0
  4. data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.rb +333 -0
  5. data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.xml +150 -0
  6. data/lib/measures/ReplaceFanTotalEfficiency/measure.rb +330 -0
  7. data/lib/measures/ReplaceFanTotalEfficiency/measure.xml +150 -0
  8. data/lib/measures/add_apszhp_to_each_zone/measure.rb +607 -0
  9. data/lib/measures/add_apszhp_to_each_zone/measure.xml +184 -0
  10. data/lib/measures/add_energy_recovery_ventilator/measure.rb +354 -0
  11. data/lib/measures/add_energy_recovery_ventilator/measure.xml +78 -0
  12. data/lib/measures/improve_simple_glazing_by_percentage/measure.rb +81 -0
  13. data/lib/measures/improve_simple_glazing_by_percentage/measure.xml +70 -0
  14. data/lib/measures/reduce_water_use_by_percentage/measure.rb +61 -0
  15. data/lib/measures/reduce_water_use_by_percentage/measure.xml +62 -0
  16. data/lib/measures/replace_hvac_with_gshp_and_doas/measure.rb +511 -0
  17. data/lib/measures/replace_hvac_with_gshp_and_doas/measure.xml +375 -0
  18. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_AedgMeasures.rb +454 -0
  19. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Constructions.rb +221 -0
  20. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Geometry.rb +41 -0
  21. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HVAC.rb +1682 -0
  22. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HelperMethods.rb +114 -0
  23. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
  24. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Schedules.rb +142 -0
  25. data/lib/measures/replace_simple_glazing/measure.rb +86 -0
  26. data/lib/measures/replace_simple_glazing/measure.xml +78 -0
  27. data/lib/measures/set_boiler_thermal_efficiency/measure.rb +520 -0
  28. data/lib/measures/set_boiler_thermal_efficiency/measure.xml +78 -0
  29. data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.rb +207 -0
  30. data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.xml +78 -0
  31. data/lib/measures/tenant_star_internal_loads/measure.rb +134 -0
  32. data/lib/measures/tenant_star_internal_loads/measure.xml +67 -0
  33. data/lib/measures/tenant_star_internal_loads/resources/os_lib_helper_methods.rb +401 -0
  34. data/lib/measures/vr_fwith_doas/measure.rb +468 -0
  35. data/lib/measures/vr_fwith_doas/measure.xml +298 -0
  36. data/lib/measures/vr_fwith_doas/resources/OsLib_AedgMeasures.rb +454 -0
  37. data/lib/measures/vr_fwith_doas/resources/OsLib_Constructions.rb +221 -0
  38. data/lib/measures/vr_fwith_doas/resources/OsLib_Geometry.rb +41 -0
  39. data/lib/measures/vr_fwith_doas/resources/OsLib_HVAC.rb +1516 -0
  40. data/lib/measures/vr_fwith_doas/resources/OsLib_HelperMethods.rb +114 -0
  41. data/lib/measures/vr_fwith_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
  42. data/lib/measures/vr_fwith_doas/resources/OsLib_Schedules.rb +142 -0
  43. data/lib/openstudio/ee_measures/version.rb +1 -1
  44. data/openstudio-ee.gemspec +7 -5
  45. metadata +48 -9
@@ -0,0 +1,184 @@
1
+ <measure>
2
+ <schema_version>3.0</schema_version>
3
+ <name>add_apszhp_to_each_zone</name>
4
+ <uid>2d81d612-3235-429f-ba0a-46b8bf3b4e92</uid>
5
+ <version_id>10d37243-c94f-4542-934f-3953c44f75f3</version_id>
6
+ <version_modified>20180223T005547Z</version_modified>
7
+ <xml_checksum>87BA8B1E</xml_checksum>
8
+ <class_name>AddAPSZHPToEachZone</class_name>
9
+ <display_name>Add a PSZ-HP to each zone</display_name>
10
+ <description>This will add a Rooftop Packaged Single Zone Heat Pump (RTU with DX cooling and DX heating coils) to each zone of the model.</description>
11
+ <modeler_description>Add a System 4 - PSZ-HP - unit for each zone. This is a single zone system.
12
+ Parameters:
13
+ - Double: COP cooling and COP heating (Double)
14
+ - Boolean: supplementary electric heating coil (Boolean)
15
+ - Pressure rise (Optional Double)
16
+ - Deletion of existing HVAC equipment (Boolean)
17
+ - DCV enabled or not (Boolean)
18
+ - Fan type: Variable Volume Fan (VFD) or not (Constant Volume) (Choice)
19
+ - Filter for the zone name (String): only zones that contains the string you input in filter will receive this system.</modeler_description>
20
+ <arguments>
21
+ <argument>
22
+ <name>delete_existing</name>
23
+ <display_name>Delete any existing HVAC equipment?</display_name>
24
+ <type>Boolean</type>
25
+ <required>true</required>
26
+ <model_dependent>false</model_dependent>
27
+ <choices>
28
+ <choice>
29
+ <value>true</value>
30
+ <display_name>true</display_name>
31
+ </choice>
32
+ <choice>
33
+ <value>false</value>
34
+ <display_name>false</display_name>
35
+ </choice>
36
+ </choices>
37
+ </argument>
38
+ <argument>
39
+ <name>cop_cooling</name>
40
+ <display_name>COP Cooling (SI)</display_name>
41
+ <type>Double</type>
42
+ <required>true</required>
43
+ <model_dependent>false</model_dependent>
44
+ <default_value>3.1</default_value>
45
+ </argument>
46
+ <argument>
47
+ <name>cop_heating</name>
48
+ <display_name>COP Heating (SI)</display_name>
49
+ <type>Double</type>
50
+ <required>true</required>
51
+ <model_dependent>false</model_dependent>
52
+ <default_value>3.1</default_value>
53
+ </argument>
54
+ <argument>
55
+ <name>has_electric_coil</name>
56
+ <display_name>Include supplementary electric heating coils?</display_name>
57
+ <type>Boolean</type>
58
+ <required>false</required>
59
+ <model_dependent>false</model_dependent>
60
+ <default_value>true</default_value>
61
+ <choices>
62
+ <choice>
63
+ <value>true</value>
64
+ <display_name>true</display_name>
65
+ </choice>
66
+ <choice>
67
+ <value>false</value>
68
+ <display_name>false</display_name>
69
+ </choice>
70
+ </choices>
71
+ </argument>
72
+ <argument>
73
+ <name>has_dcv</name>
74
+ <display_name>Enable Demand Controlled Ventilation?</display_name>
75
+ <type>Boolean</type>
76
+ <required>false</required>
77
+ <model_dependent>false</model_dependent>
78
+ <default_value>false</default_value>
79
+ <choices>
80
+ <choice>
81
+ <value>true</value>
82
+ <display_name>true</display_name>
83
+ </choice>
84
+ <choice>
85
+ <value>false</value>
86
+ <display_name>false</display_name>
87
+ </choice>
88
+ </choices>
89
+ </argument>
90
+ <argument>
91
+ <name>fan_type</name>
92
+ <display_name>Select fan type:</display_name>
93
+ <type>Choice</type>
94
+ <required>true</required>
95
+ <model_dependent>false</model_dependent>
96
+ <choices>
97
+ <choice>
98
+ <value>Constant Volume (default)</value>
99
+ <display_name>Constant Volume (default)</display_name>
100
+ </choice>
101
+ <choice>
102
+ <value>Variable Volume (VFD)</value>
103
+ <display_name>Variable Volume (VFD)</display_name>
104
+ </choice>
105
+ </choices>
106
+ </argument>
107
+ <argument>
108
+ <name>fan_pressure_rise</name>
109
+ <display_name>Fan Pressure Rise (Pa)</display_name>
110
+ <description>Leave blank for default value</description>
111
+ <type>Double</type>
112
+ <required>false</required>
113
+ <model_dependent>false</model_dependent>
114
+ </argument>
115
+ <argument>
116
+ <name>filter_type</name>
117
+ <display_name>How do you want to choose the affected zones?</display_name>
118
+ <type>Choice</type>
119
+ <required>true</required>
120
+ <model_dependent>false</model_dependent>
121
+ <choices>
122
+ <choice>
123
+ <value>By Space Type</value>
124
+ <display_name>By Space Type</display_name>
125
+ </choice>
126
+ <choice>
127
+ <value>By Space Type's 'Standards Space Type'</value>
128
+ <display_name>By Space Type's 'Standards Space Type'</display_name>
129
+ </choice>
130
+ <choice>
131
+ <value>By Zone Filter</value>
132
+ <display_name>By Zone Filter</display_name>
133
+ </choice>
134
+ </choices>
135
+ </argument>
136
+ <argument>
137
+ <name>space_type</name>
138
+ <display_name>a. Which Space Type?</display_name>
139
+ <type>Choice</type>
140
+ <required>false</required>
141
+ <model_dependent>false</model_dependent>
142
+ </argument>
143
+ <argument>
144
+ <name>standards_space_type</name>
145
+ <display_name>b. Which Standards Space Type</display_name>
146
+ <type>Choice</type>
147
+ <required>false</required>
148
+ <model_dependent>false</model_dependent>
149
+ </argument>
150
+ <argument>
151
+ <name>zone_filter</name>
152
+ <display_name>c. Only Apply to Zones that contain the following string</display_name>
153
+ <description>Case insensitive. For example, type 'retail' to apply to zones that have the word 'retail' or 'REtaiL' in their name. Leave blank to apply to all zones</description>
154
+ <type>String</type>
155
+ <required>false</required>
156
+ <model_dependent>false</model_dependent>
157
+ </argument>
158
+ </arguments>
159
+ <outputs/>
160
+ <provenances/>
161
+ <tags>
162
+ <tag>HVAC.Whole System</tag>
163
+ </tags>
164
+ <attributes>
165
+ <attribute>
166
+ <name>Uses SketchUp API</name>
167
+ <value>false</value>
168
+ <datatype>boolean</datatype>
169
+ </attribute>
170
+ <attribute>
171
+ <name>Measure Type</name>
172
+ <value>ModelMeasure</value>
173
+ <datatype>string</datatype>
174
+ </attribute>
175
+ </attributes>
176
+ <files>
177
+ <file>
178
+ <filename>measure.rb</filename>
179
+ <filetype>rb</filetype>
180
+ <usage_type></usage_type>
181
+ <checksum>E46EE4C8</checksum>
182
+ </file>
183
+ </files>
184
+ </measure>
@@ -0,0 +1,354 @@
1
+ # frozen_string_literal: true
2
+
3
+ # see the URL below for information on how to write OpenStudio measures
4
+ # http://openstudio.nrel.gov/openstudio-measure-writing-guide
5
+
6
+ # see the URL below for access to C++ documentation on model objects (click on "model" in the main window to view model objects)
7
+ # http://openstudio.nrel.gov/sites/openstudio.nrel.gov/files/nv_data/cpp_documentation_it/model/html/namespaces.html
8
+
9
+ # start the measure
10
+ class AddEnergyRecoveryVentilator < OpenStudio::Ruleset::ModelUserScript
11
+ # define the name that a user will see, this method may be deprecated as
12
+ # the display name in PAT comes from the name field in measure.xml
13
+ def name
14
+ return 'AddEnergyRecoveryVentilator'
15
+ end
16
+
17
+ # define the arguments that the user will input
18
+ # define the arguments that the user will input
19
+ # define the arguments that the user will input
20
+ def arguments(model)
21
+ args = OpenStudio::Ruleset::OSArgumentVector.new
22
+
23
+ # Determine how many air loops in model
24
+ air_loop_handles = OpenStudio::StringVector.new
25
+ air_loop_display_names = OpenStudio::StringVector.new
26
+
27
+ # Get/show all unitary air conditioners from current loaded model.
28
+ air_loop_handles << '0'
29
+ air_loop_display_names << '*All air loops*'
30
+
31
+ i_air_loop = 1
32
+ model.getAirLoopHVACs.each do |air_loop|
33
+ air_loop_handles << i_air_loop.to_s
34
+ air_loop_display_names << air_loop.name.to_s
35
+
36
+ i_air_loop += 1
37
+ end
38
+
39
+ if i_air_loop == 1
40
+ info_widget = OpenStudio::Ruleset::OSArgument.makeBoolArgument('info_widget', true)
41
+ info_widget.setDisplayName('!!!!*** This Measure is not Applicable to loaded Model. Read the description and choose an appropriate baseline model. ***!!!!')
42
+ info_widget.setDefaultValue(true)
43
+ args << info_widget
44
+ return args
45
+ end
46
+
47
+ air_loop_widget = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('air_loop_widget', air_loop_handles, air_loop_display_names, true)
48
+ air_loop_widget.setDisplayName('Apply the measure to ')
49
+ air_loop_widget.setDefaultValue(air_loop_display_names[0])
50
+ args << air_loop_widget
51
+
52
+ # Sensible Effectiveness at 100% Heating Air Flow (default of 0.76)
53
+ sensible_eff_at_100_heating = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('sensible_eff_at_100_heating', false)
54
+ sensible_eff_at_100_heating.setDisplayName('Sensible Effectiveness at 100% Heating Air Flow')
55
+ sensible_eff_at_100_heating.setDefaultValue(0.76)
56
+ args << sensible_eff_at_100_heating
57
+
58
+ # Latent Effectiveness at 100% Heating Air Flow (default of 0.76)
59
+ latent_eff_at_100_heating = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('latent_eff_at_100_heating', false)
60
+ latent_eff_at_100_heating.setDisplayName('Latent Effectiveness at 100% Heating Air Flow')
61
+ latent_eff_at_100_heating.setDefaultValue(0.68)
62
+ args << latent_eff_at_100_heating
63
+
64
+ # Sensible Effectiveness at 75% Heating Air Flow (default of 0.76)
65
+ sensible_eff_at_75_heating = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('sensible_eff_at_75_heating', false)
66
+ sensible_eff_at_75_heating.setDisplayName('Sensible Effectiveness at 75% Heating Air Flow')
67
+ sensible_eff_at_75_heating.setDefaultValue(0.81)
68
+ args << sensible_eff_at_75_heating
69
+
70
+ # Latent Effectiveness at 100% Heating Air Flow (default of 0.76)
71
+ latent_eff_at_75_heating = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('latent_eff_at_75_heating', false)
72
+ latent_eff_at_75_heating.setDisplayName('Latent Effectiveness at 75% Heating Air Flow')
73
+ latent_eff_at_75_heating.setDefaultValue(0.73)
74
+ args << latent_eff_at_75_heating
75
+
76
+ # Sensible Effectiveness at 100% Cooling Air Flow (default of 0.76)
77
+ sensible_eff_at_100_cooling = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('sensible_eff_at_100_cooling', false)
78
+ sensible_eff_at_100_cooling.setDisplayName('Sensible Effectiveness at 100% Cooling Air Flow')
79
+ sensible_eff_at_100_cooling.setDefaultValue(0.76)
80
+ args << sensible_eff_at_100_cooling
81
+
82
+ # Latent Effectiveness at 100% Cooling Air Flow (default of 0.76)
83
+ latent_eff_at_100_cooling = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('latent_eff_at_100_cooling', false)
84
+ latent_eff_at_100_cooling.setDisplayName('Latent Effectiveness at 100% Cooling Air Flow')
85
+ latent_eff_at_100_cooling.setDefaultValue(0.68)
86
+ args << latent_eff_at_100_cooling
87
+
88
+ # Sensible Effectiveness at 75% Cooling Air Flow (default of 0.76)
89
+ sensible_eff_at_75_cooling = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('sensible_eff_at_75_cooling', false)
90
+ sensible_eff_at_75_cooling.setDisplayName('Sensible Effectiveness at 75% Cooling Air Flow')
91
+ sensible_eff_at_75_cooling.setDefaultValue(0.81)
92
+ args << sensible_eff_at_75_cooling
93
+
94
+ # Latent Effectiveness at 100% Cooling Air Flow (default of 0.76)
95
+ latent_eff_at_75_cooling = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('latent_eff_at_75_cooling', false)
96
+ latent_eff_at_75_cooling.setDisplayName('Latent Effectiveness at 75% Cooling Air Flow')
97
+ latent_eff_at_75_cooling.setDefaultValue(0.73)
98
+ args << latent_eff_at_75_cooling
99
+
100
+ # Show ASHRAE standards
101
+ heat_exchanger_type_handles = OpenStudio::StringVector.new
102
+ heat_exchanger_type_display_names = OpenStudio::StringVector.new
103
+
104
+ heat_exchanger_type_handles << '0'
105
+ heat_exchanger_type_display_names << 'Rotary'
106
+
107
+ heat_exchanger_type_widget = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('heat_exchanger_type_widget', heat_exchanger_type_handles, heat_exchanger_type_display_names, true)
108
+ heat_exchanger_type_widget.setDisplayName('Heat Exchanger Type.')
109
+ heat_exchanger_type_widget.setDefaultValue(heat_exchanger_type_display_names[0])
110
+ args << heat_exchanger_type_widget
111
+
112
+ # Nominal electric power [W] (Note: this is optional. If no value is entered, do nothing)
113
+ nominal_electric_power = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('nominal_electric_power', false)
114
+ nominal_electric_power.setDisplayName('Nominal electric power [W]')
115
+ args << nominal_electric_power
116
+
117
+ return args
118
+ end # end the arguments method
119
+
120
+ def reportValueChangeInfo(value_old, value_new, value_name, airloop_name, runner)
121
+ if value_old.nil?
122
+ runner.registerInfo("Initial: The #{value_name} on #{airloop_name} was not set.")
123
+ else
124
+ runner.registerInfo("Initial: The #{value_name} on #{airloop_name} was #{value_old}.")
125
+ end
126
+ runner.registerInfo("Final: The #{value_name} on #{airloop_name} was set to be #{value_new}.")
127
+ return
128
+ end
129
+
130
+ def setSensibleEffectiveness100Cooling(erv, value_new, airloop_name, runner)
131
+ value_old = erv.getSensibleEffectivenessat100CoolingAirFlow
132
+ erv.setSensibleEffectivenessat100CoolingAirFlow(value_new)
133
+ reportValueChangeInfo(value_old, value_new, 'Sensible Effectiveness at 100% Cooling Air Flow', airloop_name, runner)
134
+ return
135
+ end
136
+
137
+ def setSensibleEffectiveness75Cooling(erv, value_new, airloop_name, runner)
138
+ value_old = erv.getSensibleEffectivenessat75CoolingAirFlow
139
+ erv.setSensibleEffectivenessat75CoolingAirFlow(value_new)
140
+ reportValueChangeInfo(value_old, value_new, 'Sensible Effectiveness at 75% Cooling Air Flow', airloop_name, runner)
141
+ return
142
+ end
143
+
144
+ def setLatentEffectiveness100Cooling(erv, value_new, airloop_name, runner)
145
+ value_old = erv.getLatentEffectivenessat100CoolingAirFlow
146
+ erv.setLatentEffectivenessat100CoolingAirFlow(value_new)
147
+ reportValueChangeInfo(value_old, value_new, 'Latent Effectiveness at 100% Cooling Air Flow', airloop_name, runner)
148
+ return
149
+ end
150
+
151
+ def setLatentEffectiveness75Cooling(erv, value_new, airloop_name, runner)
152
+ value_old = erv.getLatentEffectivenessat75CoolingAirFlow
153
+ erv.setLatentEffectivenessat75CoolingAirFlow(value_new)
154
+ reportValueChangeInfo(value_old, value_new, 'Latent Effectiveness at 75% Cooling Air Flow', airloop_name, runner)
155
+ return
156
+ end
157
+
158
+ def setSensibleEffectiveness100Heating(erv, value_new, airloop_name, runner)
159
+ value_old = erv.getSensibleEffectivenessat100HeatingAirFlow
160
+ erv.setSensibleEffectivenessat100HeatingAirFlow(value_new)
161
+ reportValueChangeInfo(value_old, value_new, 'Sensible Effectiveness at 100% Heating Air Flow', airloop_name, runner)
162
+ return
163
+ end
164
+
165
+ def setSensibleEffectiveness75Heating(erv, value_new, airloop_name, runner)
166
+ value_old = erv.getSensibleEffectivenessat75HeatingAirFlow
167
+ erv.setSensibleEffectivenessat75HeatingAirFlow(value_new)
168
+ reportValueChangeInfo(value_old, value_new, 'Sensible Effectiveness at 75% Heating Air Flow', airloop_name, runner)
169
+ return
170
+ end
171
+
172
+ def setLatentEffectiveness100Heating(erv, value_new, airloop_name, runner)
173
+ value_old = erv.getLatentEffectivenessat100HeatingAirFlow
174
+ erv.setLatentEffectivenessat100HeatingAirFlow(value_new)
175
+ reportValueChangeInfo(value_old, value_new, 'Latent Effectiveness at 100% Heating Air Flow', airloop_name, runner)
176
+ return
177
+ end
178
+
179
+ def setLatentEffectiveness75Heating(erv, value_new, airloop_name, runner)
180
+ value_old = erv.getLatentEffectivenessat75HeatingAirFlow
181
+ erv.setLatentEffectivenessat75HeatingAirFlow(value_new)
182
+ reportValueChangeInfo(value_old, value_new, 'Latent Effectiveness at 75% Heating Air Flow', airloop_name, runner)
183
+ return
184
+ end
185
+
186
+ def setNominalElectricPower(erv, value_new, airloop_name, runner)
187
+ value_old = erv.getNominalElectricPower
188
+ erv.setNominalElectricPower(value_new)
189
+ reportValueChangeInfo(value_old, value_new, 'Nominal electric power', airloop_name, runner)
190
+ return
191
+ end
192
+
193
+ def isOutOfRange(value_new, value_name, runner)
194
+ if (value_new < 0) || (value_new > 1)
195
+ runner.registerError("OutOfBound! The #{value_name} must be between 0 and 1. Reset the value.")
196
+ return true
197
+ end
198
+ return false
199
+ end
200
+
201
+ # define what happens when the measure is run
202
+ def run(model, runner, user_arguments)
203
+ super(model, runner, user_arguments)
204
+
205
+ # use the built-in error checking
206
+ if !runner.validateUserArguments(arguments(model), user_arguments)
207
+ return false
208
+ end
209
+
210
+ # Determine if the measure is applicable to the model, if not just return and no changes are made.
211
+ info_widget = runner.getOptionalWorkspaceObjectChoiceValue('info_widget', user_arguments, model)
212
+ if !(info_widget.nil? || info_widget.empty?)
213
+ runner.registerInfo('This measure is not applicable.')
214
+ return true
215
+ end
216
+
217
+ air_loop_widget = runner.getOptionalWorkspaceObjectChoiceValue('air_loop_widget', user_arguments, model)
218
+ handle = runner.getStringArgumentValue('air_loop_widget', user_arguments)
219
+ air_loop_index = handle.to_i
220
+
221
+ sensible_eff_at_100_heating = runner.getDoubleArgumentValue('sensible_eff_at_100_heating', user_arguments)
222
+ latent_eff_at_100_heating = runner.getDoubleArgumentValue('latent_eff_at_100_heating', user_arguments)
223
+ sensible_eff_at_75_heating = runner.getDoubleArgumentValue('sensible_eff_at_75_heating', user_arguments)
224
+ latent_eff_at_75_heating = runner.getDoubleArgumentValue('latent_eff_at_75_heating', user_arguments)
225
+
226
+ sensible_eff_at_100_cooling = runner.getDoubleArgumentValue('sensible_eff_at_100_cooling', user_arguments)
227
+ latent_eff_at_100_cooling = runner.getDoubleArgumentValue('latent_eff_at_100_cooling', user_arguments)
228
+ sensible_eff_at_75_cooling = runner.getDoubleArgumentValue('sensible_eff_at_75_cooling', user_arguments)
229
+ latent_eff_at_75_cooling = runner.getDoubleArgumentValue('latent_eff_at_75_cooling', user_arguments)
230
+
231
+ if isOutOfRange(sensible_eff_at_100_heating, 'sensible_eff_at_100_heating', runner)
232
+ return false
233
+ end
234
+ if isOutOfRange(latent_eff_at_100_heating, 'latent_eff_at_100_heating', runner)
235
+ return false
236
+ end
237
+ if isOutOfRange(sensible_eff_at_75_heating, 'sensible_eff_at_75_heating', runner)
238
+ return false
239
+ end
240
+ if isOutOfRange(latent_eff_at_75_heating, 'latent_eff_at_75_heating', runner)
241
+ return false
242
+ end
243
+ if isOutOfRange(sensible_eff_at_100_cooling, 'sensible_eff_at_100_cooling', runner)
244
+ return false
245
+ end
246
+ if isOutOfRange(latent_eff_at_100_cooling, 'latent_eff_at_100_cooling', runner)
247
+ return false
248
+ end
249
+ if isOutOfRange(sensible_eff_at_75_cooling, 'sensible_eff_at_75_cooling', runner)
250
+ return false
251
+ end
252
+ if isOutOfRange(latent_eff_at_75_cooling, 'latent_eff_at_75_cooling', runner)
253
+ return false
254
+ end
255
+
256
+ heat_exchanger_type_widget = runner.getOptionalWorkspaceObjectChoiceValue('heat_exchanger_type_widget', user_arguments, model)
257
+ handle = runner.getStringArgumentValue('heat_exchanger_type_widget', user_arguments)
258
+ heat_exchanger_type_index = handle.to_i
259
+
260
+ heat_exchanger_type_list = ['Rotary']
261
+ heat_type = heat_exchanger_type_list[heat_exchanger_type_index]
262
+
263
+ nominal_electric_power = runner.getOptionalDoubleArgumentValue('nominal_electric_power', user_arguments)
264
+ if nominal_electric_power.empty?
265
+ nominal_electric_power = nil
266
+ else
267
+ nominal_electric_power = runner.getDoubleArgumentValue('nominal_electric_power', user_arguments)
268
+ end
269
+
270
+ # loop through all air loops
271
+ i_air_loop = 0
272
+ model.getAirLoopHVACs.each do |air_loop|
273
+ # check if the airloop already has an ERV either on a specified air loop or all air loops
274
+ i_air_loop += 1
275
+ if (air_loop_index != 0) && (air_loop_index != i_air_loop)
276
+ next
277
+ end
278
+
279
+ has_ERV = false
280
+ air_loop.supplyComponents.each do |supply_component|
281
+ # check if the supply component is an ERV
282
+ if !supply_component.to_HeatExchangerAirToAirSensibleAndLatent.empty?
283
+ has_ERV = true
284
+ erv = supply_component.to_HeatExchangerAirToAirSensibleAndLatent.get
285
+ erv.setHeatExchangerType(heat_type)
286
+ setSensibleEffectiveness100Cooling(erv, sensible_eff_at_100_cooling, air_loop.name, runner)
287
+ setSensibleEffectiveness75Cooling(erv, sensible_eff_at_75_cooling, air_loop.name, runner)
288
+ setLatentEffectiveness100Cooling(erv, latent_eff_at_100_cooling, air_loop.name, runner)
289
+ setLatentEffectiveness75Cooling(erv, latent_eff_at_75_cooling, air_loop.name, runner)
290
+
291
+ setSensibleEffectiveness100Heating(erv, sensible_eff_at_100_heating, air_loop.name, runner)
292
+ setSensibleEffectiveness75Heating(erv, sensible_eff_at_75_heating, air_loop.name, runner)
293
+ setLatentEffectiveness100Heating(erv, latent_eff_at_100_heating, air_loop.name, runner)
294
+ setLatentEffectiveness75Heating(erv, latent_eff_at_75_heating, air_loop.name, runner)
295
+
296
+ # erv.setEconomizerLockout('Yes')
297
+ # erv.setEconomizerLockout(true)
298
+ erv.setString(23, 'Yes')
299
+
300
+ # erv.setSupplyAirOutletTemperatureControl ('No')
301
+ # erv.setSupplyAirOutletTemperatureControl (false)
302
+ erv.setString(17, 'No')
303
+ if !nominal_electric_power.nil?
304
+ setNominalElectricPower(erv, nominal_electric_power, air_loop.name, runner)
305
+ end
306
+ end
307
+ end
308
+ air_loop.supplyComponents.each do |supply_component|
309
+ # if no ERV was found, see if the air loop has an outdoor air system
310
+ if has_ERV == false
311
+ if !supply_component.to_AirLoopHVACOutdoorAirSystem.empty?
312
+ # get the outdoor air system
313
+ oa_system = supply_component.to_AirLoopHVACOutdoorAirSystem.get
314
+ # create a new heat exchanger and add it to the outdoor air system
315
+ erv = OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent.new(model)
316
+ oa_node = oa_system.outboardOANode
317
+ if !oa_node.empty?
318
+ # set node connection
319
+ erv.addToNode(oa_node.get)
320
+ # set required fields to a single default value
321
+ erv.setHeatExchangerType(heat_type)
322
+ setSensibleEffectiveness100Cooling(erv, sensible_eff_at_100_cooling, air_loop.name, runner)
323
+ setSensibleEffectiveness75Cooling(erv, sensible_eff_at_75_cooling, air_loop.name, runner)
324
+ setLatentEffectiveness100Cooling(erv, latent_eff_at_100_cooling, air_loop.name, runner)
325
+ setLatentEffectiveness75Cooling(erv, latent_eff_at_75_cooling, air_loop.name, runner)
326
+
327
+ setSensibleEffectiveness100Heating(erv, sensible_eff_at_100_heating, air_loop.name, runner)
328
+ setSensibleEffectiveness75Heating(erv, sensible_eff_at_75_heating, air_loop.name, runner)
329
+ setLatentEffectiveness100Heating(erv, latent_eff_at_100_heating, air_loop.name, runner)
330
+ setLatentEffectiveness75Heating(erv, latent_eff_at_75_heating, air_loop.name, runner)
331
+
332
+ # Temporary solution, may need to fix later. 12/22/2013 Da
333
+ # erv.setEconomizerLockout('Yes')
334
+ # erv.setEconomizerLockout(true)
335
+ erv.setString(23, 'Yes')
336
+
337
+ # erv.setSupplyAirOutletTemperatureControl ('No')
338
+ # erv.setSupplyAirOutletTemperatureControl (false)
339
+ erv.setString(17, 'No')
340
+
341
+ if !nominal_electric_power.nil?
342
+ setNominalElectricPower(erv, nominal_electric_power, air_loop.name, runner)
343
+ end
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
349
+ return true
350
+ end # end the run method
351
+ end # end the measure
352
+
353
+ # this allows the measure to be use by the application
354
+ AddEnergyRecoveryVentilator.new.registerWithApplication