Merge remote-tracking branch 'origin/main' into Transys

This commit is contained in:
Guille Gutierrez 2024-01-22 05:50:18 +01:00
commit 60f329ef4f
17 changed files with 52021 additions and 1404 deletions

View File

@ -8,6 +8,8 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
import json import json
import urllib.request import urllib.request
from pathlib import Path
import xmltodict import xmltodict
import hub.helpers.constants as cte import hub.helpers.constants as cte
@ -28,12 +30,11 @@ class NrcanCatalog(Catalog):
Nrcan catalog class Nrcan catalog class
""" """
def __init__(self, path): def __init__(self, path):
path = str(path / 'nrcan.xml') self._schedules_path = Path(path / 'nrcan_schedules.json').resolve()
self._space_types_path = Path(path / 'nrcan_space_types.json').resolve()
self._space_compliance_path = Path(path / 'nrcan_space_compliance_2015.json').resolve()
self._content = None self._content = None
self._schedules = {} self._schedules = {}
with open(path, 'r', encoding='utf-8') as xml:
self._metadata = xmltodict.parse(xml.read())
self._base_url = self._metadata['nrcan']['@base_url']
self._load_schedules() self._load_schedules()
self._content = Content(self._load_archetypes()) self._content = Content(self._load_archetypes())
@ -55,11 +56,9 @@ class NrcanCatalog(Catalog):
return Schedule(hub_type, raw['values'], data_type, time_step, time_range, day_types) return Schedule(hub_type, raw['values'], data_type, time_step, time_range, day_types)
def _load_schedules(self): def _load_schedules(self):
usage = self._metadata['nrcan']
url = f'{self._base_url}{usage["schedules"]}'
_schedule_types = [] _schedule_types = []
with urllib.request.urlopen(url) as json_file: with open(self._schedules_path, 'r') as f:
schedules_type = json.load(json_file) schedules_type = json.load(f)
for schedule_type in schedules_type['tables']['schedules']['table']: for schedule_type in schedules_type['tables']['schedules']['table']:
schedule = NrcanCatalog._extract_schedule(schedule_type) schedule = NrcanCatalog._extract_schedule(schedule_type)
if schedule_type['name'] not in _schedule_types: if schedule_type['name'] not in _schedule_types:
@ -80,14 +79,11 @@ class NrcanCatalog(Catalog):
def _load_archetypes(self): def _load_archetypes(self):
usages = [] usages = []
name = self._metadata['nrcan'] with open(self._space_types_path, 'r') as f:
url_1 = f'{self._base_url}{name["space_types"]}' space_types = json.load(f)['tables']['space_types']['table']
url_2 = f'{self._base_url}{name["space_types_compliance"]}'
with urllib.request.urlopen(url_1) as json_file:
space_types = json.load(json_file)['tables']['space_types']['table']
space_types = [st for st in space_types if st['space_type'] == 'WholeBuilding'] space_types = [st for st in space_types if st['space_type'] == 'WholeBuilding']
with urllib.request.urlopen(url_2) as json_file: with open(self._space_compliance_path, 'r') as f:
space_types_compliance = json.load(json_file)['tables']['space_compliance']['table'] space_types_compliance = json.load(f)['tables']['space_compliance']['table']
space_types_compliance = [st for st in space_types_compliance if st['space_type'] == 'WholeBuilding'] space_types_compliance = [st for st in space_types_compliance if st['space_type'] == 'WholeBuilding']
space_types_dictionary = {} space_types_dictionary = {}
for space_type in space_types_compliance: for space_type in space_types_compliance:

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nrcan base_url="https://raw.githubusercontent.com/NREL/openstudio-standards/master/lib/openstudio-standards/standards/necb/">
<space_types>NECB2015/data/space_types.json</space_types>
<space_types_compliance>NECB2015/qaqc/qaqc_data/space_compliance_2015.json</space_types_compliance>>
<schedules>NECB2015/data/schedules.json</schedules>
</nrcan>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -276,11 +276,11 @@ class Idf:
self._idf.newidfobject(self._COMPACT_SCHEDULE, **_kwargs) self._idf.newidfobject(self._COMPACT_SCHEDULE, **_kwargs)
def _write_schedules_file(self, usage, schedule): def _write_schedules_file(self, usage, schedule):
file_name = str((Path(self._output_path) / f'{schedule.type} schedules {usage}.dat').resolve()) file_name = str((Path(self._output_path) / f'{schedule.type} schedules {usage}.csv').resolve())
with open(file_name, 'w', encoding='utf8') as file: with open(file_name, 'w', encoding='utf8') as file:
for value in schedule.values: for value in schedule.values:
file.write(f'{str(value)},\n') file.write(f'{str(value)},\n')
return file_name return Path(file_name).name
def _add_file_schedule(self, usage, schedule, file_name): def _add_file_schedule(self, usage, schedule, file_name):
_schedule = self._idf.newidfobject(self._FILE_SCHEDULE, Name=f'{schedule.type} schedules {usage}') _schedule = self._idf.newidfobject(self._FILE_SCHEDULE, Name=f'{schedule.type} schedules {usage}')
@ -403,7 +403,7 @@ class Idf:
self._idf.newidfobject(self._PEOPLE, self._idf.newidfobject(self._PEOPLE,
Name=f'{zone_name}_occupancy', Name=f'{zone_name}_occupancy',
Zone_or_ZoneList_Name=zone_name, Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Number_of_People_Schedule_Name=f'Occupancy schedules {thermal_zone.usage_name}', Number_of_People_Schedule_Name=f'Occupancy schedules {thermal_zone.usage_name}',
Number_of_People_Calculation_Method="People", Number_of_People_Calculation_Method="People",
Number_of_People=number_of_people, Number_of_People=number_of_people,
@ -420,7 +420,7 @@ class Idf:
self._idf.newidfobject(self._LIGHTS, self._idf.newidfobject(self._LIGHTS,
Name=f'{zone_name}_lights', Name=f'{zone_name}_lights',
Zone_or_ZoneList_Name=zone_name, Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=f'Lighting schedules {thermal_zone.usage_name}', Schedule_Name=f'Lighting schedules {thermal_zone.usage_name}',
Design_Level_Calculation_Method=method, Design_Level_Calculation_Method=method,
Watts_per_Zone_Floor_Area=watts_per_zone_floor_area, Watts_per_Zone_Floor_Area=watts_per_zone_floor_area,
@ -439,7 +439,7 @@ class Idf:
self._idf.newidfobject(self._APPLIANCES, self._idf.newidfobject(self._APPLIANCES,
Fuel_Type=fuel_type, Fuel_Type=fuel_type,
Name=f'{zone_name}_appliance', Name=f'{zone_name}_appliance',
Zone_or_ZoneList_Name=zone_name, Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=f'Appliance schedules {thermal_zone.usage_name}', Schedule_Name=f'Appliance schedules {thermal_zone.usage_name}',
Design_Level_Calculation_Method=method, Design_Level_Calculation_Method=method,
Power_per_Zone_Floor_Area=watts_per_zone_floor_area, Power_per_Zone_Floor_Area=watts_per_zone_floor_area,
@ -453,7 +453,7 @@ class Idf:
_infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS _infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._INFILTRATION, self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration', Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_Name=zone_name, Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=schedule, Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='AirChanges/Hour', Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
Air_Changes_per_Hour=_infiltration Air_Changes_per_Hour=_infiltration
@ -464,7 +464,7 @@ class Idf:
_air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS _air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._VENTILATION, self._idf.newidfobject(self._VENTILATION,
Name=f'{zone_name}_ventilation', Name=f'{zone_name}_ventilation',
Zone_or_ZoneList_Name=zone_name, Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=schedule, Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='AirChanges/Hour', Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
Air_Changes_per_Hour=_air_change Air_Changes_per_Hour=_air_change
@ -627,8 +627,8 @@ class Idf:
self._idf.intersect_match() self._idf.intersect_match()
def _add_shading(self, building): def _add_shading(self, building):
for surface in building.surfaces: for i, surface in enumerate(building.surfaces):
shading = self._idf.newidfobject(self._SHADING, Name=f'{surface.name}') shading = self._idf.newidfobject(self._SHADING, Name=f'{building.name}_{i}')
coordinates = self._matrix_to_list(surface.solid_polygon.coordinates, coordinates = self._matrix_to_list(surface.solid_polygon.coordinates,
self._city.lower_corner) self._city.lower_corner)
shading.setcoords(coordinates) shading.setcoords(coordinates)
@ -636,17 +636,17 @@ class Idf:
if solar_reflectance is None: if solar_reflectance is None:
solar_reflectance = ConfigurationHelper().short_wave_reflectance solar_reflectance = ConfigurationHelper().short_wave_reflectance
self._idf.newidfobject(self._SHADING_PROPERTY, self._idf.newidfobject(self._SHADING_PROPERTY,
Shading_Surface_Name=f'{surface.name}', Shading_Surface_Name=f'{building.name}_{i}',
Diffuse_Solar_Reflectance_of_Unglazed_Part_of_Shading_Surface=solar_reflectance, Diffuse_Solar_Reflectance_of_Unglazed_Part_of_Shading_Surface=solar_reflectance,
Fraction_of_Shading_Surface_That_Is_Glazed=0) Fraction_of_Shading_Surface_That_Is_Glazed=0)
def _add_pure_geometry(self, building, zone_name): def _add_pure_geometry(self, building, zone_name):
for surface in building.surfaces: for index, surface in enumerate(building.surfaces):
outside_boundary_condition = 'Outdoors' outside_boundary_condition = 'Outdoors'
sun_exposure = 'SunExposed' sun_exposure = 'SunExposed'
wind_exposure = 'WindExposed' wind_exposure = 'WindExposed'
idf_surface_type = self.idf_surfaces[surface.type] idf_surface_type = self.idf_surfaces[surface.type]
_kwargs = {'Name': f'{surface.name}', _kwargs = {'Name': f'Building_{building.name}_surface_{index}',
'Surface_Type': idf_surface_type, 'Surface_Type': idf_surface_type,
'Zone_Name': zone_name} 'Zone_Name': zone_name}
if surface.type == cte.GROUND: if surface.type == cte.GROUND:
@ -655,7 +655,7 @@ class Idf:
wind_exposure = 'NoWind' wind_exposure = 'NoWind'
if surface.percentage_shared is not None and surface.percentage_shared > 0.5: if surface.percentage_shared is not None and surface.percentage_shared > 0.5:
outside_boundary_condition = 'Surface' outside_boundary_condition = 'Surface'
outside_boundary_condition_object = surface.name outside_boundary_condition_object = f'Building_{building.name}_surface_{index}'
sun_exposure = 'NoSun' sun_exposure = 'NoSun'
wind_exposure = 'NoWind' wind_exposure = 'NoWind'
_kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object _kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object
@ -680,12 +680,12 @@ class Idf:
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:
for boundary in thermal_zone.thermal_boundaries: for index, boundary in enumerate(thermal_zone.thermal_boundaries):
idf_surface_type = self.idf_surfaces[boundary.parent_surface.type] idf_surface_type = self.idf_surfaces[boundary.parent_surface.type]
outside_boundary_condition = 'Outdoors' outside_boundary_condition = 'Outdoors'
sun_exposure = 'SunExposed' sun_exposure = 'SunExposed'
wind_exposure = 'WindExposed' wind_exposure = 'WindExposed'
_kwargs = {'Name': f'{boundary.parent_surface.name}', _kwargs = {'Name': f'Building_{building.name}_surface_{index}',
'Surface_Type': idf_surface_type, 'Surface_Type': idf_surface_type,
'Zone_Name': zone_name} 'Zone_Name': zone_name}
if boundary.parent_surface.type == cte.GROUND: if boundary.parent_surface.type == cte.GROUND:
@ -694,7 +694,7 @@ class Idf:
wind_exposure = 'NoWind' wind_exposure = 'NoWind'
if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared > 0.5: if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared > 0.5:
outside_boundary_condition = 'Surface' outside_boundary_condition = 'Surface'
outside_boundary_condition_object = boundary.parent_surface.name outside_boundary_condition_object = f'Building_{building.name}_surface_{index}'
sun_exposure = 'NoSun' sun_exposure = 'NoSun'
wind_exposure = 'NoWind' wind_exposure = 'NoWind'
_kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object _kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
! HVAC: None. ! HVAC: None.
! !
Version,9.5; Version,23.2;
Timestep,4; Timestep,4;
@ -127,31 +127,25 @@
No, !- Do HVAC Sizing Simulation for Sizing Periods No, !- Do HVAC Sizing Simulation for Sizing Periods
1; !- Maximum Number of HVAC Sizing Simulation Passes 1; !- Maximum Number of HVAC Sizing Simulation Passes
Output:Table:SummaryReports, AnnualBuildingUtilityPerformanceSummary, Output:VariableDictionary,Regular;
DemandEndUseComponentsSummary,
SensibleHeatGainSummary,
InputVerificationandResultsSummary,
AdaptiveComfortSummary,
Standard62.1Summary,
ClimaticDataSummary,
EquipmentSummary,
EnvelopeSummary,
LightingSummary,
HVACSizingSummary,
SystemSummary,
ComponentSizingSummary,
OutdoorAirSummary,
ObjectCountSummary,
EndUseEnergyConsumptionOtherFuelsMonthly,
PeakEnergyEndUseOtherFuelsMonthly;
Output:Variable,*,Site Outdoor Air Drybulb Temperature,Timestep;
OutputControl:Table:Style, CommaAndHTML,JtoKWH; Output:Variable,*,Site Outdoor Air Wetbulb Temperature,Timestep;
Output:Meter,DISTRICTHEATING:Facility,hourly; Output:Variable,*,Site Outdoor Air Dewpoint Temperature,Timestep;
Output:Meter,DISTRICTCOOLING:Facility,hourly;
Output:Meter,InteriorEquipment:Electricity,hourly; Output:Variable,*,Site Solar Azimuth Angle,Timestep;
Output:Meter,InteriorLights:Electricity,hourly;
Output:Variable,*,Site Solar Altitude Angle,Timestep;
Output:Variable,*,Site Direct Solar Radiation Rate per Area,Timestep;
Output:Variable,*,Site Diffuse Solar Radiation Rate per Area,Timestep;
OutputControl:Table:Style,
HTML; !- Column Separator
Output:Table:SummaryReports,
AllSummary; !- Report 1 Name
OutputControl:IlluminanceMap:Style,
Comma; !- Column separator

View File

@ -213,8 +213,6 @@ 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)
if len(surfaces) > 1:
raise ValueError('too many surfaces!!!!')
building = Building(f'{building_name}', surfaces, year_of_construction, function) building = Building(f'{building_name}', surfaces, year_of_construction, function)
for alias in building_aliases: for alias in building_aliases:
building.add_alias(alias) building.add_alias(alias)

View File

@ -70,7 +70,7 @@ class InselMonthlyEnergyBalance:
total_day += value total_day += value
for day_type in schedule.day_types: for day_type in schedule.day_types:
total_lighting += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] \ total_lighting += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] \
* lighting_density / cte.WATTS_HOUR_TO_JULES * lighting_density * cte.WATTS_HOUR_TO_JULES
lighting_demand.append(total_lighting * area) lighting_demand.append(total_lighting * area)
for schedule in thermal_zone.appliances.schedules: for schedule in thermal_zone.appliances.schedules:
@ -79,7 +79,7 @@ class InselMonthlyEnergyBalance:
total_day += value total_day += value
for day_type in schedule.day_types: for day_type in schedule.day_types:
total_appliances += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] \ total_appliances += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] \
* appliances_density / cte.WATTS_HOUR_TO_JULES * appliances_density * cte.WATTS_HOUR_TO_JULES
appliances_demand.append(total_appliances * area) appliances_demand.append(total_appliances * area)
for schedule in thermal_zone.domestic_hot_water.schedules: for schedule in thermal_zone.domestic_hot_water.schedules:
@ -89,7 +89,7 @@ class InselMonthlyEnergyBalance:
for day_type in schedule.day_types: for day_type in schedule.day_types:
demand = ( demand = (
peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY
* (service_temperature - cold_water[i_month]) / cte.WATTS_HOUR_TO_JULES * (service_temperature - cold_water[i_month]) * cte.WATTS_HOUR_TO_JULES
) )
total_dhw_demand += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] * demand total_dhw_demand += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] * demand
domestic_hot_water_demand.append(total_dhw_demand * area) domestic_hot_water_demand.append(total_dhw_demand * area)

