Merge branch 'main' into feature/cerc_idf

This commit is contained in:
Guille Gutierrez 2024-11-30 07:33:26 +01:00
commit 1f3d981ace
36 changed files with 1894 additions and 1406 deletions

View File

@ -15,11 +15,20 @@ class Archetype:
""" """
Archetype class Archetype class
""" """
def __init__(self, name, systems):
def __init__(self, name, systems, archetype_cluster_id=None):
self._cluster_id = archetype_cluster_id
self._name = name self._name = name
self._systems = systems self._systems = systems
@property
def cluster_id(self):
"""
Get id
:return: string
"""
return self._cluster_id
@property @property
def name(self): def name(self):
""" """
@ -43,8 +52,9 @@ class Archetype:
_systems.append(_system.to_dictionary()) _systems.append(_system.to_dictionary())
content = { content = {
'Archetype': { 'Archetype': {
'cluster_id': self.cluster_id,
'name': self.name, 'name': self.name,
'systems': _systems 'systems': _systems
}
} }
}
return content return content

View File

@ -119,7 +119,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
'height [m]': self.height, 'height [m]': self.height,
'layers': _layers, 'layers': _layers,
'maximum operating temperature [Celsius]': self.maximum_operating_temperature, 'maximum operating temperature [Celsius]': self.maximum_operating_temperature,
'storage_medium': self.storage_medium.to_dictionary(), 'storage_medium': _medias,
'heating coil capacity [W]': self.heating_coil_capacity 'heating coil capacity [W]': self.heating_coil_capacity
} }
} }

View File

@ -69,10 +69,10 @@ class MontrealCustomCatalog(Catalog):
storage_system = ThermalStorageSystem(equipment_id) storage_system = ThermalStorageSystem(equipment_id)
storage_systems = [storage_system] storage_systems = [storage_system]
if model_name == 'PV system': if model_name == 'PV system':
system_type = 'Photovoltaic' system_type = 'photovoltaic'
generation_system = PvGenerationSystem(equipment_id, generation_system = PvGenerationSystem(equipment_id,
name=None, name=None,
system_type= system_type, system_type=system_type,
model_name=model_name, model_name=model_name,
electricity_efficiency=electricity_efficiency, electricity_efficiency=electricity_efficiency,
energy_storage_systems=storage_systems energy_storage_systems=storage_systems

View File

@ -30,7 +30,8 @@ class MontrealFutureSystemCatalogue(Catalog):
path = str(path / 'montreal_future_systems.xml') path = str(path / 'montreal_future_systems.xml')
with open(path, 'r', encoding='utf-8') as xml: with open(path, 'r', encoding='utf-8') as xml:
self._archetypes = xmltodict.parse(xml.read(), self._archetypes = xmltodict.parse(xml.read(),
force_list=['pv_generation_component', 'templateStorages', 'demand']) force_list=['pv_generation_component', 'templateStorages', 'demand',
'system', 'system_id'])
self._storage_components = self._load_storage_components() self._storage_components = self._load_storage_components()
self._generation_components = self._load_generation_components() self._generation_components = self._load_generation_components()
@ -49,7 +50,7 @@ class MontrealFutureSystemCatalogue(Catalog):
'non_pv_generation_component'] 'non_pv_generation_component']
if non_pv_generation_components is not None: if non_pv_generation_components is not None:
for non_pv in non_pv_generation_components: for non_pv in non_pv_generation_components:
system_id = non_pv['system_id'] system_id = non_pv['generation_system_id']
name = non_pv['name'] name = non_pv['name']
system_type = non_pv['system_type'] system_type = non_pv['system_type']
model_name = non_pv['model_name'] model_name = non_pv['model_name']
@ -181,7 +182,7 @@ class MontrealFutureSystemCatalogue(Catalog):
'pv_generation_component'] 'pv_generation_component']
if pv_generation_components is not None: if pv_generation_components is not None:
for pv in pv_generation_components: for pv in pv_generation_components:
system_id = pv['system_id'] system_id = pv['generation_system_id']
name = pv['name'] name = pv['name']
system_type = pv['system_type'] system_type = pv['system_type']
model_name = pv['model_name'] model_name = pv['model_name']
@ -381,6 +382,7 @@ class MontrealFutureSystemCatalogue(Catalog):
_system_archetypes = [] _system_archetypes = []
system_clusters = self._archetypes['EnergySystemCatalog']['system_archetypes']['system_archetype'] system_clusters = self._archetypes['EnergySystemCatalog']['system_archetypes']['system_archetype']
for system_cluster in system_clusters: for system_cluster in system_clusters:
archetype_id = system_cluster['@cluster_id']
name = system_cluster['name'] name = system_cluster['name']
systems = system_cluster['systems']['system_id'] systems = system_cluster['systems']['system_id']
integer_system_ids = [int(item) for item in systems] integer_system_ids = [int(item) for item in systems]
@ -388,7 +390,7 @@ class MontrealFutureSystemCatalogue(Catalog):
for system_archetype in self._systems: for system_archetype in self._systems:
if int(system_archetype.id) in integer_system_ids: if int(system_archetype.id) in integer_system_ids:
_systems.append(system_archetype) _systems.append(system_archetype)
_system_archetypes.append(Archetype(name=name, systems=_systems)) _system_archetypes.append(Archetype(archetype_cluster_id=archetype_id, name=name, systems=_systems))
return _system_archetypes return _system_archetypes
def _load_materials(self): def _load_materials(self):

View File

@ -27,7 +27,7 @@ class Building(CityObject):
""" """
Building(CityObject) class Building(CityObject) class
""" """
def __init__(self, name, surfaces, year_of_construction, function, terrains=None, city=None): def __init__(self, name, surfaces, year_of_construction, function, usages=None, terrains=None, city=None):
super().__init__(name, surfaces) super().__init__(name, surfaces)
self._city = city self._city = city
self._households = None self._households = None
@ -36,6 +36,7 @@ class Building(CityObject):
self._terrains = terrains self._terrains = terrains
self._year_of_construction = year_of_construction self._year_of_construction = year_of_construction
self._function = function self._function = function
self._usages = usages
self._average_storey_height = None self._average_storey_height = None
self._storeys_above_ground = None self._storeys_above_ground = None
self._floor_area = None self._floor_area = None
@ -92,6 +93,7 @@ class Building(CityObject):
logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type) logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
self._domestic_hot_water_peak_load = None self._domestic_hot_water_peak_load = None
self._fuel_consumption_breakdown = {} self._fuel_consumption_breakdown = {}
self._systems_archetype_cluster_id = None
self._pv_generation = {} self._pv_generation = {}
@property @property
@ -256,7 +258,17 @@ class Building(CityObject):
:param value: str :param value: str
""" """
if value is not None: if value is not None:
self._function = str(value) self._function = value
@property
def usages(self) -> Union[None, list]:
"""
Get building usages, if none, assume usage is function
:return: None or list of functions
"""
if self._usages is None and self._function is not None:
self._usages = [{'usage': self._function, 'ratio': 1 }]
return self._usages
@property @property
def average_storey_height(self) -> Union[None, float]: def average_storey_height(self) -> Union[None, float]:
@ -593,19 +605,6 @@ class Building(CityObject):
""" """
self._city = value self._city = value
@property
def usages_percentage(self):
"""
Get the usages and percentages for the building
"""
_usage = ''
for internal_zone in self.internal_zones:
if internal_zone.usages is None:
continue
for usage in internal_zone.usages:
_usage = f'{_usage}{usage.name}_{usage.percentage} '
return _usage.rstrip()
@property @property
def energy_systems(self) -> Union[None, List[EnergySystem]]: def energy_systems(self) -> Union[None, List[EnergySystem]]:
""" """
@ -867,53 +866,87 @@ class Building(CityObject):
Get energy consumption of different sectors Get energy consumption of different sectors
return: dict return: dict
""" """
fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0], fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0] if self.lighting_electrical_demand else 0,
cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][0]}} cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][0] if self.appliances_electrical_demand else 0}}
energy_systems = self.energy_systems energy_systems = self.energy_systems
for energy_system in energy_systems: if energy_systems is not None:
demand_types = energy_system.demand_types for energy_system in energy_systems:
generation_systems = energy_system.generation_systems demand_types = energy_system.demand_types
for demand_type in demand_types: generation_systems = energy_system.generation_systems
for generation_system in generation_systems: for demand_type in demand_types:
if generation_system.system_type != cte.PHOTOVOLTAIC: for generation_system in generation_systems:
if generation_system.fuel_type not in fuel_breakdown: if generation_system.system_type != cte.PHOTOVOLTAIC:
fuel_breakdown[generation_system.fuel_type] = {} if generation_system.fuel_type not in fuel_breakdown:
if demand_type in generation_system.energy_consumption: fuel_breakdown[generation_system.fuel_type] = {}
fuel_breakdown[f'{generation_system.fuel_type}'][f'{demand_type}'] = ( if demand_type in generation_system.energy_consumption:
generation_system.energy_consumption)[f'{demand_type}'][cte.YEAR][0] fuel_breakdown[f'{generation_system.fuel_type}'][f'{demand_type}'] = (
storage_systems = generation_system.energy_storage_systems generation_system.energy_consumption)[f'{demand_type}'][cte.YEAR][0]
if storage_systems: storage_systems = generation_system.energy_storage_systems
for storage_system in storage_systems: if storage_systems:
if storage_system.type_energy_stored == 'thermal' and storage_system.heating_coil_energy_consumption: for storage_system in storage_systems:
fuel_breakdown[cte.ELECTRICITY][f'{demand_type}'] += storage_system.heating_coil_energy_consumption[cte.YEAR][0] if storage_system.type_energy_stored == 'thermal' and storage_system.heating_coil_energy_consumption:
#TODO: When simulation models of all energy system archetypes are created, this part can be removed fuel_breakdown[cte.ELECTRICITY][f'{demand_type}'] += (
heating_fuels = [] storage_system.heating_coil_energy_consumption)[f'{demand_type}'][cte.YEAR][0]
dhw_fuels = [] #TODO: When simulation models of all energy system archetypes are created, this part can be removed
for energy_system in self.energy_systems: heating_fuels = []
if cte.HEATING in energy_system.demand_types: dhw_fuels = []
for generation_system in energy_system.generation_systems: for energy_system in self.energy_systems:
heating_fuels.append(generation_system.fuel_type) if cte.HEATING in energy_system.demand_types:
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types: for generation_system in energy_system.generation_systems:
for generation_system in energy_system.generation_systems: heating_fuels.append(generation_system.fuel_type)
dhw_fuels.append(generation_system.fuel_type) if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
for key in fuel_breakdown: for generation_system in energy_system.generation_systems:
if key == cte.ELECTRICITY and cte.COOLING not in fuel_breakdown[key]: dhw_fuels.append(generation_system.fuel_type)
for energy_system in energy_systems: for key in fuel_breakdown:
if cte.COOLING in energy_system.demand_types and cte.COOLING not in fuel_breakdown[key]: if key == cte.ELECTRICITY and cte.COOLING not in fuel_breakdown[key]:
for generation_system in energy_system.generation_systems:
fuel_breakdown[generation_system.fuel_type][cte.COOLING] = self.cooling_consumption[cte.YEAR][0]
for fuel in heating_fuels:
if cte.HEATING not in fuel_breakdown[fuel]:
for energy_system in energy_systems: for energy_system in energy_systems:
if cte.HEATING in energy_system.demand_types: if cte.COOLING in energy_system.demand_types and cte.COOLING not in fuel_breakdown[key]:
for generation_system in energy_system.generation_systems: if self.cooling_consumption:
fuel_breakdown[generation_system.fuel_type][cte.HEATING] = self.heating_consumption[cte.YEAR][0] fuel_breakdown[energy_system.generation_systems[0].fuel_type][cte.COOLING] = self.cooling_consumption[cte.YEAR][0]
for fuel in dhw_fuels: for fuel in heating_fuels:
if cte.DOMESTIC_HOT_WATER not in fuel_breakdown[fuel]: if cte.HEATING not in fuel_breakdown[fuel]:
for energy_system in energy_systems: for energy_system in energy_systems:
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types: if cte.HEATING in energy_system.demand_types:
for generation_system in energy_system.generation_systems: if self.heating_consumption:
fuel_breakdown[generation_system.fuel_type][cte.DOMESTIC_HOT_WATER] = self.domestic_hot_water_consumption[cte.YEAR][0] fuel_breakdown[energy_system.generation_systems[0].fuel_type][cte.HEATING] = self.heating_consumption[cte.YEAR][0]
for fuel in dhw_fuels:
if cte.DOMESTIC_HOT_WATER not in fuel_breakdown[fuel]:
for energy_system in energy_systems:
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
if self.domestic_hot_water_consumption:
fuel_breakdown[energy_system.generation_systems[0].fuel_type][cte.DOMESTIC_HOT_WATER] = self.domestic_hot_water_consumption[cte.YEAR][0]
self._fuel_consumption_breakdown = fuel_breakdown self._fuel_consumption_breakdown = fuel_breakdown
return self._fuel_consumption_breakdown return self._fuel_consumption_breakdown
@property
def energy_systems_archetype_cluster_id(self):
"""
Get energy systems archetype id
:return: str
"""
return self._systems_archetype_cluster_id
@energy_systems_archetype_cluster_id.setter
def energy_systems_archetype_cluster_id(self, value):
"""
Set energy systems archetype id
:param value: str
"""
self._systems_archetype_cluster_id = value
@property
def pv_generation(self):
"""
temporary attribute to get the onsite pv generation in W
:return: dict
"""
return self._pv_generation
@pv_generation.setter
def pv_generation(self, value):
"""
temporary attribute to set the onsite pv generation in W
:param value: float
"""
self._pv_generation = value

View File

@ -157,6 +157,7 @@ class Surface:
if self._inclination is None: if self._inclination is None:
self._inclination = np.arccos(self.perimeter_polygon.normal[2]) self._inclination = np.arccos(self.perimeter_polygon.normal[2])
return self._inclination return self._inclination
@property @property
def type(self): def type(self):
""" """

View File

@ -34,7 +34,7 @@ class ThermalZone:
volume, volume,
footprint_area, footprint_area,
number_of_storeys, number_of_storeys,
usage_name=None): usages=None):
self._id = None self._id = None
self._parent_internal_zone = parent_internal_zone self._parent_internal_zone = parent_internal_zone
self._footprint_area = footprint_area self._footprint_area = footprint_area
@ -51,10 +51,6 @@ class ThermalZone:
self._view_factors_matrix = None self._view_factors_matrix = None
self._total_floor_area = None self._total_floor_area = None
self._number_of_storeys = number_of_storeys self._number_of_storeys = number_of_storeys
self._usage_name = usage_name
self._usage_from_parent = False
if usage_name is None:
self._usage_from_parent = True
self._hours_day = None self._hours_day = None
self._days_year = None self._days_year = None
self._mechanical_air_change = None self._mechanical_air_change = None
@ -64,7 +60,12 @@ class ThermalZone:
self._internal_gains = None self._internal_gains = None
self._thermal_control = None self._thermal_control = None
self._domestic_hot_water = None self._domestic_hot_water = None
self._usages = None self._usage_name = None
self._usages = usages
self._usage_from_parent = False
if usages is None:
self._usage_from_parent = True
@property @property
def parent_internal_zone(self) -> InternalZone: def parent_internal_zone(self) -> InternalZone:
@ -77,24 +78,11 @@ class ThermalZone:
@property @property
def usages(self): def usages(self):
""" """
Get the thermal zone usages including percentage with the format [percentage]-usage_[percentage]-usage... Get the thermal zone usages
Eg: 70-office_30-residential
:return: str :return: str
""" """
if self._usage_from_parent: if self._usage_from_parent:
self._usages = copy.deepcopy(self._parent_internal_zone.usages) self._usages = copy.deepcopy(self._parent_internal_zone.usages)
else:
values = self._usage_name.split('_')
usages = []
for value in values:
usages.append(value.split('-'))
self._usages = []
for parent_usage in self._parent_internal_zone.usages:
for value in usages:
if parent_usage.name == value[1]:
new_usage = copy.deepcopy(parent_usage)
new_usage.percentage = float(value[0]) / 100
self._usages.append(new_usage)
return self._usages return self._usages
@property @property

View File

