energy_validation_tool/energy_validation.py

120 lines
5.2 KiB
Python

import json
import random
import datetime
from pathlib import Path
from hub.imports.geometry_factory import GeometryFactory
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.results_factory import ResultFactory
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 sra import Sra
from meb import Meb
class EnergyValidation:
def __init__(self):
self.weather_file = Path('./data/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
self.climate_file_name = 'Montreal'
self.tmp_folder = Path('./tmp').resolve()
self.storage_path = Path('./storage').resolve()
self.climate_file = Path(f'{self.storage_path}/{self.climate_file_name}.cli').resolve()
self.meb_folder = Path('./results/meb').resolve()
self.ep_folder = Path('./results/ep').resolve()
def _sort_buildings(self, buildings_to_simulate):
sorted_buildings = {}
for building in buildings_to_simulate:
code_utili = building['properties']['CODE_UTILI']
if not sorted_buildings.get(code_utili):
sorted_buildings[code_utili] = []
sorted_buildings[code_utili].append(building)
return sorted_buildings
def run(self, building_set, building_quantities):
sorted_buildings = self._sort_buildings(building_set)
building_to_simulate = []
min_m2_satisfied = False
for code_utili in building_quantities:
if code_utili not in sorted_buildings:
print(f'CODE_UTILI:{code_utili} is not found in the provided dataset.')
else:
for building in range(building_quantities[code_utili]):
# only select buildings with an area of 500 m^2 or more
while not min_m2_satisfied:
building_to_simulate.append(sorted_buildings[code_utili][random.randrange(
len(sorted_buildings[code_utili]))])
if building_to_simulate[0]['bldgarea'] < 500:
building_to_simulate.clear()
else:
min_m2_satisfied = True
building_id = building_to_simulate[0]['id']
geojson = {
"type": "FeatureCollection",
"features": building_to_simulate
}
geojson_file = open(f'tmp/{building_id}_energy_validation.geojson', 'w')
geojson_file.write(json.dumps(geojson, indent=2))
geojson_file.close()
city = GeometryFactory('geojson',
path=f'tmp/{building_id}_energy_validation.geojson',
height_field='building_height',
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=MontrealFunctionToHubFunction().dictionary).city
ConstructionFactory('nrcan', city).enrich()
UsageFactory('nrcan', city).enrich()
if city.climate_reference_city is None:
city.name = f'Concordia current status {building_id}'
city.climate_reference_city = city.location
self.climate_file_name = city.location
city.climate_file = self.climate_file
print(f'{building_id} starting sra')
start = datetime.datetime.now()
ExportsFactory('sra', city, self.tmp_folder, weather_file=self.weather_file, weather_format='epw').export()
sra_file = (self.tmp_folder / f'{city.name}_sra.xml').resolve()
Sra(sra_file, self.tmp_folder).run()
ResultFactory('sra', city, self.tmp_folder).enrich()
sra_time = datetime.datetime.now() - start
print(f"{building_id} SRA time: {sra_time}\n")
print(f'{building_id} starting meb')
start = datetime.datetime.now()
for building in city.buildings:
building.attic_heated = 0
building.basement_heated = 1
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', city, self.meb_folder).export()
Meb(self.meb_folder).run()
meb_time = datetime.datetime.now() - start
print(f"{building_id} meb time: {meb_time}\n")
#print('starting energy plus')
building_to_simulate.clear()
data_file = open('data/VMTrial_cleaned.geojson', 'r')
city = json.load(data_file)
buildings = city['features']
test_batch = {
'1000': 50,
'4413': 10,
'1921': 5
}
test = EnergyValidation()
test.run(building_set=buildings, building_quantities=test_batch)