complete modification of the structure of the classes that define the buildig for a better adjustment to the different data sources and the connected tools. NOT finished
This commit is contained in:
parent
69169b45b1
commit
77a8969a7e
|
@ -9,131 +9,131 @@ from typing import Union, List
|
|||
|
||||
|
||||
class Schedule:
|
||||
"""
|
||||
"""
|
||||
Schedule class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._id = None
|
||||
self._type = None
|
||||
self._values = None
|
||||
self._data_type = None
|
||||
self._time_step = None
|
||||
self._time_range = None
|
||||
self._day_types = None
|
||||
def __init__(self):
|
||||
self._id = None
|
||||
self._type = None
|
||||
self._values = None
|
||||
self._data_type = None
|
||||
self._time_step = None
|
||||
self._time_range = None
|
||||
self._day_types = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get schedule id, an universally unique identifier randomly generated
|
||||
:return: str
|
||||
"""
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
if self._id is None:
|
||||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule type
|
||||
:return: None or str
|
||||
"""
|
||||
return self._type
|
||||
return self._type
|
||||
|
||||
@type.setter
|
||||
def type(self, value):
|
||||
"""
|
||||
@type.setter
|
||||
def type(self, value):
|
||||
"""
|
||||
Set schedule type
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._type = str(value)
|
||||
if value is not None:
|
||||
self._type = str(value)
|
||||
|
||||
@property
|
||||
def values(self):
|
||||
"""
|
||||
@property
|
||||
def values(self):
|
||||
"""
|
||||
Get schedule values
|
||||
:return: [Any]
|
||||
"""
|
||||
return self._values
|
||||
return self._values
|
||||
|
||||
@values.setter
|
||||
def values(self, value):
|
||||
"""
|
||||
@values.setter
|
||||
def values(self, value):
|
||||
"""
|
||||
Set schedule values
|
||||
:param: [Any]
|
||||
"""
|
||||
self._values = value
|
||||
self._values = value
|
||||
|
||||
@property
|
||||
def data_type(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def data_type(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule data type from:
|
||||
['any_number', 'fraction', 'on_off', 'temperature', 'humidity', 'control_type']
|
||||
:return: None or str
|
||||
"""
|
||||
return self._data_type
|
||||
return self._data_type
|
||||
|
||||
@data_type.setter
|
||||
def data_type(self, value):
|
||||
"""
|
||||
@data_type.setter
|
||||
def data_type(self, value):
|
||||
"""
|
||||
Set schedule data type
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._data_type = str(value)
|
||||
if value is not None:
|
||||
self._data_type = str(value)
|
||||
|
||||
@property
|
||||
def time_step(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def time_step(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule time step from:
|
||||
['second', 'minute', 'hour', 'day', 'week', 'month']
|
||||
:return: None or str
|
||||
"""
|
||||
return self._time_step
|
||||
return self._time_step
|
||||
|
||||
@time_step.setter
|
||||
def time_step(self, value):
|
||||
"""
|
||||
@time_step.setter
|
||||
def time_step(self, value):
|
||||
"""
|
||||
Set schedule time step
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._time_step = str(value)
|
||||
if value is not None:
|
||||
self._time_step = str(value)
|
||||
|
||||
@property
|
||||
def time_range(self) -> Union[None, str]:
|
||||
"""
|
||||
@property
|
||||
def time_range(self) -> Union[None, str]:
|
||||
"""
|
||||
Get schedule time range from:
|
||||
['minute', 'hour', 'day', 'week', 'month', 'year']
|
||||
:return: None or str
|
||||
"""
|
||||
return self._time_range
|
||||
return self._time_range
|
||||
|
||||
@time_range.setter
|
||||
def time_range(self, value):
|
||||
"""
|
||||
@time_range.setter
|
||||
def time_range(self, value):
|
||||
"""
|
||||
Set schedule time range
|
||||
:param: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._time_range = str(value)
|
||||
if value is not None:
|
||||
self._time_range = str(value)
|
||||
|
||||
@property
|
||||
def day_types(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
@property
|
||||
def day_types(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get schedule day types, as many as needed from:
|
||||
['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'holiday', 'winter_design_day',
|
||||
'summer_design_day']
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._day_types
|
||||
return self._day_types
|
||||
|
||||
@day_types.setter
|
||||
def day_types(self, value):
|
||||
"""
|
||||
@day_types.setter
|
||||
def day_types(self, value):
|
||||
"""
|
||||
Set schedule day types
|
||||
:param: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._day_types = [str(i) for i in value]
|
||||
if value is not None:
|
||||
self._day_types = [str(i) for i in value]
|
||||
|
|
|
@ -5,18 +5,15 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List, Union, TypeVar
|
||||
from typing import List, Union
|
||||
import numpy as np
|
||||
from city_model_structure.building_demand.surface import Surface
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.storey import Storey
|
||||
from city_model_structure.city_object import CityObject
|
||||
from city_model_structure.building_demand.household import Household
|
||||
from city_model_structure.building_demand.internal_zone import InternalZone
|
||||
from city_model_structure.attributes.polyhedron import Polyhedron
|
||||
|
||||
ThermalZone = TypeVar('ThermalZone')
|
||||
|
||||
|
||||
class Building(CityObject):
|
||||
"""
|
||||
|
@ -36,9 +33,7 @@ class Building(CityObject):
|
|||
self._roof_type = None
|
||||
self._storeys = None
|
||||
self._internal_zones = None
|
||||
self._shell = None
|
||||
self._thermal_zones = None
|
||||
self._usage_zones = None
|
||||
self._shell = None
|
||||
self._type = 'building'
|
||||
self._heating = dict()
|
||||
self._cooling = dict()
|
||||
|
@ -108,22 +103,6 @@ class Building(CityObject):
|
|||
"""
|
||||
return self._walls
|
||||
|
||||
@property
|
||||
def usage_zones(self) -> Union[None, List[UsageZone]]:
|
||||
"""
|
||||
Get city object usage zones
|
||||
:return: [UsageZone]
|
||||
"""
|
||||
return self._usage_zones
|
||||
|
||||
@usage_zones.setter
|
||||
def usage_zones(self, value):
|
||||
"""
|
||||
Set city object usage zones
|
||||
:param value: [UsageZone]
|
||||
"""
|
||||
self._usage_zones = value
|
||||
|
||||
@property
|
||||
def terrains(self) -> Union[None, List[Surface]]:
|
||||
"""
|
||||
|
@ -166,22 +145,6 @@ class Building(CityObject):
|
|||
if value is not None:
|
||||
self._basement_heated = int(value)
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
"""
|
||||
Get building thermal zones
|
||||
:return: [ThermalZone]
|
||||
"""
|
||||
return self._thermal_zones
|
||||
|
||||
@thermal_zones.setter
|
||||
def thermal_zones(self, value):
|
||||
"""
|
||||
Set city object thermal zones
|
||||
:param value: [ThermalZone]
|
||||
"""
|
||||
self._thermal_zones = value
|
||||
|
||||
@property
|
||||
def heated_volume(self):
|
||||
"""
|
||||
|
@ -368,9 +331,11 @@ class Building(CityObject):
|
|||
Get building heated flag
|
||||
:return: Boolean
|
||||
"""
|
||||
if self.thermal_zones is None:
|
||||
if self.internal_zones is None:
|
||||
return False
|
||||
for thermal_zone in self.thermal_zones:
|
||||
if thermal_zone.hvac_system is not None:
|
||||
return True
|
||||
for internal_zone in self.internal_zones:
|
||||
if internal_zone.usage_zones is not None:
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
if usage_zone.thermal_control is not None:
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -3,7 +3,7 @@ Appliances module
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
|
@ -12,28 +12,28 @@ class Appliances:
|
|||
Appliances class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._lighting_density = None
|
||||
self._appliances_density = None
|
||||
self._convective_fraction = None
|
||||
self._radiant_fraction = None
|
||||
self._radiative_fraction = None
|
||||
self._latent_fraction = None
|
||||
self._schedule = None
|
||||
self._schedules = None
|
||||
|
||||
@property
|
||||
def lighting_density(self) -> Union[None, float]:
|
||||
def appliances_density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get lighting density in Watts per m2
|
||||
Get appliances density in Watts per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._lighting_density
|
||||
return self._appliances_density
|
||||
|
||||
@lighting_density.setter
|
||||
def lighting_density(self, value):
|
||||
@appliances_density.setter
|
||||
def appliances_density(self, value):
|
||||
"""
|
||||
Set lighting density in Watts per m2
|
||||
Set appliances density in Watts per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._lighting_density = float(value)
|
||||
self._appliances_density = float(value)
|
||||
|
||||
@property
|
||||
def convective_fraction(self) -> Union[None, float]:
|
||||
|
@ -53,21 +53,21 @@ class Appliances:
|
|||
self._convective_fraction = float(value)
|
||||
|
||||
@property
|
||||
def radiant_fraction(self) -> Union[None, float]:
|
||||
def radiative_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get radiant fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._radiant_fraction
|
||||
return self._radiative_fraction
|
||||
|
||||
@radiant_fraction.setter
|
||||
def radiant_fraction(self, value):
|
||||
@radiative_fraction.setter
|
||||
def radiative_fraction(self, value):
|
||||
"""
|
||||
Set radiant fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._radiant_fraction = float(value)
|
||||
self._radiative_fraction = float(value)
|
||||
|
||||
@property
|
||||
def latent_fraction(self) -> Union[None, float]:
|
||||
|
@ -87,17 +87,17 @@ class Appliances:
|
|||
self._latent_fraction = float(value)
|
||||
|
||||
@property
|
||||
def schedule(self) -> Union[None, Schedule]:
|
||||
def schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get schedule
|
||||
:return: None or Schedule
|
||||
Get schedules
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._schedule
|
||||
return self._schedules
|
||||
|
||||
@schedule.setter
|
||||
def schedule(self, value):
|
||||
@schedules.setter
|
||||
def schedules(self, value):
|
||||
"""
|
||||
Set schedule
|
||||
:param value: Schedule
|
||||
Set schedules
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._schedule = value
|
||||
self._schedules = value
|
||||
|
|
|
@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import Union
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@ class InternalGains:
|
|||
self._convective_fraction = None
|
||||
self._radiative_fraction = None
|
||||
self._latent_fraction = None
|
||||
self._schedule = None
|
||||
self._schedules = None
|
||||
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
|
@ -107,17 +107,17 @@ class InternalGains:
|
|||
self._latent_fraction = float(value)
|
||||
|
||||
@property
|
||||
def schedule(self) -> Union[None, Schedule]:
|
||||
def schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get internal gain schedule
|
||||
:return: Schedule
|
||||
:return: [Schedule]
|
||||
"""
|
||||
return self._schedule
|
||||
return self._schedules
|
||||
|
||||
@schedule.setter
|
||||
def schedule(self, value):
|
||||
@schedules.setter
|
||||
def schedules(self, value):
|
||||
"""
|
||||
Set internal gain schedule
|
||||
:param value: Schedule
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._schedule = value
|
||||
self._schedules = value
|
||||
|
|
|
@ -3,9 +3,13 @@ InternalZone module. It saves the original geometrical information from interior
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from typing import Union, List
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
from city_model_structure.attributes.polyhedron import Polyhedron
|
||||
from city_model_structure.energy_systems.hvac_system import HvacSystem
|
||||
|
||||
|
||||
class InternalZone:
|
||||
|
@ -18,7 +22,9 @@ class InternalZone:
|
|||
self._geometry = None
|
||||
self._volume = None
|
||||
self._area = area
|
||||
self._usage_zones = []
|
||||
self._thermal_zones = None
|
||||
self._usage_zones = None
|
||||
self._hvac_system = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -82,3 +88,36 @@ class InternalZone:
|
|||
:param value: [UsageZone]
|
||||
"""
|
||||
self._usage_zones = value
|
||||
|
||||
@property
|
||||
def hvac_system(self) -> Union[None, HvacSystem]:
|
||||
"""
|
||||
Get HVAC system installed for this thermal zone
|
||||
:return: None or HvacSystem
|
||||
"""
|
||||
return self._hvac_system
|
||||
|
||||
@hvac_system.setter
|
||||
def hvac_system(self, value):
|
||||
"""
|
||||
Set HVAC system installed for this thermal zone
|
||||
:param value: HvacSystem
|
||||
"""
|
||||
self._hvac_system = value
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
"""
|
||||
Get building thermal zones
|
||||
:return: [ThermalZone]
|
||||
"""
|
||||
return self._thermal_zones
|
||||
|
||||
@thermal_zones.setter
|
||||
def thermal_zones(self, value):
|
||||
"""
|
||||
Set city object thermal zones
|
||||
:param value: [ThermalZone]
|
||||
"""
|
||||
self._thermal_zones = value
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ Lighting module
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
|
@ -14,9 +14,9 @@ class Lighting:
|
|||
def __init__(self):
|
||||
self._lighting_density = None
|
||||
self._convective_fraction = None
|
||||
self._radiant_fraction = None
|
||||
self._radiative_fraction = None
|
||||
self._latent_fraction = None
|
||||
self._schedule = None
|
||||
self._schedules = None
|
||||
|
||||
@property
|
||||
def lighting_density(self) -> Union[None, float]:
|
||||
|
@ -53,21 +53,21 @@ class Lighting:
|
|||
self._convective_fraction = float(value)
|
||||
|
||||
@property
|
||||
def radiant_fraction(self) -> Union[None, float]:
|
||||
def radiative_fraction(self) -> Union[None, float]:
|
||||
"""
|
||||
Get radiant fraction
|
||||
:return: None or float
|
||||
"""
|
||||
return self._radiant_fraction
|
||||
return self._radiative_fraction
|
||||
|
||||
@radiant_fraction.setter
|
||||
def radiant_fraction(self, value):
|
||||
@radiative_fraction.setter
|
||||
def radiative_fraction(self, value):
|
||||
"""
|
||||
Set radiant fraction
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._radiant_fraction = float(value)
|
||||
self._radiative_fraction = float(value)
|
||||
|
||||
@property
|
||||
def latent_fraction(self) -> Union[None, float]:
|
||||
|
@ -87,17 +87,17 @@ class Lighting:
|
|||
self._latent_fraction = float(value)
|
||||
|
||||
@property
|
||||
def schedule(self) -> Union[None, Schedule]:
|
||||
def schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get schedule
|
||||
:return: None or Schedule
|
||||
Get schedules
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._schedule
|
||||
return self._schedules
|
||||
|
||||
@schedule.setter
|
||||
def schedule(self, value):
|
||||
@schedules.setter
|
||||
def schedules(self, value):
|
||||
"""
|
||||
Set schedule
|
||||
:param value: Schedule
|
||||
Set schedules
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._schedule = value
|
||||
self._schedules = value
|
||||
|
|
|
@ -15,9 +15,9 @@ class Occupancy:
|
|||
def __init__(self):
|
||||
self._occupancy_density = None
|
||||
self._sensible_convective_internal_gain = None
|
||||
self._sensible_radiant_internal_gain = None
|
||||
self._sensible_radiative_internal_gain = None
|
||||
self._latent_internal_gain = None
|
||||
self._occupancy_schedule = None
|
||||
self._occupancy_schedules = None
|
||||
self._occupants = None
|
||||
|
||||
@property
|
||||
|
@ -55,21 +55,21 @@ class Occupancy:
|
|||
self._sensible_convective_internal_gain = float(value)
|
||||
|
||||
@property
|
||||
def sensible_radiant_internal_gain(self) -> Union[None, float]:
|
||||
def sensible_radiative_internal_gain(self) -> Union[None, float]:
|
||||
"""
|
||||
Get sensible radiant internal gain in Watts per m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._sensible_radiant_internal_gain
|
||||
return self._sensible_radiative_internal_gain
|
||||
|
||||
@sensible_radiant_internal_gain.setter
|
||||
def sensible_radiant_internal_gain(self, value):
|
||||
@sensible_radiative_internal_gain.setter
|
||||
def sensible_radiative_internal_gain(self, value):
|
||||
"""
|
||||
Set sensible radiant internal gain in Watts per m2
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._sensible_radiant_internal_gain = float(value)
|
||||
self._sensible_radiative_internal_gain = float(value)
|
||||
|
||||
@property
|
||||
def latent_internal_gain(self) -> Union[None, float]:
|
||||
|
@ -89,20 +89,20 @@ class Occupancy:
|
|||
self._latent_internal_gain = float(value)
|
||||
|
||||
@property
|
||||
def occupancy_schedule(self) -> Union[None, Schedule]:
|
||||
def occupancy_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get occupancy schedule
|
||||
:return: None or Schedule
|
||||
Get occupancy schedules
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._occupancy_schedule
|
||||
return self._occupancy_schedules
|
||||
|
||||
@occupancy_schedule.setter
|
||||
def occupancy_schedule(self, value):
|
||||
@occupancy_schedules.setter
|
||||
def occupancy_schedules(self, value):
|
||||
"""
|
||||
Set occupancy schedule
|
||||
:param value: Schedule
|
||||
Set occupancy schedules
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._occupancy_schedule = value
|
||||
self._occupancy_schedules = value
|
||||
|
||||
@property
|
||||
def occupants(self) -> Union[None, List[Occupant]]:
|
||||
|
|
|
@ -3,7 +3,7 @@ ThermalControl module
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import Union
|
||||
from typing import Union, List
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
|
@ -12,35 +12,59 @@ class ThermalControl:
|
|||
ThermalControl class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._heating_set_point = None
|
||||
self._cooling_set_point = None
|
||||
self._hvac_availability = None
|
||||
self._mean_heating_set_point = None
|
||||
self._heating_set_back = None
|
||||
self._mean_cooling_set_point = None
|
||||
self._hvac_availability_schedules = None
|
||||
self._heating_set_point_schedules = None
|
||||
self._cooling_set_point_schedules = None
|
||||
|
||||
@staticmethod
|
||||
def _maximum_value(schedules):
|
||||
maximum = -1000
|
||||
for schedule in schedules:
|
||||
for value in schedule.values:
|
||||
if value > maximum:
|
||||
maximum = value
|
||||
return maximum
|
||||
|
||||
@staticmethod
|
||||
def _minimum_value(schedules):
|
||||
minimum = 1000
|
||||
for schedule in schedules:
|
||||
for value in schedule.values:
|
||||
if value < minimum:
|
||||
minimum = value
|
||||
return minimum
|
||||
|
||||
@property
|
||||
def heating_set_point(self) -> Union[None, Schedule]:
|
||||
def mean_heating_set_point(self) -> Union[None, float]:
|
||||
"""
|
||||
Get heating set point defined for a thermal zone in Celsius
|
||||
:return: None or Schedule
|
||||
:return: None or float
|
||||
"""
|
||||
return self._heating_set_point
|
||||
if self._mean_heating_set_point is None:
|
||||
if self.heating_set_point_schedules is not None:
|
||||
self._mean_heating_set_point = self._maximum_value(self.heating_set_point_schedules)
|
||||
return self._mean_heating_set_point
|
||||
|
||||
@heating_set_point.setter
|
||||
def heating_set_point(self, value):
|
||||
@mean_heating_set_point.setter
|
||||
def mean_heating_set_point(self, value):
|
||||
"""
|
||||
Set heating set point defined for a thermal zone in Celsius
|
||||
:param value: Schedule
|
||||
:param value: float
|
||||
"""
|
||||
self._heating_set_point = value
|
||||
self._mean_heating_set_point = value
|
||||
|
||||
@property
|
||||
def heating_set_back(self) -> Union[None, float]:
|
||||
"""
|
||||
Get heating set back defined for a thermal zone in Celsius
|
||||
Heating set back is the only parameter which is not a schedule as it is either one value or it is implicit in the
|
||||
set point schedule
|
||||
:return: None or float
|
||||
"""
|
||||
if self._heating_set_back is None:
|
||||
if self.heating_set_point_schedules is not None:
|
||||
self._heating_set_back = self._minimum_value(self.heating_set_point_schedules)
|
||||
return self._heating_set_back
|
||||
|
||||
@heating_set_back.setter
|
||||
|
@ -53,34 +77,68 @@ class ThermalControl:
|
|||
self._heating_set_back = float(value)
|
||||
|
||||
@property
|
||||
def cooling_set_point(self) -> Union[None, Schedule]:
|
||||
def mean_cooling_set_point(self) -> Union[None, float]:
|
||||
"""
|
||||
Get cooling set point defined for a thermal zone in Celsius
|
||||
:return: None or Schedule
|
||||
:return: None or float
|
||||
"""
|
||||
return self._cooling_set_point
|
||||
if self._mean_cooling_set_point is None:
|
||||
if self.cooling_set_point_schedules is not None:
|
||||
self._mean_cooling_set_point = self._minimum_value(self.cooling_set_point_schedules)
|
||||
return self._mean_cooling_set_point
|
||||
|
||||
@cooling_set_point.setter
|
||||
def cooling_set_point(self, value):
|
||||
@mean_cooling_set_point.setter
|
||||
def mean_cooling_set_point(self, value):
|
||||
"""
|
||||
Set cooling set point defined for a thermal zone in Celsius
|
||||
:param value: Schedule
|
||||
:param value: float
|
||||
"""
|
||||
self._cooling_set_point = value
|
||||
self._mean_cooling_set_point = value
|
||||
|
||||
@property
|
||||
def hvac_availability(self) -> Union[None, Schedule]:
|
||||
def hvac_availability_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get the availability of the conditioning system defined for a thermal zone
|
||||
:return: None or Schedule
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._hvac_availability
|
||||
return self._hvac_availability_schedules
|
||||
|
||||
@hvac_availability.setter
|
||||
def hvac_availability(self, value):
|
||||
@hvac_availability_schedules.setter
|
||||
def hvac_availability_schedules(self, value):
|
||||
"""
|
||||
Set the availability of the conditioning system defined for a thermal zone
|
||||
:param value: Schedule
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._hvac_availability = value
|
||||
self._hvac_availability_schedules = value
|
||||
|
||||
@property
|
||||
def heating_set_point_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get heating set point schedule defined for a thermal zone in Celsius
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._heating_set_point_schedules
|
||||
|
||||
@heating_set_point_schedules.setter
|
||||
def heating_set_point_schedules(self, value):
|
||||
"""
|
||||
Set heating set point schedule defined for a thermal zone in Celsius
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._heating_set_point_schedules = value
|
||||
|
||||
@property
|
||||
def cooling_set_point_schedules(self) -> Union[None, List[Schedule]]:
|
||||
"""
|
||||
Get cooling set point schedule defined for a thermal zone in Celsius
|
||||
:return: None or [Schedule]
|
||||
"""
|
||||
return self._cooling_set_point_schedules
|
||||
|
||||
@cooling_set_point_schedules.setter
|
||||
def cooling_set_point_schedules(self, value):
|
||||
"""
|
||||
Set cooling set point schedule defined for a thermal zone in Celsius
|
||||
:param value: [Schedule]
|
||||
"""
|
||||
self._cooling_set_point_schedules = value
|
||||
|
|
|
@ -5,11 +5,11 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
import uuid
|
||||
from typing import List, Union, Tuple, TypeVar
|
||||
from typing import List, Union, TypeVar
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
from city_model_structure.energy_systems.hvac_system import HvacSystem
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
ThermalBoundary = TypeVar('ThermalBoundary')
|
||||
|
||||
|
@ -27,11 +27,12 @@ class ThermalZone:
|
|||
self._indirectly_heated_area_ratio = None
|
||||
self._infiltration_rate_system_on = None
|
||||
self._infiltration_rate_system_off = None
|
||||
self._usage_zones = None
|
||||
self._volume = volume
|
||||
self._ordinate_number = None
|
||||
self._usage_zones = None
|
||||
self._thermal_control = None
|
||||
self._hvac_system = None
|
||||
self._view_factors_matrix = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -142,22 +143,6 @@ class ThermalZone:
|
|||
"""
|
||||
self._infiltration_rate_system_off = value
|
||||
|
||||
@property
|
||||
def usage_zones(self) -> Tuple[float, UsageZone]:
|
||||
"""
|
||||
Get list of usage zones and the percentage of thermal zone's volume affected by that usage
|
||||
:return: [UsageZone]
|
||||
"""
|
||||
return self._usage_zones
|
||||
|
||||
@usage_zones.setter
|
||||
def usage_zones(self, values):
|
||||
"""
|
||||
Set list of usage zones and the percentage of thermal zone's volume affected by that usage
|
||||
:param values: Tuple[float, UsageZone]
|
||||
"""
|
||||
self._usage_zones = values
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
"""
|
||||
|
@ -183,10 +168,29 @@ class ThermalZone:
|
|||
if value is not None:
|
||||
self._ordinate_number = int(value)
|
||||
|
||||
@property
|
||||
def usage_zones(self) -> [UsageZone]:
|
||||
"""
|
||||
Get list of usage zones and the percentage of thermal zone's volume affected by that usage
|
||||
From internal_zone
|
||||
:return: [UsageZone]
|
||||
"""
|
||||
return self._usage_zones
|
||||
|
||||
@usage_zones.setter
|
||||
def usage_zones(self, values):
|
||||
"""
|
||||
Set list of usage zones and the percentage of thermal zone's volume affected by that usage
|
||||
From internal_zone
|
||||
:param values: [UsageZone]
|
||||
"""
|
||||
self._usage_zones = values
|
||||
|
||||
@property
|
||||
def thermal_control(self) -> Union[None, ThermalControl]:
|
||||
"""
|
||||
Get thermal control of this thermal zone
|
||||
From internal_zone
|
||||
:return: None or ThermalControl
|
||||
"""
|
||||
return self._thermal_control
|
||||
|
@ -195,6 +199,7 @@ class ThermalZone:
|
|||
def thermal_control(self, value):
|
||||
"""
|
||||
Set thermal control for this thermal zone
|
||||
From internal_zone
|
||||
:param value: ThermalControl
|
||||
"""
|
||||
self._thermal_control = value
|
||||
|
@ -203,6 +208,7 @@ class ThermalZone:
|
|||
def hvac_system(self) -> Union[None, HvacSystem]:
|
||||
"""
|
||||
Get HVAC system installed for this thermal zone
|
||||
From internal_zone
|
||||
:return: None or HvacSystem
|
||||
"""
|
||||
return self._hvac_system
|
||||
|
@ -211,6 +217,23 @@ class ThermalZone:
|
|||
def hvac_system(self, value):
|
||||
"""
|
||||
Set HVAC system installed for this thermal zone
|
||||
From internal_zone
|
||||
:param value: HvacSystem
|
||||
"""
|
||||
self._hvac_system = value
|
||||
|
||||
@property
|
||||
def view_factors_matrix(self):
|
||||
"""
|
||||
Get thermal zone view factors matrix
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._view_factors_matrix
|
||||
|
||||
@view_factors_matrix.setter
|
||||
def view_factors_matrix(self, value):
|
||||
"""
|
||||
Set thermal zone view factors matrix
|
||||
:param value: [[float]]
|
||||
"""
|
||||
self._view_factors_matrix = value
|
||||
|
|
|
@ -11,6 +11,7 @@ from city_model_structure.building_demand.internal_gains import InternalGains
|
|||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.lighting import Lighting
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
|
||||
|
||||
class UsageZone:
|
||||
|
@ -20,6 +21,7 @@ class UsageZone:
|
|||
def __init__(self):
|
||||
self._id = None
|
||||
self._usage = None
|
||||
self._percentage = None
|
||||
self._not_detailed_source_mean_annual_internal_gains = None
|
||||
self._hours_day = None
|
||||
self._days_year = None
|
||||
|
@ -29,6 +31,7 @@ class UsageZone:
|
|||
self._lighting = None
|
||||
self._appliances = None
|
||||
self._internal_gains = None
|
||||
self._thermal_control = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -40,6 +43,40 @@ class UsageZone:
|
|||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def usage(self) -> Union[None, str]:
|
||||
"""
|
||||
Get usage zone usage
|
||||
:return: None or str
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
@usage.setter
|
||||
def usage(self, value):
|
||||
"""
|
||||
Set usage zone usage
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._usage = str(value)
|
||||
|
||||
@property
|
||||
def percentage(self):
|
||||
"""
|
||||
Get usage zone percentage in range[0,1]
|
||||
:return: float
|
||||
"""
|
||||
return self._percentage
|
||||
|
||||
@percentage.setter
|
||||
def percentage(self, value):
|
||||
"""
|
||||
Set usage zone percentage in range[0,1]
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._percentage = float(value)
|
||||
|
||||
@property
|
||||
def not_detailed_source_mean_annual_internal_gains(self) -> List[InternalGains]:
|
||||
"""
|
||||
|
@ -107,23 +144,6 @@ class UsageZone:
|
|||
if value is not None:
|
||||
self._mechanical_air_change = float(value)
|
||||
|
||||
@property
|
||||
def usage(self) -> Union[None, str]:
|
||||
"""
|
||||
Get usage zone usage
|
||||
:return: None or str
|
||||
"""
|
||||
return self._usage
|
||||
|
||||
@usage.setter
|
||||
def usage(self, value):
|
||||
"""
|
||||
Set usage zone usage
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._usage = str(value)
|
||||
|
||||
@property
|
||||
def electrical_app_average_consumption_sqm_year(self) -> Union[None, float]:
|
||||
"""
|
||||
|
@ -199,22 +219,22 @@ class UsageZone:
|
|||
_internal_gain = InternalGains()
|
||||
_internal_gain.type = cte.OCCUPANCY
|
||||
_total_heat_gain = (self.occupancy.sensible_convective_internal_gain
|
||||
+ self.occupancy.sensible_radiant_internal_gain
|
||||
+ self.occupancy.sensible_radiative_internal_gain
|
||||
+ self.occupancy.latent_internal_gain)
|
||||
_internal_gain.average_internal_gain = _total_heat_gain
|
||||
_internal_gain.latent_fraction = self.occupancy.latent_internal_gain / _total_heat_gain
|
||||
_internal_gain.radiative_fraction = self.occupancy.sensible_radiant_internal_gain / _total_heat_gain
|
||||
_internal_gain.radiative_fraction = self.occupancy.sensible_radiative_internal_gain / _total_heat_gain
|
||||
_internal_gain.convective_fraction = self.occupancy.sensible_convective_internal_gain / _total_heat_gain
|
||||
_internal_gain.schedule = self.occupancy.occupancy_schedule
|
||||
_internal_gain.schedules = self.occupancy.occupancy_schedules
|
||||
self._internal_gains = [_internal_gain]
|
||||
if self.lighting is not None:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.type = cte.LIGHTING
|
||||
_internal_gain.average_internal_gain = self.lighting.lighting_density
|
||||
_internal_gain.latent_fraction = self.lighting.latent_fraction
|
||||
_internal_gain.radiative_fraction = self.lighting.radiant_fraction
|
||||
_internal_gain.radiative_fraction = self.lighting.radiative_fraction
|
||||
_internal_gain.convective_fraction = self.lighting.convective_fraction
|
||||
_internal_gain.schedule = self.lighting.schedule
|
||||
_internal_gain.schedules = self.lighting.schedules
|
||||
if self._internal_gains is not None:
|
||||
self._internal_gains.append(_internal_gain)
|
||||
else:
|
||||
|
@ -222,13 +242,29 @@ class UsageZone:
|
|||
if self.appliances is not None:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.type = cte.APPLIANCES
|
||||
_internal_gain.average_internal_gain = self.appliances.lighting_density
|
||||
_internal_gain.average_internal_gain = self.appliances.appliances_density
|
||||
_internal_gain.latent_fraction = self.appliances.latent_fraction
|
||||
_internal_gain.radiative_fraction = self.appliances.radiant_fraction
|
||||
_internal_gain.radiative_fraction = self.appliances.radiative_fraction
|
||||
_internal_gain.convective_fraction = self.appliances.convective_fraction
|
||||
_internal_gain.schedule = self.appliances.schedule
|
||||
_internal_gain.schedules = self.appliances.schedules
|
||||
if self._internal_gains is not None:
|
||||
self._internal_gains.append(_internal_gain)
|
||||
else:
|
||||
self._internal_gains = [_internal_gain]
|
||||
return self._internal_gains
|
||||
|
||||
@property
|
||||
def thermal_control(self) -> Union[None, ThermalControl]:
|
||||
"""
|
||||
Get thermal control of this thermal zone
|
||||
:return: None or ThermalControl
|
||||
"""
|
||||
return self._thermal_control
|
||||
|
||||
@thermal_control.setter
|
||||
def thermal_control(self, value):
|
||||
"""
|
||||
Set thermal control for this thermal zone
|
||||
:param value: ThermalControl
|
||||
"""
|
||||
self._thermal_control = value
|
||||
|
|
BIN
data/usage/comnet_schedules_archetypes.xlsx
Normal file
BIN
data/usage/comnet_schedules_archetypes.xlsx
Normal file
Binary file not shown.
|
@ -84,7 +84,7 @@
|
|||
<weekDayProfile>
|
||||
<source>DIN 18599-10</source>
|
||||
<values>16.0 16.0 16.0 16.0 16.0 16.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 0.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
</values>
|
||||
</weekDayProfile>
|
||||
</schedule>
|
||||
|
@ -117,7 +117,7 @@
|
|||
<schedule>
|
||||
<weekDayProfile>
|
||||
<values>16.0 16.0 16.0 16.0 16.0 16.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 0.0
|
||||
20.0 20.0 20.0 20.0 20.0 20.0 20.0
|
||||
</values>
|
||||
</weekDayProfile>
|
||||
</schedule>
|
||||
|
|
|
@ -11,6 +11,7 @@ KELVIN = 273.15
|
|||
HOUR_TO_MINUTES = 60
|
||||
METERS_TO_FEET = 3.28084
|
||||
BTU_H_TO_WATTS = 0.29307107
|
||||
KILO_WATTS_HOUR_TO_JULES = 3600000
|
||||
|
||||
# time
|
||||
SECOND = 'second'
|
||||
|
|
|
@ -25,23 +25,25 @@ class CaPhysicsParameters(NrelPhysicsInterface):
|
|||
city = self._city
|
||||
# it is assumed that all buildings have the same archetypes' keys
|
||||
for building in city.buildings:
|
||||
archetype = self._search_archetype(ConstructionHelper.nrcan_from_function(building.function),
|
||||
building.year_of_construction)
|
||||
if archetype is None:
|
||||
try:
|
||||
archetype = self._search_archetype(ConstructionHelper.nrcan_from_function(building.function),
|
||||
building.year_of_construction)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function: '
|
||||
f'{ConstructionHelper.nrcan_from_function(building.function)} '
|
||||
f'and building year of construction: {building.year_of_construction}\n')
|
||||
continue
|
||||
return
|
||||
|
||||
# if building has no thermal zones defined from geometry, one thermal zone per storey is assigned
|
||||
if building.thermal_zones is None:
|
||||
self._create_storeys(building, archetype)
|
||||
thermal_zones = []
|
||||
for storey in building.storeys:
|
||||
thermal_zones.append(storey.thermal_zone)
|
||||
building.thermal_zones = thermal_zones
|
||||
if len(building.internal_zones) == 1:
|
||||
if building.internal_zones[0].thermal_zones is None:
|
||||
self._create_storeys(building, archetype)
|
||||
thermal_zones = []
|
||||
for storey in building.storeys:
|
||||
thermal_zones.append(storey.thermal_zone)
|
||||
building.internal_zones[0].thermal_zones = thermal_zones
|
||||
|
||||
self._assign_values(building, archetype)
|
||||
self._assign_values(building.internal_zones, archetype)
|
||||
|
||||
def _search_archetype(self, function, year_of_construction):
|
||||
for building_archetype in self._building_archetypes:
|
||||
|
@ -54,31 +56,32 @@ class CaPhysicsParameters(NrelPhysicsInterface):
|
|||
return building_archetype
|
||||
return None
|
||||
|
||||
def _assign_values(self, building, archetype):
|
||||
for thermal_zone in building.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrcan_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
thermal_boundary.u_value = thermal_boundary_archetype.overall_u_value
|
||||
thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
try:
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
except ValueError:
|
||||
# This is the normal operation way when the windows are defined in the geometry
|
||||
continue
|
||||
if thermal_boundary.thermal_openings is not None:
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening_archetype is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening_archetype
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.overall_u_value = thermal_opening_archetype.overall_u_value
|
||||
def _assign_values(self, internal_zones, archetype):
|
||||
for internal_zone in internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrcan_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
thermal_boundary.u_value = thermal_boundary_archetype.overall_u_value
|
||||
thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
try:
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
except ValueError:
|
||||
# This is the normal operation way when the windows are defined in the geometry
|
||||
continue
|
||||
if thermal_boundary.thermal_openings is not None:
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening_archetype is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening_archetype
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.overall_u_value = thermal_opening_archetype.overall_u_value
|
||||
|
||||
@staticmethod
|
||||
def _create_storeys(building, archetype):
|
||||
|
|
|
@ -12,7 +12,7 @@ class ConstructionHelper:
|
|||
Construction helper
|
||||
"""
|
||||
# NREL
|
||||
function_to_nrel = {
|
||||
_function_to_nrel = {
|
||||
cte.RESIDENTIAL: 'residential',
|
||||
cte.SFH: 'single family house',
|
||||
cte.MFH: 'multifamily house',
|
||||
|
@ -27,12 +27,12 @@ class ConstructionHelper:
|
|||
cte.OFFICE: 'office',
|
||||
cte.LARGE_OFFICE: 'large office'
|
||||
}
|
||||
nrel_function_default_value = 'residential'
|
||||
nrel_standards = {
|
||||
|
||||
_nrel_standards = {
|
||||
'ASHRAE Std189': 1,
|
||||
'ASHRAE 90.1_2004': 2
|
||||
}
|
||||
reference_city_to_nrel_climate_zone = {
|
||||
_reference_city_to_nrel_climate_zone = {
|
||||
'Miami': 'ASHRAE_2004:1A',
|
||||
'Houston': 'ASHRAE_2004:2A',
|
||||
'Phoenix': 'ASHRAE_2004:2B',
|
||||
|
@ -51,6 +51,7 @@ class ConstructionHelper:
|
|||
'Fairbanks': 'ASHRAE_2004:8A'
|
||||
}
|
||||
nrel_window_types = [cte.WINDOW, cte.DOOR, cte.SKYLIGHT]
|
||||
|
||||
nrel_construction_types = {
|
||||
cte.WALL: 'exterior wall',
|
||||
cte.INTERIOR_WALL: 'interior wall',
|
||||
|
@ -62,7 +63,7 @@ class ConstructionHelper:
|
|||
}
|
||||
|
||||
# NRCAN
|
||||
function_to_nrcan = {
|
||||
_function_to_nrcan = {
|
||||
cte.RESIDENTIAL: 'residential',
|
||||
cte.SFH: 'single family house',
|
||||
cte.MFH: 'multifamily house',
|
||||
|
@ -78,8 +79,9 @@ class ConstructionHelper:
|
|||
cte.LARGE_OFFICE: 'large office',
|
||||
cte.OFFICE_WORKSHOP: 'residential'
|
||||
}
|
||||
nrcan_function_default_value = 'residential'
|
||||
|
||||
nrcan_window_types = [cte.WINDOW]
|
||||
|
||||
nrcan_construction_types = {
|
||||
cte.WALL: 'wall',
|
||||
cte.GROUND_WALL: 'basement_wall',
|
||||
|
@ -97,10 +99,9 @@ class ConstructionHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return ConstructionHelper.function_to_nrel[function]
|
||||
return ConstructionHelper._function_to_nrel[function]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default NREL function "residential"\n')
|
||||
return ConstructionHelper.nrel_function_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
||||
@staticmethod
|
||||
def yoc_to_nrel_standard(year_of_construction):
|
||||
|
@ -136,7 +137,7 @@ class ConstructionHelper:
|
|||
:return: str
|
||||
"""
|
||||
reference_city = ConstructionHelper.city_to_reference_city(city)
|
||||
return ConstructionHelper.reference_city_to_nrel_climate_zone[reference_city]
|
||||
return ConstructionHelper._reference_city_to_nrel_climate_zone[reference_city]
|
||||
|
||||
@staticmethod
|
||||
def nrcan_from_function(function):
|
||||
|
@ -146,7 +147,6 @@ class ConstructionHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return ConstructionHelper.function_to_nrcan[function]
|
||||
return ConstructionHelper._function_to_nrcan[function]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default NRCAN function "residential"\n')
|
||||
return ConstructionHelper.nrcan_function_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
|
|
@ -33,23 +33,25 @@ class UsPhysicsParameters(NrelPhysicsInterface):
|
|||
building_type = ConstructionHelper.nrel_from_function(building.function)
|
||||
if building_type is None:
|
||||
return
|
||||
archetype = self._search_archetype(building_type,
|
||||
ConstructionHelper.yoc_to_nrel_standard(building.year_of_construction),
|
||||
self._climate_zone)
|
||||
if archetype is None:
|
||||
try:
|
||||
archetype = self._search_archetype(building_type,
|
||||
ConstructionHelper.yoc_to_nrel_standard(building.year_of_construction),
|
||||
self._climate_zone)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function: {building.function} '
|
||||
f'and building year of construction: {building.year_of_construction}\n')
|
||||
continue
|
||||
return
|
||||
|
||||
# if building has no thermal zones defined from geometry, one thermal zone per storey is assigned
|
||||
if building.thermal_zones is None:
|
||||
self._create_storeys(building, archetype)
|
||||
thermal_zones = []
|
||||
for storey in building.storeys:
|
||||
thermal_zones.append(storey.thermal_zone)
|
||||
building.thermal_zones = thermal_zones
|
||||
if len(building.internal_zones) == 1:
|
||||
if building.internal_zones[0].thermal_zones is None:
|
||||
self._create_storeys(building, archetype)
|
||||
thermal_zones = []
|
||||
for storey in building.storeys:
|
||||
thermal_zones.append(storey.thermal_zone)
|
||||
building.internal_zones[0].thermal_zones = thermal_zones
|
||||
|
||||
self._assign_values(building, archetype)
|
||||
self._assign_values(building.internal_zones, archetype)
|
||||
|
||||
def _search_archetype(self, building_type, standard, climate_zone):
|
||||
for building_archetype in self._building_archetypes:
|
||||
|
@ -60,52 +62,53 @@ class UsPhysicsParameters(NrelPhysicsInterface):
|
|||
return building_archetype
|
||||
return None
|
||||
|
||||
def _assign_values(self, building, archetype):
|
||||
for thermal_zone in building.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrel_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance
|
||||
thermal_boundary.outside_thermal_absorptance = thermal_boundary_archetype.outside_thermal_absorptance
|
||||
thermal_boundary.outside_visible_absorptance = thermal_boundary_archetype.outside_visible_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
try:
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
except ValueError:
|
||||
# This is the normal operation way when the windows are defined in the geometry
|
||||
continue
|
||||
thermal_boundary.layers = []
|
||||
for layer_archetype in thermal_boundary_archetype.layers:
|
||||
layer = Layer()
|
||||
layer.thickness = layer_archetype.thickness
|
||||
material = Material()
|
||||
material.name = layer_archetype.name
|
||||
material.no_mass = layer_archetype.no_mass
|
||||
material.density = layer_archetype.density
|
||||
material.conductivity = layer_archetype.conductivity
|
||||
material.specific_heat = layer_archetype.specific_heat
|
||||
material.solar_absorptance = layer_archetype.solar_absorptance
|
||||
material.thermal_absorptance = layer_archetype.thermal_absorptance
|
||||
material.visible_absorptance = layer_archetype.visible_absorptance
|
||||
material.thermal_resistance = layer_archetype.thermal_resistance
|
||||
layer.material = material
|
||||
thermal_boundary.layers.append(layer)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening_archetype is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening_archetype
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.conductivity = thermal_opening_archetype.conductivity
|
||||
thermal_opening.thickness = thermal_opening_archetype.thickness
|
||||
thermal_opening.back_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.back_side_solar_transmittance_at_normal_incidence
|
||||
thermal_opening.front_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.front_side_solar_transmittance_at_normal_incidence
|
||||
def _assign_values(self, internal_zones, archetype):
|
||||
for internal_zone in internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
thermal_zone.additional_thermal_bridge_u_value = archetype.additional_thermal_bridge_u_value
|
||||
thermal_zone.effective_thermal_capacity = archetype.effective_thermal_capacity
|
||||
thermal_zone.indirectly_heated_area_ratio = archetype.indirectly_heated_area_ratio
|
||||
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_system_on
|
||||
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_system_off
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
construction_type = ConstructionHelper.nrel_construction_types[thermal_boundary.type]
|
||||
thermal_boundary_archetype = self._search_construction_in_archetype(archetype, construction_type)
|
||||
thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance
|
||||
thermal_boundary.outside_thermal_absorptance = thermal_boundary_archetype.outside_thermal_absorptance
|
||||
thermal_boundary.outside_visible_absorptance = thermal_boundary_archetype.outside_visible_absorptance
|
||||
thermal_boundary.construction_name = thermal_boundary_archetype.construction_name
|
||||
try:
|
||||
thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio
|
||||
except ValueError:
|
||||
# This is the normal operation way when the windows are defined in the geometry
|
||||
continue
|
||||
thermal_boundary.layers = []
|
||||
for layer_archetype in thermal_boundary_archetype.layers:
|
||||
layer = Layer()
|
||||
layer.thickness = layer_archetype.thickness
|
||||
material = Material()
|
||||
material.name = layer_archetype.name
|
||||
material.no_mass = layer_archetype.no_mass
|
||||
material.density = layer_archetype.density
|
||||
material.conductivity = layer_archetype.conductivity
|
||||
material.specific_heat = layer_archetype.specific_heat
|
||||
material.solar_absorptance = layer_archetype.solar_absorptance
|
||||
material.thermal_absorptance = layer_archetype.thermal_absorptance
|
||||
material.visible_absorptance = layer_archetype.visible_absorptance
|
||||
material.thermal_resistance = layer_archetype.thermal_resistance
|
||||
layer.material = material
|
||||
thermal_boundary.layers.append(layer)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening_archetype is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening_archetype
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.conductivity = thermal_opening_archetype.conductivity
|
||||
thermal_opening.thickness = thermal_opening_archetype.thickness
|
||||
thermal_opening.back_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.back_side_solar_transmittance_at_normal_incidence
|
||||
thermal_opening.front_side_solar_transmittance_at_normal_incidence = \
|
||||
thermal_opening_archetype.front_side_solar_transmittance_at_normal_incidence
|
||||
|
||||
@staticmethod
|
||||
def _create_storeys(building, archetype):
|
||||
|
|
|
@ -12,229 +12,207 @@ class GeometryHelper:
|
|||
Geometry helper
|
||||
"""
|
||||
# function
|
||||
pluto_to_function = {
|
||||
'A0': 'single family house',
|
||||
'A1': 'single family house',
|
||||
'A2': 'single family house',
|
||||
'A3': 'single family house',
|
||||
'A4': 'single family house',
|
||||
'A5': 'single family house',
|
||||
'A6': 'single family house',
|
||||
'A7': 'single family house',
|
||||
'A8': 'single family house',
|
||||
'A9': 'single family house',
|
||||
'B1': 'multifamily house',
|
||||
'B2': 'multifamily house',
|
||||
'B3': 'multifamily house',
|
||||
'B9': 'multifamily house',
|
||||
'C0': 'residential',
|
||||
'C1': 'residential',
|
||||
'C2': 'residential',
|
||||
'C3': 'residential',
|
||||
'C4': 'residential',
|
||||
'C5': 'residential',
|
||||
'C6': 'residential',
|
||||
'C7': 'residential',
|
||||
'C8': 'residential',
|
||||
'C9': 'residential',
|
||||
'D0': 'residential',
|
||||
'D1': 'residential',
|
||||
'D2': 'residential',
|
||||
'D3': 'residential',
|
||||
'D4': 'residential',
|
||||
'D5': 'residential',
|
||||
'D6': 'residential',
|
||||
'D7': 'residential',
|
||||
'D8': 'residential',
|
||||
'D9': 'residential',
|
||||
'E1': 'warehouse',
|
||||
'E3': 'warehouse',
|
||||
'E4': 'warehouse',
|
||||
'E5': 'warehouse',
|
||||
'E7': 'warehouse',
|
||||
'E9': 'warehouse',
|
||||
'F1': 'warehouse',
|
||||
'F2': 'warehouse',
|
||||
'F4': 'warehouse',
|
||||
'F5': 'warehouse',
|
||||
'F8': 'warehouse',
|
||||
'F9': 'warehouse',
|
||||
'G0': 'office',
|
||||
'G1': 'office',
|
||||
'G2': 'office',
|
||||
'G3': 'office',
|
||||
'G4': 'office',
|
||||
'G5': 'office',
|
||||
'G6': 'office',
|
||||
'G7': 'office',
|
||||
'G8': 'office',
|
||||
'G9': 'office',
|
||||
'H1': 'hotel',
|
||||
'H2': 'hotel',
|
||||
'H3': 'hotel',
|
||||
'H4': 'hotel',
|
||||
'H5': 'hotel',
|
||||
'H6': 'hotel',
|
||||
'H7': 'hotel',
|
||||
'H8': 'hotel',
|
||||
'H9': 'hotel',
|
||||
'HB': 'hotel',
|
||||
'HH': 'hotel',
|
||||
'HR': 'hotel',
|
||||
'HS': 'hotel',
|
||||
'I1': 'hospital',
|
||||
'I2': 'outpatient',
|
||||
'I3': 'outpatient',
|
||||
'I4': 'residential',
|
||||
'I5': 'outpatient',
|
||||
'I6': 'outpatient',
|
||||
'I7': 'outpatient',
|
||||
'I9': 'outpatient',
|
||||
'J1': 'large office',
|
||||
'J2': 'large office',
|
||||
'J3': 'large office',
|
||||
'J4': 'large office',
|
||||
'J5': 'large office',
|
||||
'J6': 'large office',
|
||||
'J7': 'large office',
|
||||
'J8': 'large office',
|
||||
'J9': 'large office',
|
||||
'K1': 'strip mall',
|
||||
'K2': 'strip mall',
|
||||
'K3': 'strip mall',
|
||||
'K4': 'residential',
|
||||
'K5': 'restaurant',
|
||||
'K6': 'commercial',
|
||||
'K7': 'commercial',
|
||||
'K8': 'commercial',
|
||||
'K9': 'commercial',
|
||||
'L1': 'residential',
|
||||
'L2': 'residential',
|
||||
'L3': 'residential',
|
||||
'L8': 'residential',
|
||||
'L9': 'residential',
|
||||
'M1': 'large office',
|
||||
'M2': 'large office',
|
||||
'M3': 'large office',
|
||||
'M4': 'large office',
|
||||
'M9': 'large office',
|
||||
'N1': 'residential',
|
||||
'N2': 'residential',
|
||||
'N3': 'residential',
|
||||
'N4': 'residential',
|
||||
'N9': 'residential',
|
||||
'O1': 'office',
|
||||
'O2': 'office',
|
||||
'O3': 'office',
|
||||
'O4': 'office',
|
||||
'O5': 'office',
|
||||
'O6': 'office',
|
||||
'O7': 'office',
|
||||
'O8': 'office',
|
||||
'O9': 'office',
|
||||
'P1': 'large office',
|
||||
'P2': 'hotel',
|
||||
'P3': 'office',
|
||||
'P4': 'office',
|
||||
'P5': 'office',
|
||||
'P6': 'office',
|
||||
'P7': 'large office',
|
||||
'P8': 'large office',
|
||||
'P9': 'office',
|
||||
'Q0': 'office',
|
||||
'Q1': 'office',
|
||||
'Q2': 'office',
|
||||
'Q3': 'office',
|
||||
'Q4': 'office',
|
||||
'Q5': 'office',
|
||||
'Q6': 'office',
|
||||
'Q7': 'office',
|
||||
'Q8': 'office',
|
||||
'Q9': 'office',
|
||||
'R0': 'residential',
|
||||
'R1': 'residential',
|
||||
'R2': 'residential',
|
||||
'R3': 'residential',
|
||||
'R4': 'residential',
|
||||
'R5': 'residential',
|
||||
'R6': 'residential',
|
||||
'R7': 'residential',
|
||||
'R8': 'residential',
|
||||
'R9': 'residential',
|
||||
'RA': 'residential',
|
||||
'RB': 'residential',
|
||||
'RC': 'residential',
|
||||
'RD': 'residential',
|
||||
'RG': 'residential',
|
||||
'RH': 'residential',
|
||||
'RI': 'residential',
|
||||
'RK': 'residential',
|
||||
'RM': 'residential',
|
||||
'RR': 'residential',
|
||||
'RS': 'residential',
|
||||
'RW': 'residential',
|
||||
'RX': 'residential',
|
||||
'RZ': 'residential',
|
||||
'S0': 'residential',
|
||||
'S1': 'residential',
|
||||
'S2': 'residential',
|
||||
'S3': 'residential',
|
||||
'S4': 'residential',
|
||||
'S5': 'residential',
|
||||
'S9': 'residential',
|
||||
'T1': 'na',
|
||||
'T2': 'na',
|
||||
'T9': 'na',
|
||||
'U0': 'warehouse',
|
||||
'U1': 'warehouse',
|
||||
'U2': 'warehouse',
|
||||
'U3': 'warehouse',
|
||||
'U4': 'warehouse',
|
||||
'U5': 'warehouse',
|
||||
'U6': 'warehouse',
|
||||
'U7': 'warehouse',
|
||||
'U8': 'warehouse',
|
||||
'U9': 'warehouse',
|
||||
'V0': 'na',
|
||||
'V1': 'na',
|
||||
'V2': 'na',
|
||||
'V3': 'na',
|
||||
'V4': 'na',
|
||||
'V5': 'na',
|
||||
'V6': 'na',
|
||||
'V7': 'na',
|
||||
'V8': 'na',
|
||||
'V9': 'na',
|
||||
'W1': 'primary school',
|
||||
'W2': 'primary school',
|
||||
'W3': 'secondary school',
|
||||
'W4': 'secondary school',
|
||||
'W5': 'secondary school',
|
||||
'W6': 'secondary school',
|
||||
'W7': 'secondary school',
|
||||
'W8': 'primary school',
|
||||
'W9': 'secondary school',
|
||||
'Y1': 'large office',
|
||||
'Y2': 'large office',
|
||||
'Y3': 'large office',
|
||||
'Y4': 'large office',
|
||||
'Y5': 'large office',
|
||||
'Y6': 'large office',
|
||||
'Y7': 'large office',
|
||||
'Y8': 'large office',
|
||||
'Y9': 'large office',
|
||||
'Z0': 'na',
|
||||
'Z1': 'large office',
|
||||
'Z2': 'na',
|
||||
'Z3': 'na',
|
||||
'Z4': 'na',
|
||||
'Z5': 'na',
|
||||
'Z6': 'na',
|
||||
'Z7': 'na',
|
||||
'Z8': 'na',
|
||||
'Z9': 'na'
|
||||
_pluto_to_function = {
|
||||
'A0': cte.SFH,
|
||||
'A1': cte.SFH,
|
||||
'A2': cte.SFH,
|
||||
'A3': cte.SFH,
|
||||
'A4': cte.SFH,
|
||||
'A5': cte.SFH,
|
||||
'A6': cte.SFH,
|
||||
'A7': cte.SFH,
|
||||
'A8': cte.SFH,
|
||||
'A9': cte.SFH,
|
||||
'B1': cte.MFH,
|
||||
'B2': cte.MFH,
|
||||
'B3': cte.MFH,
|
||||
'B9': cte.MFH,
|
||||
'C0': cte.RESIDENTIAL,
|
||||
'C1': cte.RESIDENTIAL,
|
||||
'C2': cte.RESIDENTIAL,
|
||||
'C3': cte.RESIDENTIAL,
|
||||
'C4': cte.RESIDENTIAL,
|
||||
'C5': cte.RESIDENTIAL,
|
||||
'C6': cte.RESIDENTIAL,
|
||||
'C7': cte.RESIDENTIAL,
|
||||
'C8': cte.RESIDENTIAL,
|
||||
'C9': cte.RESIDENTIAL,
|
||||
'D0': cte.RESIDENTIAL,
|
||||
'D1': cte.RESIDENTIAL,
|
||||
'D2': cte.RESIDENTIAL,
|
||||
'D3': cte.RESIDENTIAL,
|
||||
'D4': cte.RESIDENTIAL,
|
||||
'D5': cte.RESIDENTIAL,
|
||||
'D6': cte.RESIDENTIAL,
|
||||
'D7': cte.RESIDENTIAL,
|
||||
'D8': cte.RESIDENTIAL,
|
||||
'D9': cte.RESIDENTIAL,
|
||||
'E1': cte.WAREHOUSE,
|
||||
'E3': cte.WAREHOUSE,
|
||||
'E4': cte.WAREHOUSE,
|
||||
'E5': cte.WAREHOUSE,
|
||||
'E7': cte.WAREHOUSE,
|
||||
'E9': cte.WAREHOUSE,
|
||||
'F1': cte.WAREHOUSE,
|
||||
'F2': cte.WAREHOUSE,
|
||||
'F4': cte.WAREHOUSE,
|
||||
'F5': cte.WAREHOUSE,
|
||||
'F8': cte.WAREHOUSE,
|
||||
'F9': cte.WAREHOUSE,
|
||||
'G0': cte.OFFICE,
|
||||
'G1': cte.OFFICE,
|
||||
'G2': cte.OFFICE,
|
||||
'G3': cte.OFFICE,
|
||||
'G4': cte.OFFICE,
|
||||
'G5': cte.OFFICE,
|
||||
'G6': cte.OFFICE,
|
||||
'G7': cte.OFFICE,
|
||||
'G8': cte.OFFICE,
|
||||
'G9': cte.OFFICE,
|
||||
'H1': cte.HOTEL,
|
||||
'H2': cte.HOTEL,
|
||||
'H3': cte.HOTEL,
|
||||
'H4': cte.HOTEL,
|
||||
'H5': cte.HOTEL,
|
||||
'H6': cte.HOTEL,
|
||||
'H7': cte.HOTEL,
|
||||
'H8': cte.HOTEL,
|
||||
'H9': cte.HOTEL,
|
||||
'HB': cte.HOTEL,
|
||||
'HH': cte.HOTEL,
|
||||
'HR': cte.HOTEL,
|
||||
'HS': cte.HOTEL,
|
||||
'I1': cte.HOSPITAL,
|
||||
'I2': cte.OUTPATIENT,
|
||||
'I3': cte.OUTPATIENT,
|
||||
'I4': cte.RESIDENTIAL,
|
||||
'I5': cte.OUTPATIENT,
|
||||
'I6': cte.OUTPATIENT,
|
||||
'I7': cte.OUTPATIENT,
|
||||
'I9': cte.OUTPATIENT,
|
||||
'J1': cte.LARGE_OFFICE,
|
||||
'J2': cte.LARGE_OFFICE,
|
||||
'J3': cte.LARGE_OFFICE,
|
||||
'J4': cte.LARGE_OFFICE,
|
||||
'J5': cte.LARGE_OFFICE,
|
||||
'J6': cte.LARGE_OFFICE,
|
||||
'J7': cte.LARGE_OFFICE,
|
||||
'J8': cte.LARGE_OFFICE,
|
||||
'J9': cte.LARGE_OFFICE,
|
||||
'K1': cte.STRIP_MALL,
|
||||
'K2': cte.STRIP_MALL,
|
||||
'K3': cte.STRIP_MALL,
|
||||
'K4': cte.RESIDENTIAL,
|
||||
'K5': cte.RESTAURANT,
|
||||
'K6': cte.COMMERCIAL,
|
||||
'K7': cte.COMMERCIAL,
|
||||
'K8': cte.COMMERCIAL,
|
||||
'K9': cte.COMMERCIAL,
|
||||
'L1': cte.RESIDENTIAL,
|
||||
'L2': cte.RESIDENTIAL,
|
||||
'L3': cte.RESIDENTIAL,
|
||||
'L8': cte.RESIDENTIAL,
|
||||
'L9': cte.RESIDENTIAL,
|
||||
'M1': cte.LARGE_OFFICE,
|
||||
'M2': cte.LARGE_OFFICE,
|
||||
'M3': cte.LARGE_OFFICE,
|
||||
'M4': cte.LARGE_OFFICE,
|
||||
'M9': cte.LARGE_OFFICE,
|
||||
'N1': cte.RESIDENTIAL,
|
||||
'N2': cte.RESIDENTIAL,
|
||||
'N3': cte.RESIDENTIAL,
|
||||
'N4': cte.RESIDENTIAL,
|
||||
'N9': cte.RESIDENTIAL,
|
||||
'O1': cte.OFFICE,
|
||||
'O2': cte.OFFICE,
|
||||
'O3': cte.OFFICE,
|
||||
'O4': cte.OFFICE,
|
||||
'O5': cte.OFFICE,
|
||||
'O6': cte.OFFICE,
|
||||
'O7': cte.OFFICE,
|
||||
'O8': cte.OFFICE,
|
||||
'O9': cte.OFFICE,
|
||||
'P1': cte.LARGE_OFFICE,
|
||||
'P2': cte.HOTEL,
|
||||
'P3': cte.OFFICE,
|
||||
'P4': cte.OFFICE,
|
||||
'P5': cte.OFFICE,
|
||||
'P6': cte.OFFICE,
|
||||
'P7': cte.LARGE_OFFICE,
|
||||
'P8': cte.LARGE_OFFICE,
|
||||
'P9': cte.OFFICE,
|
||||
'Q0': cte.OFFICE,
|
||||
'Q1': cte.OFFICE,
|
||||
'Q2': cte.OFFICE,
|
||||
'Q3': cte.OFFICE,
|
||||
'Q4': cte.OFFICE,
|
||||
'Q5': cte.OFFICE,
|
||||
'Q6': cte.OFFICE,
|
||||
'Q7': cte.OFFICE,
|
||||
'Q8': cte.OFFICE,
|
||||
'Q9': cte.OFFICE,
|
||||
'R0': cte.RESIDENTIAL,
|
||||
'R1': cte.RESIDENTIAL,
|
||||
'R2': cte.RESIDENTIAL,
|
||||
'R3': cte.RESIDENTIAL,
|
||||
'R4': cte.RESIDENTIAL,
|
||||
'R5': cte.RESIDENTIAL,
|
||||
'R6': cte.RESIDENTIAL,
|
||||
'R7': cte.RESIDENTIAL,
|
||||
'R8': cte.RESIDENTIAL,
|
||||
'R9': cte.RESIDENTIAL,
|
||||
'RA': cte.RESIDENTIAL,
|
||||
'RB': cte.RESIDENTIAL,
|
||||
'RC': cte.RESIDENTIAL,
|
||||
'RD': cte.RESIDENTIAL,
|
||||
'RG': cte.RESIDENTIAL,
|
||||
'RH': cte.RESIDENTIAL,
|
||||
'RI': cte.RESIDENTIAL,
|
||||
'RK': cte.RESIDENTIAL,
|
||||
'RM': cte.RESIDENTIAL,
|
||||
'RR': cte.RESIDENTIAL,
|
||||
'RS': cte.RESIDENTIAL,
|
||||
'RW': cte.RESIDENTIAL,
|
||||
'RX': cte.RESIDENTIAL,
|
||||
'RZ': cte.RESIDENTIAL,
|
||||
'S0': cte.RESIDENTIAL,
|
||||
'S1': cte.RESIDENTIAL,
|
||||
'S2': cte.RESIDENTIAL,
|
||||
'S3': cte.RESIDENTIAL,
|
||||
'S4': cte.RESIDENTIAL,
|
||||
'S5': cte.RESIDENTIAL,
|
||||
'S9': cte.RESIDENTIAL,
|
||||
'U0': cte.WAREHOUSE,
|
||||
'U1': cte.WAREHOUSE,
|
||||
'U2': cte.WAREHOUSE,
|
||||
'U3': cte.WAREHOUSE,
|
||||
'U4': cte.WAREHOUSE,
|
||||
'U5': cte.WAREHOUSE,
|
||||
'U6': cte.WAREHOUSE,
|
||||
'U7': cte.WAREHOUSE,
|
||||
'U8': cte.WAREHOUSE,
|
||||
'U9': cte.WAREHOUSE,
|
||||
'W1': cte.PRIMARY_SCHOOL,
|
||||
'W2': cte.PRIMARY_SCHOOL,
|
||||
'W3': cte.SECONDARY_SCHOOL,
|
||||
'W4': cte.SECONDARY_SCHOOL,
|
||||
'W5': cte.SECONDARY_SCHOOL,
|
||||
'W6': cte.SECONDARY_SCHOOL,
|
||||
'W7': cte.SECONDARY_SCHOOL,
|
||||
'W8': cte.PRIMARY_SCHOOL,
|
||||
'W9': cte.SECONDARY_SCHOOL,
|
||||
'Y1': cte.LARGE_OFFICE,
|
||||
'Y2': cte.LARGE_OFFICE,
|
||||
'Y3': cte.LARGE_OFFICE,
|
||||
'Y4': cte.LARGE_OFFICE,
|
||||
'Y5': cte.LARGE_OFFICE,
|
||||
'Y6': cte.LARGE_OFFICE,
|
||||
'Y7': cte.LARGE_OFFICE,
|
||||
'Y8': cte.LARGE_OFFICE,
|
||||
'Y9': cte.LARGE_OFFICE,
|
||||
'Z1': cte.LARGE_OFFICE
|
||||
}
|
||||
hft_to_function = {
|
||||
_hft_to_function = {
|
||||
'residential': cte.RESIDENTIAL,
|
||||
'single family house': cte.SFH,
|
||||
'multifamily house': cte.MFH,
|
||||
|
@ -251,25 +229,18 @@ class GeometryHelper:
|
|||
}
|
||||
|
||||
# usage
|
||||
function_to_usage = {
|
||||
'full service restaurant': 'restaurant',
|
||||
'highrise apartment': cte.RESIDENTIAL,
|
||||
'hospital': 'health care',
|
||||
'large hotel': 'hotel',
|
||||
'large office': 'office and administration',
|
||||
'medium office': 'office and administration',
|
||||
'midrise apartment': cte.RESIDENTIAL,
|
||||
'outpatient healthcare': 'health care',
|
||||
'primary school': 'education',
|
||||
'quick service restaurant': 'restaurant',
|
||||
'secondary school': 'education',
|
||||
'small hotel': 'hotel',
|
||||
'small office': 'office and administration',
|
||||
'stand alone retail': 'retail',
|
||||
'strip mall': 'hall',
|
||||
'supermarket': 'retail',
|
||||
'warehouse': 'industry',
|
||||
'residential': cte.RESIDENTIAL
|
||||
_function_to_usage = {
|
||||
cte.RESTAURANT: cte.RESTAURANT,
|
||||
cte.RESIDENTIAL: cte.RESIDENTIAL,
|
||||
cte.HOSPITAL: cte.HEALTH_CARE,
|
||||
cte.HOTEL: cte.HOTEL,
|
||||
cte.LARGE_OFFICE: cte.OFFICE_ADMINISTRATION,
|
||||
cte.OFFICE: cte.OFFICE_ADMINISTRATION,
|
||||
cte.PRIMARY_SCHOOL: cte.EDUCATION,
|
||||
cte.SECONDARY_SCHOOL: cte.EDUCATION,
|
||||
cte.RETAIL: cte.RETAIL,
|
||||
cte.STRIP_MALL: cte.HALL,
|
||||
cte.WAREHOUSE: cte.INDUSTRY
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -279,7 +250,7 @@ class GeometryHelper:
|
|||
:param building_hft_function: str
|
||||
:return: str
|
||||
"""
|
||||
return GeometryHelper.hft_to_function[building_hft_function]
|
||||
return GeometryHelper._hft_to_function[building_hft_function]
|
||||
|
||||
@staticmethod
|
||||
def function_from_pluto(building_pluto_function):
|
||||
|
@ -288,7 +259,7 @@ class GeometryHelper:
|
|||
:param building_pluto_function: str
|
||||
:return: str
|
||||
"""
|
||||
return GeometryHelper.pluto_to_function[building_pluto_function]
|
||||
return GeometryHelper._pluto_to_function[building_pluto_function]
|
||||
|
||||
@staticmethod
|
||||
def usage_from_function(building_function):
|
||||
|
@ -297,7 +268,7 @@ class GeometryHelper:
|
|||
:param building_function: str
|
||||
:return: str
|
||||
"""
|
||||
return GeometryHelper.function_to_usage[building_function]
|
||||
return GeometryHelper._function_to_usage[building_function]
|
||||
|
||||
@staticmethod
|
||||
def to_points_matrix(points):
|
||||
|
|
|
@ -12,7 +12,7 @@ class SchedulesHelper:
|
|||
"""
|
||||
Schedules helper
|
||||
"""
|
||||
usage_to_comnet = {
|
||||
_usage_to_comnet = {
|
||||
cte.RESIDENTIAL: 'C-12 Residential',
|
||||
cte.INDUSTRY: 'C-10 Warehouse',
|
||||
cte.OFFICE_ADMINISTRATION: 'C-5 Office',
|
||||
|
@ -23,16 +23,15 @@ class SchedulesHelper:
|
|||
cte.RESTAURANT: 'C-7 Restaurant',
|
||||
cte.EDUCATION: 'C-9 School'
|
||||
}
|
||||
comnet_default_value = 'C-12 Residential'
|
||||
|
||||
comnet_to_data_type = {
|
||||
_comnet_to_data_type = {
|
||||
'Fraction': cte.FRACTION,
|
||||
'OnOff': cte.ON_OFF,
|
||||
'Temperature': cte.TEMPERATURE
|
||||
}
|
||||
|
||||
# usage
|
||||
function_to_usage = {
|
||||
_function_to_usage = {
|
||||
'full service restaurant': cte.RESTAURANT,
|
||||
'high-rise apartment': cte.RESIDENTIAL,
|
||||
'hospital': cte.HEALTH_CARE,
|
||||
|
@ -61,10 +60,9 @@ class SchedulesHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return SchedulesHelper.usage_to_comnet[usage]
|
||||
return SchedulesHelper._usage_to_comnet[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default Comnet schedules "residential"\n')
|
||||
return SchedulesHelper.comnet_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
||||
@staticmethod
|
||||
def data_type_from_comnet(comnet_data_type):
|
||||
|
@ -74,7 +72,7 @@ class SchedulesHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return SchedulesHelper.comnet_to_data_type[comnet_data_type]
|
||||
return SchedulesHelper._comnet_to_data_type[comnet_data_type]
|
||||
except KeyError:
|
||||
raise ValueError(f"Error: comnet data type keyword not found.")
|
||||
|
||||
|
@ -85,4 +83,4 @@ class SchedulesHelper:
|
|||
:param building_function: str
|
||||
:return: str
|
||||
"""
|
||||
return SchedulesHelper.function_to_usage[building_function]
|
||||
return SchedulesHelper._function_to_usage[building_function]
|
||||
|
|
|
@ -5,10 +5,12 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons
|
|||
"""
|
||||
import sys
|
||||
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
||||
from imports.usage.hft_usage_interface import HftUsageInterface
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
|
||||
|
||||
class CaUsageParameters(HftUsageInterface):
|
||||
|
@ -18,9 +20,6 @@ class CaUsageParameters(HftUsageInterface):
|
|||
def __init__(self, city, base_path):
|
||||
super().__init__(base_path, 'ca_archetypes_reduced.xml')
|
||||
self._city = city
|
||||
# todo: this is a wrong location for self._min_air_change -> re-think where to place this info
|
||||
# and where it comes from
|
||||
self._min_air_change = 0
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
|
@ -29,19 +28,20 @@ class CaUsageParameters(HftUsageInterface):
|
|||
"""
|
||||
city = self._city
|
||||
for building in city.buildings:
|
||||
archetype = self._search_archetype(building.function)
|
||||
if archetype is None:
|
||||
try:
|
||||
print(building.function)
|
||||
archetype = self._search_archetype(building.function)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{gh.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
f' {building.function}\n')
|
||||
return
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.usage = building.function
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.percentage = 1
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
usage_zone.usage = building.function
|
||||
usage_zone.percentage = 1
|
||||
self._assign_values_usage_zone(usage_zone, archetype)
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for building_archetype in self._usage_archetypes:
|
||||
|
@ -50,26 +50,30 @@ class CaUsageParameters(HftUsageInterface):
|
|||
return None
|
||||
|
||||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype):
|
||||
def _assign_values_usage_zone(usage_zone, archetype):
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||
# Therefore, this walk around has been done.
|
||||
internal_gains = []
|
||||
for archetype_internal_gain in archetype.internal_gains:
|
||||
internal_gain = InternalGains()
|
||||
internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
internal_gains.append(internal_gain)
|
||||
usage_zone.internal_gains = internal_gains
|
||||
usage_zone.heating_setpoint = archetype.heating_setpoint
|
||||
usage_zone.heating_setback = archetype.heating_setback
|
||||
usage_zone.cooling_setpoint = archetype.cooling_setpoint
|
||||
usage_zone.occupancy_density = archetype.occupancy_density
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
|
||||
usage_zone.occupancy = _occupancy
|
||||
usage_zone.hours_day = archetype.hours_day
|
||||
usage_zone.days_year = archetype.days_year
|
||||
usage_zone.dhw_average_volume_pers_day = archetype.dhw_average_volume_pers_day
|
||||
usage_zone.dhw_preparation_temperature = archetype.dhw_preparation_temperature
|
||||
usage_zone.electrical_app_average_consumption_sqm_year = archetype.electrical_app_average_consumption_sqm_year
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = archetype.appliances.appliances_density
|
||||
usage_zone.appliances = _appliances
|
||||
_control = ThermalControl()
|
||||
_control.mean_heating_set_point = archetype.thermal_control.mean_heating_set_point
|
||||
_control.heating_set_back = archetype.thermal_control.heating_set_back
|
||||
_control.mean_cooling_set_point = archetype.thermal_control.mean_cooling_set_point
|
||||
usage_zone.thermal_control = _control
|
||||
_internal_gains = []
|
||||
for archetype_internal_gain in archetype.not_detailed_source_mean_annual_internal_gains:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
_internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
_internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
_internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
_internal_gains.append(_internal_gain)
|
||||
usage_zone.not_detailed_source_mean_annual_internal_gains = _internal_gains
|
||||
|
|
|
@ -3,6 +3,7 @@ ComnetUsageParameters model the usage properties
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import sys
|
||||
from typing import Dict
|
||||
import pandas as pd
|
||||
|
@ -11,11 +12,13 @@ import helpers.constants as cte
|
|||
from helpers.configuration_helper import ConfigurationHelper as ch
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.usage.helpers.usage_helper import UsageHelper
|
||||
from imports.schedules.helpers.schedules_helper import SchedulesHelper
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.lighting import Lighting
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class ComnetUsageParameters:
|
||||
|
@ -25,24 +28,19 @@ class ComnetUsageParameters:
|
|||
def __init__(self, city, base_path):
|
||||
self._city = city
|
||||
self._base_path = str(base_path / 'comnet_archetypes.xlsx')
|
||||
self._usage_archetypes = []
|
||||
data = self._read_file()
|
||||
for item in data['lighting']:
|
||||
for usage in UsageHelper.usage_to_comnet:
|
||||
comnet_usage = UsageHelper.usage_to_comnet[usage]
|
||||
if comnet_usage == item:
|
||||
usage_archetype = self._parse_zone_usage_type(comnet_usage, data)
|
||||
self._usage_archetypes.append(usage_archetype)
|
||||
self._data = self._read_file()
|
||||
self._comnet_schedules_path = str(base_path / 'comnet_schedules_archetypes.xlsx')
|
||||
self._xls = pd.ExcelFile(self._comnet_schedules_path)
|
||||
|
||||
def _read_file(self) -> Dict:
|
||||
"""
|
||||
reads xlsx file containing usage information into a dictionary
|
||||
reads xlsx files containing usage information into a dictionary
|
||||
:return : Dict
|
||||
"""
|
||||
number_usage_types = 33
|
||||
xl_file = pd.ExcelFile(self._base_path)
|
||||
file_data = pd.read_excel(xl_file, sheet_name="Modeling Data", skiprows=[0, 1, 2],
|
||||
nrows=number_usage_types, usecols="A:Z")
|
||||
nrows=number_usage_types, usecols="A:AB")
|
||||
|
||||
lighting_data = {}
|
||||
plug_loads_data = {}
|
||||
|
@ -50,6 +48,7 @@ class ComnetUsageParameters:
|
|||
ventilation_rate = {}
|
||||
water_heating = {}
|
||||
process_data = {}
|
||||
schedules_key = {}
|
||||
|
||||
for j in range(0, number_usage_types):
|
||||
usage_parameters = file_data.iloc[j]
|
||||
|
@ -60,53 +59,130 @@ class ComnetUsageParameters:
|
|||
ventilation_rate[usage_type] = usage_parameters[20:21].values.tolist()
|
||||
water_heating[usage_type] = usage_parameters[23:24].values.tolist()
|
||||
process_data[usage_type] = usage_parameters[24:26].values.tolist()
|
||||
schedules_key[usage_type] = usage_parameters[27:28].values.tolist()
|
||||
|
||||
return {'lighting': lighting_data,
|
||||
'plug loads': plug_loads_data,
|
||||
'occupancy': occupancy_data,
|
||||
'ventilation rate': ventilation_rate,
|
||||
'water heating': water_heating,
|
||||
'process': process_data}
|
||||
'process': process_data,
|
||||
'schedules_key': schedules_key}
|
||||
|
||||
@staticmethod
|
||||
def _parse_zone_usage_type(usage, data):
|
||||
def _parse_usage_type(comnet_usage, data, schedules_data):
|
||||
_usage_zone = UsageZone()
|
||||
_usage_zone.usage = usage
|
||||
|
||||
# lighting
|
||||
_lighting = Lighting()
|
||||
_lighting.latent_fraction = ch().comnet_lighting_latent
|
||||
_lighting.convective_fraction = ch().comnet_lighting_convective
|
||||
_lighting.radiative_fraction = ch().comnet_lighting_radiant
|
||||
_lighting.average_internal_gain = data['lighting'][usage][4]
|
||||
_lighting.lighting_density = data['lighting'][comnet_usage][4]
|
||||
|
||||
# plug loads
|
||||
_appliances = None
|
||||
if data['plug loads'][usage][0] != 'n.a.':
|
||||
if data['plug loads'][comnet_usage][0] != 'n.a.':
|
||||
_appliances = Appliances()
|
||||
_appliances.latent_fraction = ch().comnet_plugs_latent
|
||||
_appliances.convective_fraction = ch().comnet_plugs_convective
|
||||
_appliances.radiative_fraction = ch().comnet_plugs_radiant
|
||||
_appliances.average_internal_gain = data['plug loads'][usage][0]
|
||||
_appliances.appliances_density = data['plug loads'][comnet_usage][0]
|
||||
|
||||
# occupancy
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = data['occupancy'][usage][0]
|
||||
_occupancy.sensible_convective_internal_gain = data['occupancy'][usage][1] \
|
||||
_occupancy.occupancy_density = data['occupancy'][comnet_usage][0]
|
||||
_occupancy.sensible_convective_internal_gain = data['occupancy'][comnet_usage][1] \
|
||||
* ch().comnet_occupancy_sensible_convective
|
||||
_occupancy.sensible_radiant_internal_gain = data['occupancy'][usage][1] * ch().comnet_occupancy_sensible_radiant
|
||||
_occupancy.latent_internal_gain = data['occupancy'][usage][2]
|
||||
_occupancy.sensible_radiative_internal_gain = data['occupancy'][comnet_usage][1] \
|
||||
* ch().comnet_occupancy_sensible_radiant
|
||||
_occupancy.latent_internal_gain = data['occupancy'][comnet_usage][2]
|
||||
|
||||
if _occupancy.occupancy_density <= 0:
|
||||
_usage_zone.mechanical_air_change = 0
|
||||
else:
|
||||
_usage_zone.mechanical_air_change = data['ventilation rate'][usage][0] / _occupancy.occupancy_density
|
||||
_usage_zone.mechanical_air_change = data['ventilation rate'][comnet_usage][0] / _occupancy.occupancy_density
|
||||
|
||||
schedules_usage = UsageHelper.schedules_key(data['schedules_key'][comnet_usage][0])
|
||||
|
||||
_extracted_data = pd.read_excel(schedules_data, sheet_name=schedules_usage,
|
||||
skiprows=[0, 1, 2, 3], nrows=39, usecols="A:AA")
|
||||
schedules = []
|
||||
number_of_schedule_types = 13
|
||||
schedules_per_schedule_type = 3
|
||||
day_types = dict({'week_day': 0, 'saturday': 1, 'sunday': 2})
|
||||
for schedule_types in range(0, number_of_schedule_types):
|
||||
name = ''
|
||||
data_type = ''
|
||||
for schedule_day in range(0, schedules_per_schedule_type):
|
||||
_schedule = Schedule()
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.time_range = cte.DAY
|
||||
row_cells = _extracted_data.iloc[schedules_per_schedule_type * schedule_types + schedule_day]
|
||||
if schedule_day == day_types['week_day']:
|
||||
name = row_cells[0]
|
||||
data_type = row_cells[1]
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
elif schedule_day == day_types['saturday']:
|
||||
_schedule.day_types = [cte.SATURDAY]
|
||||
else:
|
||||
_schedule.day_types = [cte.SUNDAY]
|
||||
_schedule.type = name
|
||||
_schedule.data_type = SchedulesHelper.data_type_from_comnet(data_type)
|
||||
if _schedule.data_type == cte.TEMPERATURE:
|
||||
values = []
|
||||
for cell in row_cells[schedules_per_schedule_type:].to_numpy():
|
||||
values.append((float(cell) - 32.) * 5 / 9)
|
||||
_schedule.values = values
|
||||
else:
|
||||
_schedule.values = row_cells[schedules_per_schedule_type:].to_numpy()
|
||||
schedules.append(_schedule)
|
||||
|
||||
schedules_types = dict({'Occupancy': 0, 'Lights': 3, 'Receptacle': 6, 'Infiltration': 9, 'HVAC Avail': 12,
|
||||
'ClgSetPt': 15, 'HtgSetPt': 18})
|
||||
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['Occupancy']+pointer])
|
||||
_occupancy.occupancy_schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['Lights']+pointer])
|
||||
_lighting.schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['Receptacle']+pointer])
|
||||
_appliances.schedules = _schedules
|
||||
|
||||
_usage_zone.occupancy = _occupancy
|
||||
_usage_zone.lighting = _lighting
|
||||
_usage_zone.appliances = _appliances
|
||||
|
||||
_control = ThermalControl()
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['HtgSetPt']+pointer])
|
||||
_control.heating_set_point_schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['ClgSetPt']+pointer])
|
||||
_control.cooling_set_point_schedules = _schedules
|
||||
_schedules = []
|
||||
for pointer in range(0, 3):
|
||||
_schedules.append(schedules[schedules_types['HVAC Avail']+pointer])
|
||||
_control.hvac_availability_schedules = _schedules
|
||||
_usage_zone.thermal_control = _control
|
||||
|
||||
return _usage_zone
|
||||
|
||||
def _search_archetypes(self, usage):
|
||||
for item in self._data['lighting']:
|
||||
comnet_usage = UsageHelper.comnet_from_usage(usage)
|
||||
if comnet_usage == item:
|
||||
usage_archetype = self._parse_usage_type(comnet_usage, self._data, self._xls)
|
||||
return usage_archetype
|
||||
return None, None
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
Returns the city with the usage parameters assigned to the buildings
|
||||
|
@ -115,41 +191,80 @@ class ComnetUsageParameters:
|
|||
city = self._city
|
||||
for building in city.buildings:
|
||||
usage = GeometryHelper.usage_from_function(building.function)
|
||||
archetype = self._search_archetype(UsageHelper.comnet_from_usage(usage))
|
||||
if archetype is None:
|
||||
try:
|
||||
archetype_usage = self._search_archetypes(usage)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{GeometryHelper.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
return
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
if internal_zone.area is None:
|
||||
raise Exception('Internal zone area not defined, ACH cannot be calculated')
|
||||
if internal_zone.volume is None:
|
||||
raise Exception('Internal zone volume not defined, ACH cannot be calculated')
|
||||
if internal_zone.area <= 0:
|
||||
raise Exception('Internal zone area is zero, ACH cannot be calculated')
|
||||
if internal_zone.volume <= 0:
|
||||
raise Exception('Internal zone volume is zero, ACH cannot be calculated')
|
||||
volume_per_area = internal_zone.volume / internal_zone.area
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.usage = usage
|
||||
self._assign_values(usage_zone, archetype, volume_per_area)
|
||||
self._assign_values_usage_zone(usage_zone, archetype_usage, volume_per_area)
|
||||
usage_zone.percentage = 1
|
||||
self._calculate_reduced_values_from_extended_library(usage_zone, archetype_usage)
|
||||
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for building_archetype in self._usage_archetypes:
|
||||
if building_archetype.usage == building_usage:
|
||||
return building_archetype
|
||||
return None
|
||||
@staticmethod
|
||||
def _assign_values_usage_zone(usage_zone, archetype, volume_per_area):
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.occupancy when writing usage_zone.occupancy = archetype.occupancy.
|
||||
# Same happens for lighting and appliances. Therefore, this walk around has been done.
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change * cte.METERS_TO_FEET ** 2 \
|
||||
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET ** 3 / volume_per_area
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = archetype.occupancy.occupancy_density * cte.METERS_TO_FEET**2
|
||||
_occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain
|
||||
_occupancy.latent_internal_gain = archetype.occupancy.latent_internal_gain
|
||||
_occupancy.sensible_convective_internal_gain = archetype.occupancy.sensible_convective_internal_gain
|
||||
_occupancy.occupancy_schedules = archetype.occupancy.occupancy_schedules
|
||||
usage_zone.occupancy = _occupancy
|
||||
_lighting = Lighting()
|
||||
_lighting.lighting_density = archetype.lighting.lighting_density / cte.METERS_TO_FEET**2
|
||||
_lighting.convective_fraction = archetype.lighting.convective_fraction
|
||||
_lighting.radiative_fraction = archetype.lighting.radiative_fraction
|
||||
_lighting.latent_fraction = archetype.lighting.latent_fraction
|
||||
_lighting.schedules = archetype.lighting.schedules
|
||||
usage_zone.lighting = _lighting
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = archetype.appliances.appliances_density / cte.METERS_TO_FEET**2
|
||||
_appliances.convective_fraction = archetype.appliances.convective_fraction
|
||||
_appliances.radiative_fraction = archetype.appliances.radiative_fraction
|
||||
_appliances.latent_fraction = archetype.appliances.latent_fraction
|
||||
_appliances.schedules = archetype.appliances.schedules
|
||||
usage_zone.appliances = _appliances
|
||||
_control = ThermalControl()
|
||||
_control.cooling_set_point_schedules = archetype.thermal_control.cooling_set_point_schedules
|
||||
_control.heating_set_point_schedules = archetype.thermal_control.heating_set_point_schedules
|
||||
_control.hvac_availability_schedules = archetype.thermal_control.hvac_availability_schedules
|
||||
usage_zone.thermal_control = _control
|
||||
|
||||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype, volume_per_area):
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||
# Therefore, this walk around has been done.
|
||||
internal_gains = []
|
||||
for archetype_internal_gain in archetype.internal_gains:
|
||||
internal_gain = InternalGains()
|
||||
internal_gain.type = archetype_internal_gain.type
|
||||
internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
internal_gains.append(internal_gain)
|
||||
usage_zone.internal_gains = internal_gains
|
||||
usage_zone.occupancy_density = archetype.occupancy_density * cte.METERS_TO_FEET**2
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change * cte.METERS_TO_FEET**2 \
|
||||
* cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET**3 / volume_per_area
|
||||
def _calculate_reduced_values_from_extended_library(usage_zone, archetype):
|
||||
number_of_days_per_type = {'WD': 251, 'Sat': 52, 'Sun': 62}
|
||||
total = 0
|
||||
for schedule in archetype.thermal_control.hvac_availability_schedules:
|
||||
if schedule.day_types[0] == cte.SATURDAY:
|
||||
for value in schedule.values:
|
||||
total += value * number_of_days_per_type['Sat']
|
||||
elif schedule.day_types[0] == cte.SUNDAY:
|
||||
for value in schedule.values:
|
||||
total += value * number_of_days_per_type['Sun']
|
||||
else:
|
||||
for value in schedule.values:
|
||||
total += value * number_of_days_per_type['WD']
|
||||
|
||||
usage_zone.hours_day = total / 365
|
||||
usage_zone.days_year = 365
|
||||
|
|
|
@ -11,7 +11,7 @@ class UsageHelper:
|
|||
"""
|
||||
Usage helper class
|
||||
"""
|
||||
usage_to_hft = {
|
||||
_usage_to_hft = {
|
||||
cte.RESIDENTIAL: 'residential',
|
||||
cte.INDUSTRY: 'industry',
|
||||
cte.OFFICE_ADMINISTRATION: 'office and administration',
|
||||
|
@ -20,9 +20,7 @@ class UsageHelper:
|
|||
cte.RETAIL: 'retail',
|
||||
cte.HALL: 'hall',
|
||||
cte.RESTAURANT: 'restaurant',
|
||||
cte.EDUCATION: 'education'
|
||||
}
|
||||
hft_default_value = 'residential'
|
||||
cte.EDUCATION: 'education'}
|
||||
|
||||
@staticmethod
|
||||
def hft_from_usage(usage):
|
||||
|
@ -32,12 +30,11 @@ class UsageHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return UsageHelper.usage_to_hft[usage]
|
||||
return UsageHelper._usage_to_hft[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default HfT usage "residential"\n')
|
||||
return UsageHelper.hft_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
||||
usage_to_comnet = {
|
||||
_usage_to_comnet = {
|
||||
cte.RESIDENTIAL: 'BA Multifamily',
|
||||
cte.INDUSTRY: 'BA Manufacturing Facility',
|
||||
cte.OFFICE_ADMINISTRATION: 'BA Office',
|
||||
|
@ -46,9 +43,23 @@ class UsageHelper:
|
|||
cte.RETAIL: 'BA Retail',
|
||||
cte.HALL: 'BA Town Hall',
|
||||
cte.RESTAURANT: 'BA Dining: Bar Lounge/Leisure',
|
||||
cte.EDUCATION: 'BA School/University'
|
||||
}
|
||||
comnet_default_value = 'BA Multifamily'
|
||||
cte.EDUCATION: 'BA School/University'}
|
||||
|
||||
_comnet_schedules_key_to_comnet_schedules = {
|
||||
'C-1 Assembly': 'C-1 Assembly',
|
||||
'C-2 Public': 'C-2 Health',
|
||||
'C-3 Hotel Motel': 'C-3 Hotel',
|
||||
'C-4 Manufacturing': 'C-4 Manufacturing',
|
||||
'C-5 Office': 'C-5 Office',
|
||||
'C-6 Parking Garage': 'C-6 Parking',
|
||||
'C-7 Restaurant': 'C-7 Restaurant',
|
||||
'C-8 Retail': 'C-8 Retail',
|
||||
'C-9 Schools': 'C-9 School',
|
||||
'C-10 Warehouse': 'C-10 Warehouse',
|
||||
'C-11 Laboratory': 'C-11 Lab',
|
||||
'C-12 Residential': 'C-12 Residential',
|
||||
'C-13 Data Center': 'C-13 Data',
|
||||
'C-14 Gymnasium': 'C-14 Gymnasium'}
|
||||
|
||||
@staticmethod
|
||||
def comnet_from_usage(usage):
|
||||
|
@ -58,7 +69,19 @@ class UsageHelper:
|
|||
:return: str
|
||||
"""
|
||||
try:
|
||||
return UsageHelper.usage_to_comnet[usage]
|
||||
return UsageHelper._usage_to_comnet[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: keyword not found. Returned default Comnet usage "BA Multifamily"\n')
|
||||
return UsageHelper.comnet_default_value
|
||||
sys.stderr.write('Error: keyword not found.\n')
|
||||
|
||||
@staticmethod
|
||||
def schedules_key(usage):
|
||||
"""
|
||||
Get Comnet schedules key from the list found in the Comnet usage file
|
||||
:param usage: str
|
||||
:return: str
|
||||
"""
|
||||
try:
|
||||
return UsageHelper._comnet_schedules_key_to_comnet_schedules[usage]
|
||||
except KeyError:
|
||||
sys.stderr.write('Error: Comnet keyword not found. An update of the Comnet files might have been '
|
||||
'done changing the keywords.\n')
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
"""
|
||||
Hft-based interface, it reads format defined within the CERC team based on that one used in SimStadt and developed by
|
||||
the IAF team at hft-Stuttgart and enriches the city with usage parameters
|
||||
Hft-based interface, it reads format defined within the CERC team (based on that one used in SimStadt and developed by
|
||||
the IAF team at hft-Stuttgart)
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Copyright © 2022 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
import xmltodict
|
||||
from imports.usage.data_classes.usage_zone_archetype import UsageZoneArchetype as huza
|
||||
from imports.usage.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype as higa
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
from city_model_structure.attributes.schedule import Schedule
|
||||
import helpers.constants as cte
|
||||
|
||||
|
||||
class HftUsageInterface:
|
||||
|
@ -28,116 +33,196 @@ class HftUsageInterface:
|
|||
usage = usage_zone_variant['id']
|
||||
usage_archetype_variant = self._parse_zone_usage_variant(usage, usage_archetype, usage_zone_variant)
|
||||
self._usage_archetypes.append(usage_archetype_variant)
|
||||
for usage in self._usage_archetypes:
|
||||
print(usage.usage)
|
||||
|
||||
@staticmethod
|
||||
def _parse_zone_usage_type(usage, zone_usage_type):
|
||||
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']
|
||||
hours_day = zone_usage_type['occupancy']['usageHoursPerDay']
|
||||
days_year = zone_usage_type['occupancy']['usageDaysPerYear']
|
||||
cooling_setpoint = zone_usage_type['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
heating_setpoint = zone_usage_type['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
heating_setback = zone_usage_type['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
mechanical_air_change = None
|
||||
if 'ventilation' in zone_usage_type['endUses'] and zone_usage_type['endUses']['ventilation'] is not None:
|
||||
mechanical_air_change = zone_usage_type['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
dhw_average_volume_pers_day = None
|
||||
dhw_preparation_temperature = None
|
||||
if 'domestic_hot_water' in zone_usage_type['endUses']:
|
||||
# liters to cubic meters
|
||||
dhw_average_volume_pers_day = float(
|
||||
zone_usage_type['endUses']['domestic_hot_water']['averageVolumePerPersAndDay']) / 1000
|
||||
dhw_preparation_temperature = zone_usage_type['endUses']['domestic_hot_water']['preparationTemperature']
|
||||
electrical_app_average_consumption_sqm_year = None
|
||||
if 'all_electrical_appliances' in zone_usage_type['endUses']:
|
||||
if 'averageConsumptionPerSqmAndYear' in zone_usage_type['endUses']['all_electrical_appliances']:
|
||||
# kWh to J
|
||||
electrical_app_average_consumption_sqm_year = \
|
||||
float(zone_usage_type['endUses']['all_electrical_appliances']['averageConsumptionPerSqmAndYear']) / 3.6
|
||||
usage_zone_archetype = UsageZone()
|
||||
usage_zone_archetype.usage = usage
|
||||
|
||||
# todo: for internal_gain in usage_zone_variant['schedules']['internGains']:????????????????
|
||||
# There are no more internal gains? How is it saved when more than one???
|
||||
internal_gains = []
|
||||
if 'internGains' in zone_usage_type['occupancy']:
|
||||
latent_fraction = zone_usage_type['occupancy']['internGains']['latentFraction']
|
||||
convective_fraction = zone_usage_type['occupancy']['internGains']['convectiveFraction']
|
||||
average_internal_gain = zone_usage_type['occupancy']['internGains']['averageInternGainPerSqm']
|
||||
radiative_fraction = zone_usage_type['occupancy']['internGains']['radiantFraction']
|
||||
else:
|
||||
latent_fraction = 0
|
||||
convective_fraction = 0
|
||||
average_internal_gain = 0
|
||||
radiative_fraction = 0
|
||||
if 'occupancy' in zone_usage_type:
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = zone_usage_type['occupancy']['occupancyDensity'] #todo: check units
|
||||
usage_zone_archetype.hours_day = zone_usage_type['occupancy']['usageHoursPerDay']
|
||||
usage_zone_archetype.days_year = zone_usage_type['occupancy']['usageDaysPerYear']
|
||||
usage_zone_archetype.occupancy = _occupancy
|
||||
|
||||
if 'internGains' in zone_usage_type['occupancy']:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.latent_fraction = zone_usage_type['occupancy']['internGains']['latentFraction']
|
||||
_internal_gain.convective_fraction = zone_usage_type['occupancy']['internGains']['convectiveFraction']
|
||||
_internal_gain.average_internal_gain = zone_usage_type['occupancy']['internGains']['averageInternGainPerSqm']
|
||||
_internal_gain.radiative_fraction = zone_usage_type['occupancy']['internGains']['radiantFraction']
|
||||
if 'load' in zone_usage_type['occupancy']['internGains']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'internal gains load'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.ANY_NUMBER
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = zone_usage_type['occupancy']['internGains']['load']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_internal_gain.schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.not_detailed_source_mean_annual_internal_gains = [_internal_gain]
|
||||
|
||||
if 'endUses' in zone_usage_type:
|
||||
_thermal_control = ThermalControl()
|
||||
if 'space_heating' in zone_usage_type['endUses']:
|
||||
_thermal_control.mean_heating_set_point = \
|
||||
zone_usage_type['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
_thermal_control.heating_set_back = zone_usage_type['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
if 'schedule' in zone_usage_type['endUses']['space_heating']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'heating temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = zone_usage_type['endUses']['space_heating']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.heating_set_point_schedules = [_schedule]
|
||||
|
||||
if 'space_cooling' in zone_usage_type['endUses']:
|
||||
_thermal_control.mean_cooling_set_point = \
|
||||
zone_usage_type['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
if 'schedule' in zone_usage_type['endUses']['space_cooling']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'cooling temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = zone_usage_type['endUses']['space_cooling']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.cooling_set_point_schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.thermal_control = _thermal_control
|
||||
|
||||
if 'ventilation' in zone_usage_type['endUses'] and zone_usage_type['endUses']['ventilation'] is not None:
|
||||
usage_zone_archetype.mechanical_air_change = \
|
||||
zone_usage_type['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
|
||||
# todo: not used or assigned anywhere
|
||||
if 'domestic_hot_water' in zone_usage_type['endUses']:
|
||||
# liters to cubic meters
|
||||
dhw_average_volume_pers_day = float(
|
||||
zone_usage_type['endUses']['domestic_hot_water']['averageVolumePerPersAndDay']) / 1000
|
||||
dhw_preparation_temperature = zone_usage_type['endUses']['domestic_hot_water']['preparationTemperature']
|
||||
|
||||
if 'all_electrical_appliances' in zone_usage_type['endUses']:
|
||||
if 'averageConsumptionPerSqmAndYear' in zone_usage_type['endUses']['all_electrical_appliances']:
|
||||
# kWh to J
|
||||
usage_zone_archetype.electrical_app_average_consumption_sqm_year = \
|
||||
float(zone_usage_type['endUses']['all_electrical_appliances']['averageConsumptionPerSqmAndYear']) \
|
||||
* cte.KILO_WATTS_HOUR_TO_JULES
|
||||
|
||||
if 'appliance' in zone_usage_type:
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = zone_usage_type['appliance']['#text'] #todo: check units
|
||||
|
||||
usage_zone_archetype.appliances = _appliances
|
||||
|
||||
internal_gains.append(higa(average_internal_gain=average_internal_gain, convective_fraction=convective_fraction,
|
||||
radiative_fraction=radiative_fraction, latent_fraction=latent_fraction))
|
||||
usage_zone_archetype = huza(usage=usage, internal_gains=internal_gains, heating_set_point=heating_setpoint,
|
||||
heating_set_back=heating_setback, cooling_set_point=cooling_setpoint,
|
||||
occupancy_density=occupancy_density, hours_day=hours_day, days_year=days_year,
|
||||
dhw_average_volume_pers_day=dhw_average_volume_pers_day,
|
||||
dhw_preparation_temperature=dhw_preparation_temperature,
|
||||
electrical_app_average_consumption_sqm_year=electrical_app_average_consumption_sqm_year,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
return usage_zone_archetype
|
||||
|
||||
@staticmethod
|
||||
def _parse_zone_usage_variant(usage, usage_zone, usage_zone_variant):
|
||||
# for the variants all is optional because it mimics the inheritance concept from OOP
|
||||
occupancy_density = usage_zone.occupancy_density
|
||||
hours_day = usage_zone.hours_day
|
||||
days_year = usage_zone.days_year
|
||||
cooling_setpoint = usage_zone.cooling_setpoint
|
||||
heating_setpoint = usage_zone.heating_setpoint
|
||||
heating_setback = usage_zone.heating_setback
|
||||
mechanical_air_change = usage_zone.mechanical_air_change
|
||||
dhw_average_volume_pers_day = usage_zone.dhw_average_volume_pers_day
|
||||
dhw_preparation_temperature = usage_zone.dhw_preparation_temperature
|
||||
electrical_app_average_consumption_sqm_year = usage_zone.electrical_app_average_consumption_sqm_year
|
||||
# the variants mimic the inheritance concept from OOP
|
||||
usage_zone_archetype = usage_zone
|
||||
usage_zone_archetype.usage = usage
|
||||
|
||||
# todo: for internal_gain in usage_zone_variant['schedules']['internGains']:????????????????
|
||||
# There are no more internal gains? How is it saved when more than one???
|
||||
# for internal_gain in usage_zone.internal_gains:
|
||||
internal_gains = usage_zone.not_detailed_source_mean_annual_internal_gains[0]
|
||||
latent_fraction = internal_gains.latent_fraction
|
||||
convective_fraction = internal_gains.convective_fraction
|
||||
average_internal_gain = internal_gains.average_internal_gain
|
||||
radiative_fraction = internal_gains.radiative_fraction
|
||||
if 'occupancy' in usage_zone_variant:
|
||||
_occupancy = Occupancy()
|
||||
if 'occupancyDensity' in usage_zone_variant['occupancy']:
|
||||
_occupancy.occupancy_density = usage_zone_variant['occupancy']['occupancyDensity'] # todo: check units
|
||||
if 'usageHoursPerDay' in usage_zone_variant['occupancy']:
|
||||
usage_zone_archetype.hours_day = usage_zone_variant['occupancy']['usageHoursPerDay']
|
||||
if 'usageDaysPerYear' in usage_zone_variant['occupancy']:
|
||||
usage_zone_archetype.days_year = usage_zone_variant['occupancy']['usageDaysPerYear']
|
||||
usage_zone_archetype.occupancy = _occupancy
|
||||
|
||||
if 'internGains' in usage_zone_variant['occupancy']:
|
||||
_internal_gain = InternalGains()
|
||||
if 'latentFraction' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.latent_fraction = usage_zone_variant['occupancy']['internGains']['latentFraction']
|
||||
if 'convectiveFraction' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.convective_fraction = usage_zone_variant['occupancy']['internGains']['convectiveFraction']
|
||||
if 'averageInternGainPerSqm' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.average_internal_gain = \
|
||||
usage_zone_variant['occupancy']['internGains']['averageInternGainPerSqm']
|
||||
if 'radiantFraction' in usage_zone_variant['occupancy']['internGains']:
|
||||
_internal_gain.radiative_fraction = usage_zone_variant['occupancy']['internGains']['radiantFraction']
|
||||
if 'load' in usage_zone_variant['occupancy']['internGains']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'internal gains load'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.ANY_NUMBER
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = usage_zone_variant['occupancy']['internGains']['load']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_internal_gain.schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.not_detailed_source_mean_annual_internal_gains = [_internal_gain]
|
||||
|
||||
if 'endUses' in usage_zone_variant:
|
||||
_thermal_control = ThermalControl()
|
||||
if 'space_heating' in usage_zone_variant['endUses']:
|
||||
if 'heatingSetPointTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
_thermal_control.mean_heating_set_point = \
|
||||
usage_zone_variant['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
if 'heatingSetBackTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
_thermal_control.heating_set_back = usage_zone_variant['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
if 'schedule' in usage_zone_variant['endUses']['space_heating']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'heating temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = usage_zone_variant['endUses']['space_heating']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.heating_set_point_schedules = [_schedule]
|
||||
|
||||
if 'space_cooling' in usage_zone_variant['endUses'] and \
|
||||
usage_zone_variant['endUses']['space_cooling'] is not None:
|
||||
if 'coolingSetPointTemperature' in usage_zone_variant['endUses']['space_cooling']:
|
||||
_thermal_control.mean_cooling_set_point = \
|
||||
usage_zone_variant['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
if 'schedule' in usage_zone_variant['endUses']['space_cooling']:
|
||||
_schedule = Schedule()
|
||||
_schedule.type = 'cooling temperature'
|
||||
_schedule.time_range = cte.DAY
|
||||
_schedule.time_step = cte.HOUR
|
||||
_schedule.data_type = cte.TEMPERATURE
|
||||
_schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY]
|
||||
_values = usage_zone_variant['endUses']['space_cooling']['schedule']['weekDayProfile']['values']
|
||||
while ' ' in _values:
|
||||
_values = _values.replace(' ', ' ')
|
||||
_schedule.values = _values.split()
|
||||
_thermal_control.cooling_set_point_schedules = [_schedule]
|
||||
|
||||
usage_zone_archetype.thermal_control = _thermal_control
|
||||
|
||||
if 'ventilation' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['ventilation'] is not None:
|
||||
usage_zone_archetype.mechanical_air_change = \
|
||||
usage_zone_variant['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
|
||||
if 'appliance' in usage_zone_variant:
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = usage_zone_variant['appliance']['#text'] # todo: check units
|
||||
|
||||
usage_zone_archetype.appliances = _appliances
|
||||
|
||||
if 'space_cooling' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['space_cooling'] is not None:
|
||||
if 'coolingSetPointTemperature' in usage_zone_variant['endUses']['space_cooling']:
|
||||
cooling_setpoint = usage_zone_variant['endUses']['space_cooling']['coolingSetPointTemperature']
|
||||
if 'space_heating' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['space_heating'] is not None:
|
||||
if 'heatingSetPointTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
heating_setpoint = usage_zone_variant['endUses']['space_heating']['heatingSetPointTemperature']
|
||||
if 'heatingSetBackTemperature' in usage_zone_variant['endUses']['space_heating']:
|
||||
heating_setback = usage_zone_variant['endUses']['space_heating']['heatingSetBackTemperature']
|
||||
if 'ventilation' in usage_zone_variant['endUses'] and usage_zone_variant['endUses']['ventilation'] is not None:
|
||||
if 'mechanicalAirChangeRate' in usage_zone_variant['endUses']['ventilation']:
|
||||
mechanical_air_change = usage_zone_variant['endUses']['ventilation']['mechanicalAirChangeRate']
|
||||
# todo: for internal_gain in usage_zone_variant['schedules']['internGains']:????????????????
|
||||
# There are no more internal gains? How is it saved when more than one???
|
||||
if 'schedules' in usage_zone_variant:
|
||||
if 'usageHoursPerDay' in usage_zone_variant['schedules']:
|
||||
hours_day = usage_zone_variant['schedules']['usageHoursPerDay']
|
||||
if 'usageDaysPerYear' in usage_zone_variant['schedules']:
|
||||
days_year = usage_zone_variant['schedules']['usageDaysPerYear']
|
||||
if 'internalGains' in usage_zone_variant['schedules'] and usage_zone_variant['schedules'][
|
||||
'internGains'] is not None:
|
||||
internal_gains = []
|
||||
if 'latentFraction' in usage_zone_variant['schedules']['internGains']:
|
||||
latent_fraction = usage_zone_variant['schedules']['internGains']['latentFraction']
|
||||
if 'convectiveFraction' in usage_zone_variant['schedules']['internGains']:
|
||||
convective_fraction = usage_zone_variant['schedules']['internGains']['convectiveFraction']
|
||||
if 'averageInternGainPerSqm' in usage_zone_variant['schedules']['internGains']:
|
||||
average_internal_gain = usage_zone_variant['schedules']['internGains']['averageInternGainPerSqm']
|
||||
if 'radiantFraction' in usage_zone_variant['schedules']['internGains']:
|
||||
radiative_fraction = usage_zone_variant['schedules']['internGains']['radiantFraction']
|
||||
internal_gains.append(higa(average_internal_gain=average_internal_gain, convective_fraction=convective_fraction,
|
||||
radiative_fraction=radiative_fraction, latent_fraction=latent_fraction))
|
||||
usage_zone_archetype = huza(usage=usage, internal_gains=internal_gains, heating_set_point=heating_setpoint,
|
||||
heating_set_back=heating_setback, cooling_set_point=cooling_setpoint,
|
||||
occupancy_density=occupancy_density, hours_day=hours_day, days_year=days_year,
|
||||
dhw_average_volume_pers_day=dhw_average_volume_pers_day,
|
||||
dhw_preparation_temperature=dhw_preparation_temperature,
|
||||
electrical_app_average_consumption_sqm_year=electrical_app_average_consumption_sqm_year,
|
||||
mechanical_air_change=mechanical_air_change)
|
||||
return usage_zone_archetype
|
||||
|
|
|
@ -9,6 +9,9 @@ from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
|||
from imports.usage.hft_usage_interface import HftUsageInterface
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
from city_model_structure.building_demand.internal_gains import InternalGains
|
||||
from city_model_structure.building_demand.occupancy import Occupancy
|
||||
from city_model_structure.building_demand.appliances import Appliances
|
||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||
|
||||
|
||||
class HftUsageParameters(HftUsageInterface):
|
||||
|
@ -26,19 +29,21 @@ class HftUsageParameters(HftUsageInterface):
|
|||
"""
|
||||
city = self._city
|
||||
for building in city.buildings:
|
||||
archetype = self._search_archetype(gh.usage_from_function(building.function))
|
||||
if archetype is None:
|
||||
usage = gh.usage_from_function(building.function)
|
||||
try:
|
||||
archetype = self._search_archetype(usage)
|
||||
except KeyError:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{gh.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
return
|
||||
|
||||
for internal_zone in building.internal_zones:
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.usage = building.function
|
||||
usage_zone.usage = building.function
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.percentage = 1
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
usage_zone.percentage = 1
|
||||
internal_zone.usage_zones = [usage_zone]
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
for building_archetype in self._usage_archetypes:
|
||||
|
@ -51,22 +56,30 @@ class HftUsageParameters(HftUsageInterface):
|
|||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||
# Therefore, this walk around has been done.
|
||||
internal_gains = []
|
||||
for archetype_internal_gain in archetype.internal_gains:
|
||||
internal_gain = InternalGains()
|
||||
internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
internal_gains.append(internal_gain)
|
||||
usage_zone.internal_gains = internal_gains
|
||||
usage_zone.heating_setpoint = archetype.heating_setpoint
|
||||
usage_zone.heating_setback = archetype.heating_setback
|
||||
usage_zone.cooling_setpoint = archetype.cooling_setpoint
|
||||
usage_zone.occupancy_density = archetype.occupancy_density
|
||||
usage_zone.hours_day = archetype.hours_day
|
||||
usage_zone.days_year = archetype.days_year
|
||||
usage_zone.dhw_average_volume_pers_day = archetype.dhw_average_volume_pers_day
|
||||
usage_zone.dhw_preparation_temperature = archetype.dhw_preparation_temperature
|
||||
usage_zone.electrical_app_average_consumption_sqm_year = archetype.electrical_app_average_consumption_sqm_year
|
||||
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||
# usage_zone.occupancy when writing usage_zone.occupancy = archetype.occupancy.
|
||||
# Same happens for lighting and appliances. Therefore, this walk around has been done.
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
_occupancy = Occupancy()
|
||||
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
|
||||
usage_zone.occupancy = _occupancy
|
||||
_appliances = Appliances()
|
||||
_appliances.appliances_density = archetype.appliances.appliances_density
|
||||
usage_zone.appliances = _appliances
|
||||
_control = ThermalControl()
|
||||
_control.mean_heating_set_point = archetype.thermal_control.mean_heating_set_point
|
||||
_control.heating_set_back = archetype.thermal_control.heating_set_back
|
||||
_control.mean_cooling_set_point = archetype.thermal_control.mean_cooling_set_point
|
||||
_control.cooling_set_point_schedules = archetype.thermal_control.cooling_set_point_schedules
|
||||
_control.heating_set_point_schedules = archetype.thermal_control.heating_set_point_schedules
|
||||
usage_zone.thermal_control = _control
|
||||
_internal_gains = []
|
||||
for archetype_internal_gain in archetype.not_detailed_source_mean_annual_internal_gains:
|
||||
_internal_gain = InternalGains()
|
||||
_internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain
|
||||
_internal_gain.convective_fraction = archetype_internal_gain.convective_fraction
|
||||
_internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction
|
||||
_internal_gain.latent_fraction = archetype_internal_gain.latent_fraction
|
||||
_internal_gain.schedules = archetype_internal_gain.schedules
|
||||
_internal_gains.append(_internal_gain)
|
||||
usage_zone.not_detailed_source_mean_annual_internal_gains = _internal_gains
|
||||
|
|
|
@ -47,12 +47,13 @@ class TestConstructionFactory(TestCase):
|
|||
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
|
||||
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
|
||||
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
|
||||
self.assertIsNotNone(building.geometrical_zones, 'no geometrical zones created')
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
self.assertIsNotNone(building.grounds, 'building grounds is none')
|
||||
self.assertIsNotNone(building.walls, 'building walls is none')
|
||||
self.assertIsNotNone(building.roofs, 'building roofs is none')
|
||||
self.assertIsNone(building.usage_zones, 'usage zones are defined')
|
||||
self.assertTrue(len(building.thermal_zones) > 0, 'thermal zones are not defined')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNone(internal_zone.usage_zones, 'usage zones are defined')
|
||||
self.assertTrue(len(internal_zone.thermal_zones) > 0, 'thermal zones are not defined')
|
||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||
self.assertIsNone(building.terrains, 'building terrains is not none')
|
||||
|
@ -69,8 +70,8 @@ class TestConstructionFactory(TestCase):
|
|||
self.assertIsNone(building.households, 'building households is not none')
|
||||
self.assertFalse(building.is_conditioned, 'building is conditioned')
|
||||
|
||||
def _check_thermal_zones(self, building):
|
||||
for thermal_zone in building.thermal_zones:
|
||||
def _check_thermal_zones(self, internal_zone):
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
|
||||
self.assertIsNotNone(thermal_zone.floor_area, 'thermal_zone floor area is none')
|
||||
self.assertTrue(len(thermal_zone.thermal_boundaries) > 0, 'thermal_zone thermal_boundaries not defined')
|
||||
|
@ -81,9 +82,10 @@ class TestConstructionFactory(TestCase):
|
|||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_off,
|
||||
'thermal_zone infiltration_rate_system_off is none')
|
||||
self.assertIsNotNone(thermal_zone.infiltration_rate_system_on, 'thermal_zone infiltration_rate_system_on is none')
|
||||
self.assertIsNone(thermal_zone.usage_zones, 'thermal_zone usage_zones is not none')
|
||||
self.assertIsNotNone(thermal_zone.volume, 'thermal_zone volume is none')
|
||||
self.assertIsNone(thermal_zone.ordinate_number, 'thermal_zone ordinate number is not none')
|
||||
self.assertIsNotNone(thermal_zone.view_factors_matrix, 'thermal_zone view factors matrix is none')
|
||||
self.assertIsNone(thermal_zone.usage_zones, 'thermal_zone usage_zones is not none')
|
||||
self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal_control is not none')
|
||||
self.assertIsNone(thermal_zone.hvac_system, 'thermal_zone hvac_system is not none')
|
||||
|
||||
|
@ -164,27 +166,28 @@ class TestConstructionFactory(TestCase):
|
|||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.hft_to_function[building.function]
|
||||
building.function = GeometryHelper.function_from_hft(building.function)
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
self._check_thermal_zones(building)
|
||||
for thermal_zone in building.thermal_zones:
|
||||
self._check_thermal_boundaries(thermal_zone)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
self.assertIsNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.layers, 'layers is not none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self._check_thermal_zones(internal_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_boundaries(thermal_zone)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
self.assertIsNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.layers, 'layers is not none')
|
||||
|
||||
self._check_thermal_openings(thermal_boundary)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNone(thermal_opening.conductivity, 'thermal_opening conductivity is not none')
|
||||
self.assertIsNone(thermal_opening.thickness, 'thermal opening thickness is not none')
|
||||
self.assertIsNone(thermal_opening.front_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening front_side_solar_transmittance_at_normal_incidence is not none')
|
||||
self.assertIsNone(thermal_opening.back_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening back_side_solar_transmittance_at_normal_incidence is not none')
|
||||
self._check_thermal_openings(thermal_boundary)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNone(thermal_opening.conductivity, 'thermal_opening conductivity is not none')
|
||||
self.assertIsNone(thermal_opening.thickness, 'thermal opening thickness is not none')
|
||||
self.assertIsNone(thermal_opening.front_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening front_side_solar_transmittance_at_normal_incidence is not none')
|
||||
self.assertIsNone(thermal_opening.back_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening back_side_solar_transmittance_at_normal_incidence is not none')
|
||||
|
||||
def test_city_with_construction_extended_library(self):
|
||||
"""
|
||||
|
@ -193,41 +196,39 @@ class TestConstructionFactory(TestCase):
|
|||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.pluto_to_function[building.function]
|
||||
building.function = GeometryHelper.function_from_pluto(building.function)
|
||||
ConstructionFactory('nrel', city).enrich()
|
||||
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
self._check_thermal_zones(building)
|
||||
for thermal_zone in building.thermal_zones:
|
||||
self._check_thermal_boundaries(thermal_zone)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
if thermal_boundary.type is not cte.GROUND:
|
||||
self.assertIsNotNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is none')
|
||||
self.assertIsNotNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is none')
|
||||
else:
|
||||
self.assertIsNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is not none')
|
||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self._check_thermal_zones(internal_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_boundaries(thermal_zone)
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
if thermal_boundary.type is not cte.GROUND:
|
||||
self.assertIsNotNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is none')
|
||||
self.assertIsNotNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is none')
|
||||
else:
|
||||
self.assertIsNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is not none')
|
||||
self.assertIsNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is not none')
|
||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||
|
||||
self._check_thermal_openings(thermal_boundary)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNotNone(thermal_opening.conductivity, 'thermal_opening conductivity is none')
|
||||
self.assertIsNotNone(thermal_opening.thickness, 'thermal opening thickness is none')
|
||||
self.assertIsNotNone(thermal_opening.front_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening front_side_solar_transmittance_at_normal_incidence is none')
|
||||
self.assertIsNotNone(thermal_opening.back_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening back_side_solar_transmittance_at_normal_incidence is none')
|
||||
self._check_thermal_openings(thermal_boundary)
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
self.assertIsNotNone(thermal_opening.conductivity, 'thermal_opening conductivity is none')
|
||||
self.assertIsNotNone(thermal_opening.thickness, 'thermal opening thickness is none')
|
||||
self.assertIsNotNone(thermal_opening.front_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening front_side_solar_transmittance_at_normal_incidence is none')
|
||||
self.assertIsNotNone(thermal_opening.back_side_solar_transmittance_at_normal_incidence,
|
||||
'thermal opening back_side_solar_transmittance_at_normal_incidence is none')
|
||||
|
||||
@staticmethod
|
||||
def _internal_function(function_format, original_function):
|
||||
if function_format == 'hft':
|
||||
new_function = GeometryHelper.hft_to_function[original_function]
|
||||
new_function = GeometryHelper.function_from_hft(original_function)
|
||||
elif function_format == 'pluto':
|
||||
new_function = GeometryHelper.pluto_to_function[original_function]
|
||||
elif function_format == 'alkis':
|
||||
# todo: not implemented yet!!
|
||||
raise NotImplementedError
|
||||
new_function = GeometryHelper.function_from_pluto(original_function)
|
||||
else:
|
||||
raise Exception('Function key not recognized. Implemented only "hft" and "pluto"')
|
||||
return new_function
|
||||
|
|
145
unittests/test_enrichement.py
Normal file
145
unittests/test_enrichement.py
Normal file
|
@ -0,0 +1,145 @@
|
|||
"""
|
||||
TestGeometryFactory test and validate the city model structure geometric parameters
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
|
||||
|
||||
class TestGeometryFactory(TestCase):
|
||||
"""
|
||||
Non-functional TestGeometryFactory
|
||||
Load testing
|
||||
"""
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Test setup
|
||||
:return: None
|
||||
"""
|
||||
self._city = None
|
||||
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||
|
||||
def _get_citygml(self, file):
|
||||
file_path = (self._example_path / file).resolve()
|
||||
self._city = GeometryFactory('citygml', file_path).city
|
||||
self.assertIsNotNone(self._city, 'city is none')
|
||||
return self._city
|
||||
|
||||
def _check_buildings(self, city):
|
||||
for building in city.buildings:
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNotNone(internal_zone.usage_zones, 'usage zones are not defined')
|
||||
self.assertIsNotNone(internal_zone.thermal_zones, 'thermal zones are not defined')
|
||||
#self.assertIsNotNone(building.basement_heated, 'building basement_heated is none')
|
||||
#self.assertIsNotNone(building.attic_heated, 'building attic_heated is none')
|
||||
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
|
||||
self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none')
|
||||
self.assertTrue(building.is_conditioned, 'building is_conditioned is not conditioned')
|
||||
|
||||
def _check_usage_zone(self, usage_zone):
|
||||
self.assertIsNotNone(usage_zone.id, 'usage id is none')
|
||||
|
||||
def _check_thermal_zones(self, thermal_zone):
|
||||
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
|
||||
self.assertIsNone(thermal_zone.usage_zones, 'thermal_zone usage_zones is not none')
|
||||
self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal_control is not none')
|
||||
|
||||
@staticmethod
|
||||
def _prepare_case_usage_first(city, input_key, construction_key, usage_key):
|
||||
if input_key == 'pluto':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.function_from_pluto(building.function)
|
||||
elif input_key == 'hft':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.function_from_hft(building.function)
|
||||
UsageFactory(usage_key, city).enrich()
|
||||
ConstructionFactory(construction_key, city).enrich()
|
||||
|
||||
@staticmethod
|
||||
def _prepare_case_construction_first(city, input_key, construction_key, usage_key):
|
||||
if input_key == 'pluto':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.function_from_pluto(building.function)
|
||||
elif input_key == 'hft':
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.function_from_hft(building.function)
|
||||
ConstructionFactory(construction_key, city).enrich()
|
||||
UsageFactory(usage_key, city).enrich()
|
||||
|
||||
def test_enrichment(self):
|
||||
"""
|
||||
Test enrichment of the city with different order and all possible combinations
|
||||
:return: None
|
||||
"""
|
||||
file_1 = 'one_building_in_kelowna.gml'
|
||||
file_2 = 'pluto_building.gml'
|
||||
file_3 = 'C40_Final.gml'
|
||||
_construction_keys = ['nrel', 'nrcan']
|
||||
_usage_keys = ['ca', 'comnet'] # todo: add 'hft'
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
for usage_key in _usage_keys:
|
||||
city = self._get_citygml(file_1)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_construction_first(city, 'hft', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
for usage_key in _usage_keys:
|
||||
city = self._get_citygml(file_1)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_usage_first(city, 'hft', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
for usage_key in _usage_keys:
|
||||
if usage_key != 'ca':
|
||||
city = self._get_citygml(file_2)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_construction_first(city, 'pluto', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
for construction_key in _construction_keys:
|
||||
for usage_key in _usage_keys:
|
||||
if usage_key != 'ca':
|
||||
city = self._get_citygml(file_2)
|
||||
self.assertTrue(len(city.buildings) == 1)
|
||||
self._prepare_case_usage_first(city, 'pluto', construction_key, usage_key)
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._check_thermal_zones(thermal_zone)
|
||||
|
||||
city = self._get_citygml(file_3)
|
||||
self.assertTrue(len(city.buildings) == 10)
|
|
@ -51,7 +51,7 @@ class TestGeometryFactory(TestCase):
|
|||
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
|
||||
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
|
||||
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
|
||||
self.assertIsNotNone(building.geometrical_zones, 'no geometrical zones created')
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
self.assertIsNotNone(building.grounds, 'building grounds is none')
|
||||
self.assertIsNotNone(building.walls, 'building walls is none')
|
||||
self.assertIsNotNone(building.roofs, 'building roofs is none')
|
||||
|
|
|
@ -8,8 +8,6 @@ from unittest import TestCase
|
|||
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.schedules_factory import SchedulesFactory
|
||||
from imports.construction_factory import ConstructionFactory
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
|
||||
|
||||
|
@ -48,34 +46,40 @@ class TestUsageFactory(TestCase):
|
|||
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
|
||||
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
|
||||
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
|
||||
self.assertIsNotNone(building.geometrical_zones, 'no geometrical zones created')
|
||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||
self.assertIsNotNone(building.grounds, 'building grounds is none')
|
||||
self.assertIsNotNone(building.walls, 'building walls is none')
|
||||
self.assertIsNotNone(building.roofs, 'building roofs is none')
|
||||
self.assertTrue(len(building.usage_zones) > 0, 'usage zones are not defined')
|
||||
self.assertTrue(len(building.thermal_zones) > 0, 'thermal zones are not defined')
|
||||
self.assertIsNotNone(building.basement_heated, 'building basement_heated is none')
|
||||
self.assertIsNotNone(building.attic_heated, 'building attic_heated is none')
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertTrue(len(internal_zone.usage_zones) > 0, 'usage zones are not defined')
|
||||
self.assertIsNone(building.thermal_zones, 'thermal zones are defined')
|
||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||
self.assertIsNone(building.terrains, 'building terrains is not none')
|
||||
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
|
||||
self.assertIsNotNone(building.function, 'building function is none')
|
||||
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
|
||||
self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none')
|
||||
self.assertIsNone(building.average_storey_height, 'building average_storey_height is not none')
|
||||
self.assertIsNone(building.storeys_above_ground, 'building storeys_above_ground is not none')
|
||||
self.assertEqual(len(building.heating), 0, 'building heating is not none')
|
||||
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
|
||||
self.assertIsNotNone(building.eave_height, 'building eave height is none')
|
||||
self.assertIsNotNone(building.storeys, 'building storeys are not defined')
|
||||
self.assertIsNone(building.storeys, 'building storeys are defined')
|
||||
self.assertIsNotNone(building.roof_type, 'building roof type is none')
|
||||
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
|
||||
self.assertIsNone(building.households, 'building households is not none')
|
||||
self.assertTrue(building.is_conditioned, 'building is not conditioned')
|
||||
|
||||
|
||||
def _check_hvac(self, thermal_zone):
|
||||
self.assertIsNotNone(None, 'hvac')
|
||||
|
||||
def _check_control(self, thermal_zone):
|
||||
self.assertIsNotNone(None, 'control')
|
||||
def _check_usage_zone(self, usage_zone):
|
||||
self.assertIsNotNone(usage_zone.usage, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.percentage, 'usage percentage is none')
|
||||
self.assertIsNotNone(usage_zone.get_internal_gains, 'internal gains is none')
|
||||
self.assertIsNotNone(usage_zone.hours_day, 'hours per day is none')
|
||||
self.assertIsNotNone(usage_zone.days_year, 'days per year is none')
|
||||
self.assertIsNotNone(usage_zone.mechanical_air_change, 'mechanical air change is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control, 'thermal control is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.mean_heating_set_point, 'control heating set point is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.heating_set_back, 'control heating set back is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.mean_cooling_set_point, 'control cooling set point is none')
|
||||
|
||||
def test_import_comnet(self):
|
||||
"""
|
||||
|
@ -84,33 +88,45 @@ class TestUsageFactory(TestCase):
|
|||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.pluto_to_function[building.function]
|
||||
building.function = GeometryHelper.function_from_pluto(building.function)
|
||||
|
||||
UsageFactory('comnet', city).enrich()
|
||||
SchedulesFactory('comnet', city).enrich()
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_extended_usage(usage_zone)
|
||||
|
||||
def test_import_hft(self):
|
||||
"""
|
||||
Enrich the city with the usage information from hft and verify it
|
||||
"""
|
||||
# todo: read schedules!!
|
||||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.pluto_to_function[building.function]
|
||||
|
||||
UsageFactory('hft', city).enrich()
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_extended_usage(usage_zone)
|
||||
self._check_usage_zone(usage_zone)
|
||||
self.assertIsNotNone(usage_zone.thermal_control.heating_set_point_schedules,
|
||||
'control heating set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.cooling_set_point_schedules,
|
||||
'control cooling set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy, 'occupancy is none')
|
||||
occupancy = usage_zone.occupancy
|
||||
self.assertIsNotNone(occupancy.occupancy_density, 'occupancy density is none')
|
||||
self.assertIsNotNone(occupancy.latent_internal_gain, 'occupancy latent internal gain is none')
|
||||
self.assertIsNotNone(occupancy.sensible_convective_internal_gain,
|
||||
'occupancy sensible convective internal gain is none')
|
||||
self.assertIsNotNone(occupancy.sensible_radiative_internal_gain,
|
||||
'occupancy sensible radiant internal gain is none')
|
||||
self.assertIsNotNone(occupancy.occupancy_schedules, 'occupancy schedule is none')
|
||||
self.assertIsNone(occupancy.occupants, 'occupancy density is not none')
|
||||
self.assertIsNotNone(usage_zone.lighting, 'lighting is none')
|
||||
lighting = usage_zone.lighting
|
||||
self.assertIsNotNone(lighting.lighting_density, 'lighting density is none')
|
||||
self.assertIsNotNone(lighting.latent_fraction, 'lighting latent fraction is none')
|
||||
self.assertIsNotNone(lighting.convective_fraction, 'lighting convective fraction is none')
|
||||
self.assertIsNotNone(lighting.radiative_fraction, 'lighting radiant fraction is none')
|
||||
self.assertIsNotNone(lighting.schedules, 'lighting schedule is none')
|
||||
self.assertIsNotNone(usage_zone.appliances, 'appliances is none')
|
||||
appliances = usage_zone.appliances
|
||||
self.assertIsNotNone(appliances.appliances_density, 'appliances density is none')
|
||||
self.assertIsNotNone(appliances.latent_fraction, 'appliances latent fraction is none')
|
||||
self.assertIsNotNone(appliances.convective_fraction, 'appliances convective fraction is none')
|
||||
self.assertIsNotNone(appliances.radiative_fraction, 'appliances radiant fraction is none')
|
||||
self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.hvac_availability_schedules,
|
||||
'control hvac availability is none')
|
||||
|
||||
def test_import_ca(self):
|
||||
"""
|
||||
|
@ -119,34 +135,56 @@ class TestUsageFactory(TestCase):
|
|||
file = 'one_building_in_kelowna.gml'
|
||||
city = self._get_citygml(file)
|
||||
UsageFactory('ca', city).enrich()
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_reduced_usage(usage_zone)
|
||||
self._check_usage_zone(usage_zone)
|
||||
self.assertIsNotNone(usage_zone.not_detailed_source_mean_annual_internal_gains,
|
||||
'not detailed internal gains is none')
|
||||
|
||||
def _check_extended_usage(self, usage_zone):
|
||||
self.assertIsNotNone(usage_zone.usage, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.not_detailed_source_mean_annual_internal_gains, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.cooling_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setback, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy_density, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.hours_day, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.days_year, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.dhw_average_volume_pers_day, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.dhw_preparation_temperature, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.electrical_app_average_consumption_sqm_year, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.is_heated, 'thermal_zone heated is none')
|
||||
self.assertIsNotNone(usage_zone.is_cooled, 'thermal_zone cooled is none')
|
||||
def test_import_hft(self):
|
||||
"""
|
||||
Enrich the city with the usage information from hft and verify it
|
||||
"""
|
||||
file = 'pluto_building.gml'
|
||||
city = self._get_citygml(file)
|
||||
for building in city.buildings:
|
||||
building.function = GeometryHelper.function_from_pluto(building.function)
|
||||
|
||||
|
||||
def _check_reduced_usage(self, usage_zone):
|
||||
self.assertIsNotNone(usage_zone.usage, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.internal_gains, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.cooling_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setback, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.heating_setpoint, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy_density, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.hours_day, 'usage is none')
|
||||
self.assertIsNotNone(usage_zone.days_year, 'usage is none')
|
||||
UsageFactory('hft', city).enrich()
|
||||
self._check_buildings(city)
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined')
|
||||
for usage_zone in internal_zone.usage_zones:
|
||||
self._check_usage_zone(usage_zone)
|
||||
self.assertIsNotNone(usage_zone.thermal_control.heating_set_point_schedules,
|
||||
'control heating set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.thermal_control.cooling_set_point_schedules,
|
||||
'control cooling set point schedule is none')
|
||||
self.assertIsNotNone(usage_zone.occupancy, 'occupancy is none')
|
||||
occupancy = usage_zone.occupancy
|
||||
self.assertIsNotNone(occupancy.occupancy_density, 'occupancy density is none')
|
||||
self.assertIsNotNone(occupancy.latent_internal_gain, 'occupancy latent internal gain is none')
|
||||
self.assertIsNotNone(occupancy.sensible_convective_internal_gain,
|
||||
'occupancy sensible convective internal gain is none')
|
||||
self.assertIsNotNone(occupancy.sensible_radiative_internal_gain,
|
||||
'occupancy sensible radiant internal gain is none')
|
||||
self.assertIsNotNone(occupancy.occupancy_schedules, 'occupancy schedule is none')
|
||||
self.assertIsNone(occupancy.occupants, 'occupancy density is not none')
|
||||
self.assertIsNotNone(usage_zone.lighting, 'lighting is none')
|
||||
lighting = usage_zone.lighting
|
||||
self.assertIsNotNone(lighting.lighting_density, 'lighting density is none')
|
||||
self.assertIsNotNone(lighting.latent_fraction, 'lighting latent fraction is none')
|
||||
self.assertIsNotNone(lighting.convective_fraction, 'lighting convective fraction is none')
|
||||
self.assertIsNotNone(lighting.radiative_fraction, 'lighting radiant fraction is none')
|
||||
self.assertIsNotNone(lighting.schedules, 'lighting schedule is none')
|
||||
self.assertIsNotNone(usage_zone.appliances, 'appliances is none')
|
||||
appliances = usage_zone.appliances
|
||||
self.assertIsNotNone(appliances.appliances_density, 'appliances density is none')
|
||||
self.assertIsNotNone(appliances.latent_fraction, 'appliances latent fraction is none')
|
||||
self.assertIsNotNone(appliances.convective_fraction, 'appliances convective fraction is none')
|
||||
self.assertIsNotNone(appliances.radiative_fraction, 'appliances radiant fraction is none')
|
||||
self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
|
||||
|
|
Loading…
Reference in New Issue
Block a user