openstudio-ee 0.12.3 → 0.12.5

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.coverage +0 -0
  3. data/.github/workflows/test-with-openstudio.yml +109 -74
  4. data/.gitignore +21 -0
  5. data/.rubocop.yml +15 -2
  6. data/CHANGELOG.md +6 -0
  7. data/Gemfile +7 -8
  8. data/README.md +3 -2
  9. data/WORKFLOW_CHANGES.md +74 -0
  10. data/lib/measures/AddDaylightSensors/measure.rb +79 -79
  11. data/lib/measures/AddDaylightSensors/measure.xml +4 -4
  12. data/lib/measures/AddOverhangsByProjectionFactor/measure.rb +38 -41
  13. data/lib/measures/AddOverhangsByProjectionFactor/measure.xml +4 -4
  14. data/lib/measures/EnableDemandControlledVentilation/measure.rb +37 -40
  15. data/lib/measures/EnableDemandControlledVentilation/measure.xml +4 -4
  16. data/lib/measures/EnableEconomizerControl/measure.rb +36 -37
  17. data/lib/measures/EnableEconomizerControl/measure.xml +4 -4
  18. data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.rb +27 -41
  19. data/lib/measures/GLHEProExportLoadsforGroundHeatExchangerSizing/measure.xml +4 -4
  20. data/lib/measures/GLHEProGFunctionImport/measure.rb +11 -15
  21. data/lib/measures/GLHEProGFunctionImport/measure.xml +4 -4
  22. data/lib/measures/GLHEProSetupExportLoadsforGroundHeatExchangerSizing/measure.rb +5 -9
  23. data/lib/measures/GLHEProSetupExportLoadsforGroundHeatExchangerSizing/measure.xml +3 -3
  24. data/lib/measures/ImproveFanBeltEfficiency/measure.rb +78 -95
  25. data/lib/measures/ImproveFanBeltEfficiency/measure.xml +6 -6
  26. data/lib/measures/ImproveMotorEfficiency/measure.rb +75 -100
  27. data/lib/measures/ImproveMotorEfficiency/measure.xml +6 -6
  28. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.rb +137 -130
  29. data/lib/measures/IncreaseInsulationRValueForExteriorWalls/measure.xml +4 -4
  30. data/lib/measures/IncreaseInsulationRValueForExteriorWallsByPercentage/measure.rb +114 -115
  31. data/lib/measures/IncreaseInsulationRValueForExteriorWallsByPercentage/measure.xml +3 -3
  32. data/lib/measures/IncreaseInsulationRValueForRoofs/measure.rb +137 -130
  33. data/lib/measures/IncreaseInsulationRValueForRoofs/measure.xml +4 -4
  34. data/lib/measures/IncreaseInsulationRValueForRoofsByPercentage/measure.rb +114 -115
  35. data/lib/measures/IncreaseInsulationRValueForRoofsByPercentage/measure.xml +3 -3
  36. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.rb +69 -63
  37. data/lib/measures/ReduceElectricEquipmentLoadsByPercentage/measure.xml +6 -6
  38. data/lib/measures/ReduceLightingLoadsByPercentage/measure.rb +77 -66
  39. data/lib/measures/ReduceLightingLoadsByPercentage/measure.xml +6 -6
  40. data/lib/measures/ReduceNightTimeElectricEquipmentLoads/measure.rb +45 -43
  41. data/lib/measures/ReduceNightTimeElectricEquipmentLoads/measure.xml +4 -4
  42. data/lib/measures/ReduceNightTimeLightingLoads/measure.rb +45 -43
  43. data/lib/measures/ReduceNightTimeLightingLoads/measure.xml +4 -4
  44. data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.rb +58 -52
  45. data/lib/measures/ReduceSpaceInfiltrationByPercentage/measure.xml +6 -6
  46. data/lib/measures/ReduceVentilationByPercentage/measure.rb +49 -46
  47. data/lib/measures/ReduceVentilationByPercentage/measure.xml +6 -6
  48. data/lib/measures/add_variable_speed_rtu_control_logic/measure.rb +31 -23
  49. data/lib/measures/add_variable_speed_rtu_control_logic/measure.xml +4 -4
  50. data/lib/measures/create_variable_speed_rtu/measure.rb +166 -174
  51. data/lib/measures/create_variable_speed_rtu/measure.xml +6 -6
  52. data/lib/measures/fan_assist_night_ventilation/measure.rb +33 -32
  53. data/lib/measures/fan_assist_night_ventilation/measure.xml +4 -4
  54. data/lib/measures/nze_hvac/measure.rb +72 -62
  55. data/lib/measures/nze_hvac/measure.xml +4 -4
  56. data/lib/measures/replace_water_heater_mixed_with_thermal_storage_chilled_water/measure.rb +16 -19
  57. data/lib/measures/replace_water_heater_mixed_with_thermal_storage_chilled_water/measure.xml +4 -4
  58. data/lib/measures/window_enhancement/LICENSE.md +14 -0
  59. data/lib/measures/window_enhancement/README.md +112 -0
  60. data/lib/measures/window_enhancement/docs/.gitkeep +0 -0
  61. data/lib/measures/window_enhancement/measure.py +386 -0
  62. data/lib/measures/window_enhancement/measure.xml +271 -0
  63. data/lib/measures/window_enhancement/resources/EC3_lookup.py +321 -0
  64. data/lib/measures/window_enhancement/resources/Test_API.py +32 -0
  65. data/lib/measures/window_enhancement/resources/__pycache__/EC3_lookup.cpython-39.pyc +0 -0
  66. data/lib/measures/window_enhancement/resources/__pycache__/Original_EC3_lookup.py +322 -0
  67. data/lib/measures/window_enhancement/resources/__pycache__/Test_API.cpython-39.pyc +0 -0
  68. data/lib/measures/window_enhancement/resources/calculate_perimeter.py +39 -0
  69. data/lib/measures/window_enhancement/test_output.log +39 -0
  70. data/lib/openstudio/ee_measures/version.rb +1 -1
  71. data/openstudio-ee.gemspec +10 -8
  72. data/test-workflow-locally.sh +152 -0
  73. metadata +64 -35
  74. data/Jenkinsfile +0 -11
