openstudio-ee 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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