diff --git a/hub/catalog_factories/data_models/construction/archetype.py b/hub/catalog_factories/data_models/construction/archetype.py index 39b2e4ce..4e4d1e19 100644 --- a/hub/catalog_factories/data_models/construction/archetype.py +++ b/hub/catalog_factories/data_models/construction/archetype.py @@ -132,3 +132,24 @@ class Archetype: :return: float """ return self._infiltration_rate_for_ventilation_system_on + + def to_dictionary(self): + """Class content to dictionary""" + _constructions = [] + for _construction in self.constructions: + _constructions.append(_construction.to_dictionary()) + content = {'Archetype': {'id': self.id, + 'name': self.name, + 'function': self.function, + 'climate zone': self.climate_zone, + 'period of construction': self.construction_period, + 'average storey height [m]': self.average_storey_height, + 'thermal capacity [J/m3K]': self.thermal_capacity, + 'extra loses due to thermal bridges [W/m2K]': self.extra_loses_due_to_thermal_bridges, + 'indirect heated ratio': self.indirect_heated_ratio, + 'infiltration rate for ventilation off [ACH]': self.infiltration_rate_for_ventilation_system_off, + 'infiltration rate for ventilation on [ACH]': self.infiltration_rate_for_ventilation_system_on, + 'constructions': _constructions + } + } + return content diff --git a/hub/catalog_factories/data_models/construction/construction.py b/hub/catalog_factories/data_models/construction/construction.py index c178de7c..34f6e348 100644 --- a/hub/catalog_factories/data_models/construction/construction.py +++ b/hub/catalog_factories/data_models/construction/construction.py @@ -4,6 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca """ + from hub.catalog_factories.data_models.construction.layer import Layer from hub.catalog_factories.data_models.construction.window import Window @@ -67,3 +68,21 @@ class Construction: :return: Window """ return self._window + + def to_dictionary(self): + """Class content to dictionary""" + _layers = [] + for _layer in self.layers: + _layers.append(_layer.to_dictionary()) + _window = None + if self.window is not None: + _window = self.window.to_dictionary() + content = {'Construction': {'id': self.id, + 'name': self.name, + 'type': self.type, + 'window ratio': self.window_ratio, + 'window': _window, + 'layers': _layers + } + } + return content diff --git a/hub/catalog_factories/data_models/construction/content.py b/hub/catalog_factories/data_models/construction/content.py index 8fcb4ad1..dfb2753f 100644 --- a/hub/catalog_factories/data_models/construction/content.py +++ b/hub/catalog_factories/data_models/construction/content.py @@ -43,3 +43,21 @@ class Content: All windows in the catalog """ return self._windows + + def to_dictionary(self): + """Class content to dictionary""" + _archetypes = [] + for _archetype in self.archetypes: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return content + + def __str__(self): + """Print content""" + _archetypes = [] + for _archetype in self.archetypes: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return str(content) diff --git a/hub/catalog_factories/data_models/construction/layer.py b/hub/catalog_factories/data_models/construction/layer.py index a55bdde0..2be8556b 100644 --- a/hub/catalog_factories/data_models/construction/layer.py +++ b/hub/catalog_factories/data_models/construction/layer.py @@ -5,6 +5,8 @@ Copyright © 2022 Concordia CERC group Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca """ +from hub.catalog_factories.data_models.construction.material import Material + class Layer: """ @@ -33,7 +35,7 @@ class Layer: return self._name @property - def material(self): + def material(self) -> Material: """ Get layer material :return: Material @@ -47,3 +49,13 @@ class Layer: :return: None or float """ return self._thickness + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Layer': {'id': self.id, + 'name': self.name, + 'thickness [m]': self.thickness, + 'material': self.material.to_dictionary() + } + } + return content diff --git a/hub/catalog_factories/data_models/construction/material.py b/hub/catalog_factories/data_models/construction/material.py index 5109fe7c..932c1119 100644 --- a/hub/catalog_factories/data_models/construction/material.py +++ b/hub/catalog_factories/data_models/construction/material.py @@ -110,3 +110,19 @@ class Material: :return: None or float """ return self._thermal_resistance + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Material': {'id': self.id, + 'name': self.name, + 'is no-mass': self.no_mass, + 'density [kg/m3]': self.density, + 'specific heat [J/kgK]': self.specific_heat, + 'conductivity [W/mK]': self.conductivity, + 'thermal resistance [m2K/W]': self.thermal_resistance, + 'solar absorptance': self.solar_absorptance, + 'thermal absorptance': self.thermal_absorptance, + 'visible absorptance': self.visible_absorptance + } + } + return content diff --git a/hub/catalog_factories/data_models/construction/window.py b/hub/catalog_factories/data_models/construction/window.py index 96804be4..e446d0c4 100644 --- a/hub/catalog_factories/data_models/construction/window.py +++ b/hub/catalog_factories/data_models/construction/window.py @@ -64,4 +64,16 @@ class Window: Get transparent surface type, 'window' or 'skylight' :return: str """ - return self.type + return self._type + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Window': {'id': self.id, + 'name': self.name, + 'type': self.type, + 'frame ratio': self.frame_ratio, + 'g-value': self.g_value, + 'overall U value [W/m2K]': self.overall_u_value + } + } + return content diff --git a/hub/catalog_factories/data_models/cost/archetype.py b/hub/catalog_factories/data_models/cost/archetype.py index 7749f400..1667c8ec 100644 --- a/hub/catalog_factories/data_models/cost/archetype.py +++ b/hub/catalog_factories/data_models/cost/archetype.py @@ -102,7 +102,7 @@ class Archetype: @property def end_of_life_cost(self): """ - Get end of life cost in given currency + Get end of life cost in given currency per m2 :return: float """ return self._end_of_life_cost @@ -114,3 +114,19 @@ class Archetype: :return: Income """ return self._income + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Archetype': {'name': self.name, + 'level of detail': self.lod, + 'municipality': self.municipality, + 'country': self.country, + 'currency': self.currency, + 'function': self.function, + 'capital cost': self.capital_cost.to_dictionary(), + 'operational cost': self.operational_cost.to_dictionary(), + 'end of life cost [currency/m2]': self.end_of_life_cost, + 'income': self.income.to_dictionary() + } + } + return content diff --git a/hub/catalog_factories/data_models/cost/capital_cost.py b/hub/catalog_factories/data_models/cost/capital_cost.py index e68a71d1..7d4c8b82 100644 --- a/hub/catalog_factories/data_models/cost/capital_cost.py +++ b/hub/catalog_factories/data_models/cost/capital_cost.py @@ -51,3 +51,16 @@ class CapitalCost: if chapter.chapter_type == name: return chapter raise KeyError(f'Chapter name {name} not found') + + def to_dictionary(self): + """Class content to dictionary""" + _chapters = [] + for _chapter in self.general_chapters: + _chapters.append(_chapter.to_dictionary()) + content = {'Capital cost': {'design allowance': self.design_allowance, + 'overhead and profit': self.overhead_and_profit, + 'chapters': _chapters + } + } + + return content diff --git a/hub/catalog_factories/data_models/cost/chapter.py b/hub/catalog_factories/data_models/cost/chapter.py index a1a35f8d..fee87281 100644 --- a/hub/catalog_factories/data_models/cost/chapter.py +++ b/hub/catalog_factories/data_models/cost/chapter.py @@ -43,3 +43,15 @@ class Chapter: if item.type == name: return item raise KeyError(f'Item name {name} not found') + + def to_dictionary(self): + """Class content to dictionary""" + _items = [] + for _item in self.items: + _items.append(_item.to_dictionary()) + content = {'Chapter': {'chapter type': self.chapter_type, + 'items': _items + } + } + + return content diff --git a/hub/catalog_factories/data_models/cost/content.py b/hub/catalog_factories/data_models/cost/content.py index e124acd7..8e5b2dab 100644 --- a/hub/catalog_factories/data_models/cost/content.py +++ b/hub/catalog_factories/data_models/cost/content.py @@ -20,3 +20,21 @@ class Content: All archetypes in the catalog """ return self._archetypes + + def to_dictionary(self): + """Class content to dictionary""" + _archetypes = [] + for _archetype in self.archetypes: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return content + + def __str__(self): + """Print content""" + _archetypes = [] + for _archetype in self.archetypes: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return str(content) diff --git a/hub/catalog_factories/data_models/cost/fuel.py b/hub/catalog_factories/data_models/cost/fuel.py index b16fb590..55b4723b 100644 --- a/hub/catalog_factories/data_models/cost/fuel.py +++ b/hub/catalog_factories/data_models/cost/fuel.py @@ -43,10 +43,10 @@ class Fuel: @property def fixed_power(self) -> Union[None, float]: """ - Get fixed operational costs depending on the peak power consumed in currency per month per kW + Get fixed operational costs depending on the peak power consumed in currency per month per W :return: None or float """ - return self._fixed_power + return self._fixed_power/1000 @property def variable(self) -> Union[tuple[None, None], tuple[float, str]]: @@ -55,3 +55,15 @@ class Fuel: :return: None, None or float, str """ return self._variable, self._variable_units + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Fuel': {'fuel type': self.type, + 'fixed operational costs [currency/month]': self.fixed_monthly, + 'fixed operational costs depending on the peak power consumed [currency/month W]': self.fixed_power, + 'variable operational costs': self.variable[0], + 'units': self.variable[1] + } + } + + return content diff --git a/hub/catalog_factories/data_models/cost/income.py b/hub/catalog_factories/data_models/cost/income.py index 5962b579..a053512a 100644 --- a/hub/catalog_factories/data_models/cost/income.py +++ b/hub/catalog_factories/data_models/cost/income.py @@ -63,3 +63,15 @@ class Income: :return: None or float """ return self._reductions_tax + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Income': {'construction subsidy [%]': self.construction_subsidy, + 'hvac subsidy [%]': self.hvac_subsidy, + 'photovoltaic subsidy [%]': self.photovoltaic_subsidy, + 'electricity export [currency/J]': self.electricity_export, + 'reductions tax': self.reductions_tax + } + } + + return content diff --git a/hub/catalog_factories/data_models/cost/item_description.py b/hub/catalog_factories/data_models/cost/item_description.py index 7f69fb5f..a193bb23 100644 --- a/hub/catalog_factories/data_models/cost/item_description.py +++ b/hub/catalog_factories/data_models/cost/item_description.py @@ -69,3 +69,18 @@ class ItemDescription: :return: None or float """ return self._lifetime + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Item': {'type': self.type, + 'initial investment': self.initial_investment[0], + 'initial investment units': self.initial_investment[1], + 'refurbishment': self.refurbishment[0], + 'refurbishment units': self.refurbishment[1], + 'reposition': self.reposition[0], + 'reposition units': self.reposition[1], + 'life time [years]': self.lifetime + } + } + + return content diff --git a/hub/catalog_factories/data_models/cost/operational_cost.py b/hub/catalog_factories/data_models/cost/operational_cost.py index b514d034..9b20466e 100644 --- a/hub/catalog_factories/data_models/cost/operational_cost.py +++ b/hub/catalog_factories/data_models/cost/operational_cost.py @@ -59,3 +59,18 @@ class OperationalCost: :return: float """ return self._co2 + + def to_dictionary(self): + """Class content to dictionary""" + _fuels = [] + for _fuel in self.fuels: + _fuels.append(_fuel.to_dictionary()) + content = {'Maintenance': {'fuels': _fuels, + 'cost of maintaining the heating system [currency/W]': self.maintenance_heating, + 'cost of maintaining the cooling system [currency/W]': self.maintenance_cooling, + 'cost of maintaining the PV system [currency/W]': self.maintenance_pv, + 'cost of CO2 emissions [currency/kgCO2]': self.co2 + } + } + + return content diff --git a/hub/catalog_factories/data_models/energy_systems/archetype.py b/hub/catalog_factories/data_models/energy_systems/archetype.py index cd3f7c15..cdfcea1f 100644 --- a/hub/catalog_factories/data_models/energy_systems/archetype.py +++ b/hub/catalog_factories/data_models/energy_systems/archetype.py @@ -43,3 +43,15 @@ class Archetype: :return: [Equipment] """ return self._systems + + def to_dictionary(self): + """Class content to dictionary""" + _systems = [] + for _system in self.systems: + _systems.append(_system.to_dictionary()) + content = {'Archetype': {'name': self.name, + 'level of detail': self.lod, + 'systems': _systems + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/content.py b/hub/catalog_factories/data_models/energy_systems/content.py index 06b6a085..8042a73d 100644 --- a/hub/catalog_factories/data_models/energy_systems/content.py +++ b/hub/catalog_factories/data_models/energy_systems/content.py @@ -51,3 +51,21 @@ class Content: All emission equipments in the catalog """ return self._emissions + + def to_dictionary(self): + """Class content to dictionary""" + _archetypes = [] + for _archetype in self.archetypes: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return content + + def __str__(self): + """Print content""" + _archetypes = [] + for _archetype in self.archetypes: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return str(content) diff --git a/hub/catalog_factories/data_models/energy_systems/distribution_system.py b/hub/catalog_factories/data_models/energy_systems/distribution_system.py index 3f22a520..aa195649 100644 --- a/hub/catalog_factories/data_models/energy_systems/distribution_system.py +++ b/hub/catalog_factories/data_models/energy_systems/distribution_system.py @@ -29,14 +29,6 @@ class DistributionSystem: """ return self._system_id - @id.setter - def id(self, value): - """ - Set system id - :param value: float - """ - self._system_id = value - @property def name(self): """ @@ -45,14 +37,6 @@ class DistributionSystem: """ return self._name - @name.setter - def name(self, value): - """ - Set name - :param value: string - """ - self._name = value - @property def type(self): """ @@ -81,7 +65,7 @@ class DistributionSystem: def distribution_consumption_variable_flow(self): """ Get distribution_consumption if the pump or fan work at variable mass or volume flow in ratio - over energy produced (Wh/Wh) + over energy produced (J/J) :return: float """ return self._distribution_consumption_variable_flow @@ -89,7 +73,20 @@ class DistributionSystem: @property def heat_losses(self): """ - Get heat_losses in ratio over energy produced + Get heat_losses in ratio over energy produced in J/J :return: float """ return self._heat_losses + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Layer': {'id': self.id, + 'name': self.name, + 'type': self.type, + 'supply temperature [Celsius]': self.supply_temperature, + 'distribution consumption if fix flow over peak power [W/W]': self.distribution_consumption_fix_flow, + 'distribution consumption if variable flow over peak power [J/J]': self.distribution_consumption_variable_flow, + 'heat losses per energy produced [J/J]': self.heat_losses + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/emission_system.py b/hub/catalog_factories/data_models/energy_systems/emission_system.py index f869a4a4..5e9d2865 100644 --- a/hub/catalog_factories/data_models/energy_systems/emission_system.py +++ b/hub/catalog_factories/data_models/energy_systems/emission_system.py @@ -25,14 +25,6 @@ class EmissionSystem: """ return self._system_id - @id.setter - def id(self, value): - """ - Set system id - :param value: float - """ - self._system_id = value - @property def name(self): """ @@ -41,14 +33,6 @@ class EmissionSystem: """ return self._name - @name.setter - def name(self, value): - """ - Set name - :param value: string - """ - self._name = value - @property def type(self): """ @@ -60,7 +44,17 @@ class EmissionSystem: @property def parasitic_energy_consumption(self): """ - Get parasitic_energy_consumption in ratio (Wh/Wh) + Get parasitic_energy_consumption in ratio (J/J) :return: float """ return self._parasitic_energy_consumption + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Layer': {'id': self.id, + 'name': self.name, + 'type': self.type, + 'parasitic energy consumption per energy produced [J/J]': self.parasitic_energy_consumption + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index 04069a96..1728540f 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -37,14 +37,6 @@ class GenerationSystem: """ return self._system_id - @id.setter - def id(self, value): - """ - Set system id - :param value: float - """ - self._system_id = value - @property def name(self): """ @@ -53,14 +45,6 @@ class GenerationSystem: """ return self._name - @name.setter - def name(self, value): - """ - Set name - :param value: string - """ - self._name = value - @property def type(self): """ @@ -140,3 +124,24 @@ class GenerationSystem: :return: GenerationSystem """ return self._auxiliary_equipment + + def to_dictionary(self): + """Class content to dictionary""" + _auxiliary_equipment = [] + if self.auxiliary_equipment is not None: + _auxiliary_equipment = self.auxiliary_equipment.to_dictionary() + content = {'Layer': {'id': self.id, + 'name': self.name, + 'type': self.type, + 'fuel type': self.fuel_type, + 'source types': self.source_types, + 'source temperature [Celsius]': self.source_temperature, + 'source mass flow [kg/s]': self.source_mass_flow, + 'heat efficiency': self.heat_efficiency, + 'cooling efficiency': self.cooling_efficiency, + 'electricity efficiency': self.electricity_efficiency, + 'it has storage': self.storage, + 'auxiliary equipment': _auxiliary_equipment + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index c4bf0258..f5804c83 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -88,3 +88,22 @@ class System: :return: EmissionSystem """ return self._emission_system + + def to_dictionary(self): + """Class content to dictionary""" + _distribution_system = None + if self.distribution_system is not None: + _distribution_system = self.distribution_system.to_dictionary() + _emission_system = None + if self.emission_system is not None: + _emission_system = self.emission_system.to_dictionary() + content = {'Layer': {'id': self.id, + 'name': self.name, + 'level of detail': self.lod, + 'demand types': self.demand_types, + 'generation system': self.generation_system.to_dictionary(), + 'distribution system': _distribution_system, + 'emission system': _emission_system + } + } + return content diff --git a/hub/catalog_factories/data_models/greenery/content.py b/hub/catalog_factories/data_models/greenery/content.py index 2087e7f7..c2544f98 100644 --- a/hub/catalog_factories/data_models/greenery/content.py +++ b/hub/catalog_factories/data_models/greenery/content.py @@ -35,3 +35,21 @@ class Content: All soils in the catalog """ return self._soils + + def to_dictionary(self): + """Class content to dictionary""" + _archetypes = [] + for _archetype in self.vegetations: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return content + + def __str__(self): + """Print content""" + _archetypes = [] + for _archetype in self.vegetations: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + + return str(content) diff --git a/hub/catalog_factories/data_models/greenery/plant.py b/hub/catalog_factories/data_models/greenery/plant.py index ea6bfa95..470fc593 100644 --- a/hub/catalog_factories/data_models/greenery/plant.py +++ b/hub/catalog_factories/data_models/greenery/plant.py @@ -96,3 +96,22 @@ class Plant: :return: [Soil] """ return self._grows_on + + def to_dictionary(self): + """Class content to dictionary""" + _soils = [] + for _soil in self.grows_on: + _soils.append(_soil.to_dictionary()) + content = {'Plant': {'name': self.name, + 'category': self.category, + 'height [m]': self.height, + 'leaf area index': self.leaf_area_index, + 'leaf reflectivity': self.leaf_reflectivity, + 'leaf emissivity': self.leaf_emissivity, + 'minimal stomatal resistance [s/m]': self.minimal_stomatal_resistance, + 'co2 sequestration [kg????]': self.co2_sequestration, + 'soils where it grows on': _soils + } + } + + return content diff --git a/hub/catalog_factories/data_models/greenery/plant_percentage.py b/hub/catalog_factories/data_models/greenery/plant_percentage.py index 8f72846b..5cf6c48d 100644 --- a/hub/catalog_factories/data_models/greenery/plant_percentage.py +++ b/hub/catalog_factories/data_models/greenery/plant_percentage.py @@ -24,3 +24,23 @@ class PlantPercentage(HubPlant): :return: float """ return self._percentage + + def to_dictionary(self): + """Class content to dictionary""" + _soils = [] + for _soil in self.grows_on: + _soils.append(_soil.to_dictionary()) + content = {'Plant': {'name': self.name, + 'percentage': self.percentage, + 'category': self.category, + 'height [m]': self.height, + 'leaf area index': self.leaf_area_index, + 'leaf reflectivity': self.leaf_reflectivity, + 'leaf emissivity': self.leaf_emissivity, + 'minimal stomatal resistance [s/m]': self.minimal_stomatal_resistance, + 'co2 sequestration [kg????]': self.co2_sequestration, + 'soils where it grows on': _soils + } + } + + return content diff --git a/hub/catalog_factories/data_models/greenery/soil.py b/hub/catalog_factories/data_models/greenery/soil.py index 099ba03f..e815254d 100644 --- a/hub/catalog_factories/data_models/greenery/soil.py +++ b/hub/catalog_factories/data_models/greenery/soil.py @@ -110,3 +110,20 @@ class Soil: :return: float """ return self._initial_volumetric_moisture_content + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Soil': {'name': self.name, +# 'roughness': self.roughness, # todo: this line prints value=2???? + 'dry conductivity [W/m2K]': self.dry_conductivity, + 'dry density [kg/m3]': self.dry_density, + 'dry specific heat [J/kgK]': self.dry_specific_heat, + 'thermal absorptance': self.thermal_absorptance, + 'solar absorptance': self.solar_absorptance, + 'visible absorptance': self.visible_absorptance, + 'saturation volumetric moisture content [units??]': self.saturation_volumetric_moisture_content, + 'residual volumetric moisture content [units??]': self.residual_volumetric_moisture_content + } + } + + return content diff --git a/hub/catalog_factories/data_models/greenery/vegetation.py b/hub/catalog_factories/data_models/greenery/vegetation.py index ec3a9a1c..ae92fb21 100644 --- a/hub/catalog_factories/data_models/greenery/vegetation.py +++ b/hub/catalog_factories/data_models/greenery/vegetation.py @@ -171,3 +171,28 @@ class Vegetation: :return: float """ return self._soil_initial_volumetric_moisture_content + + def to_dictionary(self): + """Class content to dictionary""" + _plants = [] + for _plant in self.plant_percentages: + _plants.append(_plant.to_dictionary()) + content = {'Archetype': {'name': self.name, + 'category': self.category, + 'air gap thickness [m]': self.air_gap, + 'soil thickness [m]': self.soil_thickness, + 'soil name': self.soil_name, +# 'soil roughness': self.soil_roughness, # todo: this line prints value=2???? + 'dry soil conductivity [W/m2K]': self.dry_soil_conductivity, + 'dry soil density [kg/m3]': self.dry_soil_density, + 'dry soil specific heat [J/kgK]': self.dry_soil_specific_heat, + 'soil thermal absorptance': self.soil_thermal_absorptance, + 'soil solar absorptance': self.soil_solar_absorptance, + 'soil visible absorptance': self.soil_visible_absorptance, + 'soil saturation volumetric moisture content [units??]': self.soil_saturation_volumetric_moisture_content, + 'soil residual volumetric moisture content [units??]': self.soil_residual_volumetric_moisture_content, + 'plants': _plants + } + } + + return content diff --git a/hub/catalog_factories/data_models/usages/appliances.py b/hub/catalog_factories/data_models/usages/appliances.py index c519cf44..fd16b913 100644 --- a/hub/catalog_factories/data_models/usages/appliances.py +++ b/hub/catalog_factories/data_models/usages/appliances.py @@ -61,3 +61,16 @@ class Appliances: :return: None or [Schedule] """ return self._schedules + + def to_dictionary(self): + """Class content to dictionary""" + _schedules = [] + for _schedule in self.schedules: + _schedules.append(_schedule.to_dictionary()) + content = {'Appliances': {'density [W/m2]': self.density, + 'convective fraction': self.convective_fraction, + 'radiative fraction': self.radiative_fraction, + 'latent fraction': self.latent_fraction, + 'schedules': _schedules} + } + return content diff --git a/hub/catalog_factories/data_models/usages/content.py b/hub/catalog_factories/data_models/usages/content.py index ffc34a4f..9fe730d1 100644 --- a/hub/catalog_factories/data_models/usages/content.py +++ b/hub/catalog_factories/data_models/usages/content.py @@ -20,3 +20,21 @@ class Content: Get catalog usages """ return self._usages + + def to_dictionary(self): + """Class content to dictionary""" + _usages = [] + for _usage in self.usages: + _usages.append(_usage.to_dictionary()) + content = {'Usages': _usages} + + return content + + def __str__(self): + """Print content""" + _usages = [] + for _usage in self.usages: + _usages.append(_usage.to_dictionary()) + content = {'Usages': _usages} + + return str(content) diff --git a/hub/catalog_factories/data_models/usages/domestic_hot_water.py b/hub/catalog_factories/data_models/usages/domestic_hot_water.py index 0eb9d9f5..15fb66ba 100644 --- a/hub/catalog_factories/data_models/usages/domestic_hot_water.py +++ b/hub/catalog_factories/data_models/usages/domestic_hot_water.py @@ -52,3 +52,15 @@ class DomesticHotWater: :return: None or [Schedule] """ return self._schedules + + def to_dictionary(self): + """Class content to dictionary""" + _schedules = [] + for _schedule in self.schedules: + _schedules.append(_schedule.to_dictionary()) + content = {'Domestic hot water': {'density [W/m2]': self.density, + 'peak flow [m3/sm2]': self.peak_flow, + 'service temperature [Celsius]': self.service_temperature, + 'schedules': _schedules} + } + return content diff --git a/hub/catalog_factories/data_models/usages/internal_gain.py b/hub/catalog_factories/data_models/usages/internal_gain.py deleted file mode 100644 index 447ce80a..00000000 --- a/hub/catalog_factories/data_models/usages/internal_gain.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -Usage catalog internal gain -SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2022 Concordia CERC group -Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca -""" - - -class InternalGain: - """ - InternalGain class - """ - - def __init__(self, internal_gain_type, average_internal_gain, convective_fraction, radiative_fraction, latent_fraction, schedules): - self._type = internal_gain_type - self._average_internal_gain = average_internal_gain - self._convective_fraction = convective_fraction - self._radiative_fraction = radiative_fraction - self._latent_fraction = latent_fraction - self._schedules = schedules diff --git a/hub/catalog_factories/data_models/usages/lighting.py b/hub/catalog_factories/data_models/usages/lighting.py index 29e8a490..2d9420fe 100644 --- a/hub/catalog_factories/data_models/usages/lighting.py +++ b/hub/catalog_factories/data_models/usages/lighting.py @@ -61,3 +61,16 @@ class Lighting: :return: None or [Schedule] """ return self._schedules + + def to_dictionary(self): + """Class content to dictionary""" + _schedules = [] + for _schedule in self.schedules: + _schedules.append(_schedule.to_dictionary()) + content = {'Lighting': {'density [W/m2]': self.density, + 'convective fraction': self.convective_fraction, + 'radiative fraction': self.radiative_fraction, + 'latent fraction': self.latent_fraction, + 'schedules': _schedules} + } + return content diff --git a/hub/catalog_factories/data_models/usages/occupancy.py b/hub/catalog_factories/data_models/usages/occupancy.py index e2d7269a..353ab2d9 100644 --- a/hub/catalog_factories/data_models/usages/occupancy.py +++ b/hub/catalog_factories/data_models/usages/occupancy.py @@ -65,3 +65,16 @@ class Occupancy: :return: None or [Schedule] """ return self._schedules + + def to_dictionary(self): + """Class content to dictionary""" + _schedules = [] + for _schedule in self.schedules: + _schedules.append(_schedule.to_dictionary()) + content = {'Occupancy': {'occupancy density [persons/m2]': self.occupancy_density, + 'sensible convective internal gain [W/m2]': self.sensible_convective_internal_gain, + 'sensible radiative internal gain [W/m2]': self.sensible_radiative_internal_gain, + 'latent internal gain [W/m2]': self.latent_internal_gain, + 'schedules': _schedules} + } + return content diff --git a/hub/catalog_factories/data_models/usages/schedule.py b/hub/catalog_factories/data_models/usages/schedule.py index 5f28e37d..73f03904 100644 --- a/hub/catalog_factories/data_models/usages/schedule.py +++ b/hub/catalog_factories/data_models/usages/schedule.py @@ -73,3 +73,14 @@ class Schedule: :return: None or [str] """ return self._day_types + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Schedule': {'type': self.type, + 'time range': self.time_range, + 'time step': self.time_step, + 'data type': self.data_type, + 'day types': self.day_types, + 'values': self.values} + } + return content diff --git a/hub/catalog_factories/data_models/usages/thermal_control.py b/hub/catalog_factories/data_models/usages/thermal_control.py index 0df90b0e..7c965b06 100644 --- a/hub/catalog_factories/data_models/usages/thermal_control.py +++ b/hub/catalog_factories/data_models/usages/thermal_control.py @@ -76,3 +76,23 @@ class ThermalControl: :return: None or [Schedule] """ return self._cooling_set_point_schedules + + def to_dictionary(self): + """Class content to dictionary""" + _hvac_schedules = [] + for _schedule in self.hvac_availability_schedules: + _hvac_schedules.append(_schedule.to_dictionary()) + _heating_set_point_schedules = [] + for _schedule in self.heating_set_point_schedules: + _heating_set_point_schedules.append(_schedule.to_dictionary()) + _cooling_set_point_schedules = [] + for _schedule in self.cooling_set_point_schedules: + _cooling_set_point_schedules.append(_schedule.to_dictionary()) + content = {'Thermal control': {'mean heating set point [Celsius]': self.mean_heating_set_point, + 'heating set back [Celsius]': self.heating_set_back, + 'mean cooling set point [Celsius]': self.mean_cooling_set_point, + 'hvac availability schedules': _hvac_schedules, + 'heating set point schedules': _heating_set_point_schedules, + 'cooling set point schedules': _cooling_set_point_schedules} + } + return content diff --git a/hub/catalog_factories/data_models/usages/usage.py b/hub/catalog_factories/data_models/usages/usage.py index 25a54d5f..41065cae 100644 --- a/hub/catalog_factories/data_models/usages/usage.py +++ b/hub/catalog_factories/data_models/usages/usage.py @@ -125,3 +125,19 @@ class Usage: :return: None or DomesticHotWater """ return self._domestic_hot_water + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Usage': {'name': self.name, + 'hours a day': self.hours_day, + 'days a year': self.days_year, + 'mechanical air change [ACH]': self.mechanical_air_change, + 'ventilation rate [m3/sm2]': self.ventilation_rate, + 'occupancy': self.occupancy.to_dictionary(), + 'lighting': self.lighting.to_dictionary(), + 'appliances': self.appliances.to_dictionary(), + 'thermal control': self.thermal_control.to_dictionary(), + 'domestic hot water': self.domestic_hot_water.to_dictionary() + } + } + return content diff --git a/hub/data/construction/eilat_archetypes.json b/hub/data/construction/eilat_archetypes.json index 4a15e038..25748055 100644 --- a/hub/data/construction/eilat_archetypes.json +++ b/hub/data/construction/eilat_archetypes.json @@ -1,7 +1,7 @@ { "archetypes": [ { - "function": "Residential", + "function": "Residential_building", "period_of_construction": "1000_1980", "climate_zone": "BWh", "average_storey_height": 3, @@ -35,7 +35,7 @@ } }, { - "function": "Dormitory", + "function": "Residential_building", "period_of_construction": "2011_3000", "climate_zone": "BWh", "average_storey_height": 3, @@ -69,7 +69,7 @@ } }, { - "function": "Hotel_employees", + "function": "Residential_building", "period_of_construction": "1981_2010", "climate_zone": "BWh", "average_storey_height": 3, diff --git a/hub/data/costs/montreal_costs.xml b/hub/data/costs/montreal_costs.xml index aebffbc6..48bbfd85 100644 --- a/hub/data/costs/montreal_costs.xml +++ b/hub/data/costs/montreal_costs.xml @@ -96,7 +96,7 @@ 3.6 0.07 - 0.05 + 5 @@ -196,7 +196,7 @@ 3.6 0.05 - 0.05 + 5 \ No newline at end of file diff --git a/hub/helpers/data/hub_function_to_eilat_construction_function.py b/hub/helpers/data/hub_function_to_eilat_construction_function.py index e4ecfe87..2e8cebc6 100644 --- a/hub/helpers/data/hub_function_to_eilat_construction_function.py +++ b/hub/helpers/data/hub_function_to_eilat_construction_function.py @@ -14,9 +14,9 @@ class HubFunctionToEilatConstructionFunction: """ def __init__(self): self._dictionary = { - cte.RESIDENTIAL: 'Residential', - cte.HOTEL: 'Hotel_employees', - cte.DORMITORY: 'Dormitory' + cte.RESIDENTIAL: 'Residential_building', + cte.HOTEL: 'Residential_building', + cte.DORMITORY: 'Residential_building' } @property diff --git a/hub/helpers/data/montreal_system_to_hub_energy_generation_system.py b/hub/helpers/data/montreal_system_to_hub_energy_generation_system.py index 224431a9..df6cb398 100644 --- a/hub/helpers/data/montreal_system_to_hub_energy_generation_system.py +++ b/hub/helpers/data/montreal_system_to_hub_energy_generation_system.py @@ -29,7 +29,9 @@ class MontrealSystemToHubEnergyGenerationSystem: 'Single zone packaged rooftop unit with air cooled DX': cte.CHILLER, 'Single zone make-up air unit with air cooled DX': cte.CHILLER, 'Multi-zone built-up system with water cooled, water chiller': cte.CHILLER, - 'PV system': cte.PHOTOVOLTAIC + 'PV system': cte.PHOTOVOLTAIC, + 'Multi-zone built-up system with heat pump for cooling': cte.CHILLER, + 'Multi-zone built-up system with heat pump for heat': cte.HEAT_PUMP } @property diff --git a/hub/imports/construction/helpers/construction_helper.py b/hub/imports/construction/helpers/construction_helper.py index 7f34e853..59630d31 100644 --- a/hub/imports/construction/helpers/construction_helper.py +++ b/hub/imports/construction/helpers/construction_helper.py @@ -50,7 +50,10 @@ class ConstructionHelper: _reference_city_to_nrcan_climate_zone = { 'Montreal': '6', 'Repentigny': '6', - 'Levis': '7A' + "Montreal Int'l": '6', + 'Levis': '7A', + 'Kelowna': '5', + 'Park Slope': '4' } _reference_city_to_israel_climate_zone = { diff --git a/tests/test_exports.py b/tests/test_exports.py index 7cf74c30..7607c964 100644 --- a/tests/test_exports.py +++ b/tests/test_exports.py @@ -105,11 +105,15 @@ class TestExports(TestCase): """ export to IDF """ - file = 'FZK_Haus_LoD_2.gml' + file = 'test.geojson' file_path = (self._example_path / file).resolve() - city = GeometryFactory('citygml', + city = GeometryFactory('geojson', path=file_path, - function_to_hub=Dictionaries().alkis_function_to_hub_function).city + height_field='citygml_me', + year_of_construction_field='ANNEE_CONS', + function_field='CODE_UTILI', + function_to_hub=Dictionaries().montreal_function_to_hub_function).city + self.assertIsNotNone(city, 'city is none') EnergyBuildingsExportsFactory('idf', city, self._output_path).export() ConstructionFactory('nrcan', city).enrich() diff --git a/tests/test_results_import.py b/tests/test_results_import.py index 3534e454..a9e0959c 100644 --- a/tests/test_results_import.py +++ b/tests/test_results_import.py @@ -30,11 +30,16 @@ class TestResultsImport(TestCase): :return: None """ self._example_path = (Path(__file__).parent / 'tests_data').resolve() - self._gml_path = (self._example_path / 'FZK_Haus_LoD_2.gml').resolve() self._output_path = (Path(__file__).parent / 'tests_outputs').resolve() - self._city = GeometryFactory('citygml', - self._gml_path, - function_to_hub=Dictionaries().alkis_function_to_hub_function).city + file = 'test.geojson' + file_path = (self._example_path / file).resolve() + self._city = GeometryFactory('geojson', + path=file_path, + height_field='citygml_me', + year_of_construction_field='ANNEE_CONS', + function_field='CODE_UTILI', + function_to_hub=Dictionaries().montreal_function_to_hub_function).city + ConstructionFactory('nrcan', self._city).enrich() UsageFactory('nrcan', self._city).enrich() diff --git a/tests/test_systems_factory.py b/tests/test_systems_factory.py index 20d7d336..46d07149 100644 --- a/tests/test_systems_factory.py +++ b/tests/test_systems_factory.py @@ -36,11 +36,15 @@ class TestSystemsFactory(TestCase): :return: None """ self._example_path = (Path(__file__).parent / 'tests_data').resolve() - self._gml_path = (self._example_path / 'FZK_Haus_LoD_2.gml').resolve() self._output_path = (Path(__file__).parent / 'tests_outputs').resolve() - self._city = GeometryFactory('citygml', - self._gml_path, - function_to_hub=Dictionaries().alkis_function_to_hub_function).city + file = 'test.geojson' + file_path = (self._example_path / file).resolve() + self._city = GeometryFactory('geojson', + path=file_path, + height_field='citygml_me', + year_of_construction_field='ANNEE_CONS', + function_field='CODE_UTILI', + function_to_hub=Dictionaries().montreal_function_to_hub_function).city def test_montreal_custom_system_factory(self): """ @@ -50,7 +54,7 @@ class TestSystemsFactory(TestCase): building.energy_systems_archetype_name = 'system 1 gas' EnergySystemsFactory('montreal_custom', self._city).enrich() - self.assertEqual(1, len(self._city.energy_systems_connection_table)) + self.assertEqual(17, len(self._city.energy_systems_connection_table)) def test_montreal_custom_system_results(self): """ @@ -76,9 +80,8 @@ class TestSystemsFactory(TestCase): energy_systems_connection = self._city.energy_systems_connection_table for building in self._city.buildings: _building_energy_systems = [] - energy_systems = energy_systems_connection['Energy System Type'].where( - energy_systems_connection['Building'] == building.name - ) + energy_systems = energy_systems_connection['Energy System Type'][ + energy_systems_connection['Building'] == building.name] for energy_system in energy_systems: _generic_building_energy_systems = self._city.generic_energy_systems[energy_system] for _generic_building_energy_system in _generic_building_energy_systems: