created customized imports factory and correspondent test
This commit is contained in:
parent
eb836809a8
commit
688ba9bd37
|
@ -3,9 +3,11 @@ SanamCustomizedUsageParameters add two parameters to usage properties from ASHRA
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
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.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||
|
||||
|
||||
|
@ -14,9 +16,17 @@ class SanamCustomizedUsageParameters:
|
|||
SanamCustomizedUsageParameters class
|
||||
"""
|
||||
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._usage_archetypes = None
|
||||
|
||||
def enrich_buildings(self):
|
||||
"""
|
||||
|
@ -25,20 +35,19 @@ class SanamCustomizedUsageParameters:
|
|||
"""
|
||||
city = self._city
|
||||
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:
|
||||
sys.stderr.write(f'Building {building.name} has unknown archetype for building function:'
|
||||
f' {building.function}, that assigns building usage as '
|
||||
f'{gh.usage_from_function(building.function)}\n')
|
||||
continue
|
||||
# todo: what to do with mix-usage usage from gml?
|
||||
mix_usage = False
|
||||
if not mix_usage:
|
||||
# just one usage_zone
|
||||
for thermal_zone in building.thermal_zones:
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
thermal_zone.usage_zones = [usage_zone]
|
||||
|
||||
def _search_archetype(self, building_usage):
|
||||
|
@ -50,6 +59,18 @@ class SanamCustomizedUsageParameters:
|
|||
@staticmethod
|
||||
def _assign_values(usage_zone, archetype):
|
||||
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
|
||||
# todo: should I use this value: self._min_air_change??
|
||||
usage_zone.minimum_ventilation_rate = archetype.minimum_ventilation_rate
|
||||
usage_zone.mechanical_air_change = archetype.mechanical_air_change
|
||||
|
||||
@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
|
||||
"""
|
||||
def __init__(self, city, importer_class, base_path):
|
||||
def __init__(self, importer_class, city, base_path=None):
|
||||
if base_path is None:
|
||||
base_path = Path(Path(__file__).parent.parent / 'data/customized_imports')
|
||||
self._city = city
|
||||
self._importer_class = importer_class
|
||||
self._city = city
|
||||
self._base_path = base_path
|
||||
for building in city.buildings:
|
||||
if len(building.thermal_zones) == 0:
|
||||
|
@ -24,6 +24,8 @@ class CustomizedImportsFactory:
|
|||
|
||||
def enrich(self):
|
||||
"""
|
||||
Enrich the city given to the class using the given importer class
|
||||
:return: None
|
||||
Returns the class that will enrich the city given
|
||||
: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
|
||||
for thermal_zone in building.thermal_zones:
|
||||
usage_zone = UsageZone()
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
self._assign_values(usage_zone, archetype)
|
||||
usage_zone.volume = thermal_zone.volume
|
||||
thermal_zone.usage_zones = [usage_zone]
|
||||
|
||||
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