@@ -12,17 +12,17 @@
12
12
  class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
13
13
  # human readable name
14
14
  def name
15
- return 'Create Variable Speed RTU'
15
+ 'Create Variable Speed RTU'
16
16
  end
17
17
 
18
18
  # human readable description
19
19
  def description
20
- return "This measure examines the existing HVAC system(s) present in the current OpenStudio model. If a constant-speed system is found, the user can opt to have the measure replace that system with a variable-speed RTU. 'Variable speed' in this case means that the compressor will be operated using either two or four stages (user's choice). The user can choose between using a gas heating coil, or a direct-expansion (DX) heating coil. Additionally, the user is able to enter the EER (cooling) and COP (heating) values for each DX stage. This measure allows users to easily identify the impact of improved part-load efficiency."
20
+ "This measure examines the existing HVAC system(s) present in the current OpenStudio model. If a constant-speed system is found, the user can opt to have the measure replace that system with a variable-speed RTU. 'Variable speed' in this case means that the compressor will be operated using either two or four stages (user's choice). The user can choose between using a gas heating coil, or a direct-expansion (DX) heating coil. Additionally, the user is able to enter the EER (cooling) and COP (heating) values for each DX stage. This measure allows users to easily identify the impact of improved part-load efficiency."
21
21
  end
22
22
 
23
23
  # human readable description of modeling approach
24
24
  def modeler_description
25
- return "This measure loops through the existing airloops, looking for loops that have a constant speed fan. (Note that if an object such as an AirloopHVAC:UnitarySystem is present in the model, that the measure will NOT identify that loop as either constant- or variable-speed, since the fan is located inside the UnitarySystem object.) The user can designate which constant-speed airloop they'd like to apply the measure to, or opt to apply the measure to all airloops. The measure then replaces the supply components on the airloop with an AirloopHVAC:UnitarySystem object. Any DX coils added to the UnitarySystem object are of the type CoilCoolingDXMultiSpeed / CoilHeatingDXMultiSpeed, with the number of stages set to either two or four, depending on user input. If the user opts for a gas furnace, an 80% efficient CoilHeatingGas object is added. Fan properties (pressure rise and total efficiency) are transferred automatically from the existing (but deleted) constant speed fan to the new variable-speed fan. Currently, this measure is only applicable to the Standalone Retail DOE Prototype building model, but it has been structured to facilitate expansion to other models with a minimum of effort."
25
+ "This measure loops through the existing airloops, looking for loops that have a constant speed fan. (Note that if an object such as an AirloopHVAC:UnitarySystem is present in the model, that the measure will NOT identify that loop as either constant- or variable-speed, since the fan is located inside the UnitarySystem object.) The user can designate which constant-speed airloop they'd like to apply the measure to, or opt to apply the measure to all airloops. The measure then replaces the supply components on the airloop with an AirloopHVAC:UnitarySystem object. Any DX coils added to the UnitarySystem object are of the type CoilCoolingDXMultiSpeed / CoilHeatingDXMultiSpeed, with the number of stages set to either two or four, depending on user input. If the user opts for a gas furnace, an 80% efficient CoilHeatingGas object is added. Fan properties (pressure rise and total efficiency) are transferred automatically from the existing (but deleted) constant speed fan to the new variable-speed fan. Currently, this measure is only applicable to the Standalone Retail DOE Prototype building model, but it has been structured to facilitate expansion to other models with a minimum of effort."
26
26
  end
