Source code for honeybee_openstudio.shw

# coding=utf-8
"""OpenStudio SHWSystem translators."""
from __future__ import division

from honeybee_openstudio.load import _create_constant_schedule
from honeybee_openstudio.openstudio import OSPlantLoop, OSSetpointManagerScheduled, \
    OSPumpConstantSpeed, OSWaterHeaterMixed, OSCoilWaterHeatingAirToWaterHeatPump, \
    OSFanOnOff, OSWaterHeaterHeatPump

ELECTRIC_HEATERS = (
    'Electric_WaterHeater', 'HeatPump_WaterHeater', 'Electric_TanklessHeater')
FUEL_HEATERS = ()
PUMP_HEAD = 29891  # default from OpenStudio App (Pa)
PUMP_EFFICIENCY = 0.9  # default from OpenStudio App
HEAT_PUMP_DEADBAND = 4  # a default for Heat Pumps taken from the OpenStudio App (dc)
MIN_LOOP_TEMP = 10  # default from OpenStudio App (C)
LOOP_TEMP_DIFFERENCE = 5  # default from OpenStudio App (dC)


def _retrieve_source_zone(room_id, os_model):
    """Get the ThermalZone given the room_id for where a SHWSystem is placed."""
    source_zone_ref = os_model.getThermalZoneByName(room_id)
    if source_zone_ref.is_initialized():
        return source_zone_ref.get()
    else:  # the id probably points to a Space instead of a ThermalZone
        source_space_ref = os_model.getSpaceByName(room_id)
        if source_space_ref.is_initialized():
            source_space = source_space_ref.get()
            source_zone_ref = source_space.thermalZone()
            if source_zone_ref.is_initialized():
                return source_zone_ref.get()


