diff --git a/hub/catalog_factories/data_models/energy_systems/archetype.py b/hub/catalog_factories/data_models/energy_systems/archetype.py
index b770eae1..632fc999 100644
--- a/hub/catalog_factories/data_models/energy_systems/archetype.py
+++ b/hub/catalog_factories/data_models/energy_systems/archetype.py
@@ -7,15 +7,15 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
from typing import List
-from hub.catalog_factories.data_models.energy_systems.equipment import Equipment
+from hub.catalog_factories.data_models.energy_systems.system import System
class Archetype:
- def __init__(self, lod, name, equipments):
+ def __init__(self, lod, name, systems):
self._lod = lod
self._name = name
- self._equipments = equipments
+ self._systems = systems
@property
def lod(self):
@@ -34,9 +34,9 @@ class Archetype:
return f'{self._name}_lod{self._lod}'
@property
- def equipments(self) -> List[Equipment]:
+ def systems(self) -> List[System]:
"""
Get list of equipments that compose the total energy system
:return: [Equipment]
"""
- return self._equipments
+ return self._systems
diff --git a/hub/catalog_factories/data_models/energy_systems/content.py b/hub/catalog_factories/data_models/energy_systems/content.py
index 53c07efb..7611e1e7 100644
--- a/hub/catalog_factories/data_models/energy_systems/content.py
+++ b/hub/catalog_factories/data_models/energy_systems/content.py
@@ -7,20 +7,44 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
class Content:
- def __init__(self, archetypes, equipments):
+ def __init__(self, archetypes, systems, generations, distributions, emissions):
self._archetypes = archetypes
- self._equipments = equipments
+ self._systems = systems
+ self._generations = generations
+ self._distributions = distributions
+ self._emissions = emissions
@property
def archetypes(self):
"""
- All archetype systems in the catalog
+ All archetype system clusters in the catalog
"""
return self._archetypes
@property
- def equipments(self):
+ def systems(self):
"""
- All equipments in the catalog
+ All systems in the catalog
"""
- return self._equipments
+ return self._systems
+
+ @property
+ def generation_equipments(self):
+ """
+ All generation equipments in the catalog
+ """
+ return self._generations
+
+ @property
+ def distribution_equipments(self):
+ """
+ All distribution equipments in the catalog
+ """
+ return self._distributions
+
+ @property
+ def emission_equipments(self):
+ """
+ All emission equipments in the catalog
+ """
+ return self._emissions
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 d189ea03..77176eb4 100644
--- a/hub/catalog_factories/data_models/energy_systems/distribution_system.py
+++ b/hub/catalog_factories/data_models/energy_systems/distribution_system.py
@@ -7,15 +7,49 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
class DistributionSystem:
- def __init__(self, system_type, supply_temperature, distribution_consumption_fix_flow,
+ def __init__(self, system_id, name, system_type, supply_temperature, distribution_consumption_fix_flow,
distribution_consumption_variable_flow, heat_losses):
+ self._system_id = system_id
+ self._name = name
self._type = system_type
self._supply_temperature = supply_temperature
self._distribution_consumption_fix_flow = distribution_consumption_fix_flow
self._distribution_consumption_variable_flow = distribution_consumption_variable_flow
self._heat_losses = heat_losses
+ @property
+ def id(self):
+ """
+ Get system id
+ :return: float
+ """
+ return self._system_id
+
+ @id.setter
+ def id(self, value):
+ """
+ Set system id
+ :param value: float
+ """
+ self._system_id = value
+
+ @property
+ def name(self):
+ """
+ Get name
+ :return: string
+ """
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ """
+ Set name
+ :param value: string
+ """
+ self._name = value
+
@property
def type(self):
"""
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 d9b0f4e5..61f917fc 100644
--- a/hub/catalog_factories/data_models/energy_systems/emission_system.py
+++ b/hub/catalog_factories/data_models/energy_systems/emission_system.py
@@ -7,10 +7,45 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
class EmissionSystem:
- def __init__(self, system_type, parasitic_energy_consumption):
+ def __init__(self, system_id, name, system_type, parasitic_energy_consumption):
+
+ self._system_id = system_id
+ self._name = name
self._type = system_type
self._parasitic_energy_consumption = parasitic_energy_consumption
+ @property
+ def id(self):
+ """
+ Get system id
+ :return: float
+ """
+ return self._system_id
+
+ @id.setter
+ def id(self, value):
+ """
+ Set system id
+ :param value: float
+ """
+ self._system_id = value
+
+ @property
+ def name(self):
+ """
+ Get name
+ :return: string
+ """
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ """
+ Set name
+ :param value: string
+ """
+ self._name = value
+
@property
def type(self):
"""
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 51a5325c..79665f76 100644
--- a/hub/catalog_factories/data_models/energy_systems/generation_system.py
+++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py
@@ -10,9 +10,11 @@ from typing import Union
class GenerationSystem:
- def __init__(self, system_type, fuel_type, source_types, heat_efficiency, cooling_efficiency, electricity_efficiency,
- source_temperature, source_mass_flow, storage, auxiliary_equipment):
+ def __init__(self, system_id, name, system_type, fuel_type, source_types, heat_efficiency, cooling_efficiency,
+ electricity_efficiency, source_temperature, source_mass_flow, storage, auxiliary_equipment):
+ self._system_id = system_id
+ self._name = name
self._type = system_type
self._fuel_type = fuel_type
self._source_types = source_types
@@ -24,6 +26,38 @@ class GenerationSystem:
self._storage = storage
self._auxiliary_equipment = auxiliary_equipment
+ @property
+ def id(self):
+ """
+ Get system id
+ :return: float
+ """
+ return self._system_id
+
+ @id.setter
+ def id(self, value):
+ """
+ Set system id
+ :param value: float
+ """
+ self._system_id = value
+
+ @property
+ def name(self):
+ """
+ Get name
+ :return: string
+ """
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ """
+ Set name
+ :param value: string
+ """
+ self._name = value
+
@property
def type(self):
"""
diff --git a/hub/catalog_factories/data_models/energy_systems/equipment.py b/hub/catalog_factories/data_models/energy_systems/system.py
similarity index 94%
rename from hub/catalog_factories/data_models/energy_systems/equipment.py
rename to hub/catalog_factories/data_models/energy_systems/system.py
index 9b2ddcd4..f03a9725 100644
--- a/hub/catalog_factories/data_models/energy_systems/equipment.py
+++ b/hub/catalog_factories/data_models/energy_systems/system.py
@@ -12,10 +12,10 @@ from hub.catalog_factories.data_models.energy_systems.distribution_system import
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
-class Equipment:
+class System:
def __init__(self,
lod,
- equipment_id,
+ system_id,
name,
demand_types,
generation_system,
@@ -23,7 +23,7 @@ class Equipment:
emission_system):
self._lod = lod
- self._equipment_id = equipment_id
+ self._system_id = system_id
self._name = name
self._demand_types = demand_types
self._generation_system = generation_system
@@ -44,7 +44,7 @@ class Equipment:
Get equipment id
:return: string
"""
- return self._equipment_id
+ return self._system_id
@property
def name(self):
diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py
index 818c913d..0727e3d0 100644
--- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py
+++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py
@@ -8,10 +8,11 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
import xmltodict
from hub.catalog_factories.catalog import Catalog
-from hub.catalog_factories.data_models.energy_systems.equipment import Equipment
+from hub.catalog_factories.data_models.energy_systems.system import System
from hub.catalog_factories.data_models.energy_systems.content import Content
from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
+from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
from hub.catalog_factories.data_models.energy_systems.archetype import Archetype
@@ -19,46 +20,45 @@ class MontrealCustomCatalog(Catalog):
def __init__(self, path):
path = str(path / 'montreal_custom_systems.xml')
with open(path) as xml:
- self._archetypes = xmltodict.parse(xml.read(), force_list=('system', 'system_cluster', 'demand', 'system_id'))
+ self._archetypes = xmltodict.parse(xml.read(), force_list=('system', 'system_cluster', 'equipment',
+ 'demand', 'system_id'))
self._lod = float(self._archetypes['catalog']['@lod'])
+ self._catalog_generation_equipments = self._load_generation_equipments()
+ self._catalog_distribution_equipments = self._load_distribution_equipments()
+ self._catalog_emission_equipments = self._load_emission_equipments()
self._catalog_systems = self._load_systems()
self._catalog_archetypes = self._load_archetypes()
# store the full catalog data model in self._content
self._content = Content(self._catalog_archetypes,
- self._catalog_systems)
+ self._catalog_systems,
+ self._catalog_generation_equipments,
+ self._catalog_distribution_equipments,
+ self._catalog_emission_equipments)
- def _load_systems(self):
- _catalog_systems = []
- systems = self._archetypes['catalog']['systems']['system']
- for system in systems:
- system_id = float(system['@id'])
- system_type = system['@type']
- fuel_type = system['@fuel_type']
- name = system['name']
- demands = system['demands']['demand']
+ def _load_generation_equipments(self):
+ _equipments = []
+ equipments = self._archetypes['catalog']['generation_equipments']['equipment']
+ for equipment in equipments:
+ equipment_id = float(equipment['@id'])
+ equipment_type = equipment['@type']
+ fuel_type = equipment['@fuel_type']
+ name = equipment['name']
heating_efficiency = None
- if 'heating_efficiency' in system:
- heating_efficiency = float(system['heating_efficiency'])
+ if 'heating_efficiency' in equipment:
+ heating_efficiency = float(equipment['heating_efficiency'])
cooling_efficiency = None
- if 'cooling_efficiency' in system:
- cooling_efficiency = float(system['cooling_efficiency'])
+ if 'cooling_efficiency' in equipment:
+ cooling_efficiency = float(equipment['cooling_efficiency'])
electricity_efficiency = None
- if 'electricity_efficiency' in system:
- electricity_efficiency = float(system['electricity_efficiency'])
- distribution_heat_losses = None
- if 'distribution_heat_losses' in system:
- distribution_heat_losses = float(system['distribution_heat_losses']['#text']) / 100
- distribution_consumption_fix_flow = None
- if 'distribution_consumption_fix_flow' in system:
- distribution_consumption_fix_flow = float(system['distribution_consumption_fix_flow']['#text']) / 100
- distribution_consumption_variable_flow = None
- if 'distribution_consumption_variable_flow' in system:
- distribution_consumption_variable_flow = float(system['distribution_consumption_variable_flow']['#text']) / 100
- storage = eval(system['storage'].capitalize())
- generation_system = GenerationSystem(system_type,
+ if 'electrical_efficiency' in equipment:
+ electricity_efficiency = float(equipment['electrical_efficiency'])
+ storage = eval(equipment['storage'].capitalize())
+ generation_system = GenerationSystem(equipment_id,
+ name,
+ equipment_type,
fuel_type,
None,
heating_efficiency,
@@ -68,18 +68,87 @@ class MontrealCustomCatalog(Catalog):
None,
storage,
None)
- distribution_system = DistributionSystem(None,
+
+ _equipments.append(generation_system)
+ return _equipments
+
+ def _load_distribution_equipments(self):
+ _equipments = []
+ equipments = self._archetypes['catalog']['distribution_equipments']['equipment']
+ for equipment in equipments:
+ equipment_id = float(equipment['@id'])
+ equipment_type = equipment['@type']
+ name = equipment['name']
+ distribution_heat_losses = None
+ if 'distribution_heat_losses' in equipment:
+ distribution_heat_losses = float(equipment['distribution_heat_losses']['#text']) / 100
+ distribution_consumption_fix_flow = None
+ if 'distribution_consumption_fix_flow' in equipment:
+ distribution_consumption_fix_flow = float(equipment['distribution_consumption_fix_flow']['#text']) / 100
+ distribution_consumption_variable_flow = None
+ if 'distribution_consumption_variable_flow' in equipment:
+ distribution_consumption_variable_flow = float(equipment['distribution_consumption_variable_flow']['#text']) / 100
+
+ distribution_system = DistributionSystem(equipment_id,
+ name,
+ equipment_type,
None,
distribution_consumption_fix_flow,
distribution_consumption_variable_flow,
distribution_heat_losses)
- _catalog_systems.append(Equipment(self._lod,
- system_id,
- name,
- demands,
- generation_system,
- distribution_system,
- None))
+
+ _equipments.append(distribution_system)
+ return _equipments
+
+ def _load_emission_equipments(self):
+ _equipments = []
+ equipments = self._archetypes['catalog']['dissipation_equipments']['equipment']
+ for equipment in equipments:
+ equipment_id = float(equipment['@id'])
+ equipment_type = equipment['@type']
+ name = equipment['name']
+ parasitic_consumption = None
+ if 'parasitic_consumption' in equipment:
+ parasitic_consumption = float(equipment['parasitic_consumption']['#text']) / 100
+
+ emission_system = EmissionSystem(equipment_id,
+ name,
+ equipment_type,
+ parasitic_consumption)
+
+ _equipments.append(emission_system)
+ return _equipments
+
+ def _load_systems(self):
+ _catalog_systems = []
+ systems = self._archetypes['catalog']['systems']['system']
+ for system in systems:
+ system_id = float(system['@id'])
+ name = system['name']
+ demands = system['demands']['demand']
+ generation_equipment = system['equipments']['generation_id']
+ _generation_equipment = None
+ for equipment_archetype in self._catalog_generation_equipments:
+ if int(equipment_archetype.id) == int(generation_equipment):
+ _generation_equipment = equipment_archetype
+ distribution_equipment = system['equipments']['distribution_id']
+ _distribution_equipment = None
+ for equipment_archetype in self._catalog_distribution_equipments:
+ if int(equipment_archetype.id) == int(distribution_equipment):
+ _distribution_equipment = equipment_archetype
+ emission_equipment = system['equipments']['dissipation_id']
+ _emission_equipment = None
+ for equipment_archetype in self._catalog_emission_equipments:
+ if int(equipment_archetype.id) == int(emission_equipment):
+ _emission_equipment = equipment_archetype
+
+ _catalog_systems.append(System(self._lod,
+ system_id,
+ name,
+ demands,
+ _generation_equipment,
+ _distribution_equipment,
+ _emission_equipment))
return _catalog_systems
def _load_archetypes(self):
@@ -102,18 +171,34 @@ class MontrealCustomCatalog(Catalog):
:parm: optional category filter
"""
if category is None:
- _names = {'archetypes': [], 'systems': []}
+ _names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'distribution_equipments': [],
+ 'emission_equipments':[]}
for archetype in self._content.archetypes:
_names['archetypes'].append(archetype.name)
- for system in self._content.equipments:
+ for system in self._content.systems:
_names['systems'].append(system.name)
+ for equipment in self._content.generation_equipments:
+ _names['generation_equipments'].append(equipment.name)
+ for equipment in self._content.distribution_equipments:
+ _names['distribution_equipments'].append(equipment.name)
+ for equipment in self._content.emission_equipments:
+ _names['emission_equipments'].append(equipment.name)
else:
_names = {category: []}
if category.lower() == 'archetypes':
for archetype in self._content.archetypes:
_names[category].append(archetype.name)
elif category.lower() == 'systems':
- for system in self._content.equipments:
+ for system in self._content.systems:
+ _names[category].append(system.name)
+ elif category.lower() == 'generation_equipments':
+ for system in self._content.generation_equipments:
+ _names[category].append(system.name)
+ elif category.lower() == 'distribution_equipments':
+ for system in self._content.distribution_equipments:
+ _names[category].append(system.name)
+ elif category.lower() == 'emission_equipments':
+ for system in self._content.emission_equipments:
_names[category].append(system.name)
else:
raise ValueError(f'Unknown category [{category}]')
@@ -130,7 +215,13 @@ class MontrealCustomCatalog(Catalog):
if category.lower() == 'archetypes':
return self._content.archetypes
elif category.lower() == 'systems':
- return self._content.equipments
+ return self._content.systems
+ elif category.lower() == 'generation_equipments':
+ return self._content.generation_equipments
+ elif category.lower() == 'distribution_equipments':
+ return self._content.distribution_equipments
+ elif category.lower() == 'emission_equipments':
+ return self._content.emission_equipments
else:
raise ValueError(f'Unknown category [{category}]')
@@ -142,7 +233,16 @@ class MontrealCustomCatalog(Catalog):
for entry in self._content.archetypes:
if entry.name.lower() == name.lower():
return entry
- for entry in self._content.equipments:
+ for entry in self._content.systems:
+ if entry.name.lower() == name.lower():
+ return entry
+ for entry in self._content.generation_equipments:
+ if entry.name.lower() == name.lower():
+ return entry
+ for entry in self._content.distribution_equipments:
+ if entry.name.lower() == name.lower():
+ return entry
+ for entry in self._content.emission_equipments:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")
diff --git a/hub/city_model_structure/building.py b/hub/city_model_structure/building.py
index 4c92b4ec..7262e46e 100644
--- a/hub/city_model_structure/building.py
+++ b/hub/city_model_structure/building.py
@@ -671,15 +671,28 @@ class Building(CityObject):
Get total electricity produced onsite in Wh
return: dict
"""
+
# Add other systems whenever new ones appear
+ orientation_losses_factor = {cte.MONTH: {'north': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ 'east': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ 'south': [2.137931, 1.645503, 1.320946, 1.107817, 0.993213, 0.945175,
+ 0.967949, 1.065534, 1.24183, 1.486486, 1.918033, 2.210526],
+ 'west': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]},
+ cte.YEAR: {'north': [0],
+ 'east': [0],
+ 'south': [1.212544],
+ 'west': [0]}
+ }
for energy_system in self.energy_systems:
if energy_system.generation_system.generic_generation_system.type == cte.PHOTOVOLTAIC:
_efficiency = energy_system.generation_system.generic_generation_system.electricity_efficiency
self._onsite_electrical_production = {}
for _key in self.roofs[0].global_irradiance.keys():
- _results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key]))]
- for surface in self.surfaces:
- _results = [x + y * _efficiency * surface.perimeter_area * surface.solar_collectors_area_reduction_factor
- for x, y in zip(_results, surface.global_irradiance[_key])]
+ _results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key][cte.SRA]))]
+ for surface in self.roofs:
+ _results = [x + y * _efficiency * surface.perimeter_area
+ * surface.solar_collectors_area_reduction_factor * z
+ for x, y, z in zip(_results, surface.global_irradiance[_key][cte.SRA],
+ orientation_losses_factor[cte.MONTH]['south'])]
self._onsite_electrical_production[_key] = _results
return self._onsite_electrical_production
diff --git a/hub/city_model_structure/building_demand/surface.py b/hub/city_model_structure/building_demand/surface.py
index 10e60788..3a8adc9a 100644
--- a/hub/city_model_structure/building_demand/surface.py
+++ b/hub/city_model_structure/building_demand/surface.py
@@ -359,7 +359,6 @@ class Surface:
:return: float
"""
if self._solar_collectors_area_reduction_factor is None:
- _solar_collectors_area_reduction_factor = 0
if self.type == cte.ROOF:
_protected_building_restriction = 1
# 10 degrees range
@@ -369,12 +368,12 @@ class Surface:
_separation_of_panels = 0.46
_shadow_between_panels = 0.7
else:
- # pitched
+ # tilted
_construction_restriction = 0.9
_separation_of_panels = 0.9
_shadow_between_panels = 1
- _solar_collectors_area_reduction_factor = _protected_building_restriction * _construction_restriction \
- * _separation_of_panels * _shadow_between_panels
+ self._solar_collectors_area_reduction_factor = _protected_building_restriction * _construction_restriction \
+ * _separation_of_panels * _shadow_between_panels
return self._solar_collectors_area_reduction_factor
@solar_collectors_area_reduction_factor.setter
diff --git a/hub/data/energy_systems/montreal_custom_systems.xml b/hub/data/energy_systems/montreal_custom_systems.xml
index b49bbc62..b9eaee8e 100644
--- a/hub/data/energy_systems/montreal_custom_systems.xml
+++ b/hub/data/energy_systems/montreal_custom_systems.xml
@@ -3,26 +3,32 @@
Fuel-fired water boiler
0.85
+ false
Electric water boiler
1
+ true
Fuel-fired furnace and fuel boiler for acs
0.85
+ false
Electrical furnace and fuel boiler for acs
1
+ false
Air cooled DX with external condenser
3.23
+ false
PV system
0.22
+ true
@@ -78,15 +84,15 @@
Baseboards
- 0
+ 0
fan-coils
- 2
+ 2
inductors
- 0
+ 0
@@ -101,7 +107,6 @@
1
1
- false
4 pipe fan coils with fuel fired boiler
@@ -114,7 +119,6 @@
1
2
- false
4 pipe fan coils with electrical resistance water boiler
@@ -127,7 +131,6 @@
1
2
- true
Single zone packaged rooftop unit with fuel-fired furnace and baseboards and fuel boiler for acs
@@ -140,7 +143,6 @@
5
1
- false
Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs
@@ -153,7 +155,6 @@
5
1
- false
Single zone make-up air unit with baseboard heating with fuel fired boiler
@@ -166,7 +167,6 @@
1
1
- false
Single zone make-up air unit with electrical baseboard heating and DHW with resistance
@@ -179,7 +179,6 @@
5
3
- false
Multi-zone built-up system with baseboard heater hydronic with fuel fired boiler
@@ -192,7 +191,6 @@
1
3
- false
Multi-zone built-up system with electrical baseboard heater and electrical hot water
@@ -205,7 +203,6 @@
1
3
- false
Unitary air conditioner air cooled DX with external condenser
@@ -217,7 +214,6 @@
6
3
- false
4 pipe fan coils with water cooled, water chiller
@@ -229,7 +225,6 @@
2
2
- false
Single zone packaged rooftop unit with air cooled DX
@@ -241,7 +236,6 @@
6
3
- false
Single zone make-up air unit with air cooled DX
@@ -253,7 +247,6 @@
6
3
- false
Multi-zone built-up system with water cooled, water chiller
@@ -265,7 +258,6 @@
3
3
- false
PV system
@@ -277,7 +269,6 @@
5
3
- true
diff --git a/hub/exports/building_energy/insel/insel_monthly_energy_balance.py b/hub/exports/building_energy/insel/insel_monthly_energy_balance.py
index c5286e51..241e3bee 100644
--- a/hub/exports/building_energy/insel/insel_monthly_energy_balance.py
+++ b/hub/exports/building_energy/insel/insel_monthly_energy_balance.py
@@ -24,6 +24,8 @@ _CONSTRUCTION_CODE = {
cte.INTERIOR_SLAB: '8'
}
+_NUMBER_DAYS_PER_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
class InselMonthlyEnergyBalance(Insel):
@@ -252,7 +254,8 @@ class InselMonthlyEnergyBalance(Insel):
raise ValueError(f'surface: {surface.name} from building {building.name} has no global irradiance!')
global_irradiance = surface.global_irradiance[cte.MONTH]
for j in range(0, len(global_irradiance)):
- parameters.append(f'{j + 1} {global_irradiance.at[j, radiation_calculation_method]}')
+ parameters.append(f'{j + 1} '
+ f'{global_irradiance.at[j, radiation_calculation_method] / 24 / _NUMBER_DAYS_PER_MONTH[j]}')
else:
for j in range(0, 12):
parameters.append(f'{j + 1} 0.0')
diff --git a/hub/helpers/constants.py b/hub/helpers/constants.py
index 8b6df87b..9b50cb98 100644
--- a/hub/helpers/constants.py
+++ b/hub/helpers/constants.py
@@ -182,6 +182,8 @@ ONSITE_ELECTRICITY = 'Onsite Electricity'
PHOTOVOLTAIC = 'Photovoltaic'
BOILER = 'Boiler'
HEAT_PUMP = 'Heat Pump'
+BASEBOARD = 'Baseboard'
+CHILLER = 'Chiller'
# Geometry
EPSILON = 0.0000001
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 ba68bd47..4e5ce77a 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
@@ -11,14 +11,22 @@ import hub.helpers.constants as cte
class MontrealSystemToHubEnergyGenerationSystem:
def __init__(self):
- self._dictionary = {'Fuel-fired water boiler with baseboards': cte.BOILER,
- 'Electrical resistance water boiler': cte.BOILER,
- 'Fuel-fired furnace and fuel boiler for acs': cte.BOILER,
- 'Baseboards: hydronic with fuel boiler': cte.BOILER,
- 'Electrical baseboards and electrical boiler for acs': cte.BOILER,
- 'Air cooled DX with external condenser': cte.HEAT_PUMP,
- 'Water cooled, water chiller': cte.HEAT_PUMP,
- 'PV system': cte.PHOTOVOLTAIC
+ self._dictionary = {
+ 'Unitary air conditioner with baseboard heater fuel fired boiler': cte.BOILER,
+ '4 pipe fan coils with fuel fired boiler': cte.BOILER,
+ '4 pipe fan coils with electrical resistance water boiler': cte.BOILER,
+ 'Single zone packaged rooftop unit with fuel-fired furnace and baseboards and fuel boiler for acs': cte.BOILER,
+ 'Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs': cte.BOILER,
+ 'Single zone make-up air unit with baseboard heating with fuel fired boiler': cte.BOILER,
+ 'Single zone make-up air unit with electrical baseboard heating and DHW with resistance': cte.BASEBOARD,
+ 'Multi-zone built-up system with baseboard heater hydronic with fuel fired boiler': cte.BOILER,
+ 'Multi-zone built-up system with electrical baseboard heater and electrical hot water': cte.BASEBOARD,
+ 'Unitary air conditioner air cooled DX with external condenser': cte.CHILLER,
+ '4 pipe fan coils with water cooled, water chiller': cte.CHILLER,
+ '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
}
@property
diff --git a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py
index 9ad3ba98..255d3e25 100644
--- a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py
+++ b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py
@@ -52,7 +52,7 @@ class MontrealCustomEnergySystemParameters:
building_systems = []
data = [archetype_name, building.name]
_energy_systems_connection_table.loc[len(_energy_systems_connection_table)] = data
- for equipment in archetype.equipments:
+ for equipment in archetype.systems:
energy_system = GenericEnergySystem()
_hub_demand_types = []
for demand_type in equipment.demand_types:
diff --git a/hub/imports/results/simplified_radiosity_algorithm.py b/hub/imports/results/simplified_radiosity_algorithm.py
index e6f01cf8..fe983216 100644
--- a/hub/imports/results/simplified_radiosity_algorithm.py
+++ b/hub/imports/results/simplified_radiosity_algorithm.py
@@ -32,17 +32,18 @@ class SimplifiedRadiosityAlgorithm:
array = np.concatenate((array, np.full(total_hours, i + 1)))
return pd.DataFrame(array, columns=[cte.MONTH])
- def _get_monthly_mean_values(self, values):
+ def _get_monthly_values(self, values):
out = None
if values is not None:
if cte.MONTH not in values.columns:
values = pd.concat([self._month_hour, pd.DataFrame(values)], axis=1)
- out = values.groupby(cte.MONTH, as_index=False).mean()
+ out = values.groupby(cte.MONTH, as_index=False).sum()
del out[cte.MONTH]
return out
- def _get_yearly_mean_values(self, values):
- return values.mean()
+ @staticmethod
+ def _get_yearly_values(values):
+ return [values.sum()]
def _read_results(self):
try:
@@ -83,7 +84,7 @@ class SimplifiedRadiosityAlgorithm:
surface_id = header_id.split(':')[2]
surface = building.surface_by_id(surface_id)
new_value = pd.DataFrame(radiation[[header_id]].to_numpy(), columns=[cte.SRA])
- month_new_value = self._get_monthly_mean_values(new_value)
+ month_new_value = self._get_monthly_values(new_value)
if cte.MONTH not in surface.global_irradiance:
surface.global_irradiance[cte.MONTH] = month_new_value
else:
@@ -93,7 +94,7 @@ class SimplifiedRadiosityAlgorithm:
else:
pd.concat([surface.global_irradiance[cte.HOUR], new_value], axis=1)
if cte.YEAR not in surface.global_irradiance:
- surface.global_irradiance[cte.YEAR] = self._get_yearly_mean_values(new_value)
+ surface.global_irradiance[cte.YEAR] = pd.DataFrame(self._get_yearly_values(new_value), columns=[cte.SRA])
self._city.level_of_detail.surface_radiation = 2
for building in self._city.buildings:
building.level_of_detail.surface_radiation = 2
diff --git a/hub/unittests/test_systems_catalog.py b/hub/unittests/test_systems_catalog.py
index 03702fbd..04833292 100644
--- a/hub/unittests/test_systems_catalog.py
+++ b/hub/unittests/test_systems_catalog.py
@@ -14,13 +14,16 @@ class TestSystemsCatalog(TestCase):
def test_montreal_custom_catalog(self):
catalog = EnergySystemsCatalogFactory('montreal_custom').catalog
catalog_categories = catalog.names()
- for archetype in catalog.entries('archetypes'):
- for equipment in archetype.equipments:
- print(equipment._equipment_id)
archetypes = catalog.names('archetypes')
self.assertEqual(18, len(archetypes['archetypes']))
- equipments = catalog.names('equipments')
- self.assertEqual(10, len(equipments['equipments']))
+ systems = catalog.names('systems')
+ self.assertEqual(15, len(systems['systems']))
+ generation_equipments = catalog.names('generation_equipments')
+ self.assertEqual(6, len(generation_equipments['generation_equipments']))
+ distribution_equipments = catalog.names('distribution_equipments')
+ self.assertEqual(8, len(distribution_equipments['distribution_equipments']))
+ emission_equipments = catalog.names('emission_equipments')
+ self.assertEqual(3, len(emission_equipments['emission_equipments']))
with self.assertRaises(ValueError):
catalog.names('unknown')
diff --git a/hub/unittests/test_systems_factory.py b/hub/unittests/test_systems_factory.py
index b9395509..e98f6c29 100644
--- a/hub/unittests/test_systems_factory.py
+++ b/hub/unittests/test_systems_factory.py
@@ -69,7 +69,7 @@ class TestSystemsFactory(TestCase):
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
for building in self._city.buildings:
- building.energy_systems_archetype_name = 'system 1 gas'
+ building.energy_systems_archetype_name = 'system 1 gas pv'
EnergySystemsFactory('montreal_custom', self._city).enrich()
# Need to assign energy systems to buildings:
energy_systems_connection = self._city.energy_systems_connection_table
@@ -107,3 +107,4 @@ class TestSystemsFactory(TestCase):
self.assertLess(0, building.heating_consumption[cte.YEAR][0])
self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0])
+ self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])