created customized imports factory and correspondent test
This commit is contained in:
parent
beec608229
commit
2af8bf5db3
|
@ -3,9 +3,11 @@ SanamCustomizedUsageParameters add two parameters to usage properties from ASHRA
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
import sys
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import xmltodict
|
||||||
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
from imports.geometry.helpers.geometry_helper import GeometryHelper as gh
|
||||||
|
from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,9 +16,17 @@ class SanamCustomizedUsageParameters:
|
||||||
SanamCustomizedUsageParameters class
|
SanamCustomizedUsageParameters class
|
||||||
"""
|
"""
|
||||||
def __init__(self, city, base_path):
|
def __init__(self, city, base_path):
|
||||||
super().__init__(base_path, 'ashrae_archetypes.xml')
|
file = 'ashrae_archetypes.xml'
|
||||||
|
path = str(base_path / file)
|
||||||
|
self._usage_archetypes = []
|
||||||
|
with open(path) as xml:
|
||||||
|
self._archetypes = xmltodict.parse(xml.read(), force_list=('zoneUsageVariant', 'zoneUsageType'))
|
||||||
|
for zone_usage_type in self._archetypes['buildingUsageLibrary']['zoneUsageType']:
|
||||||
|
usage = zone_usage_type['id']
|
||||||
|
usage_archetype = self._parse_zone_usage_type(usage, zone_usage_type)
|
||||||
|
self._usage_archetypes.append(usage_archetype)
|
||||||
|
|
||||||
self._city = city
|
self._city = city
|
||||||
self._usage_archetypes = None
|
|
||||||
|
|
||||||
def enrich_buildings(self):
|
def enrich_buildings(self):
|
||||||
"""
|
"""
|
||||||
|
@ -25,20 +35,19 @@ class SanamCustomizedUsageParameters:
|
||||||
"""
|
"""
|
||||||
city = self._city
|
city = self._city
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
archetype = self._search_archetype(building.function)
|
archetype = self._search_archetype(building.function) # todo: building.function or other translation???????
|
||||||
if archetype is None:
|
if archetype is None:
|
||||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||||
f' {building.function}, that assigns building usage as '
|
f' {building.function}, that assigns building usage as '
|
||||||
f'{gh.usage_from_function(building.function)}\n')
|
f'{gh.usage_from_function(building.function)}\n')
|
||||||
continue
|
continue
|
||||||
# todo: what to do with mix-usage usage from gml?
|
|
||||||
mix_usage = False
|
mix_usage = False
|
||||||
if not mix_usage:
|
if not mix_usage:
|
||||||
# just one usage_zone
|
# just one usage_zone
|
||||||
for thermal_zone in building.thermal_zones:
|
for thermal_zone in building.thermal_zones:
|
||||||
usage_zone = UsageZone()
|
usage_zone = UsageZone()
|
||||||
usage_zone.volume = thermal_zone.volume
|
|
||||||
self._assign_values(usage_zone, archetype)
|
self._assign_values(usage_zone, archetype)
|
||||||
|
usage_zone.volume = thermal_zone.volume
|
||||||
thermal_zone.usage_zones = [usage_zone]
|
thermal_zone.usage_zones = [usage_zone]
|
||||||
|
|
||||||
def _search_archetype(self, building_usage):
|
def _search_archetype(self, building_usage):
|
||||||
|
@ -50,6 +59,18 @@ class SanamCustomizedUsageParameters:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _assign_values(usage_zone, archetype):
|
def _assign_values(usage_zone, archetype):
|
||||||
usage_zone.usage = archetype.usage
|
usage_zone.usage = archetype.usage
|
||||||
|
# Due to the fact that python is not a typed language, the wrong object type is assigned to
|
||||||
|
# usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains.
|
||||||
|
# Therefore, this walk around has been done.
|
||||||
usage_zone.occupancy_density = archetype.occupancy_density
|
usage_zone.occupancy_density = archetype.occupancy_density
|
||||||
# todo: should I use this value: self._min_air_change??
|
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||||
usage_zone.minimum_ventilation_rate = archetype.minimum_ventilation_rate
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_zone_usage_type(usage, zone_usage_type):
|
||||||
|
occupancy_density = None
|
||||||
|
if 'occupancy' in zone_usage_type:
|
||||||
|
occupancy_density = zone_usage_type['occupancy']['occupancyDensity']
|
||||||
|
mechanical_air_change = zone_usage_type['endUses']['ventilation']['minimumVentilationRate']
|
||||||
|
usage_zone_archetype = huza(usage=usage, occupancy_density=occupancy_density,
|
||||||
|
mechanical_air_change=mechanical_air_change)
|
||||||
|
return usage_zone_archetype
|
||||||
|
|
|
@ -11,11 +11,11 @@ class CustomizedImportsFactory:
|
||||||
"""
|
"""
|
||||||
CustomizedImportsFactory class
|
CustomizedImportsFactory class
|
||||||
"""
|
"""
|
||||||
def __init__(self, city, importer_class, base_path):
|
def __init__(self, importer_class, city, base_path=None):
|
||||||
if base_path is None:
|
if base_path is None:
|
||||||
base_path = Path(Path(__file__).parent.parent / 'data/customized_imports')
|
base_path = Path(Path(__file__).parent.parent / 'data/customized_imports')
|
||||||
self._city = city
|
|
||||||
self._importer_class = importer_class
|
self._importer_class = importer_class
|
||||||
|
self._city = city
|
||||||
self._base_path = base_path
|
self._base_path = base_path
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
if len(building.thermal_zones) == 0:
|
if len(building.thermal_zones) == 0:
|
||||||
|
@ -24,6 +24,8 @@ class CustomizedImportsFactory:
|
||||||
|
|
||||||
def enrich(self):
|
def enrich(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city given to the class using the given importer class
|
Returns the class that will enrich the city given
|
||||||
:return: None
|
:return: Class
|
||||||
"""
|
"""
|
||||||
|
importer = self._importer_class(self._city, self._base_path)
|
||||||
|
return importer.enrich_buildings()
|
||||||
|
|
|
@ -41,8 +41,8 @@ class CaUsageParameters(HftUsageInterface):
|
||||||
# just one usage_zone
|
# just one usage_zone
|
||||||
for thermal_zone in building.thermal_zones:
|
for thermal_zone in building.thermal_zones:
|
||||||
usage_zone = UsageZone()
|
usage_zone = UsageZone()
|
||||||
usage_zone.volume = thermal_zone.volume
|
|
||||||
self._assign_values(usage_zone, archetype)
|
self._assign_values(usage_zone, archetype)
|
||||||
|
usage_zone.volume = thermal_zone.volume
|
||||||
thermal_zone.usage_zones = [usage_zone]
|
thermal_zone.usage_zones = [usage_zone]
|
||||||
|
|
||||||
def _search_archetype(self, building_usage):
|
def _search_archetype(self, building_usage):
|
||||||
|
|
47
unittests/test_customized_imports_factory.py
Normal file
47
unittests/test_customized_imports_factory.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
"""
|
||||||
|
TestCustomizedImportsFactory tests and validates the factory to import customized data
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
"""
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from imports.geometry_factory import GeometryFactory
|
||||||
|
from imports.construction_factory import ConstructionFactory
|
||||||
|
from imports.customized_imports_factory import CustomizedImportsFactory
|
||||||
|
from imports.customized_imports.sanam_customized_usage_parameters import SanamCustomizedUsageParameters as scp
|
||||||
|
|
||||||
|
|
||||||
|
class TestCustomizedImportsFactory(TestCase):
|
||||||
|
"""
|
||||||
|
TestCustomizedImportsFactory TestCase
|
||||||
|
"""
|
||||||
|
def setUp(self) -> None:
|
||||||
|
"""
|
||||||
|
Configure test environment
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||||
|
|
||||||
|
def _get_citygml(self, file):
|
||||||
|
file_path = (self._example_path / file).resolve()
|
||||||
|
_city = GeometryFactory('citygml', file_path).city
|
||||||
|
self.assertIsNotNone(_city, 'city is none')
|
||||||
|
ConstructionFactory('nrel', _city).enrich()
|
||||||
|
|
||||||
|
return _city
|
||||||
|
|
||||||
|
def test_city_with_customized_data(self):
|
||||||
|
"""
|
||||||
|
Enrich the city with the usage information and verify it
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
|
||||||
|
file = 'one_building_in_kelowna.gml'
|
||||||
|
city = self._get_citygml(file)
|
||||||
|
|
||||||
|
CustomizedImportsFactory(scp, city).enrich()
|
||||||
|
for building in city.buildings:
|
||||||
|
self.assertIsNot(len(building.usage_zones), 0, 'no building usage_zones defined')
|
||||||
|
for usage_zone in building.usage_zones:
|
||||||
|
self.assertIsNotNone(usage_zone.mechanical_air_change, 'usage is none')
|
Loading…
Reference in New Issue
Block a user