27
27
 
28
28
  # define the arguments that the user will input
@@ -57,7 +57,8 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
57
57
  air_loop_display_names << '*All CAV Air Loops*'
58
58
 
59
59
  # make an argument for air loops
60
- object = OpenStudio::Measure::OSArgument.makeChoiceArgument('object', air_loop_handles, air_loop_display_names, true)
60
+ object = OpenStudio::Measure::OSArgument.makeChoiceArgument('object', air_loop_handles, air_loop_display_names,
61
+ true)
61
62
  object.setDisplayName('Choose an Air Loop to change from CAV to VAV.')
62
63
  object.setDefaultValue('*All CAV Air Loops*') # if no air loop is chosen this will run on all air loops
63
64
  args << object
@@ -66,7 +67,8 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
66
67
  cooling_coil_options = OpenStudio::StringVector.new
67
68
  cooling_coil_options << 'Two-Stage Compressor'
68
69
  cooling_coil_options << 'Four-Stage Compressor'
69
- cooling_coil_type = OpenStudio::Measure::OSArgument.makeChoiceArgument('cooling_coil_type', cooling_coil_options, true)
70
+ cooling_coil_type = OpenStudio::Measure::OSArgument.makeChoiceArgument('cooling_coil_type', cooling_coil_options,
71
+ true)
70
72
  cooling_coil_type.setDisplayName('Choose the type of cooling coil.')
71
73
  cooling_coil_type.setDefaultValue('Two-Stage Compressor')
72
74
  args << cooling_coil_type
@@ -99,7 +101,8 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
99
101
  heating_coil_options = OpenStudio::StringVector.new
100
102
  heating_coil_options << 'Gas Heating Coil'
101
103
  heating_coil_options << 'Heat Pump'
102
- heating_coil_type = OpenStudio::Measure::OSArgument.makeChoiceArgument('heating_coil_type', heating_coil_options, true)
104
+ heating_coil_type = OpenStudio::Measure::OSArgument.makeChoiceArgument('heating_coil_type', heating_coil_options,
105
+ true)
103
106
  heating_coil_type.setDisplayName('Choose the type of heating coil.')
104
107
  heating_coil_type.setDefaultValue('Gas Heating Coil')
105
108
  args << heating_coil_type
@@ -134,7 +137,7 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
134
137
  # quarter_hc_cop.setDefaultValue(0.0)
135
138
  args << quarter_hc_cop
136
139
 
137
- return args
140
+ args
138
141
  end # end the arguments method
139
142
 
140
143
  # define what happens when the measure is run
@@ -142,9 +145,7 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
142
145
  super(model, runner, user_arguments)
143
146
 
144
147
  # Use the built-in error checking
145
- if !runner.validateUserArguments(arguments(model), user_arguments)
146
- return false
147
- end
148
+ return false unless runner.validateUserArguments(arguments(model), user_arguments)
148
149
 
149
150
  # Assign the user inputs to variables
150
151
  object = runner.getOptionalWorkspaceObjectChoiceValue('object', user_arguments, model)
