From bf10ba82a6df0a7d5915f8ad62e0e51bfc496f87 Mon Sep 17 00:00:00 2001 From: Peter Yefi Date: Sun, 19 Feb 2023 13:57:24 -0500 Subject: [PATCH 1/3] Saved local changes --- hub/imports/sensors/concordia_gas_flow.py | 2 +- hub/imports/sensors/concordia_temperature.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hub/imports/sensors/concordia_gas_flow.py b/hub/imports/sensors/concordia_gas_flow.py index d72bd442..c665a909 100644 --- a/hub/imports/sensors/concordia_gas_flow.py +++ b/hub/imports/sensors/concordia_gas_flow.py @@ -6,7 +6,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ import pandas as pd from hub.imports.sensors.concordia_file_report import ConcordiaFileReport -from city_model_structure.iot.concordia_gas_flow_sensor import ConcordiaGasFlowSensor +from hub.city_model_structure.iot.concordia_gas_flow_sensor import ConcordiaGasFlowSensor class ConcordiaGasFlow(ConcordiaFileReport): diff --git a/hub/imports/sensors/concordia_temperature.py b/hub/imports/sensors/concordia_temperature.py index c1e4537d..c219c24a 100644 --- a/hub/imports/sensors/concordia_temperature.py +++ b/hub/imports/sensors/concordia_temperature.py @@ -6,7 +6,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ import pandas as pd from hub.imports.sensors.concordia_file_report import ConcordiaFileReport -from city_model_structure.iot.concordia_temperature_sensor import ConcordiaTemperatureSensor +from hub.city_model_structure.iot.concordia_temperature_sensor import ConcordiaTemperatureSensor class ConcordiaTemperature(ConcordiaFileReport): From c3f4c278118a619f4588cd827d33f09bc562fd23 Mon Sep 17 00:00:00 2001 From: Peter Yefi Date: Mon, 20 Feb 2023 18:36:34 -0500 Subject: [PATCH 2/3] Added heat pump energy demand and fossil fuel consumption results --- .../energy_systems/heat_pump.py | 32 ++++++++ .../results/insel_heatpump_energy_demand.py | 38 ++++++++++ hub/imports/results_factory.py | 22 +++++- hub/unittests/test_heat_pump_results.py | 74 +++++++++++++++++++ 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 hub/imports/results/insel_heatpump_energy_demand.py create mode 100644 hub/unittests/test_heat_pump_results.py diff --git a/hub/city_model_structure/energy_systems/heat_pump.py b/hub/city_model_structure/energy_systems/heat_pump.py index bb78dc72..120155c5 100644 --- a/hub/city_model_structure/energy_systems/heat_pump.py +++ b/hub/city_model_structure/energy_systems/heat_pump.py @@ -4,6 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Peter Yefi peteryefi@gmail.com """ +from typing import List +from pandas.core.series import Series class HeatPump: @@ -13,6 +15,8 @@ class HeatPump: def __init__(self): self._model = None + self._hp_monthly_fossil_consumption = None + self._hp_monthly_electricity_demand = None @property def model(self) -> str: @@ -30,3 +34,31 @@ class HeatPump: """ if self._model is None: self._model = value + + @property + def hp_monthly_fossil_consumption(self) -> List: + """ + Fossil fuel consumption that results from insel simulation + ":return: [] + :return: + """ + return self._hp_monthly_fossil_consumption + + @hp_monthly_fossil_consumption.setter + def hp_monthly_fossil_consumption(self, value): + if type(value) is Series: + self._hp_monthly_fossil_consumption = value + + @property + def hp_monthly_electricity_demand(self) -> List: + """ + Electricity demand that results from insel simulation + ":return: [] + :return: + """ + return self._hp_monthly_electricity_demand + + @hp_monthly_electricity_demand.setter + def hp_monthly_electricity_demand(self, value): + if type(value) == Series: + self._hp_monthly_electricity_demand = value diff --git a/hub/imports/results/insel_heatpump_energy_demand.py b/hub/imports/results/insel_heatpump_energy_demand.py new file mode 100644 index 00000000..98cb439f --- /dev/null +++ b/hub/imports/results/insel_heatpump_energy_demand.py @@ -0,0 +1,38 @@ +""" +Insel Heap pump energy demand and fossil fuel consumption +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder peter.yefi@gmail.cm +""" + +from pathlib import Path +import pandas as pd + + +class InselHeatPumpEnergyDemand: + """ + Import Energy demand and fossil fuel consumption results + """ + def __init__(self, city, base_path, hp_model): + """ + :param city: the city + :param base_path: the insel simulation output file + :param hp_model: the heatpump model for both air source and water to water + """ + self._city = city + self._hp_model = hp_model + with open(Path(base_path).resolve()) as csv_file: + df = pd.read_csv(csv_file) + self._monthly_electricity_demand = df.iloc[:, 1] + self._monthly_fossil_fuel_consumption = df.iloc[:, 2] + + def enrich(self): + for energy_system in self._city.energy_systems: + if energy_system.air_source_hp is not None: + if energy_system.air_source_hp.model == self._hp_model: + energy_system.air_source_hp.hp_monthly_fossil_consumption = self._monthly_fossil_fuel_consumption + + if energy_system.water_to_water_hp is not None: + if energy_system.water_to_water_hp.model == self._hp_model: + energy_system.water_to_water_hp.hp_monthly_electricity_demand = self._monthly_electricity_demand + diff --git a/hub/imports/results_factory.py b/hub/imports/results_factory.py index afa90fb6..62adf124 100644 --- a/hub/imports/results_factory.py +++ b/hub/imports/results_factory.py @@ -11,13 +11,23 @@ from hub.helpers.utils import validate_import_export_type from hub.hub_logger import logger from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm from hub.imports.results.insel_monthly_energry_balance import InselMonthlyEnergyBalance +from hub.imports.results.insel_heatpump_energy_demand import InselHeatPumpEnergyDemand class ResultFactory: """ - UsageFactory class + ResultFactory class """ - def __init__(self, handler, city, base_path=None): + + def __init__(self, handler, city, base_path=None, hp_model=None): + """ + + :param handler: pointer to results class to be called + :param city: the city object + :param base_path: the path to result output file + :param hp_model: (optional) the heat pump model for which + results are being retrieved + """ if base_path is None: base_path = Path(Path(__file__).parent.parent / 'data/results') self._handler = '_' + handler.lower().replace(' ', '_') @@ -28,6 +38,7 @@ class ResultFactory: raise Exception(err_msg) self._city = city self._base_path = base_path + self._hp_model = hp_model def _sra(self): """ @@ -35,6 +46,13 @@ class ResultFactory: """ SimplifiedRadiosityAlgorithm(self._city, self._base_path).enrich() + def _heat_pump(self): + """ + Enrich the city (energy system specifically) with heat pump insel simulation + results + """ + InselHeatPumpEnergyDemand(self._city, self._base_path, self._hp_model).enrich() + def _insel_meb(self): """ Enrich the city with insel monthly energy balance results diff --git a/hub/unittests/test_heat_pump_results.py b/hub/unittests/test_heat_pump_results.py new file mode 100644 index 00000000..fa7d2d15 --- /dev/null +++ b/hub/unittests/test_heat_pump_results.py @@ -0,0 +1,74 @@ +""" +Test EnergySystemsFactory and various heatpump models +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Peter Yefi peteryefi@gmail.com +""" +from unittest import TestCase +from hub.imports.geometry_factory import GeometryFactory +from hub.imports.energy_systems_factory import EnergySystemsFactory +from hub.exports.energy_systems_factory import EnergySystemsExportFactory +from hub.imports.results_factory import ResultFactory +import os +from pandas.core.series import Series + +# User defined paramenters +user_input = { + 'StartYear': 2020, + 'EndYear': 2021, + 'MaximumHPEnergyInput': 8000, + 'HoursOfStorageAtMaxDemand': 1, + 'BuildingSuppTemp': 40, + 'TemperatureDifference': 15, + 'FuelLHV': 47100, + 'FuelPrice': 0.12, + 'FuelEF': 1887, + 'FuelDensity': 0.717, + 'HPSupTemp': 60 +} + + +class TestHeatPumpResults(TestCase): + """ + TestHeatPumpResults + """ + + def setUp(self) -> None: + """ + Test setup + :return: None + """ + city_file = "tests_data/C40_Final.gml" + self._output_path = "tests_data/as_user_output.csv" + self._city = GeometryFactory('citygml', path=city_file).city + EnergySystemsFactory('air source hp', self._city).enrich() + + def test_air_source_series_heat_pump_012_results(self): + EnergySystemsExportFactory(city=self._city, user_input=user_input, hp_model='012', + output_path=self._output_path).export() + ResultFactory('heat pump', self._city, self._output_path, '012').enrich() + + for energy_system in self._city.energy_systems: + self.assertIsNone(energy_system.water_to_water_hp) + if energy_system.air_source_hp.model == '012': + self.assertIsInstance(energy_system.air_source_hp.hp_monthly_fossil_consumption, Series) + self.assertEqual(energy_system.air_source_hp.hp_monthly_fossil_consumption.iloc[5], 1.51325583) + self.assertEqual(energy_system.air_source_hp.hp_monthly_fossil_consumption.iloc[12], 35.853598782915) + + def test_air_source_series_heat_pump_015_results(self): + EnergySystemsExportFactory(city=self._city, user_input=user_input, hp_model='140', + output_path=self._output_path).export() + ResultFactory('heat pump', self._city, self._output_path, '140').enrich() + + for energy_system in self._city.energy_systems: + self.assertIsNone(energy_system.water_to_water_hp) + if energy_system.air_source_hp.model == '140': + self.assertIsInstance(energy_system.air_source_hp.hp_monthly_fossil_consumption, Series) + self.assertEqual(energy_system.air_source_hp.hp_monthly_fossil_consumption.iloc[0], 7.91282225) + self.assertEqual(energy_system.air_source_hp.hp_monthly_fossil_consumption.iloc[2], 0.068873927) + + def tearDown(self) -> None: + try: + os.remove(self._output_path) + except OSError: + pass From 9209cf624a1daf94035a7294015d45b6c7496e69 Mon Sep 17 00:00:00 2001 From: KoaCWells Date: Mon, 20 Feb 2023 22:12:01 -0500 Subject: [PATCH 3/3] Fix import/export user factories, update repository/user.py for proper StartSession API call, fix setup.py --- hub/exports/user_factory.py | 5 ++-- hub/imports/user_factory.py | 4 ++-- hub/persistence/repositories/user.py | 5 ++-- setup.py | 36 ++++++++++++++-------------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/hub/exports/user_factory.py b/hub/exports/user_factory.py index 0c932418..68a3324d 100644 --- a/hub/exports/user_factory.py +++ b/hub/exports/user_factory.py @@ -4,8 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project CoderPeter Yefi peteryefi@gmail.com """ -from hub.persistence import UserRepo - +from hub.persistence import User class UserFactory: """ @@ -13,7 +12,7 @@ class UserFactory: """ def __init__(self, db_name, app_env, dotenv_path): - self._user_repo = UserRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) + self._user_repo = User(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) def login_user(self, email: str, password: str): """ diff --git a/hub/imports/user_factory.py b/hub/imports/user_factory.py index 3d900c1f..f4954189 100644 --- a/hub/imports/user_factory.py +++ b/hub/imports/user_factory.py @@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project CoderPeter Yefi peteryefi@gmail.com """ -from hub.persistence import UserRepo +from hub.persistence import User from hub.persistence import UserRoles @@ -14,7 +14,7 @@ class UserFactory: """ def __init__(self, db_name, app_env, dotenv_path): - self._user_repo = UserRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) + self._user_repo = User(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) def create_user(self, name: str, email: str, password: str, role: UserRoles): """ diff --git a/hub/persistence/repositories/user.py b/hub/persistence/repositories/user.py index dfa797d6..9504cc6c 100644 --- a/hub/persistence/repositories/user.py +++ b/hub/persistence/repositories/user.py @@ -114,7 +114,8 @@ class User(Repository): ).first() if user: if Auth.check_password(password, user[0].password): - return user[0] - return {'message': 'invalid login information'} + #return user[0] + return True + return False except SQLAlchemyError as err: logger.error(f'Error while fetching user by email: {err}') diff --git a/setup.py b/setup.py index c65667e9..615adc67 100644 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ setup( 'hub.imports', 'hub.imports.construction', 'hub.imports.construction.helpers', - 'hub.imports.construction.data_classes', + #'hub.imports.construction.data_classes', 'hub.imports.energy_systems', 'hub.imports.geometry', 'hub.imports.geometry.citygml_classes', @@ -87,23 +87,23 @@ setup( ('hub/config', glob.glob('hub/config/*.ini')), ('hub/catalog_factories/greenery/ecore_greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')), ('hub/data/construction.', glob.glob('hub/data/construction/*')), - ('hub/data/customized_imports/', glob.glob('hub/data/customized_imports/*.xml')), - ('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.xml')), - ('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.insel')), - ('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.xlsx')), - ('hub/data/energy_systems/*', glob.glob('hub/data/energy_systems/*.txt')), - ('hub/data/energy_systems/*', glob.glob('hub/data/energy_systems/*.yaml')), - ('hub/data/greenery/', glob.glob('hub/data/greenery/*.xml')), - ('hub/data/life_cycle_assessment/', glob.glob('hub/data/life_cycle_assessment/*.xml')), - ('hub/data/schedules/', glob.glob('hub/data/schedules/*.xml')), - ('hub/data/schedules/', glob.glob('hub/data/schedules/*.xlsx')), - ('hub/data/schedules/idf_files/', glob.glob('hub/data/schedules/idf_files/*.idf')), - ('hub/data/sensors/', glob.glob('hub/data/sensors/*.json')), - ('hub/data/usage/', glob.glob('hub/data/usage/*.xml')), - ('hub/data/usage/', glob.glob('hub/data/usage/*.xlsx')), - ('hub/data/weather/', glob.glob('hub/data/weather/*.dat')), - ('hub/data/weather/epw/', glob.glob('hub/data/weather/epw/*.epw')), - ('hub/data/weather/', glob.glob('hub/data/weather/*.dat')), + ('hub/data/customized_imports', glob.glob('hub/data/customized_imports/*.xml')), + ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.xml')), + ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.insel')), + ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.xlsx')), + ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.txt')), + ('hub/data/energy_systems', glob.glob('hub/data/energy_systems/*.yaml')), + ('hub/data/greenery', glob.glob('hub/data/greenery/*.xml')), + ('hub/data/life_cycle_assessment', glob.glob('hub/data/life_cycle_assessment/*.xml')), + ('hub/data/schedules', glob.glob('hub/data/schedules/*.xml')), + ('hub/data/schedules', glob.glob('hub/data/schedules/*.xlsx')), + ('hub/data/schedules/idf_files', glob.glob('hub/data/schedules/idf_files/*.idf')), + ('hub/data/sensors', glob.glob('hub/data/sensors/*.json')), + ('hub/data/usage', glob.glob('hub/data/usage/*.xml')), + ('hub/data/usage', glob.glob('hub/data/usage/*.xlsx')), + ('hub/data/weather', glob.glob('hub/data/weather/*.dat')), + ('hub/data/weather/epw', glob.glob('hub/data/weather/epw/*.epw')), + ('hub/data/weather', glob.glob('hub/data/weather/*.dat')), ('hub/exports/building_energy/idf_files', glob.glob('hub/exports/building_energy/idf_files/*.idf')), ('hub/exports/building_energy/idf_files', glob.glob('hub/exports/building_energy/idf_files/*.idd')), ('hub/helpers/data', glob.glob('hub/helpers/data/quebec_to_hub.json'))