""" UsageZone module SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Code contributors: Guille Gutierrez guillermo.gutierrezmorote@concordia.ca """ import uuid from typing import List, Union from city_model_structure.building_demand.internal_gain import InternalGain 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 import helpers.constants as cte class UsageZone: """ UsageZone class """ def __init__(self, not_detailed_source_mean_annual_internal_gains=None): self._id = None self._usage = None self._percentage = None self._not_detailed_source_mean_annual_internal_gains = not_detailed_source_mean_annual_internal_gains self._hours_day = None self._days_year = None # self._electrical_app_average_consumption_sqm_year = None self._mechanical_air_change = None self._occupancy = None self._lighting = None self._appliances = None self._thermal_control = None self._internal_gains = None @property def id(self): """ Get usage zone id, a universally unique identifier randomly generated :return: str """ if self._id is None: 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 hours_day(self) -> Union[None, float]: """ Get usage zone usage hours per day :return: None or float """ return self._hours_day @hours_day.setter def hours_day(self, value): """ Set usage zone usage hours per day :param value: float """ if value is not None: self._hours_day = float(value) @property def days_year(self) -> Union[None, float]: """ Get usage zone usage days per year :return: None or float """ return self._days_year @days_year.setter def days_year(self, value): """ Set usage zone usage days per year :param value: float """ if value is not None: self._days_year = float(value) @property def mechanical_air_change(self) -> Union[None, float]: """ Get usage zone mechanical air change in air change per hour (ACH) :return: None or float """ return self._mechanical_air_change @mechanical_air_change.setter def mechanical_air_change(self, value): """ Set usage zone mechanical air change in air change per hour (ACH) :param value: float """ if value is not None: self._mechanical_air_change = float(value) @property def occupancy(self) -> Union[None, Occupancy]: """ Get occupancy in the usage zone :return: None or Occupancy """ return self._occupancy @occupancy.setter def occupancy(self, value): """ Set occupancy in the usage zone :param value: Occupancy """ self._occupancy = value @property def lighting(self) -> Union[None, Lighting]: """ Get lighting information :return: None or Lighting """ return self._lighting @lighting.setter def lighting(self, value): """ Set lighting information :param value: Lighting """ self._lighting = value @property def appliances(self) -> Union[None, Appliances]: """ Get appliances information :return: None or Appliances """ return self._appliances @appliances.setter def appliances(self, value): """ Set appliances information :param value: Appliances """ self._appliances = value @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 @property def internal_gains(self) -> List[InternalGain]: """ Calculates and returns the list of all internal gains defined :return: [InternalGain] """ if self._not_detailed_source_mean_annual_internal_gains is not None: self._internal_gains = [] for _internal_gain in self._not_detailed_source_mean_annual_internal_gains: self._internal_gains.append(_internal_gain) if self.occupancy is not None: if self.occupancy.latent_internal_gain is not None: _internal_gain = InternalGain() _internal_gain.type = cte.OCCUPANCY _total_heat_gain = (self.occupancy.sensible_convective_internal_gain + self.occupancy.sensible_radiative_internal_gain + self.occupancy.latent_internal_gain) _internal_gain.average_internal_gain = _total_heat_gain if _total_heat_gain > 0: _internal_gain.latent_fraction = self.occupancy.latent_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 else: _internal_gain.latent_fraction = 0 _internal_gain.radiative_fraction = 0 _internal_gain.convective_fraction = 0 _internal_gain.schedules = self.occupancy.occupancy_schedules if self._internal_gains is not None: self._internal_gains.append(_internal_gain) else: self._internal_gains = [_internal_gain] if self.lighting is not None: _internal_gain = InternalGain() _internal_gain.type = cte.LIGHTING self._add_internal_gain(self.lighting, _internal_gain) if self._internal_gains is not None: self._internal_gains.append(_internal_gain) else: self._internal_gains = [_internal_gain] if self.appliances is not None: _internal_gain = InternalGain() _internal_gain.type = cte.APPLIANCES self._add_internal_gain(self.appliances, _internal_gain) if self._internal_gains is not None: self._internal_gains.append(_internal_gain) else: self._internal_gains = [_internal_gain] return self._internal_gains @staticmethod def _add_internal_gain(internal_gain_type, _internal_gain): _internal_gain.average_internal_gain = internal_gain_type.density _internal_gain.latent_fraction = internal_gain_type.latent_fraction _internal_gain.radiative_fraction = internal_gain_type.radiative_fraction _internal_gain.convective_fraction = internal_gain_type.convective_fraction _internal_gain.schedules = internal_gain_type.schedules