@@ -261,15 +262,13 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
261
262
  runner.registerError("The selected air loop with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
262
263
  end
263
264
  return false
265
+ elsif !object.get.to_AirLoopHVAC.empty?
266
+ selected_airloop = object.get.to_AirLoopHVAC.get
267
+ elsif !object.get.to_Building.empty?
268
+ apply_to_all_air_loops = true
264
269
  else
265
- if !object.get.to_AirLoopHVAC.empty?
266
- selected_airloop = object.get.to_AirLoopHVAC.get
267
- elsif !object.get.to_Building.empty?
268
- apply_to_all_air_loops = true
269
- else
270
- runner.registerError('Script Error - argument not showing up as air loop.')
271
- return false
272
- end
270
+ runner.registerError('Script Error - argument not showing up as air loop.')
271
+ return false
273
272
  end # end of if object.empty?
274
273
 
275
274
  # Add selected airloops to an array
@@ -289,62 +288,60 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
289
288
 
290
289
  # Find CAV fan and replace with VAV fan
291
290
  air_loop.supplyComponents.each do |supply_comp|
292
- if supply_comp.to_FanConstantVolume.is_initialized
293
-
294
- # Preserve characteristics of the original fan
295
- cav_fan = supply_comp.to_FanConstantVolume.get
296
- fan_pressure_rise = cav_fan.pressureRise
297
- fan_efficiency = cav_fan.fanEfficiency
298
- motor_efficiency = cav_fan.motorEfficiency
299
- fan_availability_schedule = cav_fan.availabilitySchedule
300
-
301
- # Get the previous and next components on the loop
302
- prev_node = cav_fan.inletModelObject.get.to_Node.get
303
- next_node = cav_fan.outletModelObject.get.to_Node.get
304
-
305
- # Make the new vav_fan and transfer existing parameters to it
306
- vav_fan = OpenStudio::Model::FanVariableVolume.new(model, model.alwaysOnDiscreteSchedule)
307
- vav_fan.setPressureRise(fan_pressure_rise)
308
- vav_fan.setFanEfficiency(fan_efficiency)
309
- vav_fan.setMotorEfficiency(motor_efficiency)
310
- vav_fan.setAvailabilitySchedule(fan_availability_schedule)
311
-
312
- # Remove the supply fan
313
- supply_comp.remove
314
-
315
- # Get back the remaining node
316
- remaining_node = nil
317
- if prev_node.outletModelObject.is_initialized
318
- remaining_node = prev_node
319
- elsif next_node.inletModelObject.is_initialized
320
- remaining_node = next_node
321
- end
322
-
323
- # Add a new AirLoopHVAC:UnitarySystem object to the node where the old fan was
324
- if remaining_node.nil?
325
- runner.registerError("Couldn't add the new AirLoopHVAC:UnitarySystem object to the loop after removing existing CAV fan.")
326
- return false
327
- else
328
- air_loop_hvac_unitary_system.addToNode(remaining_node)
329
- end
291
+ next unless supply_comp.to_FanConstantVolume.is_initialized
292
+
293
+ # Preserve characteristics of the original fan
294
+ cav_fan = supply_comp.to_FanConstantVolume.get
295
+ fan_pressure_rise = cav_fan.pressureRise
296
+ fan_efficiency = cav_fan.fanEfficiency
297
+ motor_efficiency = cav_fan.motorEfficiency
298
+ fan_availability_schedule = cav_fan.availabilitySchedule
299
+
300
+ # Get the previous and next components on the loop
301
+ prev_node = cav_fan.inletModelObject.get.to_Node.get
302
+ next_node = cav_fan.outletModelObject.get.to_Node.get
303
+
304
+ # Make the new vav_fan and transfer existing parameters to it
305
+ vav_fan = OpenStudio::Model::FanVariableVolume.new(model, model.alwaysOnDiscreteSchedule)
306
+ vav_fan.setPressureRise(fan_pressure_rise)
307
+ vav_fan.setFanEfficiency(fan_efficiency)
308
+ vav_fan.setMotorEfficiency(motor_efficiency)
309
+ vav_fan.setAvailabilitySchedule(fan_availability_schedule)
310
+
311
+ # Remove the supply fan
312
+ supply_comp.remove
313
+
314
+ # Get back the remaining node
315
+ remaining_node = nil
316
+ if prev_node.outletModelObject.is_initialized
317
+ remaining_node = prev_node
318
+ elsif next_node.inletModelObject.is_initialized
319
+ remaining_node = next_node
320
+ end
330
321
 
331
- # Change the unitary system control type to setpoint to enable the VAV fan to ramp down.
332
- air_loop_hvac_unitary_system.setString(2, 'Setpoint')
322
+ # Add a new AirLoopHVAC:UnitarySystem object to the node where the old fan was
323
+ if remaining_node.nil?
324
+ runner.registerError("Couldn't add the new AirLoopHVAC:UnitarySystem object to the loop after removing existing CAV fan.")
325
+ return false
326
+ else
327
+ air_loop_hvac_unitary_system.addToNode(remaining_node)
328
+ end
333
329
 
334
- # Add the VAV fan to the AirLoopHVAC:UnitarySystem object
335
- air_loop_hvac_unitary_system.setSupplyFan(vav_fan)
330
+ # Change the unitary system control type to setpoint to enable the VAV fan to ramp down.
331
+ air_loop_hvac_unitary_system.setString(2, 'Setpoint')
336
332
 
337
- # Set the AirLoopHVAC:UnitarySystem fan placement
338
- air_loop_hvac_unitary_system.setFanPlacement('BlowThrough')
333
+ # Add the VAV fan to the AirLoopHVAC:UnitarySystem object
334
+ air_loop_hvac_unitary_system.setSupplyFan(vav_fan)
339
335
 
340
- # Set the AirLoopHVAC:UnitarySystem Supply Air Fan Operating Mode Schedule
341
- air_loop_hvac_unitary_system.setSupplyAirFanOperatingModeSchedule(model.alwaysOnDiscreteSchedule)
336
+ # Set the AirLoopHVAC:UnitarySystem fan placement
337
+ air_loop_hvac_unitary_system.setFanPlacement('BlowThrough')
342
338
 
343
- # let the user know that a change was made
344
- changed_cav_to_vav = true
345
- runner.registerInfo("AirLoop '#{air_loop.name}' was changed from CAV to VAV")
339
+ # Set the AirLoopHVAC:UnitarySystem Supply Air Fan Operating Mode Schedule
340
+ air_loop_hvac_unitary_system.setSupplyAirFanOperatingModeSchedule(model.alwaysOnDiscreteSchedule)
346
341
 
347
- end
342
+ # let the user know that a change was made
343
+ changed_cav_to_vav = true
344
+ runner.registerInfo("AirLoop '#{air_loop.name}' was changed from CAV to VAV")
348
345
  end # next supply component
349
346
 
350
347
  # Move on to the next air loop if no CAV to VAV change happened
@@ -356,92 +353,90 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
356
353
 
357
354
  # Move the cooling coil to the AirLoopHVAC:UnitarySystem object
358
355
  air_loop.supplyComponents.each do |supply_comp|
359
- if supply_comp.to_CoilCoolingDXTwoSpeed.is_initialized
360
-
361
- existing_cooling_coil = supply_comp.to_CoilCoolingDXTwoSpeed.get
362
-
363
- # Add a new cooling coil object
364
- if cooling_coil_type == 'Two-Stage Compressor'
365
- new_cooling_coil = OpenStudio::Model::CoilCoolingDXMultiSpeed.new(model)
366
- half_speed_cc_cop = half_cc_eer.to_f / 3.412
367
- new_cooling_coil_data_1 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
368
- new_cooling_coil_data_1.setGrossRatedCoolingCOP(half_speed_cc_cop.to_f)
369
- rated_speed_cc_cop = rated_cc_eer.to_f / 3.412
370
- new_cooling_coil_data_2 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
371
- new_cooling_coil_data_2.setGrossRatedCoolingCOP(rated_speed_cc_cop.to_f)
372
- new_cooling_coil.setFuelType('Electricity')
373
- new_cooling_coil.addStage(new_cooling_coil_data_1)
374
- new_cooling_coil.addStage(new_cooling_coil_data_2)
375
- air_loop_hvac_unitary_system.setCoolingCoil(new_cooling_coil)
376
- elsif cooling_coil_type == 'Four-Stage Compressor'
377
- new_cooling_coil = OpenStudio::Model::CoilCoolingDXMultiSpeed.new(model)
378
- quarter_speed_cc_cop = quarter_cc_eer.to_f / 3.412
379
- new_cooling_coil_data_1 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
380
- new_cooling_coil_data_1.setGrossRatedCoolingCOP(quarter_speed_cc_cop.to_f)
381
- half_speed_cc_cop = half_cc_eer.to_f / 3.412
382
- new_cooling_coil_data_2 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
383
- new_cooling_coil_data_2.setGrossRatedCoolingCOP(half_speed_cc_cop.to_f)
384
- three_quarter_speed_cc_cop = three_quarter_cc_eer.to_f / 3.412
385
- new_cooling_coil_data_3 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
386
- new_cooling_coil_data_3.setGrossRatedCoolingCOP(three_quarter_speed_cc_cop.to_f)
387
- rated_speed_cc_cop = rated_cc_eer.to_f / 3.412
388
- new_cooling_coil_data_4 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
389
- new_cooling_coil_data_4.setGrossRatedCoolingCOP(rated_speed_cc_cop.to_f)
390
- new_cooling_coil.setFuelType('Electricity')
391
- new_cooling_coil.addStage(new_cooling_coil_data_1)
392
- new_cooling_coil.addStage(new_cooling_coil_data_2)
393
- new_cooling_coil.addStage(new_cooling_coil_data_3)
394
- new_cooling_coil.addStage(new_cooling_coil_data_4)
395
- air_loop_hvac_unitary_system.setCoolingCoil(new_cooling_coil)
396
- end
397
-
398
- # Remove the existing cooling coil.
399
- existing_cooling_coil.remove
356
+ next unless supply_comp.to_CoilCoolingDXTwoSpeed.is_initialized
357
+
358
+ existing_cooling_coil = supply_comp.to_CoilCoolingDXTwoSpeed.get
359
+
360
+ # Add a new cooling coil object
361
+ if cooling_coil_type == 'Two-Stage Compressor'
362
+ new_cooling_coil = OpenStudio::Model::CoilCoolingDXMultiSpeed.new(model)
363
+ half_speed_cc_cop = half_cc_eer.to_f / 3.412
364
+ new_cooling_coil_data_1 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
365
+ new_cooling_coil_data_1.setGrossRatedCoolingCOP(half_speed_cc_cop.to_f)
366
+ rated_speed_cc_cop = rated_cc_eer.to_f / 3.412
367
+ new_cooling_coil_data_2 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
368
+ new_cooling_coil_data_2.setGrossRatedCoolingCOP(rated_speed_cc_cop.to_f)
369
+ new_cooling_coil.setFuelType('Electricity')
370
+ new_cooling_coil.addStage(new_cooling_coil_data_1)
371
+ new_cooling_coil.addStage(new_cooling_coil_data_2)
372
+ air_loop_hvac_unitary_system.setCoolingCoil(new_cooling_coil)
373
+ elsif cooling_coil_type == 'Four-Stage Compressor'
374
+ new_cooling_coil = OpenStudio::Model::CoilCoolingDXMultiSpeed.new(model)
375
+ quarter_speed_cc_cop = quarter_cc_eer.to_f / 3.412
376
+ new_cooling_coil_data_1 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
377
+ new_cooling_coil_data_1.setGrossRatedCoolingCOP(quarter_speed_cc_cop.to_f)
378
+ half_speed_cc_cop = half_cc_eer.to_f / 3.412
379
+ new_cooling_coil_data_2 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
380
+ new_cooling_coil_data_2.setGrossRatedCoolingCOP(half_speed_cc_cop.to_f)
381
+ three_quarter_speed_cc_cop = three_quarter_cc_eer.to_f / 3.412
382
+ new_cooling_coil_data_3 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
383
+ new_cooling_coil_data_3.setGrossRatedCoolingCOP(three_quarter_speed_cc_cop.to_f)
384
+ rated_speed_cc_cop = rated_cc_eer.to_f / 3.412
385
+ new_cooling_coil_data_4 = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
386
+ new_cooling_coil_data_4.setGrossRatedCoolingCOP(rated_speed_cc_cop.to_f)
387
+ new_cooling_coil.setFuelType('Electricity')
388
+ new_cooling_coil.addStage(new_cooling_coil_data_1)
389
+ new_cooling_coil.addStage(new_cooling_coil_data_2)
390
+ new_cooling_coil.addStage(new_cooling_coil_data_3)
391
+ new_cooling_coil.addStage(new_cooling_coil_data_4)
392
+ air_loop_hvac_unitary_system.setCoolingCoil(new_cooling_coil)
400
393
  end
394
+
395
+ # Remove the existing cooling coil.
396
+ existing_cooling_coil.remove
401
397
  end # next supply component
402
398
 
403
399
  # Move the heating coil to the AirLoopHVAC:UnitarySystem object
404
400
  air_loop.supplyComponents.each do |supply_comp|
405
- if supply_comp.to_CoilHeatingGas.is_initialized
406
-
407
- existing_heating_coil = supply_comp.to_CoilHeatingGas.get
408
-
409
- # Remove the existing heating coil.
410
- existing_heating_coil.remove
411
-
412
- # Add a new heating coil object
413
- if heating_coil_type == 'Gas Heating Coil'
414
- new_heating_coil = OpenStudio::Model::CoilHeatingGas.new(model)
415
- new_heating_coil.setGasBurnerEfficiency(rated_hc_gas_efficiency.to_f)
416
- air_loop_hvac_unitary_system.setHeatingCoil(new_heating_coil)
417
-
418
- elsif heating_coil_type == 'Heat Pump' && cooling_coil_type == 'Two-Stage Compressor'
419
- new_heating_coil = OpenStudio::Model::CoilHeatingDXMultiSpeed.new(model)
420
- new_heating_coil_data_1 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
421
- new_heating_coil_data_1.setGrossRatedHeatingCOP(half_hc_cop.to_f)
422
- new_heating_coil_data_2 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
423
- new_heating_coil_data_2.setGrossRatedHeatingCOP(rated_hc_cop.to_f)
424
- new_heating_coil.setFuelType('Electricity')
425
- new_heating_coil.addStage(new_heating_coil_data_1)
426
- new_heating_coil.addStage(new_heating_coil_data_2)
427
- air_loop_hvac_unitary_system.setHeatingCoil(new_heating_coil)
428
- elsif heating_coil_type == 'Heat Pump' && cooling_coil_type == 'Four-Stage Compressor'
429
- new_heating_coil = OpenStudio::Model::CoilHeatingDXMultiSpeed.new(model)
430
- new_heating_coil_data_1 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
431
- new_heating_coil_data_1.setGrossRatedHeatingCOP(quarter_hc_cop.to_f)
432
- new_heating_coil_data_2 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
433
- new_heating_coil_data_2.setGrossRatedHeatingCOP(half_hc_cop.to_f)
434
- new_heating_coil_data_3 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
435
- new_heating_coil_data_3.setGrossRatedHeatingCOP(three_quarter_hc_cop.to_f)
436
- new_heating_coil_data_4 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
437
- new_heating_coil_data_4.setGrossRatedHeatingCOP(rated_hc_cop.to_f)
438
- new_heating_coil.setFuelType('Electricity')
439
- new_heating_coil.addStage(new_heating_coil_data_1)
440
- new_heating_coil.addStage(new_heating_coil_data_2)
441
- new_heating_coil.addStage(new_heating_coil_data_3)
442
- new_heating_coil.addStage(new_heating_coil_data_4)
443
- air_loop_hvac_unitary_system.setHeatingCoil(new_heating_coil)
444
- end
401
+ next unless supply_comp.to_CoilHeatingGas.is_initialized
402
+
403
+ existing_heating_coil = supply_comp.to_CoilHeatingGas.get
404
+
405
+ # Remove the existing heating coil.
406
+ existing_heating_coil.remove
407
+
408
+ # Add a new heating coil object
409
+ if heating_coil_type == 'Gas Heating Coil'
410
+ new_heating_coil = OpenStudio::Model::CoilHeatingGas.new(model)
411
+ new_heating_coil.setGasBurnerEfficiency(rated_hc_gas_efficiency.to_f)
412
+ air_loop_hvac_unitary_system.setHeatingCoil(new_heating_coil)
413
+
414
+ elsif heating_coil_type == 'Heat Pump' && cooling_coil_type == 'Two-Stage Compressor'
415
+ new_heating_coil = OpenStudio::Model::CoilHeatingDXMultiSpeed.new(model)
416
+ new_heating_coil_data_1 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
417
+ new_heating_coil_data_1.setGrossRatedHeatingCOP(half_hc_cop.to_f)
418
+ new_heating_coil_data_2 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
419
+ new_heating_coil_data_2.setGrossRatedHeatingCOP(rated_hc_cop.to_f)
420
+ new_heating_coil.setFuelType('Electricity')
421
+ new_heating_coil.addStage(new_heating_coil_data_1)
422
+ new_heating_coil.addStage(new_heating_coil_data_2)
423
+ air_loop_hvac_unitary_system.setHeatingCoil(new_heating_coil)
424
+ elsif heating_coil_type == 'Heat Pump' && cooling_coil_type == 'Four-Stage Compressor'
425
+ new_heating_coil = OpenStudio::Model::CoilHeatingDXMultiSpeed.new(model)
426
+ new_heating_coil_data_1 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
427
+ new_heating_coil_data_1.setGrossRatedHeatingCOP(quarter_hc_cop.to_f)
428
+ new_heating_coil_data_2 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
429
+ new_heating_coil_data_2.setGrossRatedHeatingCOP(half_hc_cop.to_f)
430
+ new_heating_coil_data_3 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
431
+ new_heating_coil_data_3.setGrossRatedHeatingCOP(three_quarter_hc_cop.to_f)
432
+ new_heating_coil_data_4 = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model)
433
+ new_heating_coil_data_4.setGrossRatedHeatingCOP(rated_hc_cop.to_f)
434
+ new_heating_coil.setFuelType('Electricity')
435
+ new_heating_coil.addStage(new_heating_coil_data_1)
436
+ new_heating_coil.addStage(new_heating_coil_data_2)
437
+ new_heating_coil.addStage(new_heating_coil_data_3)
438
+ new_heating_coil.addStage(new_heating_coil_data_4)
439
+ air_loop_hvac_unitary_system.setHeatingCoil(new_heating_coil)
445
440
  end