View File

@ -4,10 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project CoderPeter Yefi peteryefi@gmail.com Project CoderPeter Yefi peteryefi@gmail.com
""" """
import json
from typing import Dict from typing import Dict
from hub.persistence.repositories.application import Application from hub.persistence.repositories.application import Application
from hub.persistence.repositories.city import City from hub.persistence.repositories.city import City
from hub.persistence.repositories.city_object import CityObject from hub.persistence.repositories.city_object import CityObject
@ -99,17 +97,18 @@ class DBControl:
""" """
return self._city_object.get_by_name_or_alias_in_cities(name, cities) return self._city_object.get_by_name_or_alias_in_cities(name, cities)
def buildings_info(self, request_values, city_id) -> [CityObject]: def buildings_info(self, user_id, application_id, names_or_aliases) -> [CityObject]:
""" """
Retrieve the buildings info from the database Retrieve the buildings info from the database
:param request_values: Building names :param user_id: User ID
:param city_id: City ID :param application_id: Application ID
:param names_or_aliases: A list of names or alias for the buildings
:return: [CityObject] :return: [CityObject]
""" """
buildings = [] results = self._city_object.get_by_name_or_alias_for_user_app(user_id, application_id, names_or_aliases)
for name in request_values['names']: if results is None:
buildings.append(self.building_info(name, city_id)) return []
return buildings return results
def results(self, user_id, application_id, request_values, result_names=None) -> Dict: def results(self, user_id, application_id, request_values, result_names=None) -> Dict:
""" """

