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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Rakefile +2 -0
- data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.rb +333 -0
- data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.xml +150 -0
- data/lib/measures/ReplaceFanTotalEfficiency/measure.rb +330 -0
- data/lib/measures/ReplaceFanTotalEfficiency/measure.xml +150 -0
- data/lib/measures/add_apszhp_to_each_zone/measure.rb +607 -0
- data/lib/measures/add_apszhp_to_each_zone/measure.xml +184 -0
- data/lib/measures/add_energy_recovery_ventilator/measure.rb +354 -0
- data/lib/measures/add_energy_recovery_ventilator/measure.xml +78 -0
- data/lib/measures/improve_simple_glazing_by_percentage/measure.rb +81 -0
- data/lib/measures/improve_simple_glazing_by_percentage/measure.xml +70 -0
- data/lib/measures/reduce_water_use_by_percentage/measure.rb +61 -0
- data/lib/measures/reduce_water_use_by_percentage/measure.xml +62 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/measure.rb +511 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/measure.xml +375 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_AedgMeasures.rb +454 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Constructions.rb +221 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Geometry.rb +41 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HVAC.rb +1682 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HelperMethods.rb +114 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
- data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Schedules.rb +142 -0
- data/lib/measures/replace_simple_glazing/measure.rb +86 -0
- data/lib/measures/replace_simple_glazing/measure.xml +78 -0
- data/lib/measures/set_boiler_thermal_efficiency/measure.rb +520 -0
- data/lib/measures/set_boiler_thermal_efficiency/measure.xml +78 -0
- data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.rb +207 -0
- data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.xml +78 -0
- data/lib/measures/tenant_star_internal_loads/measure.rb +134 -0
- data/lib/measures/tenant_star_internal_loads/measure.xml +67 -0
- data/lib/measures/tenant_star_internal_loads/resources/os_lib_helper_methods.rb +401 -0
- data/lib/measures/vr_fwith_doas/measure.rb +468 -0
- data/lib/measures/vr_fwith_doas/measure.xml +298 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_AedgMeasures.rb +454 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_Constructions.rb +221 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_Geometry.rb +41 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_HVAC.rb +1516 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_HelperMethods.rb +114 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_LightingAndEquipment.rb +99 -0
- data/lib/measures/vr_fwith_doas/resources/OsLib_Schedules.rb +142 -0
- data/lib/openstudio/ee_measures/version.rb +1 -1
- data/openstudio-ee.gemspec +7 -5
- 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
|