partial completion of nrcan catalog

This commit is contained in:
Guille Gutierrez 2022-11-21 12:46:39 -05:00
parent 60b725dad6
commit 1db5b02847
3 changed files with 69 additions and 39 deletions

View File

@ -4,8 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
""" """
from typing import Dict
import pandas as pd
import json import json
import urllib.request import urllib.request
import xmltodict import xmltodict
@ -20,40 +19,26 @@ from catalog_factories.data_models.usages.schedule import Schedule
from catalog_factories.data_models.usages.thermal_control import ThermalControl from catalog_factories.data_models.usages.thermal_control import ThermalControl
from catalog_factories.data_models.usages.usage import Usage from catalog_factories.data_models.usages.usage import Usage
from catalog_factories.usage.usage_helper import UsageHelper from catalog_factories.usage.usage_helper import UsageHelper
from helpers.configuration_helper import ConfigurationHelper as ch
class NrcanCatalog(Catalog): class NrcanCatalog(Catalog):
def __init__(self, path): def __init__(self, path):
path = str(path / 'nrcan.xml') path = str(path / 'nrcan.xml')
self._content = None self._content = None
self._schedules = [] self._schedules = {}
self._lightings = []
self._occupancies = []
self._internal_gains = []
self._appliances = []
self._thermal_controls = []
usages = []
with open(path) as xml: with open(path) as xml:
self._metadata = xmltodict.parse(xml.read()) self._metadata = xmltodict.parse(xml.read())
self._base_url = self._metadata['nrcan']['@base_url'] self._base_url = self._metadata['nrcan']['@base_url']
self._load_schedules() self._load_schedules()
self._load_archetypes() self._content = Content(self._load_archetypes())
def _calculate_hours_day(self, function): def _calculate_hours_day(self, function):
days = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, cte.SUNDAY, cte.HOLIDAY] # todo: pilar need to check how to calculate this value
number_of_days_per_type = [51, 50, 50, 50, 50, 52, 52, 10] return 24
total = 0
for schedule in self._schedules[function]['HVAC Avail']:
yearly_days = number_of_days_per_type[days.index(schedule.day_types[0])]
for value in schedule.values:
total += value * yearly_days
return total / 365
@staticmethod @staticmethod
def _extract_schedule(raw): def _extract_schedule(raw):
nrcan_schedule_type = raw['category'] nrcan_schedule_type = raw['category']
print(raw)
if 'Heating' in raw['name']: if 'Heating' in raw['name']:
nrcan_schedule_type = f'{nrcan_schedule_type} Heating' nrcan_schedule_type = f'{nrcan_schedule_type} Heating'
elif 'Cooling' in raw['name']: elif 'Cooling' in raw['name']:
@ -76,14 +61,14 @@ class NrcanCatalog(Catalog):
for schedule_type in schedules_type['tables']['schedules']['table']: for schedule_type in schedules_type['tables']['schedules']['table']:
schedule = NrcanCatalog._extract_schedule(schedule_type) schedule = NrcanCatalog._extract_schedule(schedule_type)
if schedule is not None: if schedule is not None:
self._schedules.append({schedule_type['name'], schedule}) self._schedules[schedule_type['name']] = schedule
def _get_schedule(self, name): def _get_schedule(self, name):
if name in self._schedules: if name in self._schedules:
print(f'dictionary found {name}: {self._schedule[name]}') return self._schedules[name]
return self._schedule[name]
def _load_archetypes(self): def _load_archetypes(self):
usages = []
usage = self._metadata['nrcan']['standards']['usage'] usage = self._metadata['nrcan']['standards']['usage']
url = f'{self._base_url}{usage["space_types_location"]}' url = f'{self._base_url}{usage["space_types_location"]}'
with urllib.request.urlopen(url) as json_file: with urllib.request.urlopen(url) as json_file:
@ -95,25 +80,67 @@ class NrcanCatalog(Catalog):
ventilation_rate = space_type['ventilation_per_area'] ventilation_rate = space_type['ventilation_per_area']
if ventilation_rate == 0: if ventilation_rate == 0:
ventilation_rate = space_type['ventilation_per_person'] ventilation_rate = space_type['ventilation_per_person']
hours_day = 0 # self._calculate_hours_day(usage_type) hours_day = self._calculate_hours_day(usage_type)
days_year = 365 days_year = 365
occupancy_schedule_name = space_type['occupancy_schedule'] occupancy_schedule_name = space_type['occupancy_schedule']
self._load_schedule(occupancy_schedule_name)
lighting_schedule_name = space_type['lighting_schedule'] lighting_schedule_name = space_type['lighting_schedule']
appliances_schedule_name = space_type['electric_equipment_schedule'] appliance_schedule_name = space_type['electric_equipment_schedule']
# thermal control # thermal control
heating_setpoint_schedule_name = space_type['heating_setpoint_schedule'] heating_setpoint_schedule_name = space_type['heating_setpoint_schedule']
cooling_setpoint_schedule_name = space_type['cooling_setpoint_schedule'] cooling_setpoint_schedule_name = space_type['cooling_setpoint_schedule']
print(usage_type, mechanical_air_change, ventilation_rate, hours_day, days_year, occupancy_schedule_name, lighting_schedule_name, appliances_schedule_name, heating_setpoint_schedule_name, cooling_setpoint_schedule_name) occupancy_schedule = self._get_schedule(occupancy_schedule_name)
lighting_schedule = self._get_schedule(lighting_schedule_name)
appliance_schedule = self._get_schedule(appliance_schedule_name)
heating_schedule = self._get_schedule(heating_setpoint_schedule_name)
cooling_schedule = self._get_schedule(cooling_setpoint_schedule_name)
def _read_archetype_file(self) -> Dict: occupancy_density = space_type['occupancy_per_area']
""" lighting_density = space_type['lighting_per_area']
reads xml files containing metadata to access to the json file? lighting_radiative_fraction = space_type['lighting_fraction_radiant']
:return : Dict if lighting_radiative_fraction is not None:
""" lighting_convective_fraction = 1 - lighting_radiative_fraction
print(self._metadata) lighting_latent_fraction = 0
return appliances_density = space_type['electric_equipment_per_area']
appliances_radiative_fraction = space_type['electric_equipment_fraction_radiant']
if appliances_radiative_fraction is not None:
appliances_convective_fraction = 1 - appliances_radiative_fraction
appliances_latent_fraction = space_type['electric_equipment_fraction_latent']
occupancy = Occupancy(occupancy_density, 0, 0, 0, occupancy_schedule)
lighting = Lighting(lighting_density,
lighting_convective_fraction,
lighting_radiative_fraction,
lighting_latent_fraction,
lighting_schedule)
appliances = Appliances(appliances_density,
appliances_convective_fraction,
appliances_radiative_fraction,
appliances_latent_fraction,
appliance_schedule)
if heating_schedule is not None:
thermal_control = ThermalControl(max(heating_schedule.values),
min(heating_schedule.values),
min(cooling_schedule.values),
None,
heating_schedule,
cooling_schedule)
else:
thermal_control = ThermalControl(None,
None,
None,
None,
None,
None)
usages.append(Usage(usage_type,
hours_day,
days_year,
mechanical_air_change,
ventilation_rate,
occupancy,
lighting,
appliances,
thermal_control))
return usages
def names(self, category=None): def names(self, category=None):
""" """

