openstudio-standards 0.2.16 → 0.2.17.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/standards/manage_OpenStudio_Standards.rb +31 -4
- data/lib/openstudio-standards/btap/geometry.rb +1 -1
- data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +354 -2
- data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +79 -0
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +3313 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +12 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +3 -4
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +167 -93
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +2 -4
- data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +1 -0
- data/lib/openstudio-standards/refs/references.rb +3 -0
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +279 -6
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +50 -2
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +4 -0
- data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +185 -3
- data/lib/openstudio-standards/standards/Standards.Fan.rb +14 -6
- data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +1 -0
- data/lib/openstudio-standards/standards/Standards.Model.rb +1751 -383
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +130 -9
- data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +50 -3
- data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +44 -0
- data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +27 -0
- data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +543 -0
- data/lib/openstudio-standards/standards/Standards.Space.rb +665 -15
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +141 -4
- data/lib/openstudio-standards/standards/Standards.SubSurface.rb +2 -1
- data/lib/openstudio-standards/standards/Standards.Surface.rb +117 -0
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +197 -49
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +41 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +6 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/comstock_ashrae_90_1_2004.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.spc_typ.json +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.spc_typ.json +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/comstock_ashrae_90_1_2016.spc_typ.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/comstock_ashrae_90_1_2019.spc_typ.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +12 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.spc_typ.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.spc_typ.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +792 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +10 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +91 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +84 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +145 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +106 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +71 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +194 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +120 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +110 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Fan.rb +73 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +55 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +3045 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +187 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +450 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +106 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +666 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +54 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +168 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +132 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +239 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +176 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +25 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +52 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.chillers.json +112 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.climate_zone_sets.json +210 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +10384 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_sets.json +133 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.furnaces.json +43 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps.json +119 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps_heating.json +130 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +13 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.lpd_space_type.json +568 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.motors.json +264 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_baseline_hvac.json +439 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_constructions.json +685 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_economizers.json +213 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_ext_ltg.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_heat_type.json +136 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_hvac_bldg_type.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_interior_lighting.json +1837 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_swh_bldg_type.json +184 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_wwr_bldg_type.json +84 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.unitary_acs.json +148 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.water_heaters.json +157 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.climate_zone_sets.json +210 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +18329 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +340 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.materials.json +49924 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_building_rotation_exception.md +44 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/check_pump_power_and_control.md +71 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv.md +68 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv_implementation.png +0 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/elevators.md +14 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/exhaust_air_energy_recovery.md +36 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/f_c_factors.md +19 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/fan_power_credits.md +15 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/preheat_coil.md +59 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/pump_power_control.md +46 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/return_air_type.md +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_baseline_wwr.md +191 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_hw_and_chw_supply_water_temp_reset_control.md +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_num_boilers_chillers_towers.md +49 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +80 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_space_lpd.md +73 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unenclosed_and_unconditioned_spaces.md +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unmet_load_hours.md +20 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_parallel_piu_terminals_fan_control.md +23 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_terminals_min_flow_setpoint.md +21 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac_doas.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_building.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_design_specification_outdoor_air.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_electric_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_exterior_lights.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_gas_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_lights.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_spacetype.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_thermal_zone.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_connections.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment_definition.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_hvac.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_infiltration.csv +1 -0
- data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +12 -0
- data/lib/openstudio-standards/standards/deer/data/deer.fans.json +12 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps.json +1 -1
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps_heating.json +1 -1
- data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +24 -11
- data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +13 -15
- data/lib/openstudio-standards/standards/necb/NECB2011/data/province_map.json +17 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +6 -5
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +3 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +2 -3
- data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +33 -924
- data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +15 -15
- data/lib/openstudio-standards/standards/necb/common/btap_data.rb +135 -29
- data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +16 -4
- data/lib/openstudio-standards/standards/necb/common/neb_end_use_prices.csv +40 -42
- data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +1 -1
- data/lib/openstudio-standards/standards/necb/common/space_type_upgrade_map.json +89 -89
- data/lib/openstudio-standards/utilities/array.rb +11 -0
- data/lib/openstudio-standards/utilities/logging.rb +48 -0
- data/lib/openstudio-standards/utilities/object_info.rb +20 -0
- data/lib/openstudio-standards/utilities/schedule_translator.rb +348 -0
- data/lib/openstudio-standards/utilities/sqlfile.rb +68 -0
- data/lib/openstudio-standards/version.rb +2 -2
- data/lib/openstudio-standards/weather/Weather.Model.rb +42 -55
- data/lib/openstudio-standards/weather/Weather.stat_file.rb +1 -1
- data/lib/openstudio-standards.rb +35 -1
- metadata +111 -6
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1_28_Jan2022_2.xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +0 -143
@@ -0,0 +1,792 @@
|
|
1
|
+
class ASHRAE901PRM < Standard
|
2
|
+
# @!group AirLoopHVAC
|
3
|
+
|
4
|
+
# Shut off the system during unoccupied periods.
|
5
|
+
# During these times, systems will cycle on briefly if temperature drifts below setpoint.
|
6
|
+
# If the system already has a schedule other than Always-On, no change will be made.
|
7
|
+
# If the system has an Always-On schedule assigned, a new schedule will be created.
|
8
|
+
# In this case, occupied is defined as the total percent occupancy for the loop for all zones served.
|
9
|
+
# For stable baseline, schedule is Always-On for computer rooms and when health and safety exception is used
|
10
|
+
#
|
11
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
12
|
+
# @param min_occ_pct [Double] the fractional value below which the system will be considered unoccupied.
|
13
|
+
# @return [Bool] returns true if successful, false if not
|
14
|
+
def air_loop_hvac_enable_unoccupied_fan_shutoff(air_loop_hvac, min_occ_pct = 0.05)
|
15
|
+
if air_loop_hvac.additionalProperties.hasFeature('zone_group_type')
|
16
|
+
zone_group_type = air_loop_hvac.additionalProperties.getFeatureAsString('zone_group_type').get
|
17
|
+
else
|
18
|
+
zone_group_type = 'None'
|
19
|
+
end
|
20
|
+
|
21
|
+
if zone_group_type == 'computer_zones'
|
22
|
+
# Computer rooms are exempt from night cycle control
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
|
26
|
+
# Check for user data exceptions for night cycling
|
27
|
+
# If any zone has the exception, then system will not cycle
|
28
|
+
health_safety_exception = false
|
29
|
+
air_loop_hvac.thermalZones.each do |thermal_zone|
|
30
|
+
if thermal_zone.additionalProperties.hasFeature('has_health_safety_night_cycle_exception')
|
31
|
+
exception = thermal_zone.additionalProperties.getFeatureAsBoolean('has_health_safety_night_cycle_exception').get
|
32
|
+
return false if exception == true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set the system to night cycle
|
37
|
+
# The fan of a parallel PIU terminal are set to only cycle during heating operation
|
38
|
+
# This is achieved using the CycleOnAnyCoolingOrHeatingZone; During cooling operation
|
39
|
+
# the load is met by running the central system which stays off during heating
|
40
|
+
# operation
|
41
|
+
air_loop_hvac.setNightCycleControlType('CycleOnAny')
|
42
|
+
if air_loop_hvac_has_parallel_piu_air_terminals?(air_loop_hvac)
|
43
|
+
avail_mgrs = air_loop_hvac.availabilityManagers
|
44
|
+
if !avail_mgrs.nil?
|
45
|
+
avail_mgrs.each do |avail_mgr|
|
46
|
+
if avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
|
47
|
+
avail_mgr_nc = avail_mgr.to_AvailabilityManagerNightCycle.get
|
48
|
+
avail_mgr_nc.setControlType('CycleOnAnyCoolingOrHeatingZone')
|
49
|
+
zones = air_loop_hvac.thermalZones
|
50
|
+
avail_mgr_nc.setCoolingControlThermalZones(zones)
|
51
|
+
avail_mgr_nc.setHeatingZoneFansOnlyThermalZones(zones)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
model = air_loop_hvac.model
|
58
|
+
# Check if schedule was stored in an additionalProperties field of the air loop
|
59
|
+
air_loop_name = air_loop_hvac.name
|
60
|
+
if air_loop_hvac.hasAdditionalProperties
|
61
|
+
if air_loop_hvac.additionalProperties.hasFeature('fan_sched_name')
|
62
|
+
fan_sched_name = air_loop_hvac.additionalProperties.getFeatureAsString('fan_sched_name').get
|
63
|
+
fan_sched = model.getScheduleRulesetByName(fan_sched_name).get
|
64
|
+
air_loop_hvac.setAvailabilitySchedule(fan_sched)
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Check if already using a schedule other than always on
|
70
|
+
avail_sch = air_loop_hvac.availabilitySchedule
|
71
|
+
unless avail_sch == air_loop_hvac.model.alwaysOnDiscreteSchedule
|
72
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Availability schedule is already set to #{avail_sch.name}. Will assume this includes unoccupied shut down; no changes will be made.")
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get the airloop occupancy schedule
|
77
|
+
loop_occ_sch = air_loop_hvac_get_occupancy_schedule(air_loop_hvac, occupied_percentage_threshold: min_occ_pct)
|
78
|
+
flh = schedule_ruleset_annual_equivalent_full_load_hrs(loop_occ_sch)
|
79
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Annual occupied hours = #{flh.round} hr/yr, assuming a #{min_occ_pct} occupancy threshold. This schedule will be used as the HVAC operation schedule.")
|
80
|
+
|
81
|
+
# Set HVAC availability schedule to follow occupancy
|
82
|
+
air_loop_hvac.setAvailabilitySchedule(loop_occ_sch)
|
83
|
+
air_loop_hvac.supplyComponents.each do |comp|
|
84
|
+
if comp.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.is_initialized
|
85
|
+
comp.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.get.setSupplyAirFanOperatingModeSchedule(loop_occ_sch)
|
86
|
+
elsif comp.to_AirLoopHVACUnitarySystem.is_initialized
|
87
|
+
comp.to_AirLoopHVACUnitarySystem.get.setSupplyAirFanOperatingModeSchedule(loop_occ_sch)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
return true
|
92
|
+
end
|
93
|
+
|
94
|
+
# Determine if the system is a multizone VAV system
|
95
|
+
#
|
96
|
+
# @return [Bool] Returns true if required, false if not.
|
97
|
+
def air_loop_hvac_multizone_vav_system?(air_loop_hvac)
|
98
|
+
return true if air_loop_hvac.name.to_s.include?('Sys5') || air_loop_hvac.name.to_s.include?('Sys6') || air_loop_hvac.name.to_s.include?('Sys7') || air_loop_hvac.name.to_s.include?('Sys8')
|
99
|
+
|
100
|
+
return false
|
101
|
+
end
|
102
|
+
|
103
|
+
# Determine if multizone vav optimization is required.
|
104
|
+
# Not required for stable baseline.
|
105
|
+
#
|
106
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
107
|
+
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
108
|
+
# @return [Bool] returns true if required, false if not
|
109
|
+
def air_loop_hvac_multizone_vav_optimization_required?(air_loop_hvac, climate_zone)
|
110
|
+
multizone_opt_required = false
|
111
|
+
return multizone_opt_required
|
112
|
+
end
|
113
|
+
|
114
|
+
# Determine whether the VAV damper control is single maximum or dual maximum control.
|
115
|
+
# Defaults to Single Maximum for stable baseline.
|
116
|
+
#
|
117
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
118
|
+
# @return [String] the damper control type: Single Maximum, Dual Maximum
|
119
|
+
def air_loop_hvac_vav_damper_action(air_loop_hvac)
|
120
|
+
damper_action = 'Single Maximum'
|
121
|
+
return damper_action
|
122
|
+
end
|
123
|
+
|
124
|
+
# Default occupancy fraction threshold for determining if the spaces on the air loop are occupied
|
125
|
+
def air_loop_hvac_unoccupied_threshold
|
126
|
+
# Use 10% based on PRM-RM
|
127
|
+
return 0.10
|
128
|
+
end
|
129
|
+
|
130
|
+
# Determine if the system economizer must be integrated or not.
|
131
|
+
# Always required for stable baseline if there is an economizer
|
132
|
+
#
|
133
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
134
|
+
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
135
|
+
# @return [Bool] returns true if required, false if not
|
136
|
+
def air_loop_hvac_integrated_economizer_required?(air_loop_hvac, climate_zone)
|
137
|
+
return true
|
138
|
+
end
|
139
|
+
|
140
|
+
# Determine the economizer type and limits for the the PRM
|
141
|
+
# Defaults to 90.1-2007 logic.
|
142
|
+
#
|
143
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
144
|
+
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
145
|
+
# @return [Array<Double>] [economizer_type, drybulb_limit_f, enthalpy_limit_btu_per_lb, dewpoint_limit_f]
|
146
|
+
def air_loop_hvac_prm_economizer_type_and_limits(air_loop_hvac, climate_zone)
|
147
|
+
economizer_type = 'NoEconomizer'
|
148
|
+
drybulb_limit_f = nil
|
149
|
+
enthalpy_limit_btu_per_lb = nil
|
150
|
+
dewpoint_limit_f = nil
|
151
|
+
climate_zone_code = climate_zone.split('-')[-1]
|
152
|
+
|
153
|
+
if ['0B', '1B', '2B', '3B', '3C', '4B', '4C', '5B', '5C', '6B', '7A', '7B', '8A', '8B'].include? climate_zone_code
|
154
|
+
economizer_type = 'FixedDryBulb'
|
155
|
+
drybulb_limit_f = 75
|
156
|
+
elsif ['5A', '6A'].include? climate_zone_code
|
157
|
+
economizer_type = 'FixedDryBulb'
|
158
|
+
drybulb_limit_f = 70
|
159
|
+
end
|
160
|
+
|
161
|
+
return [economizer_type, drybulb_limit_f, enthalpy_limit_btu_per_lb, dewpoint_limit_f]
|
162
|
+
end
|
163
|
+
|
164
|
+
# Determine if an economizer is required per the PRM.
|
165
|
+
#
|
166
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
167
|
+
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
168
|
+
# @return [Bool] returns true if required, false if not
|
169
|
+
def air_loop_hvac_prm_baseline_economizer_required?(air_loop_hvac, climate_zone)
|
170
|
+
economizer_required = false
|
171
|
+
baseline_system_type = air_loop_hvac.additionalProperties.getFeatureAsString('baseline_system_type').get
|
172
|
+
climate_zone_code = climate_zone.split('-')[-1]
|
173
|
+
# System type 3 through 8 and 11, 12 and 13
|
174
|
+
if ['SZ_AC', 'PSZ_AC', 'PVAV_Reheat', 'VAV_Reheat', 'SZ_VAV', 'PSZ_HP', 'SZ_CV', 'PSZ_HP', 'PVAV_PFP_Boxes', 'VAV_PFP_Boxes'].include? baseline_system_type
|
175
|
+
unless ['0A', '0B', '1A', '1B', '2A', '3A', '4A'].include? climate_zone_code
|
176
|
+
economizer_required = true
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# System type 3 and 4 in computer rooms are subject to exceptions
|
181
|
+
if baseline_system_type == 'PSZ_AC' || baseline_system_type == 'PSZ_HP'
|
182
|
+
if air_loop_hvac.additionalProperties.hasFeature('zone_group_type')
|
183
|
+
if air_loop_hvac.additionalProperties.getFeatureAsString('zone_group_type').get == 'computer_zones'
|
184
|
+
economizer_required = false
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Check user_data in the zones
|
190
|
+
gas_phase_exception = false
|
191
|
+
open_refrigeration_exception = false
|
192
|
+
air_loop_hvac.thermalZones.each do |thermal_zone|
|
193
|
+
if thermal_zone.additionalProperties.hasFeature('economizer_exception_for_gas_phase_air_cleaning')
|
194
|
+
gas_phase_exception = true
|
195
|
+
end
|
196
|
+
if thermal_zone.additionalProperties.hasFeature('economizer_exception_for_open_refrigerated_cases')
|
197
|
+
open_refrigeration_exception = true
|
198
|
+
end
|
199
|
+
end
|
200
|
+
if gas_phase_exception || open_refrigeration_exception
|
201
|
+
economizer_required = false
|
202
|
+
end
|
203
|
+
return economizer_required
|
204
|
+
end
|
205
|
+
|
206
|
+
# Set fan curve for stable baseline to be VSD with fixed static pressure setpoint
|
207
|
+
# @return [string] name of appropriate curve for this code version
|
208
|
+
def air_loop_hvac_set_vsd_curve_type
|
209
|
+
return 'Multi Zone VAV with VSD and Fixed SP Setpoint'
|
210
|
+
end
|
211
|
+
|
212
|
+
# Calculate and apply the performance rating method
|
213
|
+
# baseline fan power to this air loop based on the
|
214
|
+
# system type that it represents.
|
215
|
+
#
|
216
|
+
# Fan motor efficiency will be set, and then
|
217
|
+
# fan pressure rise adjusted so that the
|
218
|
+
# fan power is the maximum allowable.
|
219
|
+
#
|
220
|
+
# Also adjusts the fan power and flow rates
|
221
|
+
# of any parallel PIU terminals on the system.
|
222
|
+
#
|
223
|
+
# return [Bool] true if successful, false if not.
|
224
|
+
def air_loop_hvac_apply_prm_baseline_fan_power(air_loop_hvac)
|
225
|
+
# Get system type associated with air loop
|
226
|
+
system_type = air_loop_hvac.additionalProperties.getFeatureAsString('baseline_system_type').get
|
227
|
+
|
228
|
+
# Find out if air loop represents a non mechanically cooled system
|
229
|
+
is_nmc = false
|
230
|
+
is_nmc = true if air_loop_hvac.additionalProperties.hasFeature('non_mechanically_cooled')
|
231
|
+
|
232
|
+
# Get all air loop fans
|
233
|
+
all_fans = air_loop_hvac_supply_return_exhaust_relief_fans(air_loop_hvac)
|
234
|
+
|
235
|
+
allowable_fan_bhp = 0.0
|
236
|
+
allowable_power_w = 0.0
|
237
|
+
fan_efficacy_w_per_cfm = 0.0
|
238
|
+
supply_fan_power_fraction = 0.0
|
239
|
+
return_fan_power_fraction = 0.0
|
240
|
+
relief_fan_power_fraction = 0.0
|
241
|
+
if system_type == 'PSZ_AC' ||
|
242
|
+
system_type == 'PSZ_HP' ||
|
243
|
+
system_type == 'PVAV_Reheat' ||
|
244
|
+
system_type == 'PVAV_PFP_Boxes' ||
|
245
|
+
system_type == 'VAV_Reheat' ||
|
246
|
+
system_type == 'VAV_PFP_Boxes' ||
|
247
|
+
system_type == 'SZ_VAV' ||
|
248
|
+
system_type == 'SZ_CV'
|
249
|
+
|
250
|
+
# Calculate the allowable fan motor bhp for the air loop
|
251
|
+
allowable_fan_bhp = air_loop_hvac_allowable_system_brake_horsepower(air_loop_hvac)
|
252
|
+
|
253
|
+
# Divide the allowable power based
|
254
|
+
# individual zone air flow
|
255
|
+
air_loop_total_zone_design_airflow = 0
|
256
|
+
air_loop_hvac.thermalZones.sort.each do |zone|
|
257
|
+
zone_air_flow = zone.designAirFlowRate.to_f
|
258
|
+
air_loop_total_zone_design_airflow += zone_air_flow
|
259
|
+
# Fractions variables are actually power at that point
|
260
|
+
supply_fan_power_fraction += zone_air_flow * zone.additionalProperties.getFeatureAsDouble('supply_fan_w').get
|
261
|
+
return_fan_power_fraction += zone_air_flow * zone.additionalProperties.getFeatureAsDouble('return_fan_w').get
|
262
|
+
relief_fan_power_fraction += zone_air_flow * zone.additionalProperties.getFeatureAsDouble('relief_fan_w').get
|
263
|
+
end
|
264
|
+
if air_loop_total_zone_design_airflow > 0
|
265
|
+
# Get average power for each category of fan
|
266
|
+
supply_fan_power_fraction /= air_loop_total_zone_design_airflow
|
267
|
+
return_fan_power_fraction /= air_loop_total_zone_design_airflow
|
268
|
+
relief_fan_power_fraction /= air_loop_total_zone_design_airflow
|
269
|
+
# Convert to power fraction
|
270
|
+
total_fan_avg_fan_w = (supply_fan_power_fraction + return_fan_power_fraction + relief_fan_power_fraction)
|
271
|
+
supply_fan_power_fraction /= total_fan_avg_fan_w
|
272
|
+
return_fan_power_fraction /= total_fan_avg_fan_w
|
273
|
+
relief_fan_power_fraction /= total_fan_avg_fan_w
|
274
|
+
else
|
275
|
+
Openstudio.logFree(OpenStudio::Error, "Total zone design airflow for #{air_loop_hvac.name} is 0.")
|
276
|
+
end
|
277
|
+
elsif system_type == 'PTAC' ||
|
278
|
+
system_type == 'PTHP' ||
|
279
|
+
system_type == 'Gas_Furnace' ||
|
280
|
+
system_type == 'Electric_Furnace'
|
281
|
+
|
282
|
+
# Determine allowable fan power
|
283
|
+
if !is_nmc
|
284
|
+
fan_efficacy_w_per_cfm = 0.3
|
285
|
+
else # is_nmc
|
286
|
+
fan_efficacy_w_per_cfm = 0.054
|
287
|
+
end
|
288
|
+
|
289
|
+
# Configuration is supply fan only
|
290
|
+
supply_fan_power_fraction = 1.0
|
291
|
+
end
|
292
|
+
|
293
|
+
supply_fan = air_loop_hvac_get_supply_fan(air_loop_hvac)
|
294
|
+
if supply_fan.nil?
|
295
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.ashrae_90_1_prm.AirLoopHVAC', "Supply not found on #{airloop.name}.")
|
296
|
+
end
|
297
|
+
supply_fan_max_flow = if supply_fan.autosizedMaximumFlowRate.is_initialized
|
298
|
+
supply_fan.autosizedMaximumFlowRate.get
|
299
|
+
else
|
300
|
+
supply_fan.maximumFlowRate.get
|
301
|
+
end
|
302
|
+
|
303
|
+
# Check that baseline system has the same
|
304
|
+
# types of fans as the proposed model, if
|
305
|
+
# not, create them. We assume that the
|
306
|
+
# system has at least a supply fan.
|
307
|
+
if return_fan_power_fraction > 0.0 && !air_loop_hvac.returnFan.is_initialized
|
308
|
+
# Create return fan
|
309
|
+
return_fan = supply_fan.clone(air_loop_hvac.model)
|
310
|
+
if return_fan.to_FanConstantVolume.is_initialized
|
311
|
+
return_fan = return_fan.to_FanConstantVolume.get
|
312
|
+
elsif return_fan.to_FanVariableVolume.is_initialized
|
313
|
+
return_fan = return_fan.to_FanVariableVolume.get
|
314
|
+
elsif return_fan.to_FanOnOff.is_initialized
|
315
|
+
return_fan = return_fan.to_FanOnOff.get
|
316
|
+
elsif return_fan.to_FanSystemModel.is_initialized
|
317
|
+
return_fan = return_fan.to_FanSystemModel.get
|
318
|
+
end
|
319
|
+
return_fan.setName("#{air_loop_hvac.name} Return Fan")
|
320
|
+
return_fan.addToNode(air_loop_hvac.returnAirNode.get)
|
321
|
+
return_fan.setMaximumFlowRate(supply_fan_max_flow)
|
322
|
+
end
|
323
|
+
if relief_fan_power_fraction > 0.0 && !air_loop_hvac.reliefFan.is_initialized
|
324
|
+
# Create return fan
|
325
|
+
relief_fan = supply_fan.clone(air_loop_hvac.model)
|
326
|
+
if relief_fan.to_FanConstantVolume.is_initialized
|
327
|
+
relief_fan = relief_fan.to_FanConstantVolume.get
|
328
|
+
elsif relief_fan.to_FanVariableVolume.is_initialized
|
329
|
+
relief_fan = relief_fan.to_FanVariableVolume.get
|
330
|
+
elsif relief_fan.to_FanOnOff.is_initialized
|
331
|
+
relief_fan = relief_fan.to_FanOnOff.get
|
332
|
+
elsif relief_fan.to_FanSystemModel.is_initialized
|
333
|
+
relief_fan = relief_fan.to_FanSystemModel.get
|
334
|
+
end
|
335
|
+
relief_fan.setName("#{air_loop_hvac.name} Relief Fan")
|
336
|
+
relief_fan.addToNode(air_loop_hvac.reliefAirNode.get)
|
337
|
+
relief_fan.setMaximumFlowRate(supply_fan_max_flow)
|
338
|
+
end
|
339
|
+
|
340
|
+
# Get all air loop fans
|
341
|
+
all_fans = air_loop_hvac_supply_return_exhaust_relief_fans(air_loop_hvac)
|
342
|
+
|
343
|
+
# Set the motor efficiencies
|
344
|
+
# for all fans based on the calculated
|
345
|
+
# allowed brake hp. Then calculate the allowable
|
346
|
+
# fan power for each fan and adjust
|
347
|
+
# the fan pressure rise accordingly
|
348
|
+
all_fans.each do |fan|
|
349
|
+
# Efficacy requirement
|
350
|
+
if fan_efficacy_w_per_cfm > 0
|
351
|
+
# Convert efficacy to metric
|
352
|
+
fan_efficacy_w_per_m3_per_s = OpenStudio.convert(fan_efficacy_w_per_cfm, 'm^3/s', 'cfm').get
|
353
|
+
fan_change_impeller_efficiency(fan, fan_baseline_impeller_efficiency(fan))
|
354
|
+
|
355
|
+
# Get fan BHP
|
356
|
+
fan_bhp = fan_brake_horsepower(fan)
|
357
|
+
|
358
|
+
# Set the motor efficiency, preserving the impeller efficiency.
|
359
|
+
# For zone HVAC fans, a bhp lookup of 0.5bhp is always used because
|
360
|
+
# they are assumed to represent a series of small fans in reality.
|
361
|
+
fan_apply_standard_minimum_motor_efficiency(fan, fan_bhp)
|
362
|
+
|
363
|
+
# Calculate a new pressure rise to hit the target W/cfm
|
364
|
+
fan_tot_eff = fan.fanEfficiency
|
365
|
+
fan_rise_new_pa = fan_efficacy_w_per_m3_per_s * fan_tot_eff
|
366
|
+
fan.setPressureRise(fan_rise_new_pa)
|
367
|
+
end
|
368
|
+
|
369
|
+
# BHP requirements
|
370
|
+
if allowable_fan_bhp > 0
|
371
|
+
fan_apply_standard_minimum_motor_efficiency(fan, allowable_fan_bhp)
|
372
|
+
allowable_power_w = allowable_fan_bhp * 746 / fan.motorEfficiency
|
373
|
+
|
374
|
+
# Breakdown fan power based on fan type
|
375
|
+
if supply_fan.name.to_s == fan.name.to_s
|
376
|
+
allowable_power_w *= supply_fan_power_fraction
|
377
|
+
elsif fan.airLoopHVAC.is_initialized
|
378
|
+
if fan.airLoopHVAC.get.returnFan.is_initialized
|
379
|
+
if fan.airLoopHVAC.get.returnFan.get.name.to_s == fan.name.to_s
|
380
|
+
allowable_power_w *= return_fan_power_fraction
|
381
|
+
end
|
382
|
+
end
|
383
|
+
if fan.airLoopHVAC.get.reliefFan.is_initialized
|
384
|
+
if fan.airLoopHVAC.get.reliefFan.get.name.to_s == fan.name.to_s
|
385
|
+
allowable_power_w *= relief_fan_power_fraction
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
fan_adjust_pressure_rise_to_meet_fan_power(fan, allowable_power_w)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
return true unless system_type == 'PVAV_PFP_Boxes' || system_type == 'VAV_PFP_Boxes'
|
394
|
+
|
395
|
+
# Adjust fan powered terminal fans power
|
396
|
+
air_loop_hvac.demandComponents.each do |dc|
|
397
|
+
next if dc.to_AirTerminalSingleDuctParallelPIUReheat.empty?
|
398
|
+
|
399
|
+
pfp_term = dc.to_AirTerminalSingleDuctParallelPIUReheat.get
|
400
|
+
air_terminal_single_duct_parallel_piu_reheat_apply_prm_baseline_fan_power(pfp_term)
|
401
|
+
end
|
402
|
+
|
403
|
+
return true
|
404
|
+
end
|
405
|
+
|
406
|
+
# Determine the allowable fan system brake horsepower
|
407
|
+
# Per Section G3.1.2.9
|
408
|
+
#
|
409
|
+
# @return [Double] allowable fan system brake horsepower
|
410
|
+
# units = horsepower
|
411
|
+
def air_loop_hvac_allowable_system_brake_horsepower(air_loop_hvac)
|
412
|
+
# Get design supply air flow rate (whether autosized or hard-sized)
|
413
|
+
dsn_air_flow_m3_per_s = 0
|
414
|
+
dsn_air_flow_cfm = 0
|
415
|
+
if air_loop_hvac.autosizedDesignSupplyAirFlowRate.is_initialized
|
416
|
+
dsn_air_flow_m3_per_s = air_loop_hvac.autosizedDesignSupplyAirFlowRate.get
|
417
|
+
dsn_air_flow_cfm = OpenStudio.convert(dsn_air_flow_m3_per_s, 'm^3/s', 'cfm').get
|
418
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.ashrae_90_1_prm.AirLoopHVAC', "* #{dsn_air_flow_cfm.round} cfm = Autosized Design Supply Air Flow Rate.")
|
419
|
+
else
|
420
|
+
dsn_air_flow_m3_per_s = air_loop_hvac.designSupplyAirFlowRate.get
|
421
|
+
dsn_air_flow_cfm = OpenStudio.convert(dsn_air_flow_m3_per_s, 'm^3/s', 'cfm').get
|
422
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.ashrae_90_1_prm.AirLoopHVAC', "* #{dsn_air_flow_cfm.round} cfm = Hard sized Design Supply Air Flow Rate.")
|
423
|
+
end
|
424
|
+
|
425
|
+
# Get the fan limitation pressure drop adjustment bhp
|
426
|
+
fan_pwr_adjustment_bhp = air_loop_hvac_fan_power_limitation_pressure_drop_adjustment_brake_horsepower(air_loop_hvac)
|
427
|
+
|
428
|
+
# Get system type associated with air loop
|
429
|
+
system_type = air_loop_hvac.additionalProperties.getFeatureAsString('baseline_system_type').get
|
430
|
+
|
431
|
+
# Calculate the Allowable Fan System brake horsepower per Table G3.1.2.9
|
432
|
+
allowable_fan_bhp = 0.0
|
433
|
+
case system_type
|
434
|
+
when 'PSZ_HP', 'PSZ_AC' # 3, 4
|
435
|
+
allowable_fan_bhp = dsn_air_flow_cfm * 0.00094 + fan_pwr_adjustment_bhp
|
436
|
+
when
|
437
|
+
'PVAV_Reheat', 'PVAV_PFP_Boxes', # 5, 6
|
438
|
+
'VAV_Reheat', 'VAV_PFP_Boxes', # 7, 8
|
439
|
+
'SZ_VAV' # 11
|
440
|
+
allowable_fan_bhp = dsn_air_flow_cfm * 0.0013 + fan_pwr_adjustment_bhp
|
441
|
+
when
|
442
|
+
'SZ_CV' # 12, 13
|
443
|
+
allowable_fan_bhp = dsn_air_flow_cfm * 0.00094 + fan_pwr_adjustment_bhp
|
444
|
+
else
|
445
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.ashrae_90_1_prm.AirLoopHVAC', "Air loop #{air_loop_hvac.name} is not associated with a baseline system.")
|
446
|
+
end
|
447
|
+
|
448
|
+
return allowable_fan_bhp
|
449
|
+
end
|
450
|
+
|
451
|
+
# Check if an air loop in user model needs to have DCV per air loop related requiremends in ASHRAE 90.1-2019 6.4.3.8
|
452
|
+
#
|
453
|
+
# @author Xuechen (Jerry) Lei, PNNL
|
454
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
455
|
+
# @return [Boolean] flag of whether air loop in user model is required to have DCV
|
456
|
+
def user_model_air_loop_hvac_demand_control_ventilation_required?(air_loop_hvac)
|
457
|
+
# all zones in the same airloop in user model are set with the same value, so use the first zone under the loop
|
458
|
+
dcv_airloop_user_exception = air_loop_hvac.thermalZones[0].additionalProperties.getFeatureAsBoolean('airloop user specified DCV exception').get
|
459
|
+
return false if dcv_airloop_user_exception
|
460
|
+
|
461
|
+
# check the following conditions at airloop level
|
462
|
+
# has air economizer OR design outdoor airflow > 3000 cfm
|
463
|
+
|
464
|
+
has_economizer = air_loop_hvac_economizer?(air_loop_hvac)
|
465
|
+
|
466
|
+
if air_loop_hvac.airLoopHVACOutdoorAirSystem.is_initialized
|
467
|
+
oa_flow_m3_per_s = get_airloop_hvac_design_oa_from_sql(air_loop_hvac)
|
468
|
+
else
|
469
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}, DCV not applicable because it has no OA intake.")
|
470
|
+
return false
|
471
|
+
end
|
472
|
+
oa_flow_cfm = OpenStudio.convert(oa_flow_m3_per_s, 'm^3/s', 'cfm').get
|
473
|
+
|
474
|
+
any_zones_req_dcv = false
|
475
|
+
air_loop_hvac.thermalZones.sort.each do |zone|
|
476
|
+
if user_model_zone_demand_control_ventilation_required?(zone)
|
477
|
+
any_zones_req_dcv = true
|
478
|
+
break
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
return true if any_zones_req_dcv && (has_economizer || (oa_flow_cfm > 3000))
|
483
|
+
|
484
|
+
return false
|
485
|
+
end
|
486
|
+
|
487
|
+
# Check if a zone in user model needs to have DCV per zone related requiremends in ASHRAE 90.1-2019 6.4.3.8
|
488
|
+
# @author Xuechen (Jerry) Lei, PNNL
|
489
|
+
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
|
490
|
+
# @return [Boolean] flag of whether thermal zone in user model is required to have DCV
|
491
|
+
def user_model_zone_demand_control_ventilation_required?(thermal_zone)
|
492
|
+
dcv_zone_user_exception = thermal_zone.additionalProperties.getFeatureAsBoolean('zone user specified DCV exception').get
|
493
|
+
return false if dcv_zone_user_exception
|
494
|
+
|
495
|
+
# check the following conditions at zone level
|
496
|
+
# zone > 500 sqft AND design occ > 25 ppl/ksqft
|
497
|
+
|
498
|
+
area_served_m2 = 0
|
499
|
+
num_people = 0
|
500
|
+
thermal_zone.spaces.each do |space|
|
501
|
+
area_served_m2 += space.floorArea
|
502
|
+
num_people += space.numberOfPeople
|
503
|
+
end
|
504
|
+
area_served_ft2 = OpenStudio.convert(area_served_m2, 'm^2', 'ft^2').get
|
505
|
+
occ_per_1000_ft2 = num_people / area_served_ft2 * 1000
|
506
|
+
|
507
|
+
return true if (area_served_ft2 > 500) && (occ_per_1000_ft2 > 25)
|
508
|
+
|
509
|
+
return false
|
510
|
+
end
|
511
|
+
|
512
|
+
# Check if the air loop in baseline model needs to have DCV
|
513
|
+
#
|
514
|
+
# @author Xuechen (Jerry) Lei, PNNL
|
515
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
516
|
+
# @return [Boolean] flag of whether the air loop in baseline is required to have DCV
|
517
|
+
def baseline_air_loop_hvac_demand_control_ventilation_required?(air_loop_hvac)
|
518
|
+
any_zone_req_dcv = false
|
519
|
+
air_loop_hvac.thermalZones.each do |zone|
|
520
|
+
if baseline_thermal_zone_demand_control_ventilation_required?(zone)
|
521
|
+
any_zone_req_dcv = true
|
522
|
+
end
|
523
|
+
end
|
524
|
+
return any_zone_req_dcv # baseline airloop needs dcv if any zone it serves needs dcv
|
525
|
+
end
|
526
|
+
|
527
|
+
# Check if the thermal zone in baseline model needs to have DCV
|
528
|
+
#
|
529
|
+
# @author Xuechen (Jerry) Lei, PNNL
|
530
|
+
# @param thermal_zone [OpenStudio::Model::ThermalZone] the thermal zone
|
531
|
+
# @return [Boolean] flag of whether thermal zone in baseline is required to have DCV
|
532
|
+
def baseline_thermal_zone_demand_control_ventilation_required?(thermal_zone)
|
533
|
+
# zone needs dcv if user model has dcv and baseline does not meet apxg exception
|
534
|
+
if thermal_zone.additionalProperties.hasFeature('apxg no need to have DCV')
|
535
|
+
# meaning it was served by an airloop in the user model, does not mean much here, conditional as a safeguard
|
536
|
+
# in case it was not served by an airloop in the user model
|
537
|
+
if !thermal_zone.additionalProperties.getFeatureAsBoolean('apxg no need to have DCV').get && # does not meet apxg exception (need to have dcv if user model has it
|
538
|
+
thermal_zone.additionalProperties.getFeatureAsBoolean('zone DCV implemented in user model').get
|
539
|
+
return true
|
540
|
+
end
|
541
|
+
end
|
542
|
+
return false
|
543
|
+
end
|
544
|
+
|
545
|
+
# Get the air loop HVAC design outdoor air flow rate by reading Standard 62.1 Summary from the sizing sql
|
546
|
+
# @author Xuechen (Jerry) Lei, PNNL
|
547
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
548
|
+
# @return [Float] Design outdoor air flow rate (m^3/s)
|
549
|
+
def get_airloop_hvac_design_oa_from_sql(air_loop_hvac)
|
550
|
+
return false unless air_loop_hvac.airLoopHVACOutdoorAirSystem.is_initialized
|
551
|
+
|
552
|
+
cooling_oa = air_loop_hvac.model.sqlFile.get.execAndReturnFirstDouble(
|
553
|
+
"SELECT Value FROM TabularDataWithStrings WHERE ReportName='Standard62.1Summary' AND ReportForString='Entire Facility' AND TableName = 'System Ventilation Requirements for Cooling' AND ColumnName LIKE 'Outdoor Air Intake Flow%Vot' AND RowName='#{air_loop_hvac.name.to_s.upcase}'"
|
554
|
+
)
|
555
|
+
heating_oa = air_loop_hvac.model.sqlFile.get.execAndReturnFirstDouble(
|
556
|
+
"SELECT Value FROM TabularDataWithStrings WHERE ReportName='Standard62.1Summary' AND ReportForString='Entire Facility' AND TableName = 'System Ventilation Requirements for Heating' AND ColumnName LIKE 'Outdoor Air Intake Flow%Vot' AND RowName='#{air_loop_hvac.name.to_s.upcase}'"
|
557
|
+
)
|
558
|
+
return [cooling_oa.to_f, heating_oa.to_f].max
|
559
|
+
end
|
560
|
+
|
561
|
+
# Set the minimum VAV damper positions.
|
562
|
+
#
|
563
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
564
|
+
# @param has_ddc [Bool] if true, will assume that there is DDC control of vav terminals.
|
565
|
+
# If false, assumes otherwise.
|
566
|
+
# @return [Bool] returns true if successful, false if not
|
567
|
+
def air_loop_hvac_apply_minimum_vav_damper_positions(air_loop_hvac, has_ddc = true)
|
568
|
+
air_loop_hvac.thermalZones.each do |zone|
|
569
|
+
zone.equipment.each do |equip|
|
570
|
+
if equip.to_AirTerminalSingleDuctVAVReheat.is_initialized
|
571
|
+
zone_oa = thermal_zone_outdoor_airflow_rate(zone)
|
572
|
+
vav_terminal = equip.to_AirTerminalSingleDuctVAVReheat.get
|
573
|
+
air_terminal_single_duct_vav_reheat_apply_minimum_damper_position(vav_terminal, zone_oa, has_ddc)
|
574
|
+
elsif equip.to_AirTerminalSingleDuctParallelPIUReheat.is_initialized
|
575
|
+
zone_oa = thermal_zone_outdoor_airflow_rate(zone)
|
576
|
+
fp_vav_terminal = equip.to_AirTerminalSingleDuctParallelPIUReheat.get
|
577
|
+
air_terminal_single_duct_parallel_piu_reheat_apply_minimum_primary_airflow_fraction(fp_vav_terminal, zone_oa)
|
578
|
+
end
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
return true
|
583
|
+
end
|
584
|
+
|
585
|
+
# Determine the limits for the type of economizer present on the AirLoopHVAC, if any.
|
586
|
+
#
|
587
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
588
|
+
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
589
|
+
# @return [Array<Double>] [drybulb_limit_f, enthalpy_limit_btu_per_lb, dewpoint_limit_f]
|
590
|
+
def air_loop_hvac_economizer_limits(air_loop_hvac, climate_zone)
|
591
|
+
drybulb_limit_f = nil
|
592
|
+
enthalpy_limit_btu_per_lb = nil
|
593
|
+
dewpoint_limit_f = nil
|
594
|
+
|
595
|
+
# Get the OA system and OA controller
|
596
|
+
oa_sys = air_loop_hvac.airLoopHVACOutdoorAirSystem
|
597
|
+
return [nil, nil, nil] unless oa_sys.is_initialized
|
598
|
+
|
599
|
+
oa_sys = oa_sys.get
|
600
|
+
oa_control = oa_sys.getControllerOutdoorAir
|
601
|
+
economizer_type = oa_control.getEconomizerControlType
|
602
|
+
|
603
|
+
case economizer_type
|
604
|
+
when 'NoEconomizer'
|
605
|
+
return [nil, nil, nil]
|
606
|
+
when 'FixedDryBulb'
|
607
|
+
climate_zone_code = climate_zone.split('-')[-1]
|
608
|
+
climate_zone_code = 7 if ['7A', '7B'].include? climate_zone_code
|
609
|
+
climate_zone_code = 8 if ['8A', '8B'].include? climate_zone_code
|
610
|
+
search_criteria = {
|
611
|
+
'template' => template,
|
612
|
+
'climate_id' => climate_zone_code
|
613
|
+
}
|
614
|
+
econ_limits = model_find_object(standards_data['prm_economizers'], search_criteria)
|
615
|
+
drybulb_limit_f = econ_limits['high_limit_shutoff']
|
616
|
+
when 'FixedEnthalpy'
|
617
|
+
enthalpy_limit_btu_per_lb = 28
|
618
|
+
when 'FixedDewPointAndDryBulb'
|
619
|
+
drybulb_limit_f = 75
|
620
|
+
dewpoint_limit_f = 55
|
621
|
+
end
|
622
|
+
|
623
|
+
return [drybulb_limit_f, enthalpy_limit_btu_per_lb, dewpoint_limit_f]
|
624
|
+
end
|
625
|
+
|
626
|
+
# Determine the fan power limitation pressure drop adjustment
|
627
|
+
# Per Table 6.5.3.1-2 (90.1-2019)
|
628
|
+
#
|
629
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
630
|
+
# @return [Double] fan power limitation pressure drop adjustment, in units of horsepower
|
631
|
+
def air_loop_hvac_fan_power_limitation_pressure_drop_adjustment_brake_horsepower(air_loop_hvac)
|
632
|
+
# Calculate Fan Power Limitation Pressure Drop Adjustment
|
633
|
+
fan_pwr_adjustment_bhp = 0
|
634
|
+
|
635
|
+
# Retrieve climate zone
|
636
|
+
climate_zone = air_loop_hvac.model.getClimateZones.getClimateZone(0)
|
637
|
+
|
638
|
+
# Check if energy recovery is required
|
639
|
+
is_energy_recovery_required = air_loop_hvac_energy_recovery_ventilator_required?(air_loop_hvac, climate_zone)
|
640
|
+
|
641
|
+
system_type = ''
|
642
|
+
# Get baseline system type if applicable
|
643
|
+
if air_loop_hvac.additionalProperties.hasFeature('baseline_system_type')
|
644
|
+
system_type = air_loop_hvac.additionalProperties.getFeatureAsString('baseline_system_type').to_s
|
645
|
+
end
|
646
|
+
|
647
|
+
air_loop_hvac.thermalZones.each do |zone|
|
648
|
+
# Take fan power deductions into account;
|
649
|
+
# Deductions are calculated based on the
|
650
|
+
# baseline model design.
|
651
|
+
# The only deduction that's applicable
|
652
|
+
# is the "System with central electric
|
653
|
+
# resistance heat" for system 6 and 8
|
654
|
+
if system_type == 'PVAV_PFP_Boxes' || system_type == 'VAV_PFP_Boxes'
|
655
|
+
if zone.additionalProperties.hasFeature('has_fan_power_deduction_system_with_central_electric_resistance_heat')
|
656
|
+
current_value = zone.additionalProperties.getFeatureAsDouble('has_fan_power_deduction_system_with_central_electric_resistance_heat')
|
657
|
+
zone.additionalProperties.setFeature('has_fan_power_deduction_system_with_central_electric_resistance_heat', current_value + 1.0)
|
658
|
+
else
|
659
|
+
zone.additionalProperties.setFeature('has_fan_power_deduction_system_with_central_electric_resistance_heat', 1.0)
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
# Determine fan power adjustment
|
664
|
+
fan_pwr_adjustment_bhp += thermal_zone_get_fan_power_limitations(zone, is_energy_recovery_required)
|
665
|
+
end
|
666
|
+
|
667
|
+
return fan_pwr_adjustment_bhp
|
668
|
+
end
|
669
|
+
|
670
|
+
# Set effectiveness value of an ERV's heat exchanger
|
671
|
+
#
|
672
|
+
# @param erv [OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent] ERV to apply efficiency values
|
673
|
+
# @param erv_type [String] ERV type: ERV or HRV
|
674
|
+
# @param heat_exchanger_type [String] Heat exchanger type: Rotary or Plate
|
675
|
+
# @return [OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent] ERV to apply efficiency values
|
676
|
+
def air_loop_hvac_apply_energy_recovery_ventilator_efficiency(erv, erv_type: 'ERV', heat_exchanger_type: 'Rotary')
|
677
|
+
heat_exchanger_air_to_air_sensible_and_latent_apply_effectiveness(erv)
|
678
|
+
|
679
|
+
return erv
|
680
|
+
end
|
681
|
+
|
682
|
+
# Determine the airflow limits that govern whether or not an ERV is required.
|
683
|
+
# Based on climate zone and % OA.
|
684
|
+
#
|
685
|
+
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
686
|
+
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
687
|
+
# @param pct_oa [Double] percentage of outdoor air
|
688
|
+
# @return [Double] the flow rate above which an ERV is required. if nil, ERV is never required.
|
689
|
+
def air_loop_hvac_energy_recovery_ventilator_flow_limit(air_loop_hvac, climate_zone, pct_oa)
|
690
|
+
if pct_oa < 0.7
|
691
|
+
erv_cfm = nil
|
692
|
+
else
|
693
|
+
# Heating thermostat setpoint threshold
|
694
|
+
temp_c = OpenStudio.convert(60, 'F', 'C').get
|
695
|
+
|
696
|
+
# Check for exceptions for each zone
|
697
|
+
air_loop_hvac.thermalZones.each do |thermal_zone|
|
698
|
+
# Get heating thermosat setpoint and comparing to heating thermostat setpoint threshold
|
699
|
+
tstat = thermal_zone.thermostat.get
|
700
|
+
if tstat.to_ThermostatSetpointDualSetpoint
|
701
|
+
tstat = tstat.to_ThermostatSetpointDualSetpoint.get
|
702
|
+
htg_sch = tstat.getHeatingSchedule
|
703
|
+
if htg_sch.is_initialized
|
704
|
+
htg_sch = htg_sch.get
|
705
|
+
if htg_sch.to_ScheduleRuleset.is_initialized
|
706
|
+
htg_sch = htg_sch.to_ScheduleRuleset.get
|
707
|
+
max_c = schedule_ruleset_annual_min_max_value(htg_sch)['max']
|
708
|
+
if max_c > temp_c
|
709
|
+
htd = true
|
710
|
+
end
|
711
|
+
elsif htg_sch.to_ScheduleConstant.is_initialized
|
712
|
+
htg_sch = htg_sch.to_ScheduleConstant.get
|
713
|
+
max_c = schedule_constant_annual_min_max_value(htg_sch)['max']
|
714
|
+
if max_c > temp_c
|
715
|
+
htd = true
|
716
|
+
end
|
717
|
+
elsif htg_sch.to_ScheduleCompact.is_initialized
|
718
|
+
htg_sch = htg_sch.to_ScheduleCompact.get
|
719
|
+
max_c = schedule_compact_annual_min_max_value(htg_sch)['max']
|
720
|
+
if max_c > temp_c
|
721
|
+
htd = true
|
722
|
+
end
|
723
|
+
else
|
724
|
+
OpenStudio.logFree(OpenStudio::Error, 'prm.log', "Zone #{thermal_zone.name} used an unknown schedule type for the heating setpoint; assuming heated.")
|
725
|
+
htd = true
|
726
|
+
end
|
727
|
+
end
|
728
|
+
elsif tstat.to_ZoneControlThermostatStagedDualSetpoint
|
729
|
+
tstat = tstat.to_ZoneControlThermostatStagedDualSetpoint.get
|
730
|
+
htg_sch = tstat.heatingTemperatureSetpointSchedule
|
731
|
+
if htg_sch.is_initialized
|
732
|
+
htg_sch = htg_sch.get
|
733
|
+
if htg_sch.to_ScheduleRuleset.is_initialized
|
734
|
+
htg_sch = htg_sch.to_ScheduleRuleset.get
|
735
|
+
max_c = schedule_ruleset_annual_min_max_value(htg_sch)['max']
|
736
|
+
if max_c > temp_c
|
737
|
+
htd = true
|
738
|
+
end
|
739
|
+
end
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
743
|
+
# Exception 1 - Systems heated to less than 60F since all baseline system provide cooling
|
744
|
+
if !htd
|
745
|
+
return nil
|
746
|
+
end
|
747
|
+
|
748
|
+
# Exception 2 - System exhausting toxic fumes
|
749
|
+
if thermal_zone.additionalProperties.hasFeature('exhaust_energy_recovery_exception_for_toxic_fumes_etc')
|
750
|
+
if thermal_zone.additionalProperties.getFeatureAsString('exhaust_energy_recovery_exception_for_toxic_fumes_etc').get == 'yes'
|
751
|
+
return nil
|
752
|
+
end
|
753
|
+
end
|
754
|
+
|
755
|
+
# Exception 3 - Commercial kitchen hoods
|
756
|
+
if thermal_zone.additionalProperties.hasFeature('exhaust_energy_recovery_exception_for_type1_kitchen_hoods')
|
757
|
+
if thermal_zone.additionalProperties.getFeatureAsString('exhaust_energy_recovery_exception_for_type1_kitchen_hoods').get == 'yes'
|
758
|
+
return nil
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
# Exception 6 - Distributed exhaust
|
763
|
+
if thermal_zone.additionalProperties.hasFeature('exhaust_energy_recovery_exception_for_type_distributed_exhaust')
|
764
|
+
if thermal_zone.additionalProperties.getFeatureAsString('exhaust_energy_recovery_exception_for_type_distributed_exhaust').get == 'yes'
|
765
|
+
return nil
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
# Exception 7 - Dehumidification
|
770
|
+
if thermal_zone.additionalProperties.hasFeature('exhaust_energy_recovery_exception_for_dehumidifcation_with_series_cooling_recovery')
|
771
|
+
if thermal_zone.additionalProperties.getFeatureAsString('exhaust_energy_recovery_exception_for_dehumidifcation_with_series_cooling_recovery').get == 'yes'
|
772
|
+
return nil
|
773
|
+
end
|
774
|
+
end
|
775
|
+
end
|
776
|
+
|
777
|
+
# Exception 4 - Heating systems in certain climate zones
|
778
|
+
if ['ASHRAE 169-2006-0A', 'ASHRAE 169-2006-0B', 'ASHRAE 169-2006-1A', 'ASHRAE 169-2006-1B', 'ASHRAE 169-2006-2A', 'ASHRAE 169-2006-2B', 'ASHRAE 169-2006-3A', 'ASHRAE 169-2006-3B', 'ASHRAE 169-2006-3C', 'ASHRAE 169-2013-0A', 'ASHRAE 169-2013-0B', 'ASHRAE 169-2013-1A', 'ASHRAE 169-2013-1B', 'ASHRAE 169-2013-2A', 'ASHRAE 169-2013-2B', 'ASHRAE 169-2013-3A', 'ASHRAE 169-2013-3B', 'ASHRAE 169-2013-3C'].include?(climate_zone)
|
779
|
+
if air_loop_hvac.additionalProperties.hasFeature('baseline_system_type')
|
780
|
+
system_type = air_loop_hvac.additionalProperties.getFeatureAsString('baseline_system_type').get
|
781
|
+
if system_type == 'Gas_Furnace' || system_type == 'Electric_Furnace'
|
782
|
+
return nil
|
783
|
+
end
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
erv_cfm = 5000
|
788
|
+
end
|
789
|
+
|
790
|
+
return erv_cfm
|
791
|
+
end
|
792
|
+
end
|