openstudio-ee 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +7 -0
  4. data/Rakefile +0 -2
  5. data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.rb +1 -1
  6. data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.xml +3 -4
  7. data/lib/measures/nze_hvac/measure.rb +8 -6
  8. data/lib/measures/nze_hvac/measure.xml +9 -9
  9. data/lib/openstudio/ee_measures/version.rb +1 -1
  10. data/openstudio-ee.gemspec +6 -8
  11. metadata +11 -50
  12. data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.rb +0 -333
  13. data/lib/measures/ImproveFanTotalEfficiencybyPercentage/measure.xml +0 -150
  14. data/lib/measures/ReplaceFanTotalEfficiency/measure.rb +0 -330
  15. data/lib/measures/ReplaceFanTotalEfficiency/measure.xml +0 -150
  16. data/lib/measures/add_apszhp_to_each_zone/measure.rb +0 -607
  17. data/lib/measures/add_apszhp_to_each_zone/measure.xml +0 -184
  18. data/lib/measures/add_energy_recovery_ventilator/measure.rb +0 -354
  19. data/lib/measures/add_energy_recovery_ventilator/measure.xml +0 -78
  20. data/lib/measures/improve_simple_glazing_by_percentage/measure.rb +0 -81
  21. data/lib/measures/improve_simple_glazing_by_percentage/measure.xml +0 -70
  22. data/lib/measures/reduce_water_use_by_percentage/measure.rb +0 -61
  23. data/lib/measures/reduce_water_use_by_percentage/measure.xml +0 -62
  24. data/lib/measures/replace_hvac_with_gshp_and_doas/measure.rb +0 -511
  25. data/lib/measures/replace_hvac_with_gshp_and_doas/measure.xml +0 -375
  26. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_AedgMeasures.rb +0 -454
  27. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Constructions.rb +0 -221
  28. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Geometry.rb +0 -41
  29. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HVAC.rb +0 -1682
  30. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_HelperMethods.rb +0 -114
  31. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_LightingAndEquipment.rb +0 -99
  32. data/lib/measures/replace_hvac_with_gshp_and_doas/resources/OsLib_Schedules.rb +0 -142
  33. data/lib/measures/replace_simple_glazing/measure.rb +0 -86
  34. data/lib/measures/replace_simple_glazing/measure.xml +0 -78
  35. data/lib/measures/set_boiler_thermal_efficiency/measure.rb +0 -520
  36. data/lib/measures/set_boiler_thermal_efficiency/measure.xml +0 -78
  37. data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.rb +0 -207
  38. data/lib/measures/set_water_heater_efficiency_heat_lossand_peak_water_flow_rate/measure.xml +0 -78
  39. data/lib/measures/tenant_star_internal_loads/measure.rb +0 -134
  40. data/lib/measures/tenant_star_internal_loads/measure.xml +0 -67
  41. data/lib/measures/tenant_star_internal_loads/resources/os_lib_helper_methods.rb +0 -401
  42. data/lib/measures/vr_fwith_doas/measure.rb +0 -468
  43. data/lib/measures/vr_fwith_doas/measure.xml +0 -298
  44. data/lib/measures/vr_fwith_doas/resources/OsLib_AedgMeasures.rb +0 -454
  45. data/lib/measures/vr_fwith_doas/resources/OsLib_Constructions.rb +0 -221
  46. data/lib/measures/vr_fwith_doas/resources/OsLib_Geometry.rb +0 -41
  47. data/lib/measures/vr_fwith_doas/resources/OsLib_HVAC.rb +0 -1516
  48. data/lib/measures/vr_fwith_doas/resources/OsLib_HelperMethods.rb +0 -114
  49. data/lib/measures/vr_fwith_doas/resources/OsLib_LightingAndEquipment.rb +0 -99
  50. data/lib/measures/vr_fwith_doas/resources/OsLib_Schedules.rb +0 -142
@@ -1,150 +0,0 @@
1
- <measure>
2
- <schema_version>3.0</schema_version>
3
- <name>replace_fan_total_efficiency</name>
4
- <uid>ebeca0aa-a432-4283-a714-17116f7c8f8c</uid>
5
- <version_id>348976a4-526f-4a56-b819-74c78f8a07e3</version_id>
6
- <version_modified>20190212T002510Z</version_modified>
7
- <xml_checksum>F78494F2</xml_checksum>
8
- <class_name>ReplaceFanTotalEfficiency</class_name>
9
- <display_name>Replace Fan Total Efficiency</display_name>
10
- <description></description>
11
- <modeler_description></modeler_description>
12
- <arguments>
13
- <argument>
14
- <name>object</name>
15
- <display_name>Choose an Air Loop to Alter.</display_name>
16
- <type>Choice</type>
17
- <required>true</required>
18
- <model_dependent>false</model_dependent>
19
- <default_value>*All Air Loops*</default_value>
20
- <choices>
21
- <choice>
22
- <value>{7d3f0300-6b06-458a-ad5e-0d5d7ec180cc}</value>
23
- <display_name>*All Air Loops*</display_name>
24
- </choice>
25
- </choices>
26
- </argument>
27
- <argument>
28
- <name>motor_eff</name>
29
- <display_name>Fan Total Efficiency Replacement in %</display_name>
30
- <type>Double</type>
31
- <required>true</required>
32
- <model_dependent>false</model_dependent>
33
- <default_value>70</default_value>
34
- </argument>
35
- <argument>
36
- <name>remove_costs</name>
37
- <display_name>Remove Baseline Costs From Effected Fans?</display_name>
38
- <type>Boolean</type>
39
- <required>true</required>
40
- <model_dependent>false</model_dependent>
41
- <default_value>false</default_value>
42
- <choices>
43
- <choice>
44
- <value>true</value>
45
- <display_name>true</display_name>
46
- </choice>
47
- <choice>
48
- <value>false</value>
49
- <display_name>false</display_name>
50
- </choice>
51
- </choices>
52
- </argument>
53
- <argument>
54
- <name>material_cost</name>
55
- <display_name>Material and Installation Costs per Motor ($).</display_name>
56
- <type>Double</type>
57
- <required>true</required>
58
- <model_dependent>false</model_dependent>
59
- <default_value>0</default_value>
60
- </argument>
61
- <argument>
62
- <name>demolition_cost</name>
63
- <display_name>Demolition Costs per Motor ($).</display_name>
64
- <type>Double</type>
65
- <required>true</required>
66
- <model_dependent>false</model_dependent>
67
- <default_value>0</default_value>
68
- </argument>
69
- <argument>
70
- <name>years_until_costs_start</name>
71
- <display_name>Years Until Costs Start (whole years).</display_name>
72
- <type>Integer</type>
73
- <required>true</required>
74
- <model_dependent>false</model_dependent>
75
- <default_value>0</default_value>
76
- </argument>
77
- <argument>
78
- <name>demo_cost_initial_const</name>
79
- <display_name>Demolition Costs Occur During Initial Construction?</display_name>
80
- <type>Boolean</type>
81
- <required>true</required>
82
- <model_dependent>false</model_dependent>
83
- <default_value>false</default_value>
84
- <choices>
85
- <choice>
86
- <value>true</value>
87
- <display_name>true</display_name>
88
- </choice>
89
- <choice>
90
- <value>false</value>
91
- <display_name>false</display_name>
92
- </choice>
93
- </choices>
94
- </argument>
95
- <argument>
96
- <name>expected_life</name>
97
- <display_name>Expected Life (whole years).</display_name>
98
- <type>Integer</type>
99
- <required>true</required>
100
- <model_dependent>false</model_dependent>
101
- <default_value>20</default_value>
102
- </argument>
103
- <argument>
104
- <name>om_cost</name>
105
- <display_name>O &amp; M Costs per Motor ($).</display_name>
106
- <type>Double</type>
107
- <required>true</required>
108
- <model_dependent>false</model_dependent>
109
- <default_value>0</default_value>
110
- </argument>
111
- <argument>
112
- <name>om_frequency</name>
113
- <display_name>O &amp; M Frequency (whole years).</display_name>
114
- <type>Integer</type>
115
- <required>true</required>
116
- <model_dependent>false</model_dependent>
117
- <default_value>1</default_value>
118
- </argument>
119
- </arguments>
120
- <outputs/>
121
- <provenances/>
122
- <tags>
123
- <tag>HVAC.Distribution</tag>
124
- </tags>
125
- <attributes>
126
- <attribute>
127
- <name>Measure Type</name>
128
- <value>ModelMeasure</value>
129
- <datatype>string</datatype>
130
- </attribute>
131
- <attribute>
132
- <name>Uses SketchUp API</name>
133
- <value>false</value>
134
- <datatype>boolean</datatype>
135
- </attribute>
136
- </attributes>
137
- <files>
138
- <file>
139
- <version>
140
- <software_program>OpenStudio</software_program>
141
- <identifier>1.0.3</identifier>
142
- <min_compatible>1.0.3</min_compatible>
143
- </version>
144
- <filename>measure.rb</filename>
145
- <filetype>rb</filetype>
146
- <usage_type>script</usage_type>
147
- <checksum>FCCFD3DA</checksum>
148
- </file>
149
- </files>
150
- </measure>
@@ -1,607 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Author: Julien Marrec
4
- # email: julien.marrec@gmail.com
5
-
6
- # start the measure
7
- class AddAPSZHPToEachZone < OpenStudio::Ruleset::ModelUserScript
8
- # define the name that a user will see, this method may be deprecated as
9
- # the display name in PAT comes from the name field in measure.xml
10
- def name
11
- return 'Add a PSZ-HP to each zone'
12
- end
13
-
14
- def description
15
- return 'This will add a Rooftop Packaged Single Zone Heat Pump (RTU with DX cooling and DX heating coils) to each zone of the model.'
16
- end
17
-
18
- def modeler_description
19
- return "Add a System 4 - PSZ-HP - unit for each zone. This is a single zone system.
20
- Parameters:
21
- - Double: COP cooling and COP heating (Double)
22
- - Boolean: supplementary electric heating coil (Boolean)
23
- - Pressure rise (Optional Double)
24
- - Deletion of existing HVAC equipment (Boolean)
25
- - DCV enabled or not (Boolean)
26
- - Fan type: Variable Volume Fan (VFD) or not (Constant Volume) (Choice)
27
- - Filter for the zone name (String): only zones that contains the string you input in filter will receive this system."
28
- end
29
-
30
- # define the arguments that the user will input
31
- def arguments(model)
32
- args = OpenStudio::Ruleset::OSArgumentVector.new
33
-
34
- delete_existing = OpenStudio::Ruleset::OSArgument.makeBoolArgument('delete_existing', true)
35
- delete_existing.setDisplayName('Delete any existing HVAC equipment?')
36
- args << delete_existing
37
-
38
- cop_cooling = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('cop_cooling', true)
39
- cop_cooling.setDisplayName('COP Cooling (SI)')
40
- cop_cooling.setDefaultValue(3.1)
41
- args << cop_cooling
42
-
43
- cop_heating = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('cop_heating', true)
44
- cop_heating.setDisplayName('COP Heating (SI)')
45
- cop_heating.setDefaultValue(3.1)
46
- args << cop_heating
47
-
48
- has_electric_coil = OpenStudio::Ruleset::OSArgument.makeBoolArgument('has_electric_coil', false)
49
- has_electric_coil.setDisplayName('Include supplementary electric heating coils?')
50
- has_electric_coil.setDefaultValue(true)
51
- args << has_electric_coil
52
-
53
- has_dcv = OpenStudio::Ruleset::OSArgument.makeBoolArgument('has_dcv', false)
54
- has_dcv.setDisplayName('Enable Demand Controlled Ventilation?')
55
- has_dcv.setDefaultValue(false)
56
- args << has_dcv
57
-
58
- chs = OpenStudio::StringVector.new
59
- chs << 'Constant Volume (default)'
60
- chs << 'Variable Volume (VFD)'
61
- fan_type = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('fan_type', chs, true)
62
- fan_type.setDisplayName('Select fan type:')
63
- args << fan_type
64
-
65
- fan_pressure_rise = OpenStudio::Ruleset::OSArgument.makeDoubleArgument('fan_pressure_rise', false)
66
- fan_pressure_rise.setDisplayName('Fan Pressure Rise (Pa)')
67
- fan_pressure_rise.setDescription('Leave blank for default value')
68
- # fan_pressure_rise.setDefaultValue(0)
69
- args << fan_pressure_rise
70
-
71
- chs = OpenStudio::StringVector.new
72
- chs << 'By Space Type'
73
- chs << "By Space Type's 'Standards Space Type'"
74
- chs << 'By Zone Filter'
75
- filter_type = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('filter_type', chs, true)
76
- filter_type.setDisplayName('How do you want to choose the affected zones?')
77
- args << filter_type
78
-
79
- # create an argument for a space type to be used in the model. Only return those that are used
80
- spaceTypes = model.getSpaceTypes
81
- usedSpaceTypes_handle = OpenStudio::StringVector.new
82
- usedSpaceTypes_displayName = OpenStudio::StringVector.new
83
-
84
- # Should normally be an OpenStudio::StringVector.new but it doesn't have a uniq! method and it works with a regular hash..
85
- standardsSpaceType = []
86
-
87
- spaceTypes.each do |spaceType|
88
- if !spaceType.spaces.empty? # only show space types used in the building
89
- usedSpaceTypes_handle << spaceType.handle.to_s
90
- usedSpaceTypes_displayName << spaceType.name.to_s
91
-
92
- if !spaceType.standardsSpaceType.empty?
93
- standardsSpaceType << spaceType.standardsSpaceType.get
94
- end
95
- end
96
- end
97
-
98
- # make an argument for space type
99
- space_type = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('space_type', usedSpaceTypes_handle, usedSpaceTypes_displayName, false)
100
- space_type.setDisplayName('a. Which Space Type?')
101
- args << space_type
102
-
103
- # Argument for Standards Space Type
104
-
105
- # First, make it unique
106
- standardsSpaceType.uniq!
107
- standards_space_type = OpenStudio::Ruleset::OSArgument.makeChoiceArgument('standards_space_type', standardsSpaceType, false)
108
- standards_space_type.setDisplayName('b. Which Standards Space Type')
109
- args << standards_space_type
110
-
111
- zone_filter = OpenStudio::Ruleset::OSArgument.makeStringArgument('zone_filter', false)
112
- zone_filter.setDisplayName('c. Only Apply to Zones that contain the following string')
113
- zone_filter.setDescription("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")
114
- args << zone_filter
115
-
116
- return args
117
- end # end the arguments method
118
-
119
- # define what happens when the measure is run
120
- def run(model, runner, user_arguments)
121
- super(model, runner, user_arguments)
122
-
123
- # use the built-in error checking
124
- if !runner.validateUserArguments(arguments(model), user_arguments)
125
- return false
126
- end
127
-
128
- # Retrieve arguments' values
129
- delete_existing = runner.getBoolArgumentValue('delete_existing', user_arguments)
130
- cop_cooling = runner.getDoubleArgumentValue('cop_cooling', user_arguments)
131
- cop_heating = runner.getDoubleArgumentValue('cop_heating', user_arguments)
132
- has_electric_coil = runner.getBoolArgumentValue('has_electric_coil', user_arguments)
133
- has_dcv = runner.getBoolArgumentValue('has_dcv', user_arguments)
134
-
135
- # Get fan_pressure_rise: this is an OptionalDouble - we'll use '.get' later
136
- fan_pressure_rise = runner.getOptionalDoubleArgumentValue('fan_pressure_rise', user_arguments)
137
-
138
- # FanType
139
- fan_type = runner.getStringArgumentValue('fan_type', user_arguments)
140
- runner.registerInfo("Fan type: #{fan_type}")
141
-
142
- if fan_type == 'Variable Volume (VFD)'
143
- has_vfd = true
144
- else
145
- has_vfd = false
146
- end
147
-
148
- filter_type = runner.getStringArgumentValue('filter_type', user_arguments)
149
-
150
- if filter_type == 'By Space Type'
151
- space_type = runner.getOptionalWorkspaceObjectChoiceValue('space_type', user_arguments, model)
152
- if !space_type.empty?
153
- space_type = space_type.get
154
- if !space_type.to_SpaceType.empty?
155
- space_type = space_type.to_SpaceType.get
156
- zones = []
157
- space_type.spaces.each do |space|
158
- if !space.thermalZone.empty?
159
- z = space.thermalZone.get
160
- zones << z
161
- end
162
- end
163
- end
164
- end
165
-
166
- elsif filter_type == "By Space Type's 'Standards Space Type'"
167
-
168
- standards_space_type = runner.getOptionalStringArgumentValue('standards_space_type', user_arguments)
169
- puts standards_space_type.class
170
-
171
- if !standards_space_type.empty?
172
- standards_space_type = standards_space_type.get
173
- puts standards_space_type
174
- space_types = model.getSpaceTypes
175
-
176
- zones = []
177
-
178
- space_types.each do |space_type|
179
- if space_type.standardsSpaceType.to_s.casecmp(standards_space_type).zero?
180
- space_type.spaces.each do |space|
181
- if !space.thermalZone.empty?
182
- z = space.thermalZone.get
183
- # We MUST check if zone isn't in there yet (or at the end do zones.uniq!) because several spaces can refer to the same thermal zone!
184
- if !zones.include?(z)
185
- zones << z
186
- end
187
- end
188
- end
189
- end
190
- end
191
- end
192
-
193
- else
194
- # Zone filter
195
- zone_filter = runner.getOptionalStringArgumentValue('zone_filter', user_arguments)
196
-
197
- # Get all thermal zones
198
- all_zones = model.getThermalZones
199
-
200
- # Array to store the zones that match the filter
201
- zones = []
202
- all_zones.each do |z|
203
- # Skip zone if name doesn't include zone_filter
204
- # Putting everything in Upper Case to make it case insensitive
205
- if !zone_filter.empty?
206
- if z.name.to_s.upcase.include? zone_filter.to_s.upcase
207
- zones << z
208
- end
209
- end
210
- end
211
-
212
- if zones.empty?
213
- runner.registerError("Your zone filter #{zone_filter} did not match anything")
214
- return false
215
- end
216
-
217
- end # End of if filter_type
218
-
219
- # Output zone names to console
220
- puts "\n\n================ ZONES THAT MATCHED THE FILTER ================\n"
221
- zones.each do |z|
222
- puts z.name
223
- end
224
-
225
- # info for initial condition
226
- initial_num_air_loops_demand_control = 0
227
- final_num_air_loops_demand_control = 0
228
- initial_num_fan_VFD = 0
229
- final_num_fan_VFD = 0
230
- delete_existing_air_loops = 0
231
- delete_existing_chiller_loops = 0
232
- delete_existing_condenser_loops = 0
233
- affected_loops = 0
234
-
235
- # If we need to delete existing HVAC loops, we'll store the PRE-EXISTING Loops in the following variables,
236
- # They will be used for clean up at the end
237
- if delete_existing
238
- air_loops = model.getAirLoopHVACs
239
- runner.registerInfo("Number of initial AirLoopHVACs: #{air_loops.size}")
240
- plant_loops = model.getPlantLoops
241
- runner.registerInfo("Number of initial PlantLoops: #{plant_loops.size}")
242
- end
243
-
244
- # For each thermal zones (zones is initialized above, depending on which filter you chose)
245
- zones.each do |z|
246
- # Create a system 4 (PSZ-HP)
247
- air_handler = OpenStudio::Model.addSystemType4(model).to_AirLoopHVAC.get
248
-
249
- # Set name of Air Loop to be thermal_zone + 'Airloop'
250
- # Local variable name convention for a non-constant (dynamic) value is 'snake_case'
251
- base_name = z.name.to_s
252
- air_handler.setName(base_name + ' AirLoop')
253
-
254
- # Get existing fan, created with System 4, constant volume by default
255
- old_fan = air_handler.supplyComponents(OpenStudio::Model::FanConstantVolume.iddObjectType).first
256
- old_fan = old_fan.to_FanConstantVolume.get
257
-
258
- # If you want a VFD, we replace it with a Variable Volume one
259
- if has_vfd
260
-
261
- # Get the outlet node after the existing fan on the loop
262
- next_node = old_fan.outletModelObject.get.to_Node.get
263
-
264
- # Create the new Variable speed fan
265
- fan = OpenStudio::Model::FanVariableVolume.new(model)
266
-
267
- # Add the new fan to the oulet node of the existing fan
268
- # before deleting the existing one
269
- fan.addToNode(next_node)
270
-
271
- # Remove the existing fan. When this happens, either the pump's
272
- # inlet or outlet node will be deleted and the other will remain
273
- old_fan.remove
274
-
275
- # Rename the fan clearly
276
- fan.setName(base_name + ' Variable Volume Fan')
277
-
278
- # If fan_pressure_rise has a non zero null value, assign it.
279
- if !fan_pressure_rise.empty?
280
- # We need the .get because this is an OptionalDouble. the .get will return a Double (float)
281
- fan.setPressureRise(fan_pressure_rise.get)
282
- runner.registerInfo("Fan '#{fan.name}' was assigned pressure rise of '#{fan_pressure_rise.get}' Pa")
283
- end
284
-
285
- final_num_fan_VFD += 1
286
-
287
- else
288
- # If VFD isn't wanted, we just rename the constant volume fan
289
- old_fan.setName(base_name + ' Constant Volume Fan')
290
-
291
- # If fan_pressure_rise has a non zero null value, assign it.
292
- if !fan_pressure_rise.empty?
293
- # We need the .get because this is an OptionalDouble. the .get will return a Double (float)
294
- old_fan.setPressureRise(fan_pressure_rise.get)
295
- puts "Fan '#{old_fan.name}' was assigned pressure rise of '#{fan_pressure_rise.get}' Pa"
296
- end
297
-
298
- end
299
-
300
- # The Cooling coil expects an OptionalDouble
301
- coil = air_handler.supplyComponents(OpenStudio::Model::CoilCoolingDXSingleSpeed.iddObjectType).first
302
- coil = coil.to_CoilCoolingDXSingleSpeed.get
303
- # Set CoolingCoil COP
304
- coil.setRatedCOP(OpenStudio::OptionalDouble.new(cop_cooling))
305
- # Set CoolingCoil Name
306
- coil.setName(base_name + ' Coil Cooling DX Single Speed')
307
-
308
- # The Heating coil expects a Double
309
- coilheating = air_handler.supplyComponents(OpenStudio::Model::CoilHeatingDXSingleSpeed.iddObjectType).first
310
- coilheating = coilheating.to_CoilHeatingDXSingleSpeed.get
311
- # Set HeatingCoil COP
312
- coilheating.setRatedCOP(cop_heating)
313
- # Set HeatingCoil Name
314
- coilheating.setName(base_name + ' Coil Heating DX Single Speed')
315
-
316
- # Delete the electric heating coil if unwanted
317
- if !has_electric_coil
318
- coilheatingelec = air_handler.supplyComponents(OpenStudio::Model::CoilHeatingElectric.iddObjectType).first
319
- coilheatingelec.remove
320
- end
321
-
322
- # Enable DCV (dunno if working)
323
- if has_dcv
324
-
325
- # get air_handler supply components
326
- supply_components = air_handler.supplyComponents
327
-
328
- # find AirLoopHVACOutdoorAirSystem on loop
329
- supply_components.each do |supply_component|
330
- hVACComponent = supply_component.to_AirLoopHVACOutdoorAirSystem
331
- if !hVACComponent.empty?
332
- hVACComponent = hVACComponent.get
333
-
334
- # get ControllerOutdoorAir
335
- controller_oa = hVACComponent.getControllerOutdoorAir
336
- controller_oa.setName(base_name + ' Controller Outdoor Air')
337
-
338
- # get ControllerMechanicalVentilation
339
- controller_mv = controller_oa.controllerMechanicalVentilation
340
-
341
- # check if demand control is enabled, if not, then enable it
342
- if controller_mv.demandControlledVentilation == true
343
- initial_num_air_loops_demand_control += 1
344
- else
345
- controller_mv.setDemandControlledVentilation(true)
346
- puts "Enabling demand control ventilation for #{air_handler.name}"
347
- end # End of if
348
- final_num_air_loops_demand_control += 1
349
-
350
- end # End of HVACComponent.empty?
351
- end # end of supply component do loop
352
-
353
- end # End of has_dcv loop
354
-
355
- # Add a branch for the zone in question
356
- air_handler.addBranchForZone(z)
357
-
358
- # Counter
359
- affected_loops += 1
360
- end # end of do loop on each thermal zone
361
-
362
- # CLEAN-UP SECTION
363
- # Idea: loop on PRE-EXISTING AirLoops, delete all that don't have any zones anymore
364
- # Then loop on chiller loop, delete all that don't have a coil connected to an air loop
365
- # then loop on condenser water, delette all that don't have a chiller anymore
366
-
367
- # If we need to delete existing HVAC loops, we'll loop on the PRE-EXISTING Loops we stored earlier
368
- if delete_existing
369
-
370
- # Arrays to store the affected loops
371
- chiller_plant_loops = []
372
- boiler_plant_loops = []
373
- condenser_plant_loops = []
374
-
375
- # Display separator for clarity
376
- runner.registerInfo('')
377
- runner.registerInfo('========================== CLEAN-UP: AIR LOOPS ==========================')
378
-
379
- # Loop on the pre-existing air loops (not the ones that were created above)
380
- air_loops.each do |air_loop|
381
- # Check if it's got a thermal zone attached left or not..
382
- # We assume we'll delete it unless...
383
- delete_flag = true
384
-
385
- air_loop.demandComponents.each do |comp|
386
- # If there is at least a single zone left, we can't delete it
387
- if comp.to_ThermalZone.is_initialized
388
- delete_flag = false
389
- end # end of if
390
- end # end of do loop on comp
391
-
392
- # If deletion is warranted
393
- if delete_flag
394
- # before deletion, let's get the potential associated plant loop.
395
- if air_loop.supplyComponents(OpenStudio::Model::CoilCoolingWater.iddObjectType).empty?
396
- puts "Air loop '#{air_loop.name}' DOES NOT HAVE a CoilHeatingWater"
397
- else
398
- cooling_coil = air_loop.supplyComponents(OpenStudio::Model::CoilCoolingWater.iddObjectType).first.to_CoilCoolingWater.get
399
- chiller_plant_loop = cooling_coil.plantLoop.get
400
- # Store handle in array
401
- chiller_plant_loops << chiller_plant_loop
402
- runner.registerInfo("Air loop '#{air_loop.name}' has a CoilCoolingWater, connected to CHILLER plant loop '#{chiller_plant_loop.name}'")
403
- end
404
- if air_loop.supplyComponents(OpenStudio::Model::CoilHeatingWater.iddObjectType).empty?
405
- puts "Air loop '#{air_loop.name}' DOES NOT HAVE a CoilHeatingWater"
406
- else
407
- heating_coil = air_loop.supplyComponents(OpenStudio::Model::CoilCoolingWater.iddObjectType).first.to_CoilCoolingWater.get
408
- boiler_plant_loop = heating_coil.plantLoop.get
409
- # Store handle in array
410
- boiler_plant_loops << boiler_plant_loop
411
- runner.registerInfo("Air loop '#{air_loop.name}' has a CoilHeatinggWater, connected to BOILER plant loop '#{boiler_plant_loop.name}'")
412
- end
413
-
414
- # Now we can delete and report.
415
- air_loop.remove
416
- runner.registerInfo("DELETED: Air loop '#{air_loop.name}' doesn't have Thermal zones attached and was removed")
417
- delete_existing_air_loops += 1
418
- else
419
- runner.registerInfo("Air Loop '#{air_loop.name}' has thermal zones and was not deleted")
420
- end # end if delete_flag
421
- end # end air_loops.each do
422
-
423
- # Display separator for clarity
424
- runner.registerInfo('')
425
- runner.registerInfo('====================== CLEAN-UP: CHILLER PLANT LOOPS ======================')
426
-
427
- # First pass on plant loops: chilled water loops.
428
- chiller_plant_loops.each do |chiller_plant_loop|
429
- puts "Chiller plant loop name: #{chiller_plant_loop.name}"
430
-
431
- # Check if the chiller plant loop has remaining demand components
432
-
433
- # Delete flag: first assumption is that yes... unless!
434
- delete_flag = true
435
-
436
- if chiller_plant_loop.demandComponents(OpenStudio::Model::CoilCoolingWater.iddObjectType).empty?
437
- puts "Chiller Plant loop '#{chiller_plant_loop.name}' DOES NOT HAVE a CoilCoolingWater"
438
- else
439
- puts "Chiller Plant loop '#{chiller_plant_loop.name}' has a CoilCoolingWater"
440
- cooling_coil = chiller_plant_loop.demandComponents(OpenStudio::Model::CoilCoolingWater.iddObjectType).first.to_CoilCoolingWater.get
441
- if cooling_coil.airLoopHVAC.empty?
442
- puts "But Cooling coil '#{cooling_coil.name}' is not connected to any airloopHVAC"
443
- else
444
- runner.registerInfo("And Cooling coil '#{cooling_coil.name}' is connected to airloopHVAC '#{cooling_coil.airLoopHVAC.get.name}' and therefore can't be deleted")
445
- # In this case, we can't delete the chiller plant loop
446
- delete_flag = false
447
- end # end cooling_coil.airLoopHVAC.empty?
448
-
449
- end # end of chiller_plant_loop.demandComponents CoilCoolingWater
450
-
451
- # We know it's a chiller plant so this is likely unnecessary, but better safe than sorry
452
- if chiller_plant_loop.demandComponents(OpenStudio::Model::WaterUseConnections.iddObjectType).empty?
453
- puts "Chiller Plant loop '#{chiller_plant_loop.name}' DOES NOT HAVE WaterUseConnections"
454
- else
455
- runner.registerInfo("Chiller Plant loop '#{chiller_plant_loop.name}' has WaterUseConnections and therefore can't be deleted")
456
- delete_flag = false
457
- end
458
-
459
- # If deletion is warranted
460
- if delete_flag
461
-
462
- # This section below is actually optional (but it's nice to only delete affected ones
463
- # before deletion, let's get the potential associated condenser water plant loop.
464
- if chiller_plant_loop.supplyComponents(OpenStudio::Model::ChillerElectricEIR.iddObjectType).empty?
465
- puts "Chiller Plant loop '#{chiller_plant_loop.name}' DOES NOT HAVE an electric chiller"
466
- else
467
- chiller = chiller_plant_loop.supplyComponents(OpenStudio::Model::ChillerElectricEIR.iddObjectType).first.to_ChillerElectricEIR.get
468
- puts "Chiller Plant loop '#{chiller_plant_loop.name}' has an electric chiller '#{chiller.name}' with condenser type '#{chiller.condenserType}'"
469
- # Check directly if chiller has a secondaryPlantLoop (no need to check if chiller.condenserType == 'WaterCooled' first)
470
- if chiller.secondaryPlantLoop.is_initialized
471
- # Chiller is WaterCooled therefore should be connected to a condenser water loop
472
- condenser_plant_loop = chiller.secondaryPlantLoop.get
473
- condenser_plant_loops << condenser_plant_loop
474
- runner.registerInfo("Chiller PlantLoop '#{chiller_plant_loop.name}' has a Water Cooled chiller connected to Condenser Plant Loop '#{condenser_plant_loop.name}'")
475
- end
476
- end
477
-
478
- # Now we can delete and report.
479
- chiller_plant_loop.remove
480
- delete_existing_chiller_loops += 1
481
- # Should I delete the chiller as well? It remains...
482
-
483
- runner.registerInfo("DELETED: Chiller PlantLoop '#{chiller_plant_loop.name}' wasn't connected to any AirLoopHVAC nor WaterUseConnections and therefore was removed")
484
-
485
- end # end of delete_flag
486
- end # end of chiller_plant_loops.each do
487
-
488
- # Display separator for clarity
489
- runner.registerInfo('')
490
- runner.registerInfo('===================== CLEAN-UP: CONDENSER PLANT LOOPS ====================')
491
- # Second pass on plant loops: condenser water loops.
492
- condenser_plant_loops.each do |condenser_plant_loop|
493
- delete_flag = true
494
-
495
- # If it has got a chiller as a demand component, it could still be empty
496
- if !condenser_plant_loop.demandComponents(OpenStudio::Model::ChillerElectricEIR.iddObjectType).empty?
497
-
498
- chiller = condenser_plant_loop.demandComponents(OpenStudio::Model::ChillerElectricEIR.iddObjectType).first.to_ChillerElectricEIR.get
499
-
500
- # If chiller is actually connected to a chilled water node, then we shall not delete it
501
- if !chiller.chilledWaterInletNodeName.empty?
502
- runner.registerInfo("On Condenser PlantLoop '#{condenser_plant_loop.name}, there is a demand component of type Chiller '#{chiller.name}'" \
503
- ' that is connected to a chilled water loop and therefore cannot be deleted')
504
- delete_flag = false
505
- else
506
- puts "Plant loop '#{condenser_plant_loop.name}, Chiller '#{chiller.name}' isn't connected to a chilled water loop"
507
- end # end of if chiller.chilledWaterInletNodeName
508
- end # end of plant_loop.demandComponents
509
-
510
- # if deletion is warranted
511
- if delete_flag
512
- condenser_plant_loop.remove
513
- delete_existing_condenser_loops += 1
514
- runner.registerInfo("DELETED: Plant loop '#{condenser_plant_loop.name}' isn't connected to any chilled water loop")
515
- end
516
- end
517
-
518
- runner.registerInfo('')
519
- runner.registerInfo("For more information, go to 'Advanced Output'")
520
-
521
- # This is the generic way of looping on all loops, checking if it's a condenser plant loop, and to delete it unless it's got a chiller that is connected to chilled water plant loop
522
- # plant_loops.each do |plant_loop|
523
- # # Skip the chiller_plant_loops
524
- # #next if chiller_plant_loops.include? plant_loop
525
- # if chiller_plant_loops.include? plant_loop
526
- # runner.registerInfo("Skipping Plant loop '#{plant_loop.name}' because it is a chiller plant")
527
- # next
528
- # end
529
- # runner.registerInfo("Plant loop '#{plant_loop.name}'")
530
- #
531
- # # Until we know that it is a condenser loop for sure, we assume we can't delete it
532
- # delete_flag = false
533
- #
534
- # # If it has got a chiller as a demand component, it's a condenser water loop
535
- # if not plant_loop.demandComponents(OpenStudio::Model::ChillerElectricEIR::iddObjectType).empty?
536
- # # Now, we assume we'll delete the loop unless it's actually connected and therefore usefull
537
- # delete_flag = true
538
- # chiller = plant_loop.demandComponents(OpenStudio::Model::ChillerElectricEIR::iddObjectType).first.to_ChillerElectricEIR.get
539
- # # If chiller is actually connected to a chilled water node, then we shall not delete it
540
- # if not chiller.chilledWaterInletNodeName.empty?
541
- # runner.registerInfo("On Condenser PlantLoop '#{plant_loop.name}, there is a demand component of type Chiller '#{chiller.name}'" +
542
- # " that is connected to a chilled water loop and therefore cannot be deleted")
543
- # delete_flag = false
544
- # else
545
- # runner.registerInfo("Plant loop '#{plant_loop.name}, Chiller '#{chiller.name}' isn't connected to a chilled water loop")
546
- # end #end of if chiller.chilledWaterInletNodeName
547
- # end #end of plant_loop.demandComponents
548
- #
549
- # # if deletion is warranted
550
- # if delete_flag
551
- # plant_loop.remove
552
- # delete_existing_condenser_loops += 1
553
- # runner.registerInfo("DELETED: Plant loop '#{plant_loop.name}'")
554
- # end
555
- #
556
- # end #end of plant_loops.each do
557
-
558
- # Third pass on plant loops: boiler water loops.
559
- # TO WRITE
560
-
561
- end # end of if delete_existing
562
-
563
- # Report Initial Condition
564
- if delete_existing
565
- air_loop_str = "\n #{delete_existing_air_loops} existing AirLoopHVACs have been deleted"
566
- chiller_plant_loop_str = "\n #{delete_existing_chiller_loops} existing Chiller PlantLoops have been deleted"
567
- condenser_plant_loop_str = "\n #{delete_existing_condenser_loops} existing Condenser PlantLoops have been deleted"
568
- else
569
- air_loop_str = ''
570
- chiller_plant_loop_str = ''
571
- condenser_plant_loop_str = ''
572
- end # end of delete_existing
573
-
574
- runner.registerInitialCondition("Initially #{initial_num_air_loops_demand_control} air loops had demand controlled ventilation enabled" +
575
- air_loop_str + chiller_plant_loop_str + condenser_plant_loop_str + "\n")
576
-
577
- # Report final condition
578
- base_str = "There are #{OpenStudio.toNeatString(affected_loops, 0, true)} zones for which a PSZ-HP system was " \
579
- "created with a Cooling COP (SI) of #{OpenStudio.toNeatString(cop_cooling, 2, true)} " \
580
- "and a Heating COP (SI) of #{OpenStudio.toNeatString(cop_heating, 2, true)}."
581
-
582
- if has_electric_coil
583
- elec_str = 'Supplementary electric heating coils were added.'
584
- else
585
- elec_str = 'Supplementary electrical heating coils were NOT included.'
586
- end # end of has_electric_coil
587
-
588
- if has_vfd
589
- fan_str = "Fan type was changed to be Variable Volume (VFD) for #{final_num_fan_VFD} fans."
590
- else
591
- fan_str = 'Fan type was chosen to be Constant Volume.'
592
- end # end of has_vfd
593
-
594
- if final_num_air_loops_demand_control == 0
595
- dcv_str = "Demand Controlled Ventilation wasn't enabled for the new air loops"
596
- else
597
- dcv_str = "#{final_num_air_loops_demand_control} air loops now have demand controlled ventilation enabled"
598
- end
599
-
600
- runner.registerFinalCondition(base_str + "\n" + elec_str + "\n" + fan_str + "\n" + dcv_str + "\n \n")
601
-
602
- return true
603
- end # end the run method
604
- end # end the measure
605
-
606
- # this allows the measure to be used by the application
607
- AddAPSZHPToEachZone.new.registerWithApplication