View File

@ -14,6 +14,7 @@ from sqlalchemy.orm import Session
from hub.city_model_structure.building import Building from hub.city_model_structure.building import Building
from hub.persistence.models import CityObject as Model from hub.persistence.models import CityObject as Model
from hub.persistence.models import City as CityModel
from hub.persistence.repository import Repository from hub.persistence.repository import Repository
@ -73,7 +74,7 @@ class CityObject(Repository):
with Session(self.engine) as session: with Session(self.engine) as session:
session.query(Model).filter(Model.name == building.name, Model.city_id == city_id).update( session.query(Model).filter(Model.name == building.name, Model.city_id == city_id).update(
{'name': building.name, {'name': building.name,
'alias': building.alias, 'aliases': building.aliases,
'object_type': building.type, 'object_type': building.type,
'year_of_construction': building.year_of_construction, 'year_of_construction': building.year_of_construction,
'function': building.function, 'function': building.function,
@ -135,6 +136,26 @@ class CityObject(Repository):
logging.error('Error while fetching city object by name and city, empty result %s', err) logging.error('Error while fetching city object by name and city, empty result %s', err)
raise IndexError from err raise IndexError from err
def get_by_name_or_alias_for_user_app(self, user_id, application_id, names) -> Union[Model, None]:
"""
Fetch city objects belonging to the user and application where the name or alias is in the names list
:param user_id: User ID
:param application_id: Application ID
:param names: a list of building aliases or names
:return [CityObject] or None
"""
with Session(self.engine) as session:
cities = session.execute(select(CityModel).where(
CityModel.user_id == user_id, CityModel.application_id == application_id
)).all()
ids = [c[0].id for c in cities]
buildings = session.execute(select(Model).where(
Model.city_id.in_(ids), Model.name.in_(names)
))
results = [r[0] for r in buildings]
print(ids, buildings)
return None
def get_by_name_or_alias_and_city(self, name, city_id) -> Union[Model, None]: def get_by_name_or_alias_and_city(self, name, city_id) -> Union[Model, None]:
""" """
Fetch a city object based on name and city id Fetch a city object based on name and city id

View File

@ -1,4 +1,4 @@
""" """
Hub version number Hub version number
""" """
__version__ = '0.1.8.34' __version__ = '0.1.8.36'

View File

@ -100,6 +100,7 @@ setup(
('hub/data/geolocation', glob.glob('hub/data/geolocation/*.txt')), ('hub/data/geolocation', glob.glob('hub/data/geolocation/*.txt')),
('hub/data/greenery', glob.glob('hub/data/greenery/*.xml')), ('hub/data/greenery', glob.glob('hub/data/greenery/*.xml')),
('hub/data/usage', glob.glob('hub/data/usage/*.xml')), ('hub/data/usage', glob.glob('hub/data/usage/*.xml')),
('hub/data/usage', glob.glob('hub/data/usage/*.json')),
('hub/data/usage', glob.glob('hub/data/usage/*.xlsx')), ('hub/data/usage', glob.glob('hub/data/usage/*.xlsx')),
('hub/data/weather', glob.glob('hub/data/weather/*.dat')), ('hub/data/weather', glob.glob('hub/data/weather/*.dat')),
('hub/data/weather/epw', glob.glob('hub/data/weather/epw/*.epw')), ('hub/data/weather/epw', glob.glob('hub/data/weather/epw/*.epw')),

View File

@ -6,7 +6,6 @@ Project Coder Peter Yefi peteryefi@gmail.com
""" """
import distutils.spawn import distutils.spawn
import glob import glob
import json
import logging import logging
import os import os
import subprocess import subprocess
@ -286,6 +285,8 @@ TestDBFactory
results, city_object_id=db_building_id) results, city_object_id=db_building_id)
self.assertEqual(17, len(city_objects_id), 'wrong number of results') self.assertEqual(17, len(city_objects_id), 'wrong number of results')
self.assertIsNotNone(city_objects_id[0], 'city_object_id is None') self.assertIsNotNone(city_objects_id[0], 'city_object_id is None')
results = control.database.results(control.user_id, control.application_id, request_values)
for _id in city_objects_id: for _id in city_objects_id:
control.database.delete_results_by_name('insel meb', city_object_id=_id) control.database.delete_results_by_name('insel meb', city_object_id=_id)
control.database.delete_city(city_id) control.database.delete_city(city_id)

View File

@ -5,11 +5,8 @@ Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com Project Coder Peter Yefi peteryefi@gmail.com
""" """
import distutils.spawn import distutils.spawn
import glob
import json
import logging import logging
import os import os
import subprocess
import unittest import unittest
from pathlib import Path from pathlib import Path
from unittest import TestCase from unittest import TestCase
@ -18,19 +15,7 @@ import sqlalchemy.exc
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.exc import ProgrammingError from sqlalchemy.exc import ProgrammingError
import hub.helpers.constants as cte
from hub.exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
from hub.exports.exports_factory import ExportsFactory
from hub.helpers.data.montreal_function_to_hub_function import MontrealFunctionToHubFunction
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.energy_systems_factory import EnergySystemsFactory
from hub.imports.geometry_factory import GeometryFactory
from hub.imports.results_factory import ResultFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory
from hub.persistence.db_control import DBControl from hub.persistence.db_control import DBControl
from hub.persistence.models import City, Application, CityObject, SimulationResults
from hub.persistence.models import User, UserRoles
from hub.persistence.repository import Repository from hub.persistence.repository import Repository
@ -129,24 +114,12 @@ TestDBFactory
""" """
@unittest.skipIf(control.skip_test, control.skip_reason) @unittest.skipIf(control.skip_test, control.skip_reason)
def test_retrieve_results(self): def test_buildings_info(self):
request_values = { request_values = {
"scenarios": [ "buildings": [
{ "01002777", "01002773", "01036804"
"current status": ["01002777", "01002773", "01036804"]
},
{
"skin retrofit": ["01002777", "01002773", "01036804"]
},
{
"system retrofit and pv": ["01002777", "01002773", "01036804"]
},
{
"skin and system retrofit with pv": ["01002777", "01002773", "01036804"]
}
] ]
} }
results = control.database.results(control.user_id, control.application_id, request_values) results = control.database.buildings_info(control.user_id, control.application_id, request_values)
self.assertEqual(12, len(results), 'wrong number of results')
print(results) print(results)

View File

@ -143,7 +143,6 @@ class TestExports(TestCase):
EnergyBuildingsExportsFactory('idf', city, self._output_path).export() EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
UsageFactory('nrcan', city).enrich() UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city).enrich() WeatherFactory('epw', city).enrich()
print(self._output_path)
try: try:
EnergyBuildingsExportsFactory('idf', city, self._output_path).export() EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
except Exception: except Exception: