Source code for dragonfly_uwg.properties.building

# coding=utf-8
"""Building UWG Properties."""
from __future__ import division

from honeybee.typing import float_in_range
from honeybee.altnumber import autocalculate

from ._refdefaults import _RefDefaults


[docs] class BuildingUWGProperties(object): """UWG Properties for Dragonfly Building. Args: host: A dragonfly_core Building object that hosts these properties. program: Text for the name of the building program. Must be one of the options below. (Default: LargeOffice). * LargeOffice * MediumOffice * SmallOffice * MidriseApartment * Retail * StripMall * PrimarySchool * SecondarySchool * SmallHotel * LargeHotel * Hospital * Outpatient * Warehouse * SuperMarket * FullServiceRestaurant * QuickServiceRestaurant vintage: Text for the vintage of the building. This will be used to set default constructions. Must be one of the options below. (Default: New). * New * 1980_Present * Pre1980 fract_heat_to_canyon: A number from 0 to 1 that represents the fraction of the building's waste heat from air conditioning that gets rejected into the urban canyon. (Default: 0.5). shgc: A number from 0 to 1 that represents the SHGC of the building's windows. Used to evaluate the amount of solar heat reflected into the street canyon. If autocalculate, it will be set by the building vintage and the Model climate zone. (Default: autocalculate). wall_albedo: A number from 0 to 1 that represents the exterior wall albedo of the building. If autocalculate, it will be set by the building program and the DoE commercial reference buildings. (Default: autocalculate). roof_albedo: A number from 0 to 1 that represents the exterior roof albedo of the building. If autocalculate, it will be set by the vintage, meaning 0.7 for New and 0.2 for 1980_Present and Pre1980. (Default: autocalculate). roof_veg_fraction: A number from 0 to 1 that represents the roof vegetation fraction of the building. (Default: 0). Properties: * host * program * vintage * fract_heat_to_canyon * shgc * wall_albedo * roof_albedo * roof_veg_fraction """ __slots__ = ('_host', '_program', '_vintage', '_fract_heat_to_canyon', '_shgc', '_wall_albedo', '_roof_albedo', '_roof_veg_fraction') PROGRAMS = \ ('LargeOffice', 'MediumOffice', 'SmallOffice', 'MidriseApartment', 'Retail', 'StripMall', 'PrimarySchool', 'SecondarySchool', 'SmallHotel', 'LargeHotel', 'Hospital', 'Outpatient', 'Warehouse', 'SuperMarket', 'FullServiceRestaurant', 'QuickServiceRestaurant') VINTAGES = ('New', '1980_Present', 'Pre1980') _VINTAGE_MAP = {'New': 'new', '1980_Present': 'pst80', 'Pre1980': 'pre80'} def __init__(self, host, program='LargeOffice', vintage='New', fract_heat_to_canyon=0.5, shgc=autocalculate, wall_albedo=autocalculate, roof_albedo=autocalculate, roof_veg_fraction=0): """Initialize Building UWG properties.""" self._host = host self.program = program self.vintage = vintage self.fract_heat_to_canyon = fract_heat_to_canyon self.shgc = shgc self.wall_albedo = wall_albedo self.roof_albedo = roof_albedo self.roof_veg_fraction = roof_veg_fraction @property def host(self): """Get the Building object hosting these properties.""" return self._host @property def program(self): """Get or set text for the name of the building program.""" return self._program @program.setter def program(self, value): assert value in self.PROGRAMS, 'Program "{}" is not acceptable for the UWG. ' \ 'Choose from the following:\n{}'.format(value, '\n'.join(self.PROGRAMS)) self._program = value @property def program_uwg(self): """Get text for the building program in a format that the UWG likes.""" if self._program == 'Retail': return 'standaloneretail' elif self._program == 'MediumOffice': return 'medoffice' return self._program.lower() @property def vintage(self): """Get or set text for the vintage of the building.""" return self._vintage @vintage.setter def vintage(self, value): assert value in self.VINTAGES, 'Vintage "{}" is not acceptable for the UWG. ' \ 'Choose from the following:\n{}'.format(value, '\n'.join(self.VINTAGES)) self._vintage = value @property def vintage_uwg(self): """Get text for the building vintage in a format that the UWG likes.""" return self._VINTAGE_MAP[self._vintage] @property def fract_heat_to_canyon(self): """Get or set the fraction of the bldg heat rejected to the urban canyon.""" return self._fract_heat_to_canyon @fract_heat_to_canyon.setter def fract_heat_to_canyon(self, value): self._fract_heat_to_canyon = float_in_range(value, 0, 1, 'fract_heat_to_canyon') @property def shgc(self): """Get or set the SHGC of the building.""" return self._shgc if self._shgc is not None else autocalculate @shgc.setter def shgc(self, value): if value == autocalculate: self._shgc = None else: self._shgc = float_in_range(value, 0, 1, 'shgc') @property def wall_albedo(self): """Get or set the exterior wall albedo of the building.""" if self._wall_albedo is None: return _RefDefaults.wall_albedo_by_type(self._program) return self._wall_albedo @wall_albedo.setter def wall_albedo(self, value): if value == autocalculate: self._wall_albedo = None else: self._wall_albedo = float_in_range(value, 0, 1, 'wall_albedo') @property def roof_albedo(self): """Get or set the exterior roof albedo of the building.""" if self._roof_albedo is None: return _RefDefaults.roof_albedo_by_era(self._vintage) return self._roof_albedo @roof_albedo.setter def roof_albedo(self, value): if value == autocalculate: self._roof_albedo = None else: self._roof_albedo = float_in_range(value, 0, 1, 'roof_albedo') @property def roof_veg_fraction(self): """Get or set the roof vegetation fraction of the building.""" return self._roof_veg_fraction @roof_veg_fraction.setter def roof_veg_fraction(self, value): self._roof_veg_fraction = float_in_range(value, 0, 1, 'roof_veg_fraction')
[docs] def default_shgc(self, climate_zone): """Get the default DoE Reference Building SHGC for this building. This is used whenever the building's shgc property is autocalculate. Args: climate_zone: Text for the ASHRAE climate zone, which must include the humidity letter (eg. "4A") unless it is climate zone 7 or 8. """ return _RefDefaults.shgc_by_era_zone(self._vintage, climate_zone)
[docs] def infer_program_from_energy_program(self): """Attempt to infer the UWG building program from the honeybee-energy program. The inferring will happen by first finding the most common energy ProgramType among the assigned Room2Ds. If the identifier of this most common program contains the name of an acceptable UWG building program, it will be assigned as this object's building program. If no match is found or there's no honeybee-energy extension installed, this object's program will remain unchanged. """ try: room_progs = [rm.properties.energy.program_type.identifier for rm in self.host.unique_room_2ds] except AttributeError: # dragonfly-energy extension is not installed room_progs = None if room_progs is not None: primary_prog = max(set(room_progs), key=room_progs.count) for prog in self.PROGRAMS: if prog in primary_prog: self._program = prog break
[docs] @classmethod def from_dict(cls, data, host): """Create BuildingUWGProperties from a dictionary. Note that the dictionary must be a non-abridged version for this classmethod to work. Args: data: A dictionary representation of BuildingUWGProperties. host: A Building object that hosts these properties. """ assert data['type'] == 'BuildingUWGProperties', \ 'Expected BuildingUWGProperties. Got {}.'.format(data['type']) prog, era, f_can, shgc, w_alb, r_alb, r_veg = cls._default_keys(data) return cls(host, prog, era, f_can, shgc, w_alb, r_alb, r_veg)
[docs] def apply_properties_from_dict(self, abridged_data): """Apply properties from a BuildingUWGPropertiesAbridged dictionary. Args: abridged_data: A BuildingUWGPropertiesAbridged dictionary (typically coming from a Model). """ prog, era, f_can, shgc, w_alb, r_alb, r_veg = self._default_keys(abridged_data) self.program = prog self.vintage = era self.fract_heat_to_canyon = f_can self.shgc = shgc self.wall_albedo = w_alb self.roof_albedo = r_alb self.roof_veg_fraction = r_veg
[docs] def to_dict(self, abridged=False): """Return Building UWG properties as a dictionary. Args: abridged: Boolean for whether the full dictionary of the Building should be written (False) or just the identifier of the the individual properties (True). Default: False. """ base = {'uwg': {}} base['uwg']['type'] = 'BuildingUWGProperties' if not \ abridged else 'BuildingUWGPropertiesAbridged' # write all of the required properties base['uwg']['program'] = self._program base['uwg']['vintage'] = self._vintage base['uwg']['fract_heat_to_canyon'] = self._fract_heat_to_canyon base['uwg']['roof_veg_fraction'] = self._roof_veg_fraction # write all of the optional properties if self._shgc is not None: base['uwg']['shgc'] = self._shgc if self._wall_albedo is not None: base['uwg']['wall_albedo'] = self._wall_albedo if self._roof_albedo is not None: base['uwg']['roof_albedo'] = self._roof_albedo return base
@staticmethod def _default_keys(data): prog = data['program'] if 'program' in data else 'LargeOffice' era = data['vintage'] if 'vintage' in data else 'New' f_can = data['fract_heat_to_canyon'] if 'fract_heat_to_canyon' in data else 0.5 shgc = autocalculate if 'shgc' not in data or \ data['shgc'] == autocalculate.to_dict() else data['shgc'] w_alb = autocalculate if 'wall_albedo' not in data or \ data['wall_albedo'] == autocalculate.to_dict() else data['wall_albedo'] r_alb = autocalculate if 'roof_albedo' not in data or \ data['roof_albedo'] == autocalculate.to_dict() else data['roof_albedo'] r_veg = data['roof_veg_fraction'] if 'roof_veg_fraction' in data else 0 return prog, era, f_can, shgc, w_alb, r_alb, r_veg
[docs] def duplicate(self, new_host=None): """Get a copy of this object. new_host: A new Building object that hosts these properties. If None, the properties will be duplicated with the same host. """ _host = new_host or self._host _new_obj = BuildingUWGProperties( _host, self._program, self._vintage, self._fract_heat_to_canyon) _new_obj._shgc = self._shgc _new_obj._wall_albedo = self._wall_albedo _new_obj._roof_albedo = self._roof_albedo _new_obj._roof_veg_fraction = self._roof_veg_fraction return _new_obj
[docs] def ToString(self): return self.__repr__()
def __repr__(self): return 'Building UWG Properties: {}'.format(self.host.identifier)