diff --git a/data/occupancy/demo_schedules.xlsx b/data/occupancy/demo_schedules.xlsx new file mode 100644 index 00000000..8d64d7ed Binary files /dev/null and b/data/occupancy/demo_schedules.xlsx differ diff --git a/occupancy/occupancy_factory.py b/occupancy/occupancy_factory.py new file mode 100644 index 00000000..f51a08d6 --- /dev/null +++ b/occupancy/occupancy_factory.py @@ -0,0 +1,30 @@ +""" +PhysicsFactory retrieve the specific physics module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca +""" + +from pathlib import Path +from occupancy.occupancy_feeders.demo_occupancy_parameters import DemoOccupancyParameters + + +class OccupancyFactory: + """ + PhysicsFactor class + """ + def __init__(self, handler, city, base_path=Path(Path(__file__).parent.parent / 'data/occupancy')): + self._handler = '_' + handler.lower().replace(' ', '_') + self._city = city + self._base_path = base_path + self.factory() + + def _demo(self): + # TODO: what to do? + DemoOccupancyParameters(self._city, self._base_path) + + def factory(self): + """ + Enrich the city with the physics information + :return: None + """ + getattr(self, self._handler, lambda: None)() diff --git a/occupancy/occupancy_feeders/demo_occupancy_parameters.py b/occupancy/occupancy_feeders/demo_occupancy_parameters.py new file mode 100644 index 00000000..cecc0e8e --- /dev/null +++ b/occupancy/occupancy_feeders/demo_occupancy_parameters.py @@ -0,0 +1,34 @@ +""" +PhysicsFactory retrieve the specific physics module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca +""" +import pandas as pd +from occupancy.occupancy_feeders.helpers.occupancy_helper import OccupancyHelper + + +class DemoOccupancyParameters: + + def __init__(self, city, base_path): + self._city = city + self._demo_schedules_path = base_path / 'demo_schedules.xlsx' + xls = pd.ExcelFile(self._demo_schedules_path) + for building in city.buildings: + occupancy = pd.read_excel(xls, sheet_name=OccupancyHelper.pluto_occupancy_function(building.function), + skiprows=[0, 1, 2, 3]) + for index, row in occupancy.iterrows(): + building.week_day_schedule = [row['1am'], row['2am'], row['3am'], row['4am'], row['5am'], row['6am'], + row['7am'], row['8am'], row['9am'], row['10am'], row['11am'], row['12am'], + row['1pm'], row['2pm'], row['3pm'], row['4pm'], row['5pm'], row['6pm'], + row['7pm'], row['8pm'], row['9pm'], row['10pm'], row['11pm'], row['12pm']] + row = occupancy.iloc[index + 1] + building.saturday_schedule = [row['1am'], row['2am'], row['3am'], row['4am'], row['5am'], row['6am'], + row['7am'], row['8am'], row['9am'], row['10am'], row['11am'], row['12am'], + row['1pm'], row['2pm'], row['3pm'], row['4pm'], row['5pm'], row['6pm'], + row['7pm'], row['8pm'], row['9pm'], row['10pm'], row['11pm'], row['12pm']] + row = occupancy.iloc[index + 2] + building.sunday_schedule = [row['1am'], row['2am'], row['3am'], row['4am'], row['5am'], row['6am'], + row['7am'], row['8am'], row['9am'], row['10am'], row['11am'], row['12am'], + row['1pm'], row['2pm'], row['3pm'], row['4pm'], row['5pm'], row['6pm'], + row['7pm'], row['8pm'], row['9pm'], row['10pm'], row['11pm'], row['12pm']] + break diff --git a/occupancy/occupancy_feeders/helpers/occupancy_helper.py b/occupancy/occupancy_feeders/helpers/occupancy_helper.py new file mode 100644 index 00000000..ffadb7ca --- /dev/null +++ b/occupancy/occupancy_feeders/helpers/occupancy_helper.py @@ -0,0 +1,21 @@ +""" +Geometry helper +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca +""" + + +class OccupancyHelper: + occupancy_function = { + 'I1': 'C-2 Health', + 'C1': 'C-12 Residential' + } + + @staticmethod + def pluto_occupancy_function(building_pluto_function): + """ + Get nrel function from the given pluto function + :param building_pluto_function: str + :return: str + """ + return OccupancyHelper.occupancy_function[building_pluto_function] diff --git a/tests/test_idf.py b/tests/test_idf.py index bc30987b..a7376baa 100644 --- a/tests/test_idf.py +++ b/tests/test_idf.py @@ -40,6 +40,5 @@ class TestIdf(TestCase): _idf.add_zone(building.name) for surface in building.surfaces: _idf.add_surface(surface, building.name) - _idf.run() diff --git a/tests/test_occupancy_factory.py b/tests/test_occupancy_factory.py new file mode 100644 index 00000000..a8dc53f8 --- /dev/null +++ b/tests/test_occupancy_factory.py @@ -0,0 +1,45 @@ +""" +TestOccupancyFactory test and validate the city model structure occupancy parameters +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca +""" +import os +from pathlib import Path +from unittest import TestCase + +from geometry.geometry_factory import GeometryFactory +from occupancy.occupancy_factory import OccupancyFactory + + +class TestOccupancyFactory(TestCase): + """ + TestOccupancyFactory TestCase + """ + + def setUp(self) -> None: + """ + Test setup + :return: None + """ + self._city_gml = None + self._example_path = (Path(__file__).parent.parent / 'tests_data').resolve() + + def _get_citygml(self): + if self._city_gml is None: + file_path = (self._example_path / 'buildings.gml').resolve() + self._city_gml = GeometryFactory('citygml', file_path).city + self.assertIsNotNone(self._city_gml, 'city is none') + return self._city_gml + + def test_demo(self): + city = self._get_citygml() + OccupancyFactory('demo', city) + for building in city.buildings: + self.assertTrue(building.week_day_schedule) + self.assertTrue(building.saturday_schedule) + self.assertTrue(building.sunday_schedule) + print("building " + building.name + " [" + building.function + "]") + print(building.week_day_schedule) + print(building.saturday_schedule) + print(building.sunday_schedule) +