View File

@ -21,13 +21,14 @@ class UsageHelper:
'Thermostat Setpoint Heating': cte.HEATING_SET_POINT, # Compose 'Thermostat Setpoint' + 'Heating' 'Thermostat Setpoint Heating': cte.HEATING_SET_POINT, # Compose 'Thermostat Setpoint' + 'Heating'
} }
_nrcan_data_type_to_hub_data_type = { _nrcan_data_type_to_hub_data_type = {
'Fraction': cte.FRACTION, 'FRACTION': cte.FRACTION,
'ON_OFF': cte.ON_OFF, 'ON_OFF': cte.ON_OFF,
'TEMPERATURE': cte.ANY_NUMBER 'TEMPERATURE': cte.ANY_NUMBER
} }
_nrcan_time_to_hub_time = { _nrcan_time_to_hub_time = {
'Hourly': cte.HOUR 'Hourly': cte.HOUR,
'Constant': cte.CONSTANT
} }
_nrcan_day_type_to_hub_days = { _nrcan_day_type_to_hub_days = {

View File

@ -14,8 +14,10 @@ class TestConstructionCatalog(TestCase):
catalog = UsageCatalogFactory('comnet').catalog catalog = UsageCatalogFactory('comnet').catalog
self.assertIsNotNone(catalog, 'catalog is none') self.assertIsNotNone(catalog, 'catalog is none')
content = catalog.entries() content = catalog.entries()
self.assertEqual(len(content.usages), 32, 'Wrong number of usages') self.assertEqual(32, len(content.usages), 'Wrong number of usages')
def test_nrcan_catalog(self): def test_nrcan_catalog(self):
catalog = UsageCatalogFactory('nrcan').catalog catalog = UsageCatalogFactory('nrcan').catalog
self.assertIsNotNone(catalog, 'catalog is none') self.assertIsNotNone(catalog, 'catalog is none')
content = catalog.entries()
self.assertEqual(274, len(content.usages), 'Wrong number of usages')