Source code for honeybee_phhvac.heat_pumps

# -*- coding: utf-8 -*-
# -*- Python Version: 2.7 -*-

"""Honeybee-PH-HVAC-Equipment: Heat-Pump Devices."""

import sys

try:
    from typing import Any, Dict, List, Sequence
except ImportError:
    pass  # IronPython 2.7

try:
    from honeybee_phhvac import _base
except ImportError as e:
    raise ImportError("\nFailed to import honeybee_phhvac:\n\t{}".format(e))

# -----------------------------------------------------------------------------
# Heat Pump Base


[docs] class UnknownPhHeatPumpTypeError(Exception): def __init__(self, _heater_types, _received_type): # type: (List[str], str) -> None self.msg = 'Error: Unknown HBPH-Heat-pump system type? Got: "{}" but only types: {} are allowed?'.format( _received_type, _heater_types ) super(UnknownPhHeatPumpTypeError, self).__init__(self.msg)
[docs] class PhHeatPumpSystem(_base._PhHVACBase): """Base class for all HBPH-Cooling-Systems.""" def __init__(self): super(PhHeatPumpSystem, self).__init__() self.heat_pump_class_name = self.__class__.__name__ self.percent_coverage = 1.0 self.cooling_params = PhHeatPumpCoolingParams()
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpSystem, self).to_dict() d["heat_pump_class_name"] = self.heat_pump_class_name d["percent_coverage"] = self.percent_coverage return d
[docs] def base_attrs_from_dict(self, _input_dict): # type: (PhHeatPumpSystem, Dict[str, Any]) -> PhHeatPumpSystem self.identifier = _input_dict["identifier"] self.display_name = _input_dict["display_name"] self.user_data = _input_dict.get("user_data", {}) self.heat_pump_class_name = _input_dict["heat_pump_class_name"] self.percent_coverage = _input_dict["percent_coverage"] return self
[docs] def check_dict_type(self, _input_dict): # type: (Dict[str, Any]) -> None """Check that the input dict type is correct for the Heat Pump System being constructed.""" heat_pump_class_name = _input_dict["heat_pump_class_name"] msg = "Error creating Heat Pump System from dict. Expected '{}' but got '{}'".format( self.__class__.__name__, heat_pump_class_name ) assert heat_pump_class_name == str(self.__class__.__name__), msg return None
[docs] @classmethod def from_dict(cls, input_dict): # type: (Dict[str, Any]) -> PhHeatPumpSystem raise NotImplementedError("Error: from_dict() called from BaseClass")
def __lt__(self, other): # type: (PhHeatPumpSystem) -> bool return self.identifier < other.identifier
[docs] def move(self, moving_vec3D): """Move the System's elements along a vector. Args: moving_vec3D: A Vector3D with the direction and distance to move the ray. """ pass
[docs] def rotate(self, axis_vec3D, angle_degrees, origin_pt3D): """Rotate the System's elements by a certain angle around an axis_vec3D and origin_pt3D. Right hand rule applies: If axis_vec3D has a positive orientation, rotation will be clockwise. If axis_vec3D has a negative orientation, rotation will be counterclockwise. Args: axis_vec3D: A Vector3D axis_vec3D representing the axis_vec3D of rotation. angle_degrees: An angle for rotation in degrees. origin_pt3D: A Point3D for the origin_pt3D around which the object will be rotated. """ pass
[docs] def rotate_xy(self, angle_degrees, origin_pt3D): """Rotate the System's elements counterclockwise in the XY plane by a certain angle. Args: angle_degrees: An angle in degrees. origin_pt3D: A Point3D for the origin_pt3D around which the object will be rotated. """ pass
[docs] def reflect(self, normal_vec3D, origin_pt3D): """Reflected the System's elements across a plane with the input normal vector and origin_pt3D. Args: normal_vec3D: A Vector3D representing the normal vector for the plane across which the line segment will be reflected. THIS VECTOR MUST BE NORMALIZED. origin_pt3D: A Point3D representing the origin_pt3D from which to reflect. """ pass
[docs] def scale(self, scale_factor, origin_pt3D=None): """Scale the System's elements by a factor from an origin_pt3D point. Args: scale_factor: A number representing how much the line segment should be scaled. origin_pt3D: A Point3D representing the origin_pt3D from which to scale. If None, it will be scaled from the World origin_pt3D (0, 0, 0). """ pass
def __copy__(self): # type: () -> PhHeatPumpSystem return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpSystem """Duplicate the System.""" raise NotImplementedError("Error: duplicate() called from BaseClass")
# ----------------------------------------------------------------------------- # Heat-Pump Cooling Parameters
[docs] class PhHeatPumpCoolingParams_Base(_base._PhHVACBase): """Base class for all HBPH-Cooling-Parameters.""" def __init__(self): super(PhHeatPumpCoolingParams_Base, self).__init__() self.used = False
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpCoolingParams_Base, self).to_dict() d["used"] = self.used return d
[docs] def base_attrs_from_dict(self, _input_dict): # type: (PhHeatPumpCoolingParams_Base, Dict[str, Any]) -> PhHeatPumpCoolingParams_Base self.identifier = _input_dict["identifier"] self.display_name = _input_dict["display_name"] self.user_data = _input_dict.get("user_data", {}) self.used = _input_dict["used"] return self
[docs] @classmethod def from_dict(cls, input_dict): raise NotImplementedError("Error: from_dict() called from PhHeatPumpCoolingParams_Base?")
def __copy__(self): raise NotImplementedError("Error: __copy__() called from PhHeatPumpCoolingParams_Base?")
[docs] def duplicate(self): # type: () -> PhHeatPumpCoolingParams_Base raise NotImplementedError("Error: duplicate() called from PhHeatPumpCoolingParams_Base?")
def __str__(self): # type: () -> str return "{}(used={})".format(self.__class__.__name__, self.used)
[docs] class PhHeatPumpCoolingParams_Ventilation(PhHeatPumpCoolingParams_Base): """Cooling via the Fresh-Air Ventilation System (ERV).""" def __init__(self): super(PhHeatPumpCoolingParams_Ventilation, self).__init__() self.single_speed = False self.min_coil_temp = 12.0 self.capacity = 10.0 self.annual_COP = 4.0
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpCoolingParams_Ventilation, self).to_dict() d["single_speed"] = self.single_speed d["min_coil_temp"] = self.min_coil_temp d["capacity"] = self.capacity d["annual_COP"] = self.annual_COP return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpCoolingParams_Ventilation new_obj = cls() new_obj.base_attrs_from_dict(_input_dict) new_obj.single_speed = _input_dict["single_speed"] new_obj.min_coil_temp = _input_dict["min_coil_temp"] new_obj.capacity = _input_dict["capacity"] new_obj.annual_COP = _input_dict["annual_COP"] return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpCoolingParams_Ventilation new_obj = PhHeatPumpCoolingParams_Ventilation() new_obj.identifier = self.identifier new_obj.display_name = self.display_name new_obj.user_data = self.user_data new_obj.used = self.used new_obj.single_speed = self.single_speed new_obj.min_coil_temp = self.min_coil_temp new_obj.capacity = self.capacity new_obj.annual_COP = self.annual_COP return new_obj
[docs] class PhHeatPumpCoolingParams_Recirculation(PhHeatPumpCoolingParams_Base): """Cooling via a 'recirculation' system (typical AC).""" def __init__(self): super(PhHeatPumpCoolingParams_Recirculation, self).__init__() self.single_speed = False self.min_coil_temp = 12.0 self.flow_rate_m3_hr = 100.0 self.flow_rate_variable = True self.capacity = 10.0 self.annual_COP = 4.0
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpCoolingParams_Recirculation, self).to_dict() d["single_speed"] = self.single_speed d["min_coil_temp"] = self.min_coil_temp d["flow_rate_m3_hr"] = self.flow_rate_m3_hr d["flow_rate_variable"] = self.flow_rate_variable d["capacity"] = self.capacity d["annual_COP"] = self.annual_COP return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpCoolingParams_Recirculation new_obj = cls() new_obj.base_attrs_from_dict(_input_dict) new_obj.single_speed = _input_dict["single_speed"] new_obj.min_coil_temp = _input_dict["min_coil_temp"] new_obj.flow_rate_m3_hr = _input_dict["flow_rate_m3_hr"] new_obj.flow_rate_variable = _input_dict["flow_rate_variable"] new_obj.capacity = _input_dict["capacity"] new_obj.annual_COP = _input_dict["annual_COP"] return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpCoolingParams_Recirculation new_obj = PhHeatPumpCoolingParams_Recirculation() new_obj.identifier = self.identifier new_obj.display_name = self.display_name new_obj.user_data = self.user_data new_obj.used = self.used new_obj.single_speed = self.single_speed new_obj.min_coil_temp = self.min_coil_temp new_obj.flow_rate_m3_hr = self.flow_rate_m3_hr new_obj.flow_rate_variable = self.flow_rate_variable new_obj.capacity = self.capacity new_obj.annual_COP = self.annual_COP return new_obj
[docs] class PhHeatPumpCoolingParams_Dehumidification(PhHeatPumpCoolingParams_Base): """Cooling via dedicated dehumidification system.""" def __init__(self): super(PhHeatPumpCoolingParams_Dehumidification, self).__init__() self.useful_heat_loss = False self.annual_COP = 4.0
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpCoolingParams_Dehumidification, self).to_dict() d["useful_heat_loss"] = self.useful_heat_loss d["annual_COP"] = self.annual_COP return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpCoolingParams_Dehumidification new_obj = cls() new_obj.base_attrs_from_dict(_input_dict) new_obj.useful_heat_loss = _input_dict["useful_heat_loss"] new_obj.annual_COP = _input_dict["annual_COP"] return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpCoolingParams_Dehumidification new_obj = PhHeatPumpCoolingParams_Dehumidification() new_obj.identifier = self.identifier new_obj.display_name = self.display_name new_obj.user_data = self.user_data new_obj.used = self.used new_obj.useful_heat_loss = self.useful_heat_loss new_obj.annual_COP = self.annual_COP return new_obj
[docs] class PhHeatPumpCoolingParams_Panel(PhHeatPumpCoolingParams_Base): """Cooling via radiant panels.""" def __init__(self): super(PhHeatPumpCoolingParams_Panel, self).__init__() self.annual_COP = 4.0
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpCoolingParams_Panel, self).to_dict() d["annual_COP"] = self.annual_COP return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpCoolingParams_Panel new_obj = cls() new_obj.base_attrs_from_dict(_input_dict) new_obj.annual_COP = _input_dict["annual_COP"] return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpCoolingParams_Panel new_obj = PhHeatPumpCoolingParams_Panel() new_obj.identifier = self.identifier new_obj.display_name = self.display_name new_obj.user_data = self.user_data new_obj.used = self.used new_obj.annual_COP = self.annual_COP return new_obj
[docs] class PhHeatPumpCoolingParams: """A Collection of Cooling Parameters for various types of systems.""" def __init__(self): self.percent_coverage = 1.0 self.ventilation = PhHeatPumpCoolingParams_Ventilation() self.recirculation = PhHeatPumpCoolingParams_Recirculation() self.dehumidification = PhHeatPumpCoolingParams_Dehumidification() self.panel = PhHeatPumpCoolingParams_Panel()
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = {} d["percent_coverage"] = self.percent_coverage d["ventilation"] = self.ventilation.to_dict() d["recirculation"] = self.recirculation.to_dict() d["dehumidification"] = self.dehumidification.to_dict() d["panel"] = self.panel.to_dict() return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpCoolingParams new_obj = cls() new_obj.percent_coverage = _input_dict["percent_coverage"] new_obj.ventilation = PhHeatPumpCoolingParams_Ventilation.from_dict(_input_dict["ventilation"]) new_obj.recirculation = PhHeatPumpCoolingParams_Recirculation.from_dict(_input_dict["recirculation"]) new_obj.dehumidification = PhHeatPumpCoolingParams_Dehumidification.from_dict(_input_dict["dehumidification"]) new_obj.panel = PhHeatPumpCoolingParams_Panel.from_dict(_input_dict["panel"]) return new_obj
def __str__(self): # type: () -> str return "{}(percent_coverage={}, ventilation={}, recirculation={}, dehumidification={}, panel={})".format( self.__class__.__name__, self.percent_coverage, self.ventilation.used, self.recirculation.used, self.dehumidification.used, self.panel.used, )
[docs] def ToString(self): # type: () -> str return str(self)
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpCoolingParams new_obj = PhHeatPumpCoolingParams() new_obj.percent_coverage = self.percent_coverage new_obj.ventilation = self.ventilation.duplicate() new_obj.recirculation = self.recirculation.duplicate() new_obj.dehumidification = self.dehumidification.duplicate() new_obj.panel = self.panel.duplicate() return new_obj
# ----------------------------------------------------------------------------- # -- Heat Pumps Types
[docs] class PhHeatPumpAnnual(PhHeatPumpSystem): """Electric heat-pump with only Annual performance values.""" def __init__(self): super(PhHeatPumpAnnual, self).__init__() self.annual_COP = 2.5 self.total_system_perf_ratio = 0.4
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpAnnual, self).to_dict() d["annual_COP"] = self.annual_COP d["total_system_perf_ratio"] = self.total_system_perf_ratio d["cooling_params"] = self.cooling_params.to_dict() return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpAnnual new_obj = cls() new_obj.check_dict_type(_input_dict) new_obj.base_attrs_from_dict(_input_dict) new_obj.annual_COP = _input_dict["annual_COP"] new_obj.total_system_perf_ratio = _input_dict["total_system_perf_ratio"] new_obj.cooling_params = PhHeatPumpCoolingParams.from_dict(_input_dict["cooling_params"]) return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpAnnual new_obj = PhHeatPumpAnnual() new_obj.identifier = self.identifier new_obj.display_name = self.display_name new_obj.percent_coverage = self.percent_coverage new_obj.user_data = self.user_data new_obj.annual_COP = self.annual_COP new_obj.total_system_perf_ratio = self.total_system_perf_ratio new_obj.cooling_params = self.cooling_params.duplicate() return new_obj
[docs] class PhHeatPumpRatedMonthly(PhHeatPumpSystem): """Electric heat-pump with 2 separate monthly performance values.""" def __init__(self): super(PhHeatPumpRatedMonthly, self).__init__() self.COP_1 = 2.5 self.ambient_temp_1 = -8.333 # =17F self.COP_2 = 2.5 self.ambient_temp_2 = 8.333 # =47F @property def monthly_COPS(self): return [self.COP_1, self.COP_2] @monthly_COPS.setter def monthly_COPS(self, _cops): # type: (Sequence[float]) -> None self.COP_1 = _cops[0] try: self.COP_2 = _cops[1] except IndexError: self.COP_2 = _cops[0] return @property def monthly_temps(self): return [self.ambient_temp_1, self.ambient_temp_2] @monthly_temps.setter def monthly_temps(self, _cops): # type: (Sequence[float]) -> None self.ambient_temp_1 = _cops[0] try: self.ambient_temp_2 = _cops[1] except IndexError: self.ambient_temp_2 = _cops[0] return
[docs] def to_dict(self): # type: () -> Dict[str, Any] d = super(PhHeatPumpRatedMonthly, self).to_dict() d["COP_1"] = self.COP_1 d["ambient_temp_1"] = self.ambient_temp_1 d["COP_2"] = self.COP_2 d["ambient_temp_2"] = self.ambient_temp_2 d["cooling_params"] = self.cooling_params.to_dict() return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpRatedMonthly new_obj = cls() new_obj.check_dict_type(_input_dict) new_obj.base_attrs_from_dict(_input_dict) new_obj.COP_1 = _input_dict["COP_1"] new_obj.ambient_temp_1 = _input_dict["ambient_temp_1"] new_obj.COP_2 = _input_dict["COP_2"] new_obj.ambient_temp_2 = _input_dict["ambient_temp_2"] new_obj.cooling_params = PhHeatPumpCoolingParams.from_dict(_input_dict["cooling_params"]) return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatPumpRatedMonthly new_obj = PhHeatPumpRatedMonthly() new_obj.identifier = self.identifier new_obj.display_name = self.display_name new_obj.percent_coverage = self.percent_coverage new_obj.user_data = self.user_data new_obj.COP_1 = self.COP_1 new_obj.ambient_temp_1 = self.ambient_temp_1 new_obj.COP_2 = self.COP_2 new_obj.ambient_temp_2 = self.ambient_temp_2 new_obj.cooling_params = self.cooling_params.duplicate() return new_obj
[docs] class PhHeatPumpCombined(PhHeatPumpSystem): def __init__(self): msg = "Sorry, Combined Heat Pumps are not yet supported in HBPH." raise NotImplementedError(msg)
# -----------------------------------------------------------------------------
[docs] class PhHeatPumpSystemBuilder(object): """Constructor class for HBPH-CoolingSystems"""
[docs] @classmethod def from_dict(cls, _input_dict): # type: (Dict[str, Any]) -> PhHeatPumpSystem """Find the right heat-pump constructor class from the module based on the 'type' name.""" valid_class_type_names = [nm for nm in dir(sys.modules[__name__]) if nm.startswith("PhHeatPump")] heat_pump_class_name = _input_dict["heat_pump_class_name"] if heat_pump_class_name not in valid_class_type_names: raise UnknownPhHeatPumpTypeError(valid_class_type_names, heat_pump_class_name) heat_pump_class = getattr(sys.modules[__name__], heat_pump_class_name) new_equipment = heat_pump_class.from_dict(_input_dict) return new_equipment
def __str__(self): return "{}()".format(self.__class__.__name__) def __repr__(self): return str(self)
[docs] def ToString(self): return str(self)