# -*- coding: utf-8 -*-
# -*- Python Version: 2.7 -*-
"""HB-PH-HVAC Model Properties."""
try:
from typing import Any, Dict, Optional
except ImportError:
pass # Python 2.7
try:
from itertools import izip as zip # type: ignore
except ImportError:
pass # Python3
try:
from honeybee import extensionutil, model
except ImportError as e:
raise ImportError("\nFailed to import honeybee:\n\t{}".format(e))
try:
from honeybee_phhvac.heat_pumps import PhHeatPumpSystemBuilder
from honeybee_phhvac.heating import PhHeatingSystemBuilder
from honeybee_phhvac.hot_water_system import PhHotWaterSystem
from honeybee_phhvac.renewable_devices import PhRenewableEnergyDeviceBuilder
from honeybee_phhvac.supportive_device import PhSupportiveDevice
from honeybee_phhvac.ventilation import PhExhaustDeviceBuilder, PhVentilationSystem
except ImportError as e:
raise ImportError("\nFailed to import honeybee_phhvac:\n\t{}".format(e))
[docs]
class ModelPhHvacProperties(object):
def __init__(self, _host):
# type: (Optional[model.Model]) -> None
self._host = _host
@property
def host(self):
# type: () -> Optional[model.Model]
return self._host
def __copy__(self, new_host=None):
# type: (Any) -> ModelPhHvacProperties
_host = new_host or self._host
new_properties_obj = ModelPhHvacProperties(_host)
return new_properties_obj
[docs]
def duplicate(self, new_host=None):
# type: (Any) -> ModelPhHvacProperties
return self.__copy__(new_host=new_host)
[docs]
def to_dict(self, abridged=False):
# type: (bool) -> dict[str, dict]
d = {}
if abridged == False:
d["type"] = "ModelPhHvacProperties"
else:
d["type"] = "ModelPhHvacPropertiesAbridged"
return {"ph_hvac": d}
[docs]
@classmethod
def from_dict(cls, _dict, host):
# type: (dict[str, Any], Any) -> ModelPhHvacProperties
if _dict["type"] not in ("ModelPhHvacProperties", "ModelPhHvacPropertiesAbridged"):
raise ValueError(
"Expected ModelPhHvacProperties or ModelPhHvacPropertiesAbridged. Got {}.".format(_dict["type"])
)
new_prop = cls(host)
return new_prop
@staticmethod
def _build_mechanical_devices_from_dict(data):
# type: (list[dict]) -> dict[str, dict[str, Any]]
"""Return a dict of the mechanical systems, keyed by system-type then identifier."""
mechanical_systems = {
"ventilation_systems": {},
"heating_systems": {},
"heat_pump_systems": {},
"exhaust_vent_devices": {},
"supportive_devices": {},
"renewable_devices": {},
"hot_water_systems": {},
}
for room_dict in data:
d = room_dict.get("ventilation_system", {})
if d:
mechanical_systems["ventilation_systems"][d["identifier"]] = PhVentilationSystem.from_dict(d)
for d in room_dict.get("heating_systems", []):
mechanical_systems["heating_systems"][d["identifier"]] = PhHeatingSystemBuilder.from_dict(d)
for d in room_dict.get("heat_pump_systems", []):
mechanical_systems["heat_pump_systems"][d["identifier"]] = PhHeatPumpSystemBuilder.from_dict(d)
for d in room_dict.get("supportive_devices", []):
mechanical_systems["supportive_devices"][d["identifier"]] = PhSupportiveDevice.from_dict(d)
for d in room_dict.get("exhaust_vent_devices", []):
mechanical_systems["exhaust_vent_devices"][d["identifier"]] = PhExhaustDeviceBuilder.from_dict(d)
for d in room_dict.get("renewable_devices", []):
mechanical_systems["renewable_devices"][d["identifier"]] = PhRenewableEnergyDeviceBuilder.from_dict(d)
d = room_dict.get("hot_water_system", {})
if d:
mechanical_systems["hot_water_systems"][d["identifier"]] = PhHotWaterSystem.from_dict(d)
return mechanical_systems
[docs]
@staticmethod
def load_properties_from_dict(data):
# type: (Dict[str, Dict]) -> None
"""Load the ModelPhHvacProperties attributes from an HB-Model dictionary as Python objects.
Loaded objects include: None
The function is called when re-serializing an HB-Model object from a
dictionary. It will load honeybee_ph entities as Python objects and returns
a tuple of dictionaries with all the de-serialized Honeybee-PH objects.
Arguments:
----------
data: A dictionary representation of an entire honeybee-core Model.
Note that this dictionary must have ModelPhProperties
in order for this method to successfully apply the .ph properties.
Note: data is an HB-Model dict and .keys() will include:
[
'display_name', 'identifier', 'tolerance',
'angle_tolerance', 'rooms', 'type', 'version',
'units', 'orphaned_shades', 'properties'
]
"""
assert "ph_hvac" in data["properties"], "Error: HB-Model Dictionary possesses no ModelPhHvacProperties?"
return None
[docs]
def apply_properties_from_dict(self, data):
# type: (Dict[str, Any]) -> None
"""Apply the ".ph_hvac" properties of a dictionary to the host Model of this object.
This method is called when the HB-Model is de-serialized from a dict back into
a Python object. In an 'Abridged' HBJSON file, all the property information
is stored at the model level, not at the sub-model object level. In that case,
this method is used to apply the right property data back onto all the sub-model
objects (faces, rooms, apertures, etc).
Arguments:
----------
* data (dict[str, Any]): A dictionary representation of an entire honeybee-core
Model. Note that this dictionary must have ModelPhHvacProperties
in order for this method to successfully apply the .ph properties.
Note: data is an HB-Model dict and .keys() will include:
[
'display_name', 'identifier', 'tolerance',
'angle_tolerance', 'rooms', 'type', 'version',
'units', 'orphaned_shades', 'properties'
]
Returns:
--------
* None
"""
if not self.host:
return None
assert "ph_hvac" in data["properties"], "Error: Dictionary possesses no ModelPhHvacProperties?"
# -------------------------------------------------------------------------------
# -- 1) Re-build all of the 'ModelPhHvac' objects from the HB-Model dict as python objects
_ = self.load_properties_from_dict(data)
# -------------------------------------------------------------------------------
# -- 2) Collect lists of .ph_hvac property dictionaries at the sub-model level (room, face, etc)
(
room_ph_dicts,
face_ph_dicts,
shd_ph_dicts,
ap_ph_dicts,
dr_ph_dicts,
) = extensionutil.model_extension_dicts(data, "ph_hvac", [], [], [], [], [])
# -------------------------------------------------------------------------------
# -- 3) Re-Build all of the mechanical HVAC objects from the HB-Model dict as python objects
mechanical_systems = self._build_mechanical_devices_from_dict(room_ph_dicts)
# -------------------------------------------------------------------------------
# -- Pass the Mechanical Devices to the Rooms
for room, room_dict in zip(self.host.rooms, room_ph_dicts):
if not room_dict:
continue
room.properties.ph_hvac.apply_properties_from_dict(room_dict, mechanical_systems)
# -- Pull out all the Apertures, Faces, Shades, and Doors from the HB-Model
apertures, faces, shades, doors = [], [], [], []
for hb_room in self.host.rooms:
for face in hb_room.faces:
faces.append(face)
for aperture in face.apertures:
apertures.append(aperture)
for face, face_dict in zip(faces, face_ph_dicts):
face.properties.ph_hvac.apply_properties_from_dict(face_dict)
for aperture, ap_dict in zip(apertures, ap_ph_dicts):
aperture.properties.ph_hvac.apply_properties_from_dict(ap_dict)
for shade, ap_dict in zip(shades, shd_ph_dicts):
shade.properties.ph_hvac.apply_properties_from_dict(ap_dict)
for door, ap_dict in zip(doors, dr_ph_dicts):
door.properties.ph_hvac.apply_properties_from_dict(ap_dict)