Source code for honeybee_phhvac.heating

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

"""Honeybee-PH-HVAC-Equipment: Heating Devices."""

import sys
from copy import copy

try:
    from typing import Any, Optional
except ImportError:
    pass  # IronPython 2.7

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


[docs] class UnknownPhHeatingTypeError(Exception): def __init__(self, _heater_types, _received_type): # type: (list[str], str) -> None self.msg = 'Error: Unknown HBPH-Heating-SubSystem type? Got: "{}" but only types: {} are allowed?'.format( _received_type, _heater_types ) super(UnknownPhHeatingTypeError, self).__init__(self.msg)
[docs] class PhHeatingSystem(_base._PhHVACBase): """Base class for all PH-Heating Systems (elec, boiler, etc...)""" def __init__(self): super(PhHeatingSystem, self).__init__() self.heating_type = self.__class__.__name__ self.percent_coverage = 1.0
[docs] def to_dict(self): # type: () -> dict d = super(PhHeatingSystem, self).to_dict() d["heating_type"] = self.heating_type d["percent_coverage"] = self.percent_coverage return d
[docs] def base_attrs_from_dict(self, _input_dict): # type: (PhHeatingSystem, dict) -> PhHeatingSystem self.identifier = _input_dict["identifier"] self.display_name = _input_dict["display_name"] self.user_data = _input_dict["user_data"] self.heating_type = _input_dict["heating_type"] self.percent_coverage = _input_dict["percent_coverage"] return self
[docs] def check_dict_type(self, _input_dict): # type: (dict) -> None """Check that the input dict type is correct for the Heating System being constructed.""" heating_type = _input_dict["heating_type"] msg = "Error creating Heating System from dict. Expected '{}' but got '{}'".format( self.__class__.__name__, heating_type ) assert heating_type == str(self.__class__.__name__), msg return None
[docs] @classmethod def from_dict(cls, _input_dict): raise NotImplementedError("Error: from_dict() called on BaseClass.")
def __lt__(self, other): # type: (PhHeatingSystem) -> bool return self.identifier < other.identifier
[docs] def move(self, moving_vec3D): """Move the System's elements along a vector. Args: moving_vec: A Vector3D with the direction and distance to move the ray. """ pass
[docs] def rotate(self, axis_vec3D, angle_degree, origin_pt3D): """Rotate the System's elements by a certain angle around an axis and origin. Right hand rule applies: If axis has a positive orientation, rotation will be clockwise. If axis has a negative orientation, rotation will be counterclockwise. Args: axis: A Vector3D axis representing the axis of rotation. angle: An angle for rotation in degrees. origin: A Point3D for the origin around which the object will be rotated. """ pass
[docs] def rotate_xy(self, angle_degree, origin_pt3D): """Rotate the System's elements counterclockwise in the XY plane by a certain angle. Args: angle: An angle in degrees. origin: A Point3D for the origin 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. Args: normal: A Vector3D representing the normal vector for the plane across which the line segment will be reflected. THIS VECTOR MUST BE NORMALIZED. origin: A Point3D representing the origin from which to reflect. """ pass
[docs] def scale(self, scale_factor, origin=None): """Scale the System's elements by a factor from an origin point. Args: factor: A number representing how much the line segment should be scaled. origin: A Point3D representing the origin from which to scale. If None, it will be scaled from the World origin (0, 0, 0). """ pass
[docs] def duplicate(self): # type: () -> PhHeatingSystem raise NotImplementedError("Error: duplicate() called on BaseClass.")
def __copy__(self): raise NotImplementedError("Error: __copy__() called on BaseClass.")
# ----------------------------------------------------------------------------- # Heating Types
[docs] class PhHeatingDirectElectric(PhHeatingSystem): """Heating via direct-electric (resistance heating).""" def __init__(self): super(PhHeatingDirectElectric, self).__init__()
[docs] def to_dict(self): # type: () -> dict[str, Any] d = super(PhHeatingDirectElectric, self).to_dict() return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (dict[str, Any]) -> PhHeatingDirectElectric new_obj = cls() new_obj.check_dict_type(_input_dict) new_obj.base_attrs_from_dict(_input_dict) return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatingDirectElectric obj = PhHeatingDirectElectric() obj.identifier = self.identifier obj.display_name = self.display_name obj.percent_coverage = self.percent_coverage obj.user_data = copy(self.user_data) return obj
[docs] class PhHeatingFossilBoiler(PhHeatingSystem): """Heating via boiler using fossil-fuel (gas, oil)""" def __init__(self): super(PhHeatingFossilBoiler, self).__init__() self.fuel = fuels.NATURAL_GAS self.condensing = True self.in_conditioned_space = True self.effic_at_30_percent_load = 0.98 self.effic_at_nominal_load = 0.94 self.avg_rtrn_temp_at_30_percent_load = 30 self.avg_temp_at_70C_55C = 41 self.avg_temp_at_55C_45C = 35 self.avg_temp_at_32C_28C = 24
[docs] def to_dict(self): # type: () -> dict[str, Any] d = super(PhHeatingFossilBoiler, self).to_dict() d["fuel"] = self.fuel d["condensing"] = self.condensing d["in_conditioned_space"] = self.in_conditioned_space d["effic_at_30_percent_load"] = self.effic_at_30_percent_load d["effic_at_nominal_load"] = self.effic_at_nominal_load d["avg_rtrn_temp_at_30_percent_load"] = self.avg_rtrn_temp_at_30_percent_load d["avg_temp_at_70C_55C"] = self.avg_temp_at_70C_55C d["avg_temp_at_55C_45C"] = self.avg_temp_at_55C_45C d["avg_temp_at_32C_28C"] = self.avg_temp_at_32C_28C return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (dict[str, Any]) -> PhHeatingFossilBoiler new_obj = cls() new_obj.check_dict_type(_input_dict) new_obj.base_attrs_from_dict(_input_dict) new_obj.fuel = _input_dict["fuel"] new_obj.condensing = _input_dict["condensing"] new_obj.in_conditioned_space = _input_dict["in_conditioned_space"] new_obj.effic_at_30_percent_load = _input_dict["effic_at_30_percent_load"] new_obj.effic_at_nominal_load = _input_dict["effic_at_nominal_load"] new_obj.avg_rtrn_temp_at_30_percent_load = _input_dict["avg_rtrn_temp_at_30_percent_load"] new_obj.avg_temp_at_70C_55C = _input_dict["avg_temp_at_70C_55C"] new_obj.avg_temp_at_55C_45C = _input_dict["avg_temp_at_55C_45C"] new_obj.avg_temp_at_32C_28C = _input_dict["avg_temp_at_32C_28C"] return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatingFossilBoiler obj = PhHeatingFossilBoiler() obj.identifier = self.identifier obj.display_name = self.display_name obj.percent_coverage = self.percent_coverage obj.user_data = copy(self.user_data) obj.fuel = self.fuel obj.condensing = self.condensing obj.in_conditioned_space = self.in_conditioned_space obj.effic_at_30_percent_load = self.effic_at_30_percent_load obj.effic_at_nominal_load = self.effic_at_nominal_load obj.avg_rtrn_temp_at_30_percent_load = self.avg_rtrn_temp_at_30_percent_load obj.avg_temp_at_70C_55C = self.avg_temp_at_70C_55C obj.avg_temp_at_55C_45C = self.avg_temp_at_55C_45C obj.avg_temp_at_32C_28C = self.avg_temp_at_32C_28C return obj
[docs] class PhHeatingWoodBoiler(PhHeatingSystem): """Heating via boiler using wood (log, pellet).""" def __init__(self): super(PhHeatingWoodBoiler, self).__init__() self.fuel = fuels.WOOD_LOG self.in_conditioned_space = True self.effic_in_basic_cycle = 0.6 self.effic_in_const_operation = 0.7 self.avg_frac_heat_output = 0.4 self.temp_diff_on_off = 30 self.rated_capacity = 15 # kW self.demand_basic_cycle = 1 # kWh self.power_stationary_run = 1 # W self.power_standard_run = None # type: Optional[float] self.no_transport_pellets = None # type: Optional[bool] self.only_control = None # type: Optional[bool] self.area_mech_room = None # type: Optional[float] @property def useful_heat_output(self): return 0.9 * self.rated_capacity # kWH @property def avg_power_output(self): return 0.5 * self.rated_capacity # kW
[docs] def to_dict(self): # type: () -> dict d = super(PhHeatingWoodBoiler, self).to_dict() d["fuel"] = self.fuel d["in_conditioned_space"] = self.in_conditioned_space d["effic_in_basic_cycle"] = self.effic_in_basic_cycle d["effic_in_const_operation"] = self.effic_in_const_operation d["avg_frac_heat_output"] = self.avg_frac_heat_output d["temp_diff_on_off"] = self.temp_diff_on_off d["rated_capacity"] = self.rated_capacity d["demand_basic_cycle"] = self.demand_basic_cycle d["power_stationary_run"] = self.power_stationary_run d["power_standard_run"] = self.power_standard_run d["no_transport_pellets"] = self.no_transport_pellets d["only_control"] = self.only_control d["area_mech_room"] = self.area_mech_room return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (dict) -> PhHeatingWoodBoiler new_obj = cls() new_obj.check_dict_type(_input_dict) new_obj.base_attrs_from_dict(_input_dict) new_obj.fuel = _input_dict["fuel"] new_obj.in_conditioned_space = _input_dict["in_conditioned_space"] new_obj.effic_in_basic_cycle = _input_dict["effic_in_basic_cycle"] new_obj.effic_in_const_operation = _input_dict["effic_in_const_operation"] new_obj.avg_frac_heat_output = _input_dict["avg_frac_heat_output"] new_obj.temp_diff_on_off = _input_dict["temp_diff_on_off"] new_obj.rated_capacity = _input_dict["rated_capacity"] new_obj.demand_basic_cycle = _input_dict["demand_basic_cycle"] new_obj.power_stationary_run = _input_dict["power_stationary_run"] new_obj.no_transport_pellets = _input_dict["no_transport_pellets"] new_obj.only_control = _input_dict["only_control"] new_obj.area_mech_room = _input_dict["area_mech_room"] return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatingWoodBoiler obj = PhHeatingWoodBoiler() obj.identifier = self.identifier obj.display_name = self.display_name obj.percent_coverage = self.percent_coverage obj.user_data = copy(self.user_data) obj.fuel = self.fuel obj.in_conditioned_space = self.in_conditioned_space obj.effic_in_basic_cycle = self.effic_in_basic_cycle obj.effic_in_const_operation = self.effic_in_const_operation obj.avg_frac_heat_output = self.avg_frac_heat_output obj.temp_diff_on_off = self.temp_diff_on_off obj.rated_capacity = self.rated_capacity obj.demand_basic_cycle = self.demand_basic_cycle obj.power_stationary_run = self.power_stationary_run obj.power_standard_run = self.power_standard_run obj.no_transport_pellets = self.no_transport_pellets obj.only_control = self.only_control obj.area_mech_room = self.area_mech_room return obj
[docs] class PhHeatingDistrict(PhHeatingSystem): """Heating via district-heat.""" def __init__(self): super(PhHeatingDistrict, self).__init__() self.fuel = fuels.GAS_CGS_70_PHC self.util_factor_of_heat_transfer_station = 0.5
[docs] def to_dict(self): # type: () -> dict d = super(PhHeatingDistrict, self).to_dict() d["fuel"] = self.fuel d["util_factor_of_heat_transfer_station"] = self.util_factor_of_heat_transfer_station return d
[docs] @classmethod def from_dict(cls, _input_dict): # type: (dict) -> PhHeatingDistrict new_obj = cls() new_obj.check_dict_type(_input_dict) new_obj.base_attrs_from_dict(_input_dict) new_obj.fuel = _input_dict["fuel"] new_obj.util_factor_of_heat_transfer_station = _input_dict["util_factor_of_heat_transfer_station"] return new_obj
def __copy__(self): return self.duplicate()
[docs] def duplicate(self): # type: () -> PhHeatingDistrict obj = PhHeatingDistrict() obj.identifier = self.identifier obj.display_name = self.display_name obj.percent_coverage = self.percent_coverage obj.user_data = copy(self.user_data) obj.fuel = self.fuel obj.util_factor_of_heat_transfer_station = self.util_factor_of_heat_transfer_station return obj
# -----------------------------------------------------------------------------
[docs] class PhHeatingSystemBuilder(object): """Constructor class for PH-HeatingSystems"""
[docs] @classmethod def from_dict(cls, _input_dict): # type: (dict[str, Any]) -> PhHeatingSystem """Find the right appliance constructor class from the module based on the 'type' name.""" valid_class_types = [nm for nm in dir(sys.modules[__name__]) if nm.startswith("Ph")] heating_type = _input_dict["heating_type"] if heating_type not in valid_class_types: raise UnknownPhHeatingTypeError(valid_class_types, heating_type) heating_class = getattr(sys.modules[__name__], heating_type) new_equipment = heating_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)