lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb in openstudio-standards-0.2.12.rc6 vs lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb in openstudio-standards-0.2.12.rc7

- old
+ new

@@ -80,18 +80,91 @@ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ZoneHVACComponent', "For #{zone_hvac_component.name}: fan efficacy set to #{fan_efficacy_new_w_per_cfm.round(2)} W/cfm.") return true end + # Default occupancy fraction threshold for determining if the spaces served by the zone hvac are occupied + def zone_hvac_unoccupied_threshold + return 0.15 + end + + # If the supply air fan operating mode schedule is always off (to follow load), + # and the zone requires ventilation, override it to follow the zone occupancy schedule + def zone_hvac_component_occupancy_ventilation_control(zone_hvac_component) + ventilation = false + # Zone HVAC operating schedule if providing ventilation + if zone_hvac_component.to_ZoneHVACFourPipeFanCoil.is_initialized + zone_hvac_component = zone_hvac_component.to_ZoneHVACFourPipeFanCoil.get + if zone_hvac_component.maximumOutdoorAirFlowRate.is_initialized + oa_rate = zone_hvac_component.maximumOutdoorAirFlowRate.get + ventilation = true if oa_rate > 0.0 + end + ventilation = true if zone_hvac_component.isMaximumOutdoorAirFlowRateAutosized + elsif zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.is_initialized + zone_hvac_component = zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.get + if zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.is_initialized + oa_rate = zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.get + ventilation = true if oa_rate > 0.0 + end + ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized + elsif zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.is_initialized + zone_hvac_component = zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.get + if zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.is_initialized + oa_rate = zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.get + ventilation = true if oa_rate > 0.0 + end + ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized + elsif zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.is_initialized + zone_hvac_component = zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.get + if zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.is_initialized + oa_rate = zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.get + ventilation = true if oa_rate > 0.0 + end + ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized + elsif zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.is_initialized + zone_hvac_component = zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.get + if zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.is_initialized + oa_rate = zone_hvac_component.outdoorAirFlowRateWhenNoCoolingorHeatingisNeeded.get + ventilation = true if oa_rate > 0.0 + end + ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized + end + return false unless ventilation + + # if supply air fan operating schedule is always off, + # override to provide ventilation during occupied hours + existing_sch = zone_hvac_component.supplyAirFanOperatingModeSchedule + if existing_sch.is_initialized + existing_sch = existing_sch.get + if existing_sch.name.is_initialized + OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.ZoneHVACComponent', "#{zone_hvac_component.name} has ventilation, and schedule is set to always on; keeping always on schedule.") + return false if existing_sch.name.get.to_s.downcase.include? 'always on discrete' + end + end + + thermal_zone = zone_hvac_component.thermalZone.get + occ_threshold = zone_hvac_unoccupied_threshold + occ_sch = thermal_zones_get_occupancy_schedule([thermal_zone], + sch_name: "#{zone_hvac_component.name} Occ Sch", + occupied_percentage_threshold: occ_threshold) + zone_hvac_component.setSupplyAirFanOperatingModeSchedule(occ_sch) + OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.ZoneHVACComponent', "#{zone_hvac_component.name} has ventilation. Setting fan operating mode schedule to align with zone occupancy schedule.") + + return true + end + # Apply all standard required controls to the zone equipment # # @return [Bool] returns true if successful, false if not def zone_hvac_component_apply_standard_controls(zone_hvac_component) # Vestibule heating control if zone_hvac_component_vestibule_heating_control_required?(zone_hvac_component) zone_hvac_component_apply_vestibule_heating_control(zone_hvac_component) end + + # zone ventilation occupancy control for systems with ventilation + zone_hvac_component_occupancy_ventilation_control(zone_hvac_component) return true end # Determine if vestibule heating control is required.