446
441
  end # next supply component
447
442
 
@@ -449,38 +444,35 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
449
444
  airloop_outlet_node = air_loop.supplyOutletNode
450
445
 
451
446
  # Identify if there is a setpoint manager on the AirLoop outlet node
452
- if !airloop_outlet_node.setpointManagers.empty?
447
+ if airloop_outlet_node.setpointManagers.empty?
448
+ runner.registerInfo("No setpoint manager on node '#{airloop_outlet_node.name}'.")
449
+ else
453
450
  setpoint_manager = airloop_outlet_node.setpointManagers[0]
454
451
  # runner.registerInfo("Setpoint manager on node '#{airloop_outlet_node.name}' is '#{setpoint_manager.name}'.")
455
- else
456
- runner.registerInfo("No setpoint manager on node '#{airloop_outlet_node.name}'.")
457
452
  end
458
453
 
459
454
  # Set the controlling zone location to the zone on the airloop
460
455
  air_loop.demandComponents.each do |demand_comp|
461
- if demand_comp.to_AirTerminalSingleDuctUncontrolled.is_initialized
462
-
463
- terminal_obj = demand_comp.to_AirTerminalSingleDuctUncontrolled.get
464
-
465
- # Record the zone that the terminal unit is in.
466
- # If zone cannot be determined, skip to next demand component
467
- # and warn user that this the associated zone could not be found
468
- term_zone = nil
469
- model.getThermalZones.each do |zone|
470
- zone.equipment.each do |equip|
471
- if equip == terminal_obj
472
- term_zone = zone
473
- end
474
- end
475
- end
476
- if term_zone.nil?
477
- runner.registerWarning("Could not determine the zone for terminal '#{new_vav_terminal.name}', cannot assign to AirLoopHVAC:UnitarySystem object.")
478
- next
479
- else
480
- # Associate the zone with the AirLoopHVAC:UnitarySystem object
481
- air_loop_hvac_unitary_system.setControllingZoneorThermostatLocation(term_zone)
456
+ next unless demand_comp.to_AirTerminalSingleDuctUncontrolled.is_initialized
457
+
458
+ terminal_obj = demand_comp.to_AirTerminalSingleDuctUncontrolled.get
459
+
460
+ # Record the zone that the terminal unit is in.
461
+ # If zone cannot be determined, skip to next demand component
462
+ # and warn user that this the associated zone could not be found
463
+ term_zone = nil
464
+ model.getThermalZones.each do |zone|
465
+ zone.equipment.each do |equip|
466
+ term_zone = zone if equip == terminal_obj
482
467
  end