[docs] def shw_system_to_openstudio(shw, os_shw_connections, total_flow, water_temp, os_model): """Translate a Honeybee SHWSystem to OpenStudio PlantLoop with equipment. Args: shw: The Honeybee-energy SHWSystem object to be translated to OpenStudio. This input can also be None, in which case a default system will be created using a plant loop with a generic District Heating water heater. os_shw_connections: A list of OpenStudio WaterUseConnections objects for all of the connections to be made to the system. These are typically obtained by using the hot_water_to_openstudio function in this package on the Room.properties.energy.service_hot_water object. total_flow: A number for the total flow rate of water in the system in m3/s. This is typically obtained by summing the individual Room flow rates across the system. water_temp: A number for the temperature of the water in Celsius. This is typically obtained by taking the maximum hot water temperature across the individual Room target_temperature. os_model: The OpenStudio Model to which the service hot water system will be added. """ # set the overall properties if the system is None (default) if shw is None: shw_id = equip_type = 'Default_District_SHW' else: shw_id = shw.identifier equip_type = shw.equipment_type # create the plant loop hot_water_plant = OSPlantLoop(os_model) hot_water_plant.setName('SHW Loop {}'.format(shw_id)) target_temp = round(water_temp, 3) hot_water_plant.setMaximumLoopTemperature(target_temp) hot_water_plant.setMinimumLoopTemperature(MIN_LOOP_TEMP) # edit the sizing information to be for a hot water loop loop_sizing = hot_water_plant.sizingPlant() loop_sizing.setLoopType('Heating') loop_sizing.setDesignLoopExitTemperature(target_temp) loop_sizing.setLoopDesignTemperatureDifference(LOOP_TEMP_DIFFERENCE) # add a setpoint manager for the loop hot_sch_name = '{}C Hot Water'.format(target_temp) hot_sch = _create_constant_schedule(hot_sch_name, target_temp, os_model) sp_manager = OSSetpointManagerScheduled(os_model, hot_sch) sp_manager.addToNode(hot_water_plant.supplyOutletNode()) # add a constant speed pump for the loop hot_water_pump = OSPumpConstantSpeed(os_model) hot_water_pump.setName('SHW Pump') hot_water_pump.setRatedPumpHead(PUMP_HEAD) hot_water_pump.setMotorEfficiency(PUMP_EFFICIENCY) hot_water_pump.addToNode(hot_water_plant.supplyInletNode()) # add the equipment to the plant loop depending on the equipment type if equip_type == 'Default_District_SHW': # add a district heating system to supply the heat for the loop district_hw = OSWaterHeaterMixed(os_model) district_hw.setName('Ideal Service Hot Water Heater') district_hw.setHeaterFuelType('DistrictHeating') district_hw.setOffCycleParasiticFuelType('DistrictHeating') district_hw.setOnCycleParasiticFuelType('DistrictHeating') district_hw.setHeaterThermalEfficiency(1.0) district_hw.setHeaterMaximumCapacity(1000000) district_hw.setTankVolume(0) district_hw.setHeaterControlType('Modulate') a_sch_id = '22C Ambient Condition' a_sch = _create_constant_schedule(a_sch_id, 22, os_model) district_hw.setAmbientTemperatureSchedule(a_sch) district_hw.setOffCycleLossCoefficienttoAmbientTemperature(0) district_hw.setOnCycleLossCoefficienttoAmbientTemperature(0) hot_water_plant.addSupplyBranchForComponent(district_hw) # try to minimize the impact of the pump as much as possible hot_water_pump.setEndUseSubcategory('Water Systems') hot_water_pump.setMotorEfficiency(0.9) else: # add a water heater to supply the heat for the loop heater = OSWaterHeaterMixed(os_model) if equip_type in ELECTRIC_HEATERS: heater.setHeaterFuelType('Electricity') heater.setOffCycleParasiticFuelType('Electricity') heater.setOnCycleParasiticFuelType('Electricity') # set the water heater efficiency if equip_type == 'HeatPump_WaterHeater': heater.setHeaterThermalEfficiency(1.0) else: heater.setHeaterThermalEfficiency(shw.heater_efficiency) # set the ambient condition of the water tank if isinstance(shw.ambient_condition, str): # id of a room where heater is heater_in_zone = True source_zone = _retrieve_source_zone(shw.ambient_condition, os_model) if source_zone is not None: heater.setAmbientTemperatureThermalZone(source_zone) heater.setAmbientTemperatureIndicator('ThermalZone') else: # a temperature condition in which the heater exists heater_in_zone = False a_sch_id = '{}C Ambient Condition'.format(shw.ambient_condition) a_sch = _create_constant_schedule(a_sch_id, shw.ambient_condition, os_model) heater.setAmbientTemperatureSchedule(a_sch) # set the ambient loss coefficient if heater_in_zone: heater.setOffCycleLossFractiontoThermalZone(1) heater.setOnCycleLossFractiontoThermalZone(1) else: heater.setOffCycleLossCoefficienttoAmbientTemperature( shw.ambient_loss_coefficient) heater.setOnCycleLossCoefficienttoAmbientTemperature( shw.ambient_loss_coefficient) # set the capacity and and controls of the water heater heater.setHeaterMaximumCapacity(1000000) if equip_type in ('Gas_TanklessHeater', 'Electric_TanklessHeater'): heater.setName('SHW Tankless WaterHeater') heater.setTankVolume(0) heater.setHeaterControlType('Modulate') heater.setOffCycleLossCoefficienttoAmbientTemperature(0) heater.setOnCycleLossCoefficienttoAmbientTemperature(0) else: heater.setName('SHW WaterHeater') heater.setTankVolume(total_flow) # if it's a heat pump system, then add the pump if equip_type == 'HeatPump_WaterHeater': # create a coil for the heat pump heat_pump = OSCoilWaterHeatingAirToWaterHeatPump(os_model) heat_pump.setName('SHW HPWH DX Coil') heat_pump.setRatedCOP(shw.heater_efficiency) # add a fan for the heat pump system fan = OSFanOnOff(os_model) fan.setName('HPWH Fan') fan.setEndUseSubcategory('Water Systems') set_p_sch_id = 'HPWH Setpoint - {}'.format(shw_id) set_p_sch_val = water_temp + (HEAT_PUMP_DEADBAND * 2) setpt_sch = _create_constant_schedule(set_p_sch_id, set_p_sch_val, os_model) inlet_sch_id = 'Inlet Air Mixer Fraction - {}'.format(shw_id) inlet_sch = _create_constant_schedule(inlet_sch_id, 0.2, os_model) # add a water heater to supply the heat for the loop heat_sys = OSWaterHeaterHeatPump(os_model, heat_pump, heater, fan, setpt_sch, inlet_sch) heat_sys.setDeadBandTemperatureDifference(HEAT_PUMP_DEADBAND) source_zone = _retrieve_source_zone(shw.ambient_condition, os_model) if source_zone is not None: heat_sys.addToThermalZone(source_zone) heat_sys.setName('SHW WaterHeater HeatPump') # add the water heater to the loop hot_water_plant.addSupplyBranchForComponent(heater) # add all of the water use connections to the loop for shw_conn in os_shw_connections: hot_water_plant.addDemandBranchForComponent(shw_conn) return hot_water_plant