Merge remote-tracking branch 'origin/master'
# Conflicts: # city_model_structure/building_demand/usage_zone.py # unittests/test_usage_factory.py
This commit is contained in:
commit
5e51947d6a
|
@ -6,27 +6,27 @@ Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
|
||||
class Catalog:
|
||||
"""
|
||||
Catalog name
|
||||
Catalogs base class not implemented instance of the Catalog base class, catalogs will inherit from this class.
|
||||
"""
|
||||
|
||||
@property
|
||||
def names(self):
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Base property to return the catalog entries names
|
||||
:return: not implemented error
|
||||
:return: Catalog names filter by category if provided
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Base property to return the catalog entries
|
||||
:return: not implemented error
|
||||
:return: Catalog content filter by category if provided
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Base property to return the catalog entry matching the given name
|
||||
:return: not implemented error
|
||||
:return: Catalog entry with the matching name
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -5,8 +5,9 @@ Copyright © 2022 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import TypeVar
|
||||
from catalogs.greenery.greenery_catalog import GreeneryCatalog
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
||||
class GreeneryCatalogFactory:
|
||||
"""
|
||||
|
@ -19,25 +20,17 @@ class GreeneryCatalogFactory:
|
|||
self._path = base_path
|
||||
|
||||
@property
|
||||
def _nrel(self) -> GreeneryCatalog:
|
||||
def _nrel(self):
|
||||
"""
|
||||
Return a greenery catalog using ecore as datasource
|
||||
Return a greenery catalog based in NREL using ecore as datasource
|
||||
:return: GreeneryCatalog
|
||||
"""
|
||||
return GreeneryCatalog((self._path / 'ecore_greenery_catalog.xml').resolve())
|
||||
|
||||
@property
|
||||
def catalog(self) -> GreeneryCatalog:
|
||||
def catalog(self) -> Catalog:
|
||||
"""
|
||||
Enrich the city given to the class using the class given handler
|
||||
:return: City
|
||||
:return: Catalog
|
||||
"""
|
||||
return getattr(self, self._file_type, lambda: None)
|
||||
|
||||
@property
|
||||
def catalog_debug(self) -> GreeneryCatalog:
|
||||
"""
|
||||
Enrich the city given to the class using the class given handler
|
||||
:return: City
|
||||
"""
|
||||
return GreeneryCatalog((self._path / 'ecore_greenery_catalog.xml').resolve())
|
||||
|
|
|
@ -104,7 +104,6 @@ class Polygon:
|
|||
if module != 0:
|
||||
angle = abs(np.arcsin(scalar_product / module))
|
||||
angle_sum += angle
|
||||
print(angle_sum)
|
||||
return abs(angle_sum - math.pi*2) < cte.EPSILON
|
||||
|
||||
def contains_polygon(self, polygon):
|
||||
|
@ -112,13 +111,10 @@ class Polygon:
|
|||
Determines if the given polygon is contained by the current polygon
|
||||
:return: boolean
|
||||
"""
|
||||
print('contains')
|
||||
for point in polygon.points:
|
||||
print(point.coordinates, self.contains_point(point))
|
||||
|
||||
for point in polygon.points:
|
||||
if not self.contains_point(point):
|
||||
return False
|
||||
print('Belong!')
|
||||
return True
|
||||
|
||||
@property
|
||||
|
|
|
@ -31,6 +31,7 @@ class ThermalOpening:
|
|||
self._inside_emissivity = None
|
||||
self._alpha_coefficient = None
|
||||
self._radiative_coefficient = None
|
||||
self._construction_name = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -290,3 +291,17 @@ class ThermalOpening:
|
|||
"""
|
||||
if value is not None:
|
||||
self._radiative_coefficient = float(value)
|
||||
|
||||
@property
|
||||
def construction_name(self):
|
||||
"""
|
||||
Get thermal opening construction name
|
||||
"""
|
||||
return self._construction_name
|
||||
|
||||
@construction_name.setter
|
||||
def construction_name(self, value):
|
||||
"""
|
||||
Set thermal opening construction name
|
||||
"""
|
||||
self._construction_name = value
|
||||
|
|
|
@ -8,8 +8,9 @@ from __future__ import annotations
|
|||
import sys
|
||||
import pickle
|
||||
import math
|
||||
from typing import List, Union
|
||||
import copy
|
||||
import pyproj
|
||||
from typing import List, Union
|
||||
from pyproj import Transformer
|
||||
from pathlib import Path
|
||||
|
||||
|
@ -18,6 +19,7 @@ from city_model_structure.city_object import CityObject
|
|||
from city_model_structure.city_objects_cluster import CityObjectsCluster
|
||||
from city_model_structure.buildings_cluster import BuildingsCluster
|
||||
from city_model_structure.fuel import Fuel
|
||||
from city_model_structure.iot.station import Station
|
||||
from city_model_structure.machine import Machine
|
||||
from city_model_structure.parts_consisting_building import PartsConsistingBuilding
|
||||
from city_model_structure.subway_entrance import SubwayEntrance
|
||||
|
@ -433,3 +435,9 @@ class City:
|
|||
return lca_material
|
||||
return None
|
||||
|
||||
@property
|
||||
def copy(self) -> City:
|
||||
"""
|
||||
Get a copy of the current city
|
||||
"""
|
||||
return copy.deepcopy(self)
|
||||
|
|
|
@ -44,6 +44,14 @@ class CityObject:
|
|||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set building name
|
||||
:return: str
|
||||
"""
|
||||
self._name = value
|
||||
|
||||
@property
|
||||
def lod(self) -> int:
|
||||
"""
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
"""
|
||||
Energy Sensor module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from city_model_structure.iot.sensor import Sensor
|
||||
|
||||
|
||||
class ConcordiaEnergySensor(Sensor):
|
||||
"""
|
||||
Concordia energy sensor.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._interval = 5
|
||||
self._interval_units = 'minutes'
|
||||
self._type = 'ConcordiaEnergySensor'
|
||||
self._units = 'kW'
|
||||
self._measures = pd.DataFrame(columns=["Date time", "Energy consumption"])
|
||||
|
||||
@property
|
||||
def measures(self) -> pd.DataFrame:
|
||||
"""
|
||||
Get sensor measures [yyyy-mm-dd, hh:mm:ss kW]
|
||||
:return: DataFrame["Date time", "Energy consumption"]
|
||||
"""
|
||||
return self._measures
|
||||
|
||||
@measures.deleter
|
||||
def measures(self):
|
||||
"""
|
||||
Delete sensor measures
|
||||
"""
|
||||
self._measures.drop = None
|
||||
|
||||
def add_period(self, measures):
|
||||
"""
|
||||
Add or update a period measures to the dataframe
|
||||
"""
|
||||
measures = self._measures.append(measures, ignore_index=True)
|
||||
self._measures = measures.drop_duplicates('Date time', keep='last')
|
|
@ -1,45 +0,0 @@
|
|||
"""
|
||||
Gas Flow Sensor module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from city_model_structure.iot.sensor import Sensor
|
||||
|
||||
|
||||
class ConcordiaGasFlowSensor(Sensor):
|
||||
"""
|
||||
Concordia gas flow sensor.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._interval = 5
|
||||
self._interval_units = 'minutes'
|
||||
self._type = 'ConcordiaGasFlowSensor'
|
||||
self._units = 'm3'
|
||||
self._measures = pd.DataFrame(columns=["Date time", "Gas Flow Cumulative Monthly"])
|
||||
|
||||
@property
|
||||
def measures(self) -> pd.DataFrame:
|
||||
"""
|
||||
Get sensor measures [yyyy-mm-dd, hh:mm:ss m3]
|
||||
:return: DataFrame["Date time", "Gas Flow Cumulative Monthly"]
|
||||
"""
|
||||
return self._measures
|
||||
|
||||
@measures.deleter
|
||||
def measures(self):
|
||||
"""
|
||||
Delete sensor measures
|
||||
"""
|
||||
self._measures.drop = None
|
||||
|
||||
def add_period(self, measures):
|
||||
"""
|
||||
Add or update a period measures to the dataframe
|
||||
"""
|
||||
measures = self._measures.append(measures, ignore_index=True)
|
||||
self._measures = measures.drop_duplicates('Date time', keep='last')
|
|
@ -1,45 +0,0 @@
|
|||
"""
|
||||
Temperature Sensor module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from city_model_structure.iot.sensor import Sensor
|
||||
|
||||
|
||||
class ConcordiaTemperatureSensor(Sensor):
|
||||
"""
|
||||
Concordia temperature sensor.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._interval = 5
|
||||
self._interval_units = 'minutes'
|
||||
self._type = 'ConcordiaTemperatureSensor'
|
||||
self._units = 'Celsius'
|
||||
self._measures = pd.DataFrame(columns=["Date time", "Temperature"])
|
||||
|
||||
@property
|
||||
def measures(self) -> pd.DataFrame:
|
||||
"""
|
||||
Get sensor measures [yyyy-mm-dd, hh:mm:ss Celsius]
|
||||
:return: DataFrame["Date time", "Temperature"]
|
||||
"""
|
||||
return self._measures
|
||||
|
||||
@measures.deleter
|
||||
def measures(self):
|
||||
"""
|
||||
Delete sensor measures
|
||||
"""
|
||||
self._measures.drop = None
|
||||
|
||||
def add_period(self, measures):
|
||||
"""
|
||||
Add or update a period measures to the dataframe
|
||||
"""
|
||||
measures = self._measures.append(measures, ignore_index=True)
|
||||
self._measures = measures.drop_duplicates('Date time', keep='last')
|
|
@ -5,6 +5,8 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
"""
|
||||
|
||||
from helpers.location import Location
|
||||
from city_model_structure.iot.sensor_measure import SensorMeasure
|
||||
from city_model_structure.iot.sensor_type import SensorType
|
||||
|
||||
|
||||
class Sensor:
|
||||
|
@ -37,7 +39,7 @@ class Sensor:
|
|||
self._name = str(value)
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
def type(self) -> SensorType:
|
||||
"""
|
||||
Get sensor type
|
||||
:return: str
|
||||
|
@ -69,7 +71,7 @@ class Sensor:
|
|||
self._location = value
|
||||
|
||||
@property
|
||||
def measures(self):
|
||||
def measures(self) -> [SensorMeasure]:
|
||||
"""
|
||||
Raises not implemented error
|
||||
"""
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,7 +12,8 @@ class ThermalOpeningArchetype:
|
|||
def __init__(self, conductivity=None, frame_ratio=None, g_value=None, thickness=None,
|
||||
back_side_solar_transmittance_at_normal_incidence=None,
|
||||
front_side_solar_transmittance_at_normal_incidence=None, overall_u_value=None,
|
||||
openable_ratio=None, inside_emissivity=None, alpha_coefficient=None, radiative_coefficient=None):
|
||||
openable_ratio=None, inside_emissivity=None, alpha_coefficient=None, radiative_coefficient=None,
|
||||
construction_name=None):
|
||||
self._conductivity = conductivity
|
||||
self._frame_ratio = frame_ratio
|
||||
self._g_value = g_value
|
||||
|
@ -24,6 +25,7 @@ class ThermalOpeningArchetype:
|
|||
self._inside_emissivity = inside_emissivity
|
||||
self._alpha_coefficient = alpha_coefficient
|
||||
self._radiative_coefficient = radiative_coefficient
|
||||
self._construction_name = construction_name
|
||||
|
||||
@property
|
||||
def conductivity(self):
|
||||
|
@ -112,3 +114,17 @@ class ThermalOpeningArchetype:
|
|||
:return: float
|
||||
"""
|
||||
return self._radiative_coefficient
|
||||
|
||||
@property
|
||||
def construction_name(self):
|
||||
"""
|
||||
Get thermal opening construction name
|
||||
"""
|
||||
return self._construction_name
|
||||
|
||||
@construction_name.setter
|
||||
def construction_name(self, value):
|
||||
"""
|
||||
Set thermal opening construction name
|
||||
"""
|
||||
self._construction_name = value
|
||||
|
|
|
@ -109,6 +109,7 @@ class NrelPhysicsInterface:
|
|||
if 'window' in construction and construction['window'] is not None:
|
||||
window_ratio = construction['window_ratio']['#text']
|
||||
w_lib = self._search_construction_type('window', construction['window'])
|
||||
window_construction_name = w_lib['@name']
|
||||
frame_ratio = w_lib['frame_ratio']['#text']
|
||||
if 'conductivity' in w_lib:
|
||||
conductivity = w_lib['conductivity']['#text']
|
||||
|
@ -128,7 +129,8 @@ class NrelPhysicsInterface:
|
|||
thickness=thickness, back_side_solar_transmittance_at_normal_incidence=
|
||||
back_side_solar_transmittance_at_normal_incidence,
|
||||
front_side_solar_transmittance_at_normal_incidence=
|
||||
front_side_solar_transmittance_at_normal_incidence)
|
||||
front_side_solar_transmittance_at_normal_incidence,
|
||||
construction_name=window_construction_name)
|
||||
else:
|
||||
overall_u_value = w_lib['overall_u_value']['#text']
|
||||
units = w_lib['overall_u_value']['@units']
|
||||
|
|
|
@ -99,6 +99,7 @@ class UsPhysicsParameters(NrelPhysicsInterface):
|
|||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if thermal_boundary_archetype.thermal_opening_archetype is not None:
|
||||
thermal_opening_archetype = thermal_boundary_archetype.thermal_opening_archetype
|
||||
thermal_opening.construction_name = thermal_opening_archetype.construction_name
|
||||
thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio
|
||||
thermal_opening.g_value = thermal_opening_archetype.g_value
|
||||
thermal_opening.conductivity = thermal_opening_archetype.conductivity
|
||||
|
|
|
@ -28,7 +28,7 @@ class ConstructionFactory:
|
|||
def _nrcan(self):
|
||||
"""
|
||||
Enrich the city by using NRCAN information
|
||||
:alert: NRCAN handler only contains simplified construction information
|
||||
:alert: NRCAN handler only contains simplified construction information (residential)
|
||||
"""
|
||||
CaPhysicsParameters(self._city, self._base_path).enrich_buildings()
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
from numpy import inf
|
||||
#from rhino3dm import *
|
||||
#from rhino3dm._rhino3dm import MeshType
|
||||
from rhino3dm import *
|
||||
from rhino3dm._rhino3dm import MeshType
|
||||
|
||||
from city_model_structure.attributes.point import Point
|
||||
import numpy as np
|
||||
|
||||
|
@ -14,7 +15,6 @@ from city_model_structure.attributes.polygon import Polygon
|
|||
from city_model_structure.building import Building
|
||||
from city_model_structure.city import City
|
||||
from city_model_structure.building_demand.surface import Surface as LibsSurface
|
||||
from helpers.constants import EPSILON
|
||||
from imports.geometry.helpers.geometry_helper import GeometryHelper
|
||||
|
||||
|
||||
|
@ -29,7 +29,6 @@ class Rhino:
|
|||
@staticmethod
|
||||
def _in_perimeter(wall, corner):
|
||||
res = wall.contains_point(Point(corner))
|
||||
print(f'belong: {res} wall:({wall.coordinates}) corner: ({corner})')
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
|
@ -96,7 +95,6 @@ class Rhino:
|
|||
windows.append(Polygon(surface.perimeter_polygon.inverse))
|
||||
else:
|
||||
buildings.append(rhino_object)
|
||||
print(f'windows: {len(windows)}')
|
||||
# todo: this method will be pretty inefficient
|
||||
for hole in windows:
|
||||
corner = hole.coordinates[0]
|
||||
|
|
|
@ -6,7 +6,7 @@ Contributor Mohammad Reza mohammad.seyedabadi@mail.concordia.ca
|
|||
"""
|
||||
import xmltodict
|
||||
from pathlib import Path
|
||||
from city_model_structure.building_demand.material import Material
|
||||
from city_model_structure.lca_material import LcaMaterial as LMaterial
|
||||
|
||||
class LcaMaterial:
|
||||
def __init__(self, city, base_path):
|
||||
|
@ -15,14 +15,14 @@ class LcaMaterial:
|
|||
self._lca = None
|
||||
|
||||
def enrich(self):
|
||||
self._city.materials = []
|
||||
self._city.lca_materials = []
|
||||
path = Path(self._base_path / 'lca_data.xml').resolve()
|
||||
|
||||
with open(path) as xml:
|
||||
self._lca = xmltodict.parse(xml.read())
|
||||
|
||||
for material in self._lca["library"]["building_materials"]['material']:
|
||||
_material = Material()
|
||||
_material = LMaterial()
|
||||
_material.type = material['@type']
|
||||
_material.id = material['@id']
|
||||
_material.name = material['@name']
|
||||
|
@ -37,4 +37,4 @@ class LcaMaterial:
|
|||
_material.cost=material['cost']['#text']
|
||||
_material._cost_unit=material['cost']['@unit']
|
||||
|
||||
self._city.materials.append(_material)
|
||||
self._city.lca_materials.append(_material)
|
||||
|
|
|
@ -5,9 +5,6 @@ Copyright © 2021 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from imports.sensors.concordia_energy_consumption import ConcordiaEnergyConsumption
|
||||
from imports.sensors.concordia_gas_flow import ConcordiaGasFlow
|
||||
from imports.sensors.concordia_temperature import ConcordiaTemperature
|
||||
|
||||
|
||||
class SensorsFactory:
|
||||
|
@ -26,19 +23,19 @@ class SensorsFactory:
|
|||
"""
|
||||
Enrich the city by using concordia energy consumption sensors as data source
|
||||
"""
|
||||
ConcordiaEnergyConsumption(self._city, self._end_point, self._base_path)
|
||||
raise NotImplementedError('need to be reimplemented')
|
||||
|
||||
def _cgf(self):
|
||||
"""
|
||||
Enrich the city by using concordia gas flow sensors as data source
|
||||
"""
|
||||
ConcordiaGasFlow(self._city, self._end_point, self._base_path)
|
||||
raise NotImplementedError('need to be reimplemented')
|
||||
|
||||
def _ct(self):
|
||||
"""
|
||||
Enrich the city by using concordia temperature sensors as data source
|
||||
"""
|
||||
ConcordiaTemperature(self._city, self._end_point, self._base_path)
|
||||
raise NotImplementedError('need to be reimplemented')
|
||||
|
||||
def enrich(self):
|
||||
"""
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
"""
|
||||
TestSensorsFactory test and validate the city model structure schedules
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2021 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from city_model_structure.building import Building
|
||||
from city_model_structure.buildings_cluster import BuildingsCluster
|
||||
from city_model_structure.city import City
|
||||
from imports.sensors_factory import SensorsFactory
|
||||
|
||||
|
||||
class TestSensorsFactory(TestCase):
|
||||
"""
|
||||
TestSchedulesFactory TestCase
|
||||
"""
|
||||
|
||||
def setUp(self) -> None:
|
||||
"""
|
||||
Configure test environment
|
||||
:return:
|
||||
"""
|
||||
self._city = TestSensorsFactory._mockup_city()
|
||||
self._end_point = (Path(__file__).parent /
|
||||
'tests_data/EV-GM energy demand weekly report_01-26-20_04-30.csv').resolve()
|
||||
|
||||
@staticmethod
|
||||
def _mockup_city():
|
||||
lower_corner = [0, 0, 0]
|
||||
upper_corner = [10, 10, 10]
|
||||
srs_name = 'Mockup_city'
|
||||
buildings = []
|
||||
lod = 2
|
||||
surfaces = []
|
||||
year_of_construction = 2021
|
||||
function = "office"
|
||||
city = City(lower_corner, upper_corner, srs_name)
|
||||
buildings.append(Building("EV", lod, surfaces, year_of_construction, function, lower_corner))
|
||||
buildings.append(Building("GM", lod, surfaces, year_of_construction, function, lower_corner))
|
||||
buildings.append(Building("MB", lod, surfaces, year_of_construction, function, lower_corner))
|
||||
for building in buildings:
|
||||
city.add_city_object(building)
|
||||
buildings_cluster = BuildingsCluster("GM_MB_EV", buildings)
|
||||
city.add_city_objects_cluster(buildings_cluster)
|
||||
return city
|
||||
|
||||
def test_city_with_sensors(self):
|
||||
"""
|
||||
Load concordia sensors and verify it
|
||||
"""
|
||||
SensorsFactory('cec', self._city, self._end_point).enrich()
|
||||
SensorsFactory('cgf', self._city, self._end_point).enrich()
|
||||
SensorsFactory('ct', self._city, self._end_point).enrich()
|
||||
for city_object in self._city.city_objects:
|
||||
print(city_object.name, len(city_object.sensors))
|
||||
for sensor in city_object.sensors:
|
||||
print(sensor.name)
|
Loading…
Reference in New Issue
Block a user