483
468
  end
469
+ if term_zone.nil?
470
+ runner.registerWarning("Could not determine the zone for terminal '#{new_vav_terminal.name}', cannot assign to AirLoopHVAC:UnitarySystem object.")
471
+ next
472
+ else
473
+ # Associate the zone with the AirLoopHVAC:UnitarySystem object
474
+ air_loop_hvac_unitary_system.setControllingZoneorThermostatLocation(term_zone)
475
+ end
484
476
  end
485
477
  end # Next selected airloop
486
478
 
@@ -503,7 +495,7 @@ class CreateVariableSpeedRTU < OpenStudio::Measure::ModelMeasure
503
495
  runner.registerAsNotApplicable('This measure is not applicable; no variable speed RTUs were added.')
504
496
  end
505
497
 
506
- return true
498
+ true
507
499
  end # end the run method
508
500
  end # end the measure
509
501
 
@@ -3,8 +3,8 @@
3
3
  <schema_version>3.1</schema_version>
4
4
  <name>create_variable_speed_rtu</name>
5
5
  <uid>7fb36b3a-5591-4627-a2b0-7709fbeae593</uid>
6
- <version_id>63704b85-41cc-4370-b58c-2541b041d4cc</version_id>
7
- <version_modified>2025-08-08T15:15:56Z</version_modified>
6
+ <version_id>e5c92bb5-8adf-4393-a5ba-8f0158973e21</version_id>
7
+ <version_modified>2025-09-25T15:33:42Z</version_modified>
8
8
  <xml_checksum>A9D5932A</xml_checksum>
