From e544eb2ed52e679767e1691370bdd86e45e6d1f2 Mon Sep 17 00:00:00 2001 From: guille Date: Wed, 22 Nov 2023 08:51:53 +0100 Subject: [PATCH] initial implementation of trnsys exporter --- hub/exports/building_energy/trnsys.py | 63 +++++++++++++++++++ .../energy_building_exports_factory.py | 12 ++++ 2 files changed, 75 insertions(+) create mode 100644 hub/exports/building_energy/trnsys.py diff --git a/hub/exports/building_energy/trnsys.py b/hub/exports/building_energy/trnsys.py new file mode 100644 index 00000000..7dbe3325 --- /dev/null +++ b/hub/exports/building_energy/trnsys.py @@ -0,0 +1,63 @@ +""" +export a city into B18 (TRNSYS 18) format +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2022 Concordia CERC group +Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca +""" + +from pathlib import Path + + +class Trnsys: + """ + TRNSYS class + """ + + def __init__(self, city, path, target_buildings=None): + self._city = city + self._path = path + self._buildings = self._city.buildings + if target_buildings is not None: + buildings = [] + for building in target_buildings: + buildings.append(self._city.city_object(building)) + self._buildings = buildings + + def _building_information(self, f, building): + f.write('[Building Information]\n') + f.write(f'Name: {building.name}\n') + f.write(f'Location: {self._city.location.city}, {self._city.location.country}\n') + f.write(f'Total Floors: {building.storeys_above_ground}\n') + f.write(f'Year Build: {building.year_of_construction}\n') + + @staticmethod + def _geometry_information(f, building): + f.write('[Geometry]\n') + f.write(f'Length: {building.upper_corner[0] - building.lower_corner[0]}\n') + f.write(f'Width: {building.upper_corner[1] - building.lower_corner[1]}\n') + f.write(f'Height: {building.upper_corner[2] - building.lower_corner[2]}\n') + + @staticmethod + def _wall_construction(f, building): + basic_thermal_boundary = building.walls[0].associated_thermal_boundaries[0] + + f.write('[Wall Construction]\n') + f.write(f'Wall Type: Multi-Layered Wall\n') + f.write(f'Layers: {len(basic_thermal_boundary.layers)}') + f.write(f'Height: {building.upper_corner[2] - building.lower_corner[2]}\n') + + @staticmethod + def _wall_information(f, building): + f.write('[Wall Section]\n') + f.write(f'Material: {building.upper_corner[0] - building.lower_corner[0]}\n') + f.write(f'Width: {building.upper_corner[1] - building.lower_corner[1]}\n') + f.write(f'Height: {building.upper_corner[2] - building.lower_corner[2]}\n') + + def export(self): + for building in self._buildings: + path = Path(self._path / f'{building.name}.b18') + with open(path, 'w', encoding='utf-8') as f: + self._building_information(f, building) + Trnsys._geometry_information(f, building) + Trnsys._wall_information(f, building) + diff --git a/hub/exports/energy_building_exports_factory.py b/hub/exports/energy_building_exports_factory.py index 952e4a12..abbb9de1 100644 --- a/hub/exports/energy_building_exports_factory.py +++ b/hub/exports/energy_building_exports_factory.py @@ -12,6 +12,7 @@ import requests from hub.exports.building_energy.energy_ade import EnergyAde from hub.exports.building_energy.idf import Idf from hub.exports.building_energy.insel.insel_monthly_energy_balance import InselMonthlyEnergyBalance +from hub.exports.building_energy.trnsys import Trnsys from hub.helpers.utils import validate_import_export_type from hub.imports.weather.helpers.weather import Weather as wh @@ -60,6 +61,17 @@ class EnergyBuildingsExportsFactory: return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path, target_buildings=self._target_buildings) + @property + def _trnsys(self): + """ + Export the city to TRNSYS 18 format + + Currently only b18 files will be generated + + :return: None + """ + return Trnsys(self._city, self._path, target_buildings=self._target_buildings) + @property def _insel_monthly_energy_balance(self): """