@ -28,9 +28,7 @@ class PvGenerationSystem(GenerationSystem):
self._height = None self._height = None
self._electricity_power_output = {} self._electricity_power_output = {}
self._tilt_angle = None self._tilt_angle = None
self._surface_azimuth = None self._installed_capacity = None
self._solar_altitude_angle = None
self._solar_azimuth_angle = None
@property @property
def nominal_electricity_output(self): def nominal_electricity_output(self):
@ -225,33 +223,17 @@ class PvGenerationSystem(GenerationSystem):
self._electricity_power_output = value self._electricity_power_output = value
@property @property
def tilt_angle(self): def installed_capacity(self):
""" """
Get tilt angle of PV system in degrees Get the total installed nominal capacity in W
:return: float :return: float
""" """
return self._tilt_angle return self._installed_capacity
@tilt_angle.setter @installed_capacity.setter
def tilt_angle(self, value): def installed_capacity(self, value):
""" """
Set PV system tilt angle in degrees Set the total installed nominal capacity in W
:param value: float :param value: float
""" """
self._tilt_angle = value self._installed_capacity = value
@property
def surface_azimuth(self):
"""
Get surface azimuth angle of PV system in degrees. 0 is North
:return: float
"""
return self._surface_azimuth
@surface_azimuth.setter
def surface_azimuth(self, value):
"""
Set PV system tilt angle in degrees
:param value: float
"""
self._surface_azimuth = value

View File

@ -339,7 +339,7 @@
"infiltration_rate_area_for_ventilation_system_off": 0.0055, "infiltration_rate_area_for_ventilation_system_off": 0.0055,
"constructions": { "constructions": {
"OutdoorsWall": { "OutdoorsWall": {
"opaque_surface_name": " C_1941_1960_FACEXT1", "opaque_surface_name": "C_1941_1960_FACEXT1",
"transparent_surface_name": "C_1941_1960_WIN1", "transparent_surface_name": "C_1941_1960_WIN1",
"transparent_ratio": { "transparent_ratio": {
"north": "30", "north": "30",

View File

@ -1,774 +0,0 @@
{
"archetypes": [
{
"function": "Large multifamily building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Medium multifamily building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Small multifamily building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Single-family building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Large multifamily building",
"period_of_construction": "1961_1980",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 3000,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
"transparent_ratio": {
"north": "60",
"east": "60",
"south": "60",
"west": "60"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR4"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Large multifamily building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Medium multifamily building",
"period_of_construction": "1800_1900",
"climate_zone": "B3",
"average_storey_height": 4.39,
"thermal_capacity": 3330,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "A_B1900_FACEXT1",
"transparent_surface_name": "A_B1900_WIN2",
"transparent_ratio": {
"north": "20",
"east": "20",
"south": "20",
"west": "20"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "A_B1900_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "A_B1900_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Medium multifamily building",
"period_of_construction": "1901_1940",
"climate_zone": "B3",
"average_storey_height": 3.65,
"thermal_capacity": 3420,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "B_1901_1940_FACEXT1",
"transparent_surface_name": "B_1901_1940_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "B_1901_1940_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "B_1901_1940_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Medium multifamily building",
"period_of_construction": "1941_1960",
"climate_zone": "B3",
"average_storey_height": 3.6,
"thermal_capacity": 3000,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": " C_1941_1960_FACEXT1",
"transparent_surface_name": "C_1941_1960_WIN1",
"transparent_ratio": {
"north": "30",
"east": "30",
"south": "30",
"west": "30"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "C_1941_1960_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "C_1941_1960_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Medium multifamily building",
"period_of_construction": "1961_1980",
"climate_zone": "B3",
"average_storey_height": 4.5,
"thermal_capacity": 3540,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
"transparent_ratio": {
"north": "55",
"east": "55",
"south": "55",
"west": "55"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Medium multifamily building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Medium multifamily building",
"period_of_construction": "2008_2014",
"climate_zone": "B3",
"average_storey_height": 2.75,
"thermal_capacity": 3290,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "F_2008_2014_FACEXT1",
"transparent_surface_name": "F_2008_2014_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "F_2008_2014_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "F_2008_2014_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Small multifamily building",
"period_of_construction": "1800_1980",
"climate_zone": "B3",
"average_storey_height": 3.8,
"thermal_capacity": 3527.9,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Small multifamily building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Small multifamily building",
"period_of_construction": "2008_2014",
"climate_zone": "B3",
"average_storey_height": 2.75,
"thermal_capacity": 3290,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "F_2008_2014_FACEXT1",
"transparent_surface_name": "F_2008_2014_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "F_2008_2014_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "F_2008_2014_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Small multifamily building",
"period_of_construction": "2015_2019",
"climate_zone": "B3",
"average_storey_height": 2.75,
"thermal_capacity": 3290,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "G_2015_2019_FACEXT1",
"transparent_surface_name": "G_2015_2019_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "G_2015_2019_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "G_2015_2019_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Single-family building",
"period_of_construction": "1800_1980",
"climate_zone": "B3",
"average_storey_height": 3.68,
"thermal_capacity": 4400,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Single-family building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Single-family building",
"period_of_construction": "2008_2014",
"climate_zone": "B3",
"average_storey_height": 3.75,
"thermal_capacity": 3200,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "F_2008_2014_FACEXT1",
"transparent_surface_name": "F_2008_2014_WIN1",
"transparent_ratio": {
"north": "60",
"east": "60",
"south": "60",
"west": "60"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "F_2008_2014_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "F_2008_2014_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
},
{
"function": "Single-family building",
"period_of_construction": "2015_2019",
"climate_zone": "B3",
"average_storey_height": 3.75,
"thermal_capacity": 3200,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "G_2015_2019_FACEXT1",
"transparent_surface_name": "G_2015_2019_WIN1",
"transparent_ratio": {
"north": "60",
"east": "60",
"south": "60",
"west": "60"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "G_2015_2019_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "G_2015_2019_FLOORGR1"
}
},
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0
}
]
}

View File

@ -198,7 +198,7 @@
<equipments> <equipments>
<generation_id>3</generation_id> <generation_id>3</generation_id>
<distribution_id>8</distribution_id> <distribution_id>8</distribution_id>
g </equipments> </equipments>
</system> </system>
<system id="5"> <system id="5">
<name>Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs</name> <name>Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs</name>
@ -240,7 +240,7 @@ g </equipments>
<demand>domestic_hot_water</demand> <demand>domestic_hot_water</demand>
</demands> </demands>
<equipments> <equipments>
<generation_id>2</generation_id> <generation_id>1</generation_id>
<distribution_id>3</distribution_id> <distribution_id>3</distribution_id>
</equipments> </equipments>
</system> </system>
@ -302,7 +302,7 @@ g </equipments>
</demands> </demands>
<equipments> <equipments>
<generation_id>5</generation_id> <generation_id>5</generation_id>
<distribution_id>6</distribution_id> <distribution_id>4</distribution_id>
</equipments> </equipments>
</system> </system>
<system id="15"> <system id="15">

File diff suppressed because it is too large Load Diff

View File

@ -253,7 +253,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>7</system_id> <system_id>7</system_id>
<name>template Photovoltaic Module</name> <name>template Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name/> <model_name/>
<manufacturer/> <manufacturer/>
<nominal_electricity_output/> <nominal_electricity_output/>
@ -264,7 +264,7 @@
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature> <standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation> <standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>500</standard_test_condition_maximum_power> <standard_test_condition_maximum_power>500</standard_test_condition_maximum_power>
<cell_temperature_coefficient/> <cell_temperature_coefficient>0.3</cell_temperature_coefficient>
<width>2.0</width> <width>2.0</width>
<height>1.0</height> <height>1.0</height>
<distribution_systems/> <distribution_systems/>
@ -274,7 +274,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>8</system_id> <system_id>8</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>RE400CAA Pure 2</model_name> <model_name>RE400CAA Pure 2</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>305</nominal_electricity_output> <nominal_electricity_output>305</nominal_electricity_output>
@ -295,7 +295,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>9</system_id> <system_id>9</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>RE410CAA Pure 2</model_name> <model_name>RE410CAA Pure 2</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>312</nominal_electricity_output> <nominal_electricity_output>312</nominal_electricity_output>
@ -316,7 +316,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>10</system_id> <system_id>10</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>RE420CAA Pure 2</model_name> <model_name>RE420CAA Pure 2</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>320</nominal_electricity_output> <nominal_electricity_output>320</nominal_electricity_output>
@ -337,7 +337,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>11</system_id> <system_id>11</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>RE430CAA Pure 2</model_name> <model_name>RE430CAA Pure 2</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>327</nominal_electricity_output> <nominal_electricity_output>327</nominal_electricity_output>
@ -358,7 +358,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>12</system_id> <system_id>12</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>REC600AA Pro M</model_name> <model_name>REC600AA Pro M</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>457</nominal_electricity_output> <nominal_electricity_output>457</nominal_electricity_output>
@ -379,7 +379,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>13</system_id> <system_id>13</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>REC610AA Pro M</model_name> <model_name>REC610AA Pro M</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>464</nominal_electricity_output> <nominal_electricity_output>464</nominal_electricity_output>
@ -400,7 +400,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>14</system_id> <system_id>14</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>REC620AA Pro M</model_name> <model_name>REC620AA Pro M</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>472</nominal_electricity_output> <nominal_electricity_output>472</nominal_electricity_output>
@ -421,7 +421,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>15</system_id> <system_id>15</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>REC630AA Pro M</model_name> <model_name>REC630AA Pro M</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>480</nominal_electricity_output> <nominal_electricity_output>480</nominal_electricity_output>
@ -442,7 +442,7 @@
<pv_generation_component> <pv_generation_component>
<system_id>16</system_id> <system_id>16</system_id>
<name>Photovoltaic Module</name> <name>Photovoltaic Module</name>
<system_type>Photovoltaic</system_type> <system_type>photovoltaic</system_type>
<model_name>REC640AA Pro M</model_name> <model_name>REC640AA Pro M</model_name>
<manufacturer>REC</manufacturer> <manufacturer>REC</manufacturer>
<nominal_electricity_output>487</nominal_electricity_output> <nominal_electricity_output>487</nominal_electricity_output>

View File

@ -468,7 +468,7 @@ class Idf:
def _add_infiltration_surface(self, thermal_zone, zone_name): def _add_infiltration_surface(self, thermal_zone, zone_name):
schedule = f'INF_CONST schedules {thermal_zone.usage_name}' schedule = f'INF_CONST schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_area_system_off*1 _infiltration = thermal_zone.infiltration_rate_area_system_off* cte.INFILTRATION_75PA_TO_4PA
self._idf.newidfobject(self._INFILTRATION, self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration', Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name, Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
@ -730,7 +730,10 @@ class Idf:
else: else:
# idf only allows setting wwr for external walls # idf only allows setting wwr for external walls
wwr = 0 wwr = 0
self._idf.set_wwr(wwr) try:
self._idf.set_wwr(wwr, construction='window_construction_1')
except ValueError:
self._idf.set_wwr(0, construction='window_construction_1')
def _add_surfaces(self, building, zone_name): def _add_surfaces(self, building, zone_name):
for thermal_zone in building.thermal_zones_from_internal_zones: for thermal_zone in building.thermal_zones_from_internal_zones:

View File

@ -146,7 +146,7 @@ class CesiumjsTileset:
'max_height': building.max_height, 'max_height': building.max_height,
'year_of_construction': building.year_of_construction, 'year_of_construction': building.year_of_construction,
'function': building.function, 'function': building.function,
'usages_percentage': building.usages_percentage 'usages_percentage': building.usages
} }
}, },
'content': { 'content': {

View File

@ -316,6 +316,7 @@ GRID = 'Grid'
ONSITE_ELECTRICITY = 'Onsite Electricity' ONSITE_ELECTRICITY = 'Onsite Electricity'
PHOTOVOLTAIC = 'Photovoltaic' PHOTOVOLTAIC = 'Photovoltaic'
BOILER = 'Boiler' BOILER = 'Boiler'
FURNACE = 'Furnace'
HEAT_PUMP = 'Heat Pump' HEAT_PUMP = 'Heat Pump'
BASEBOARD = 'Baseboard' BASEBOARD = 'Baseboard'
ELECTRICITY_GENERATOR = 'Electricity generator' ELECTRICITY_GENERATOR = 'Electricity generator'

View File

@ -17,6 +17,7 @@ class MontrealCustomFuelToHubFuel:
self._dictionary = { self._dictionary = {
'gas': cte.GAS, 'gas': cte.GAS,
'natural gas': cte.GAS, 'natural gas': cte.GAS,
'biomass': cte.BIOMASS,
'electricity': cte.ELECTRICITY, 'electricity': cte.ELECTRICITY,
'renewable': cte.RENEWABLE, 'renewable': cte.RENEWABLE,
'butane': cte.BUTANE, 'butane': cte.BUTANE,

View File

@ -15,10 +15,10 @@ class MontrealGenerationSystemToHubEnergyGenerationSystem:
def __init__(self): def __init__(self):
self._dictionary = { self._dictionary = {
'boiler': cte.BOILER, 'boiler': cte.BOILER,
'furnace': cte.BASEBOARD, 'furnace': cte.FURNACE,
'cooler': cte.CHILLER, 'cooler': cte.CHILLER,
'electricity generator': cte.ELECTRICITY_GENERATOR, 'electricity generator': cte.ELECTRICITY_GENERATOR,
'Photovoltaic': cte.PHOTOVOLTAIC, 'photovoltaic': cte.PHOTOVOLTAIC,
'heat pump': cte.HEAT_PUMP, 'heat pump': cte.HEAT_PUMP,
'joule': cte.JOULE, 'joule': cte.JOULE,
'split': cte.SPLIT, 'split': cte.SPLIT,

View File

View File

@ -0,0 +1,31 @@
class ListUsageToHub:
"""
Eilat function to hub function class
"""
def __init__(self, function_dictionary=None):
self._function_dictionary = function_dictionary
def _apply_function_dictionary(self, usages):
function_dictionary = self._function_dictionary
if function_dictionary is not None:
for usage in usages:
if usage['usage'] in function_dictionary:
usage['usage'] = function_dictionary[usage['usage']]
return usages
def parse(self, usages) -> list[dict]:
"""
Get the dictionary
:return: {}
"""
usages = [{"usage": str(i["usage"]), "ratio": float(i["ratio"])} for i in usages]
usages = self._apply_function_dictionary(usages)
return usages

View File

@ -0,0 +1,19 @@
class StringUsageToHub:
"""
Eilat function to hub function class
"""
def parse(self, usages) -> list[dict]:
"""
Parse usage string in form residential-80_commercial-20
:usages: str
:return: {}
"""
parsed_usages = []
for usage in usages.split('_'):
usage_dict = {"usage": str(usage.split('-')[0]), "ratio": float(usage.split('-')[1])/100}
parsed_usages.append(usage_dict)
return parsed_usages

View File

@ -0,0 +1,31 @@
"""
Dictionaries module saves all transformations of functions and usages to access the catalogs
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from hub.helpers.parsers.list_usage_to_hub import ListUsageToHub
from hub.helpers.parsers.string_usage_to_hub import StringUsageToHub
class UsageParsers:
"""
Dictionaries class
"""
@staticmethod
def string_usage_to_hub() -> object:
"""
Hub usage to HfT usage, transformation dictionary
:return: dict
"""
return StringUsageToHub().parse
@staticmethod
def list_usage_to_hub(function_dictionary=None) -> object:
"""
Hub usage to HfT usage, transformation dictionary
:return: dict
"""
return ListUsageToHub(function_dictionary).parse

View File

@ -33,21 +33,10 @@ class NrcanPhysicsParameters:
city = self._city city = self._city
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
for building in city.buildings: for building in city.buildings:
main_function = None if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
functions = building.function.split('_') logging.error('Building %s has an unknown building function %s', building.name, building.function)
if len(functions) > 1:
maximum_percentage = 0
for function in functions:
percentage_and_function = function.split('-')
if float(percentage_and_function[0]) > maximum_percentage:
maximum_percentage = float(percentage_and_function[0])
main_function = percentage_and_function[-1]
else:
main_function = functions[-1]
if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, main_function)
continue continue
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function] function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
try: try:
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone) archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)

View File

@ -3,6 +3,7 @@ Montreal custom energy system importer
SPDX - License - Identifier: LGPL - 3.0 - or -later SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Contributor Saeed Ranjbar saeed.ranjbar@concordia.ca
""" """
import logging import logging
@ -83,9 +84,9 @@ class MontrealCustomEnergySystemParameters:
def _create_generation_systems(archetype_system): def _create_generation_systems(archetype_system):
_generation_systems = [] _generation_systems = []
for archetype_generation_system in archetype_system.generation_systems: for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'Photovoltaic': if archetype_generation_system.system_type == 'photovoltaic':
_generation_system = PvGenerationSystem() _generation_system = PvGenerationSystem()
_type = 'Photovoltaic' _type = archetype_generation_system.system_type
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[ _generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[
_type] _type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type] _fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
@ -136,14 +137,14 @@ class MontrealCustomEnergySystemParameters:
_distribution_system.distribution_consumption_variable_flow = \ _distribution_system.distribution_consumption_variable_flow = \
archetype_distribution_system.distribution_consumption_variable_flow archetype_distribution_system.distribution_consumption_variable_flow
_distribution_system.heat_losses = archetype_distribution_system.heat_losses _distribution_system.heat_losses = archetype_distribution_system.heat_losses
_emission_system = None _generic_emission_system = None
if archetype_distribution_system.emission_systems is not None: if archetype_distribution_system.emission_systems is not None:
_emission_systems = [] _emission_systems = []
for emission_system in archetype_distribution_system.emission_systems: for emission_system in archetype_distribution_system.emission_systems:
_emission_system = EmissionSystem() _generic_emission_system = EmissionSystem()
_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption _generic_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_emission_system) _emission_systems.append(_generic_emission_system)
_distribution_system.emission_systems = _emission_systems _distribution_system.emission_systems = _emission_systems
_distribution_systems.append(_distribution_system) _distribution_systems.append(_distribution_system)
return _distribution_systems return _distribution_systems

View File

@ -43,6 +43,7 @@ class MontrealFutureEnergySystemParameters:
archetype_name = building.energy_systems_archetype_name archetype_name = building.energy_systems_archetype_name
try: try:
archetype = self._search_archetypes(montreal_custom_catalog, archetype_name) archetype = self._search_archetypes(montreal_custom_catalog, archetype_name)
building.energy_systems_archetype_cluster_id = archetype.cluster_id
except KeyError: except KeyError:
logging.error('Building %s has unknown energy system archetype for system name %s', building.name, logging.error('Building %s has unknown energy system archetype for system name %s', building.name,
archetype_name) archetype_name)
@ -87,7 +88,7 @@ class MontrealFutureEnergySystemParameters:
archetype_generation_systems = archetype_system.generation_systems archetype_generation_systems = archetype_system.generation_systems
if archetype_generation_systems is not None: if archetype_generation_systems is not None:
for archetype_generation_system in archetype_system.generation_systems: for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'Photovoltaic': if archetype_generation_system.system_type == 'photovoltaic':
_generation_system = PvGenerationSystem() _generation_system = PvGenerationSystem()
_generation_system.name = archetype_generation_system.name _generation_system.name = archetype_generation_system.name
_generation_system.model_name = archetype_generation_system.model_name _generation_system.model_name = archetype_generation_system.model_name
@ -103,15 +104,21 @@ class MontrealFutureEnergySystemParameters:
_generation_system.nominal_radiation = archetype_generation_system.nominal_radiation _generation_system.nominal_radiation = archetype_generation_system.nominal_radiation
_generation_system.standard_test_condition_cell_temperature = archetype_generation_system.standard_test_condition_cell_temperature _generation_system.standard_test_condition_cell_temperature = archetype_generation_system.standard_test_condition_cell_temperature
_generation_system.standard_test_condition_maximum_power = archetype_generation_system.standard_test_condition_maximum_power _generation_system.standard_test_condition_maximum_power = archetype_generation_system.standard_test_condition_maximum_power
_generation_system.standard_test_condition_radiation = archetype_generation_system.standard_test_condition_radiation
_generation_system.cell_temperature_coefficient = archetype_generation_system.cell_temperature_coefficient _generation_system.cell_temperature_coefficient = archetype_generation_system.cell_temperature_coefficient
_generation_system.width = archetype_generation_system.width _generation_system.width = archetype_generation_system.width
_generation_system.height = archetype_generation_system.height _generation_system.height = archetype_generation_system.height
_generation_system.tilt_angle = self._city.latitude _generation_system.tilt_angle = self._city.latitude
_generic_storage_system = None _generic_storage_system = None
if archetype_generation_system.energy_storage_systems is not None: if archetype_generation_system.energy_storage_systems is not None:
_generic_storage_system = ElectricalStorageSystem() _storage_systems = []
_generic_storage_system.type_energy_stored = 'electrical' for storage_system in archetype_generation_system.energy_storage_systems:
_generation_system.energy_storage_systems = [_generic_storage_system] if storage_system.type_energy_stored == 'electrical':
_generic_storage_system = ElectricalStorageSystem()
_generic_storage_system.type_energy_stored = 'electrical'
_storage_systems.append(_generic_storage_system)
_generation_system.energy_storage_systems = _storage_systems
else: else:
_generation_system = NonPvGenerationSystem() _generation_system = NonPvGenerationSystem()
_generation_system.name = archetype_generation_system.name _generation_system.name = archetype_generation_system.name
@ -185,14 +192,14 @@ class MontrealFutureEnergySystemParameters:
_distribution_system.distribution_consumption_variable_flow = \ _distribution_system.distribution_consumption_variable_flow = \
archetype_distribution_system.distribution_consumption_variable_flow archetype_distribution_system.distribution_consumption_variable_flow
_distribution_system.heat_losses = archetype_distribution_system.heat_losses _distribution_system.heat_losses = archetype_distribution_system.heat_losses
_emission_system = None _generic_emission_system = None
if archetype_distribution_system.emission_systems is not None: if archetype_distribution_system.emission_systems is not None:
_emission_systems = [] _emission_systems = []
for emission_system in archetype_distribution_system.emission_systems: for emission_system in archetype_distribution_system.emission_systems:
_emission_system = EmissionSystem() _generic_emission_system = EmissionSystem()
_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption _generic_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_emission_system) _emission_systems.append(_generic_emission_system)
_distribution_system.emission_systems = _emission_systems _distribution_system.emission_systems = _emission_systems
_distribution_systems.append(_distribution_system) _distribution_systems.append(_distribution_system)
return _distribution_systems return _distribution_systems

View File

@ -87,7 +87,7 @@ class PalmaEnergySystemParameters:
archetype_generation_systems = archetype_system.generation_systems archetype_generation_systems = archetype_system.generation_systems
if archetype_generation_systems is not None: if archetype_generation_systems is not None:
for archetype_generation_system in archetype_system.generation_systems: for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'Photovoltaic': if archetype_generation_system.system_type == 'photovoltaic':
_generation_system = PvGenerationSystem() _generation_system = PvGenerationSystem()
_generation_system.name = archetype_generation_system.name _generation_system.name = archetype_generation_system.name
_generation_system.model_name = archetype_generation_system.model_name _generation_system.model_name = archetype_generation_system.model_name

View File

@ -35,6 +35,8 @@ class Geojson:
year_of_construction_field=None, year_of_construction_field=None,
function_field=None, function_field=None,
function_to_hub=None, function_to_hub=None,
usages_field=None,
usages_to_hub=None,
hub_crs=None hub_crs=None
): ):
self._hub_crs = hub_crs self._hub_crs = hub_crs
@ -52,6 +54,8 @@ class Geojson:
self._year_of_construction_field = year_of_construction_field self._year_of_construction_field = year_of_construction_field
self._function_field = function_field self._function_field = function_field
self._function_to_hub = function_to_hub self._function_to_hub = function_to_hub
self._usages_field = usages_field
self._usages_to_hub = usages_to_hub
with open(path, 'r', encoding='utf8') as json_file: with open(path, 'r', encoding='utf8') as json_file:
self._geojson = json.loads(json_file.read()) self._geojson = json.loads(json_file.read())
@ -117,41 +121,30 @@ class Geojson:
lod = 0 lod = 0
for feature in self._geojson['features']: for feature in self._geojson['features']:
extrusion_height = 0 extrusion_height = 0
if self._extrusion_height_field is not None: if self._extrusion_height_field is not None:
extrusion_height = float(feature['properties'][self._extrusion_height_field]) extrusion_height = float(feature['properties'][self._extrusion_height_field])
lod = 1 lod = 1
self._max_z = max(self._max_z, extrusion_height) self._max_z = max(self._max_z, extrusion_height)
year_of_construction = None year_of_construction = None
if self._year_of_construction_field is not None: if self._year_of_construction_field is not None:
year_of_construction = int(feature['properties'][self._year_of_construction_field]) year_of_construction = int(feature['properties'][self._year_of_construction_field])
function = None function = None
if self._function_field is not None: if self._function_field is not None:
function = str(feature['properties'][self._function_field]) function = str(feature['properties'][self._function_field])
if function == 'Mixed use' or function == 'mixed use':
function_parts = []
if 'usages' in feature['properties']:
usages = feature['properties']['usages']
for usage in usages:
if self._function_to_hub is not None and usage['usage'] in self._function_to_hub:
function_parts.append(f"{usage['percentage']}-{self._function_to_hub[usage['usage']]}")
else:
function_parts.append(f"{usage['percentage']}-{usage['usage']}")
else:
for key, value in feature['properties'].items():
if key.startswith("mixed_type_") and not key.endswith("_percentage"):
type_key = key
percentage_key = f"{key}_percentage"
if percentage_key in feature['properties']:
if self._function_to_hub is not None and feature['properties'][type_key] in self._function_to_hub:
usage_function = self._function_to_hub[feature['properties'][type_key]]
function_parts.append(f"{feature['properties'][percentage_key]}-{usage_function}")
else:
function_parts.append(f"{feature['properties'][percentage_key]}-{feature['properties'][type_key]}")
function = "_".join(function_parts)
if self._function_to_hub is not None: if self._function_to_hub is not None:
# use the transformation dictionary to retrieve the proper function
if function in self._function_to_hub: if function in self._function_to_hub:
function = self._function_to_hub[function] function = self._function_to_hub[function]
usages = None
if self._usages_field is not None:
if self._usages_field in feature['properties']:
usages = feature['properties'][self._usages_field]
if self._usages_to_hub is not None:
usages = self._usages_to_hub(usages)
geometry = feature['geometry'] geometry = feature['geometry']
building_aliases = [] building_aliases = []
if 'id' in feature: if 'id' in feature:
@ -170,6 +163,7 @@ class Geojson:
building_name, building_name,
building_aliases, building_aliases,
function, function,
usages,
year_of_construction, year_of_construction,
extrusion_height)) extrusion_height))
@ -178,6 +172,7 @@ class Geojson:
building_name, building_name,
building_aliases, building_aliases,
function, function,
usages,
year_of_construction, year_of_construction,
extrusion_height)) extrusion_height))
else: else:
@ -203,7 +198,7 @@ class Geojson:
transformed_coordinates = f'{transformed_coordinates} {transformed[self._X]} {transformed[self._Y]} 0.0' transformed_coordinates = f'{transformed_coordinates} {transformed[self._X]} {transformed[self._Y]} 0.0'
return transformed_coordinates.lstrip(' ') return transformed_coordinates.lstrip(' ')
def _parse_polygon(self, coordinates, building_name, building_aliases, function, year_of_construction, extrusion_height): def _parse_polygon(self, coordinates, building_name, building_aliases, function, usages, year_of_construction, extrusion_height):
surfaces = [] surfaces = []
for polygon_coordinates in coordinates: for polygon_coordinates in coordinates:
points = igh.points_from_string( points = igh.points_from_string(
@ -236,7 +231,7 @@ class Geojson:
polygon = Polygon(coordinates) polygon = Polygon(coordinates)
polygon.area = igh.ground_area(coordinates) polygon.area = igh.ground_area(coordinates)
surfaces[-1] = Surface(polygon, polygon) surfaces[-1] = Surface(polygon, polygon)
building = Building(f'{building_name}', surfaces, year_of_construction, function) building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
for alias in building_aliases: for alias in building_aliases:
building.add_alias(alias) building.add_alias(alias)
if extrusion_height == 0: if extrusion_height == 0:
@ -271,13 +266,13 @@ class Geojson:
polygon = Polygon(wall_coordinates) polygon = Polygon(wall_coordinates)
wall = Surface(polygon, polygon) wall = Surface(polygon, polygon)
surfaces.append(wall) surfaces.append(wall)
building = Building(f'{building_name}', surfaces, year_of_construction, function) building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
for alias in building_aliases: for alias in building_aliases:
building.add_alias(alias) building.add_alias(alias)
building.volume = volume building.volume = volume
return building return building
def _parse_multi_polygon(self, polygons_coordinates, building_name, building_aliases, function, year_of_construction, extrusion_height): def _parse_multi_polygon(self, polygons_coordinates, building_name, building_aliases, function, usages, year_of_construction, extrusion_height):
surfaces = [] surfaces = []
for coordinates in polygons_coordinates: for coordinates in polygons_coordinates:
for polygon_coordinates in coordinates: for polygon_coordinates in coordinates:
@ -310,7 +305,7 @@ class Geojson:
polygon = Polygon(coordinates) polygon = Polygon(coordinates)
polygon.area = igh.ground_area(coordinates) polygon.area = igh.ground_area(coordinates)
surfaces[-1] = Surface(polygon, polygon) surfaces[-1] = Surface(polygon, polygon)
building = Building(f'{building_name}', surfaces, year_of_construction, function) building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
for alias in building_aliases: for alias in building_aliases:
building.add_alias(alias) building.add_alias(alias)
if extrusion_height == 0: if extrusion_height == 0:
@ -345,7 +340,7 @@ class Geojson:
polygon = Polygon(wall_coordinates) polygon = Polygon(wall_coordinates)
wall = Surface(polygon, polygon) wall = Surface(polygon, polygon)
surfaces.append(wall) surfaces.append(wall)
building = Building(f'{building_name}', surfaces, year_of_construction, function) building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
for alias in building_aliases: for alias in building_aliases:
building.add_alias(alias) building.add_alias(alias)
building.volume = volume building.volume = volume

View File

@ -23,6 +23,8 @@ class GeometryFactory:
year_of_construction_field=None, year_of_construction_field=None,
function_field=None, function_field=None,
function_to_hub=None, function_to_hub=None,
usages_field=None,
usages_to_hub=None,
hub_crs=None): hub_crs=None):
self._file_type = '_' + file_type.lower() self._file_type = '_' + file_type.lower()
validate_import_export_type(GeometryFactory, file_type) validate_import_export_type(GeometryFactory, file_type)
@ -32,6 +34,8 @@ class GeometryFactory:
self._year_of_construction_field = year_of_construction_field self._year_of_construction_field = year_of_construction_field
self._function_field = function_field self._function_field = function_field
self._function_to_hub = function_to_hub self._function_to_hub = function_to_hub
self._usages_field = usages_field
self._usages_to_hub = usages_to_hub
self._hub_crs = hub_crs self._hub_crs = hub_crs
@property @property
@ -66,6 +70,8 @@ class GeometryFactory:
self._year_of_construction_field, self._year_of_construction_field,
self._function_field, self._function_field,
self._function_to_hub, self._function_to_hub,
self._usages_field,
self._usages_to_hub,
self._hub_crs).city self._hub_crs).city
@property @property

View File

@ -38,38 +38,36 @@ class ComnetUsageParameters:
city = self._city city = self._city
comnet_catalog = UsageCatalogFactory('comnet').catalog comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings: for building in city.buildings:
usages = []
comnet_archetype_usages = [] comnet_archetype_usages = []
building_functions = building.function.split('_') usages = building.usages
for function in building_functions:
usages.append(function.split('-'))
for usage in usages: for usage in usages:
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]] comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage['usage']]
try: try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name) comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
comnet_archetype_usages.append(comnet_archetype_usage) comnet_archetype_usages.append(comnet_archetype_usage)
except KeyError: except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name) logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
continue continue
for (i, internal_zone) in enumerate(building.internal_zones): for (i, internal_zone) in enumerate(building.internal_zones):
internal_zone_usages = [] internal_zone_usages = []
if len(building.internal_zones) > 1: if len(building.internal_zones) > 1:
volume_per_area = 0 volume_per_area = 0
if internal_zone.area is None: if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s', logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, usages[i][-1]) building.name, usages[i]['usage'])
continue continue
if internal_zone.volume is None: if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s', logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, usages[i][-1]) building.name, usages[i]['usage'])
continue continue
if internal_zone.area <= 0: if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s', logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, usages[i][-1]) building.name, usages[i]['usage'])
continue continue
volume_per_area += internal_zone.volume / internal_zone.area volume_per_area += internal_zone.volume / internal_zone.area
usage = Usage() usage = Usage()
usage.name = usages[i][-1] usage.name = usages[i]['usage']
self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature) self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature)
usage.percentage = 1 usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i]) self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i])
@ -80,20 +78,24 @@ class ComnetUsageParameters:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. ' logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. '
'NRCAN construction data for the year %s is used to calculated number of storeys above ' 'NRCAN construction data for the year %s is used to calculated number of storeys above '
'ground', building.name, usages, building.year_of_construction) 'ground', building.name, usages, building.year_of_construction)
storeys_above_ground = self.average_storey_height_calculator(self._city, building) try:
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
except ValueError as e:
logging.error(e)
continue
volume_per_area = building.volume / building.floor_area / storeys_above_ground volume_per_area = building.volume / building.floor_area / storeys_above_ground
for (j, mixed_usage) in enumerate(usages): for j, usage_type in enumerate(usages):
usage = Usage() usage = Usage()
usage.name = mixed_usage[-1] usage.name = usage_type['usage']
if len(usages) > 1: usage.percentage = float(usage_type['ratio'])
usage.percentage = float(mixed_usage[0]) / 100
else:
usage.percentage = 1
self._assign_values(usage, comnet_archetype_usages[j], volume_per_area, building.cold_water_temperature) self._assign_values(usage, comnet_archetype_usages[j], volume_per_area, building.cold_water_temperature)
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[j]) self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[j])
internal_zone_usages.append(usage) internal_zone_usages.append(usage)
internal_zone.usages = internal_zone_usages internal_zone.usages = internal_zone_usages
@staticmethod @staticmethod
def _search_archetypes(comnet_catalog, usage_name): def _search_archetypes(comnet_catalog, usage_name):
comnet_archetypes = comnet_catalog.entries('archetypes').usages comnet_archetypes = comnet_catalog.entries('archetypes').usages
@ -270,20 +272,11 @@ class ComnetUsageParameters:
def average_storey_height_calculator(city, building): def average_storey_height_calculator(city, building):
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city) climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
main_function = None
functions = building.function.split('_') if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
if len(functions) > 1: raise ValueError('Building %s has an unknown building function %s', building.name, building.function)
maximum_percentage = 0
for function in functions: function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
percentage_and_function = function.split('-')
if float(percentage_and_function[0]) > maximum_percentage:
maximum_percentage = float(percentage_and_function[0])
main_function = percentage_and_function[-1]
else:
main_function = functions[-1]
if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, main_function)
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
construction_archetype = None construction_archetype = None
average_storey_height = None average_storey_height = None
nrcan_archetypes = nrcan_catalog.entries('archetypes') nrcan_archetypes = nrcan_catalog.entries('archetypes')
@ -294,7 +287,7 @@ class ComnetUsageParameters:
construction_archetype = building_archetype construction_archetype = building_archetype
average_storey_height = building_archetype.average_storey_height average_storey_height = building_archetype.average_storey_height
if construction_archetype is None: if construction_archetype is None:
logging.error('Building %s has unknown construction archetype for building function: %s ' raise ValueError('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function, '[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, climate_zone) building.function, building.year_of_construction, climate_zone)

View File

@ -37,21 +37,18 @@ class NrcanUsageParameters:
nrcan_catalog = UsageCatalogFactory('nrcan').catalog nrcan_catalog = UsageCatalogFactory('nrcan').catalog
comnet_catalog = UsageCatalogFactory('comnet').catalog comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings: for building in city.buildings:
usages = []
nrcan_archetype_usages = [] nrcan_archetype_usages = []
comnet_archetype_usages = [] comnet_archetype_usages = []
building_functions = building.function.split('_') usages = building.usages
for function in building_functions:
usages.append(function.split('-'))
for usage in usages: for usage in usages:
usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage[-1]] usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage['usage']]
try: try:
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name) archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
nrcan_archetype_usages.append(archetype_usage) nrcan_archetype_usages.append(archetype_usage)
except KeyError: except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name) logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
continue continue
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]] comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage['usage']]
try: try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name) comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
comnet_archetype_usages.append(comnet_archetype_usage) comnet_archetype_usages.append(comnet_archetype_usage)
@ -65,19 +62,19 @@ class NrcanUsageParameters:
volume_per_area = 0 volume_per_area = 0
if internal_zone.area is None: if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s', logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, usages[i][-1]) building.name, usages[i]['usage'])
continue continue
if internal_zone.volume is None: if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s', logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, usages[i][-1]) building.name, usages[i]['usage'])
continue continue
if internal_zone.area <= 0: if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s', logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, usages[i][-1]) building.name, usages[i]['usage'])
continue continue
volume_per_area += internal_zone.volume / internal_zone.area volume_per_area += internal_zone.volume / internal_zone.area
usage = Usage() usage = Usage()
usage.name = usages[i][-1] usage.name = usages[i]['usage']
self._assign_values(usage, nrcan_archetype_usages[i], volume_per_area, building.cold_water_temperature) self._assign_values(usage, nrcan_archetype_usages[i], volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usages[i], nrcan_archetype_usages[i].occupancy.occupancy_density) self._assign_comnet_extra_values(usage, comnet_archetype_usages[i], nrcan_archetype_usages[i].occupancy.occupancy_density)
usage.percentage = 1 usage.percentage = 1
@ -86,19 +83,21 @@ class NrcanUsageParameters:
else: else:
storeys_above_ground = building.storeys_above_ground storeys_above_ground = building.storeys_above_ground
if storeys_above_ground is None: if storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. ' logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for function %s. '
'NRCAN construction data for the year %s is used to calculated number of storeys above ' 'NRCAN construction data for the year %s is used to calculated number of storeys above '
'ground', building.name, usages, building.year_of_construction) 'ground', building.name, building.function, building.year_of_construction)
storeys_above_ground = self.average_storey_height_calculator(self._city, building) try:
continue storeys_above_ground = self.average_storey_height_calculator(self._city, building)
except ValueError as e:
logging.error(e)
continue
volume_per_area = building.volume / building.floor_area / storeys_above_ground volume_per_area = building.volume / building.floor_area / storeys_above_ground
for (j, mixed_usage) in enumerate(usages): for j, usage_type in enumerate(usages):
usage = Usage() usage = Usage()
usage.name = mixed_usage[-1] usage.name = usage_type['usage']
if len(usages) > 1: usage.percentage = float(usage_type['ratio'])
usage.percentage = float(mixed_usage[0]) / 100
else:
usage.percentage = 1
self._assign_values(usage, nrcan_archetype_usages[j], volume_per_area, building.cold_water_temperature) self._assign_values(usage, nrcan_archetype_usages[j], volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usages[j], nrcan_archetype_usages[j].occupancy.occupancy_density) self._assign_comnet_extra_values(usage, comnet_archetype_usages[j], nrcan_archetype_usages[j].occupancy.occupancy_density)
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[j]) self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[j])
@ -227,20 +226,11 @@ class NrcanUsageParameters:
def average_storey_height_calculator(city, building): def average_storey_height_calculator(city, building):
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city) climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
main_function = None
functions = building.function.split('_') if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
if len(functions) > 1: raise ValueError('Building %s has an unknown building function %s', building.name, building.function)
maximum_percentage = 0
for function in functions: function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
percentage_and_function = function.split('-')
if float(percentage_and_function[0]) > maximum_percentage:
maximum_percentage = float(percentage_and_function[0])
main_function = percentage_and_function[-1]
else:
main_function = functions[-1]
if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, main_function)
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
construction_archetype = None construction_archetype = None
average_storey_height = None average_storey_height = None
nrcan_archetypes = nrcan_catalog.entries('archetypes') nrcan_archetypes = nrcan_catalog.entries('archetypes')
@ -251,7 +241,7 @@ class NrcanUsageParameters:
construction_archetype = building_archetype construction_archetype = building_archetype
average_storey_height = building_archetype.average_storey_height average_storey_height = building_archetype.average_storey_height
if construction_archetype is None: if construction_archetype is None:
logging.error('Building %s has unknown construction archetype for building function: %s ' raise ValueError('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function, '[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, climate_zone) building.function, building.year_of_construction, climate_zone)

View File

@ -1,4 +1,4 @@
""" """
Hub version number Hub version number
""" """
__version__ = '0.2.0.13' __version__ = '0.2.0.17'

View File

@ -65,6 +65,7 @@ setup(
'hub.helpers', 'hub.helpers',
'hub.helpers.peak_calculation', 'hub.helpers.peak_calculation',
'hub.helpers.data', 'hub.helpers.data',
'hub.helpers.parsers',
'hub.imports', 'hub.imports',
'hub.imports.construction', 'hub.imports.construction',
'hub.imports.construction.helpers', 'hub.imports.construction.helpers',

View File

@ -39,11 +39,11 @@ class TestSystemsCatalog(TestCase):
catalog_categories = catalog.names() catalog_categories = catalog.names()
archetypes = catalog.names() archetypes = catalog.names()
self.assertEqual(15, len(archetypes['archetypes'])) self.assertEqual(34, len(archetypes['archetypes']))
systems = catalog.names('systems') systems = catalog.names('systems')
self.assertEqual(12, len(systems['systems'])) self.assertEqual(39, len(systems['systems']))
generation_equipments = catalog.names('generation_equipments') generation_equipments = catalog.names('generation_equipments')
self.assertEqual(27, len(generation_equipments['generation_equipments'])) self.assertEqual(49, len(generation_equipments['generation_equipments']))
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
catalog.names('unknown') catalog.names('unknown')
@ -55,6 +55,7 @@ class TestSystemsCatalog(TestCase):
with self.assertRaises(IndexError): with self.assertRaises(IndexError):
catalog.get_entry('unknown') catalog.get_entry('unknown')
def test_palma_catalog(self): def test_palma_catalog(self):
catalog = EnergySystemsCatalogFactory('palma').catalog catalog = EnergySystemsCatalogFactory('palma').catalog
catalog_categories = catalog.names() catalog_categories = catalog.names()

View File

@ -114,7 +114,8 @@ class TestSystemsFactory(TestCase):
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich() ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
for building in self._city.buildings: for building in self._city.buildings:
building.energy_systems_archetype_name = 'PV+ASHP+GasBoiler+TES' building.energy_systems_archetype_name = ('Central Hydronic Air and Gas Source Heating System with Unitary Split '
'Cooling and Air Source HP DHW and Grid Tied PV')
EnergySystemsFactory('montreal_future', self._city).enrich() EnergySystemsFactory('montreal_future', self._city).enrich()
# Need to assign energy systems to buildings: # Need to assign energy systems to buildings:
for building in self._city.buildings: for building in self._city.buildings:
@ -131,7 +132,8 @@ class TestSystemsFactory(TestCase):
self.assertLess(0, building.heating_consumption[cte.YEAR][0]) self.assertLess(0, building.heating_consumption[cte.YEAR][0])
self.assertLess(0, building.cooling_consumption[cte.YEAR][0]) self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0]) self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0])
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0]) if 'PV' in building.energy_systems_archetype_name:
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])
def test_palma_system_results(self): def test_palma_system_results(self):
""" """

View File

@ -11,6 +11,7 @@ from hub.imports.geometry_factory import GeometryFactory
from hub.imports.construction_factory import ConstructionFactory from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory from hub.imports.usage_factory import UsageFactory
from hub.helpers.dictionaries import Dictionaries from hub.helpers.dictionaries import Dictionaries
from hub.helpers.usage_parsers import UsageParsers
class TestUsageFactory(TestCase): class TestUsageFactory(TestCase):
@ -75,6 +76,40 @@ class TestUsageFactory(TestCase):
self.assertIsNotNone(usage.thermal_control.heating_set_back, 'control heating set back is none') self.assertIsNotNone(usage.thermal_control.heating_set_back, 'control heating set back is none')
self.assertIsNotNone(usage.thermal_control.mean_cooling_set_point, 'control cooling set point is none') self.assertIsNotNone(usage.thermal_control.mean_cooling_set_point, 'control cooling set point is none')
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
'control heating set point schedule is none')
self.assertIsNotNone(usage.thermal_control.cooling_set_point_schedules,
'control cooling set point schedule is none')
self.assertIsNotNone(usage.occupancy, 'occupancy is none')
occupancy = usage.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.assertIsNotNone(usage.lighting, 'lighting is none')
lighting = usage.lighting
self.assertIsNotNone(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.appliances, 'appliances is none')
appliances = usage.appliances
self.assertIsNotNone(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.thermal_control.hvac_availability_schedules,
'control hvac availability is none')
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
'domestic hot water service temperature is none')
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
def test_import_comnet(self): def test_import_comnet(self):
""" """
Enrich the city with the usage information from comnet and verify it Enrich the city with the usage information from comnet and verify it
@ -91,40 +126,7 @@ class TestUsageFactory(TestCase):
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined') self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
for usage in internal_zone.usages: for usage in internal_zone.usages:
self._check_usage(usage) self._check_usage(usage)
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
'control heating set point schedule is none')
self.assertIsNotNone(usage.thermal_control.cooling_set_point_schedules,
'control cooling set point schedule is none')
self.assertIsNotNone(usage.occupancy, 'occupancy is none')
occupancy = usage.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.assertIsNotNone(usage.lighting, 'lighting is none')
lighting = usage.lighting
self.assertIsNotNone(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.appliances, 'appliances is none')
appliances = usage.appliances
self.assertIsNotNone(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.thermal_control.hvac_availability_schedules,
'control hvac availability is none')
self.assertIsNotNone(usage.domestic_hot_water.density, 'domestic hot water density is none') self.assertIsNotNone(usage.domestic_hot_water.density, 'domestic hot water density is none')
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
'domestic hot water service temperature is none')
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
def test_import_nrcan(self): def test_import_nrcan(self):
""" """
@ -148,40 +150,6 @@ class TestUsageFactory(TestCase):
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined') self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
for usage in internal_zone.usages: for usage in internal_zone.usages:
self._check_usage(usage) self._check_usage(usage)
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
'control heating set point schedule is none')
self.assertIsNotNone(usage.thermal_control.cooling_set_point_schedules,
'control cooling set point schedule is none')
self.assertIsNotNone(usage.occupancy, 'occupancy is none')
occupancy = usage.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.assertIsNotNone(usage.lighting, 'lighting is none')
lighting = usage.lighting
self.assertIsNotNone(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.appliances, 'appliances is none')
appliances = usage.appliances
self.assertIsNotNone(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.thermal_control.hvac_availability_schedules,
'control hvac availability is none')
self.assertIsNotNone(usage.domestic_hot_water.peak_flow, 'domestic hot water peak flow is none')
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
'domestic hot water service temperature is none')
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
def test_import_palma(self): def test_import_palma(self):
""" """
@ -205,38 +173,35 @@ class TestUsageFactory(TestCase):
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined') self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
for usage in internal_zone.usages: for usage in internal_zone.usages:
self._check_usage(usage) self._check_usage(usage)
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
'control heating set point schedule is none')
self.assertIsNotNone(usage.thermal_control.cooling_set_point_schedules,
'control cooling set point schedule is none')
self.assertIsNotNone(usage.occupancy, 'occupancy is none')
occupancy = usage.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.assertIsNotNone(usage.lighting, 'lighting is none')
lighting = usage.lighting
self.assertIsNotNone(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.appliances, 'appliances is none')
appliances = usage.appliances
self.assertIsNotNone(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.thermal_control.hvac_availability_schedules,
'control hvac availability is none')
self.assertIsNotNone(usage.domestic_hot_water.peak_flow, 'domestic hot water peak flow is none') self.assertIsNotNone(usage.domestic_hot_water.peak_flow, 'domestic hot water peak flow is none')
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
'domestic hot water service temperature is none')
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
def test_import_nrcan_multiusage(self):
"""
Enrich the city with the usage information from nrcan and verify it
"""
file = 'test.geojson'
file_path = (self._example_path / file).resolve()
function_dictionary = Dictionaries().montreal_function_to_hub_function
usage_parser = UsageParsers().list_usage_to_hub(function_dictionary=function_dictionary)
city = GeometryFactory('geojson',
path=file_path,
height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=function_dictionary,
usages_field='usages',
usages_to_hub=usage_parser).city
ConstructionFactory('nrcan', city).enrich()
UsageFactory('nrcan', city).enrich()
self._check_buildings(city)
for building in city.buildings:
for internal_zone in building.internal_zones:
if internal_zone.usages is not None:
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
for usage in internal_zone.usages:
self._check_usage(usage)

File diff suppressed because one or more lines are too long