9
9
  <class_name>CreateVariableSpeedRTU</class_name>
10
10
  <display_name>Create Variable Speed RTU</display_name>
@@ -17,10 +17,10 @@
17
17
  <type>Choice</type>
18
18
  <required>true</required>
19
19
  <model_dependent>false</model_dependent>
20
- <default_value>{2353cde4-420e-4711-bd87-4590e254461b}</default_value>
20
+ <default_value>{3853fbf5-025b-4518-b87e-14435a5babf0}</default_value>
21
21
  <choices>
22
22
  <choice>
23
- <value>{2353cde4-420e-4711-bd87-4590e254461b}</value>
23
+ <value>{3853fbf5-025b-4518-b87e-14435a5babf0}</value>
24
24
  <display_name>*All CAV Air Loops*</display_name>
25
25
  </choice>
26
26
  </choices>
@@ -190,13 +190,13 @@
190
190
  <filename>measure.rb</filename>
191
191
  <filetype>rb</filetype>
192
192
  <usage_type>script</usage_type>
193
- <checksum>D38F0FFA</checksum>
193
+ <checksum>922C9F5A</checksum>
194
194
  </file>
195
195
  <file>
196
196
  <filename>create_variable_speed_rtu_test.rb</filename>
197
197
  <filetype>rb</filetype>
198
198
  <usage_type>test</usage_type>
199
- <checksum>9278314B</checksum>
199
+ <checksum>F8AFEE47</checksum>
200
200
  </file>
201
201
  <file>
202
202
  <filename>example_model.osm</filename>