From 28c88e297851a7944efba796a9c61805fd350adb Mon Sep 17 00:00:00 2001 From: Andrea Gabaldon Moreno Date: Thu, 1 Aug 2024 10:16:52 -0400 Subject: [PATCH] 20240801 --- .../montreal_custom_systems.xml | 2 +- main.py | 223 +++++++++--------- main_results_in_geojson.py | 155 ------------ old_main.py | 159 +++++++++++++ 4 files changed, 266 insertions(+), 273 deletions(-) delete mode 100644 main_results_in_geojson.py create mode 100644 old_main.py diff --git a/hub/data/energy_systems/montreal_custom_systems.xml b/hub/data/energy_systems/montreal_custom_systems.xml index f3b0466f..e69b665d 100644 --- a/hub/data/energy_systems/montreal_custom_systems.xml +++ b/hub/data/energy_systems/montreal_custom_systems.xml @@ -198,7 +198,7 @@ 3 8 -g + Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs diff --git a/main.py b/main.py index 349e9be9..2b09d3e1 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ from pathlib import Path from scripts.ep_workflow import energy_plus_workflow +from hub.helpers.monthly_values import MonthlyValues from hub.imports.geometry_factory import GeometryFactory from hub.helpers.dictionaries import Dictionaries from hub.imports.construction_factory import ConstructionFactory @@ -7,36 +8,24 @@ from hub.imports.usage_factory import UsageFactory from hub.imports.weather_factory import WeatherFactory import hub.helpers.constants as cte from hub.imports.energy_systems_factory import EnergySystemsFactory +from hub.helpers.peak_loads import PeakLoads + import geopandas as gpd +import json # Specify the GeoJSON file path input_files_path = (Path(__file__).parent / 'input_files') - -building_type_2_modelling=2 -#'Lachine_New_Developments.geojson' -geojson_file_path = input_files_path / 'Lachine_moved_2024_type.geojson' -if building_type_2_modelling==1: - gdf = gpd.read_file(geojson_file_path) - # Filter gdf when 'building_type_2' is not null - filtered_gdf = gdf[gdf['building_type_2'].notnull()] - output_geojson =input_files_path /'Lachine_moved_2024_type_2.geojson' - geojson_file_path =output_geojson - filtered_gdf.to_file(output_geojson, driver='GeoJSON') - print(f"New GeoJSON saved in: {output_geojson}") -if building_type_2_modelling==2: - gdf = gpd.read_file(geojson_file_path) - # Filter gdf when 'building_type_3' is not null - filtered_gdf = gdf[gdf['building_type_3'].notnull()] - output_geojson =input_files_path /'Lachine_moved_2024_type_3.geojson' - geojson_file_path = output_geojson - filtered_gdf.to_file(output_geojson, driver='GeoJSON') - print(f"New GeoJSON saved in: {output_geojson}") - - output_path = (Path(__file__).parent / 'out_files').resolve() output_path.mkdir(parents=True, exist_ok=True) +geojson_file_path_baseline = output_path / 'updated_buildings_with_all_data_baseline.geojson' +geojson_file_path_2024 = output_path / 'updated_buildings_with_all_data.geojson' +with open(geojson_file_path_baseline , 'r') as f: + building_type_data = json.load(f) +with open(geojson_file_path_2024, 'r') as f: + building_type_data_2024 = json.load(f) + # Create city object from GeoJSON file city = GeometryFactory('geojson', - path=geojson_file_path, + path=geojson_file_path_baseline, height_field='maximum_roof_height', year_of_construction_field='year_built', function_field='building_type', @@ -45,34 +34,97 @@ city = GeometryFactory('geojson', ConstructionFactory('nrcan', city).enrich() UsageFactory('nrcan', city).enrich() WeatherFactory('epw', city).enrich() -energy_plus_workflow(city) + +# #energy plus is not going to be processed here, as demand has been obtained before +# energy_plus_workflow(city) + +#SRA algorithm +percentage_data = { + 1646: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2672.550473, "total_floor_area": 26725.50473}, + 1647: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2653.626087, "total_floor_area": 26536.26087}, + 1648: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1056.787496, "total_floor_area": 10567.87496}, + 1649: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1906.620746, "total_floor_area": 19066.20746}, + 1650: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 659.1119416, "total_floor_area": 5272.895533}, + 1651: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1167.208109, "total_floor_area": 9337.664871}, + 1652: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1193.251653, "total_floor_area": 9546.013222}, + 1653: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1491.722543, "total_floor_area": 11933.78035}, + 1654: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1168.005028, "total_floor_area": 9344.040224}, + 1655: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1264.906961, "total_floor_area": 10119.25569}, + 1656: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1281.768818, "total_floor_area": 10254.15054}, + 1657: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 290.3886018, "total_floor_area": 2323.108814}, + 1658: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 847.5095193, "total_floor_area": 6780.076155}, + 1659: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1115.319153, "total_floor_area": 8922.553224}, + 1660: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 469.2918062, "total_floor_area": 3754.33445}, + 1661: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1292.298346, "total_floor_area": 10338.38677}, + 1662: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 625.7828863, "total_floor_area": 5006.263091}, + 1663: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1876.02897, "total_floor_area": 15008.23176}, + 1664: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1118.224781, "total_floor_area": 22364.49562}, + 1665: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1502.787808, "total_floor_area": 30055.75617}, + 1666: {"type1_%": 0.891045711, "type2_%": 0.108954289, "type3_%": 0, "roof_area": 3038.486076, "total_floor_area": 30384.86076}, + 1667: {"type1_%": 0.8, "type2_%": 0.2, "type3_%": 0, "roof_area": 1343.832818, "total_floor_area": 13438.32818}, + 1668: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 961.0996956, "total_floor_area": 4805.498478}, + 1669: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 489.1282111, "total_floor_area": 1956.512845}, + 1673: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 1693.141465, "total_floor_area": 5079.424396}, + 1674: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 3248.827576, "total_floor_area": 9746.482729}, + 1675: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 4086.842191, "total_floor_area": 12260.52657}, + 1676: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2786.114146, "total_floor_area": 11144.45658}, + 1677: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 5142.784184, "total_floor_area": 15428.35255}, + 1678: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 6068.664574, "total_floor_area": 18205.99372}, + 1679: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 5646.751407, "total_floor_area": 16940.25422}, + 1680: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 1601.765953, "total_floor_area": 4805.297859}, + 1681: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 9728.221797, "total_floor_area": 29184.66539}, + 1687: {"type1_%": 0.606611029, "type2_%": 0.28211422, "type3_%": 0.11127475, "roof_area": 4268.608743, "total_floor_area": 59760.52241}, + 1688: {"type1_%": 0.92, "type2_%": 0.08, "type3_%": 0, "roof_area": 2146.654828, "total_floor_area": 38639.7869}, + 1689: {"type1_%": 0.96, "type2_%": 0.04, "type3_%": 0, "roof_area": 2860.270711, "total_floor_area": 57205.41421}, + 1690: {"type1_%": 0.94, "type2_%": 0.06, "type3_%": 0, "roof_area": 2189.732519, "total_floor_area": 28466.52275}, + 1691: {"type1_%": 0.75, "type2_%": 0.25, "type3_%": 0, "roof_area": 3159.077523, "total_floor_area": 31590.77523}, +} + +def enrich_buildings_with_geojson_data (building_type_data, city): + for building in city.buildings: + for idx, feature in enumerate(building_type_data['features']): + if feature['properties']['id'] == str(building.name): + building.heating_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('heating_demand_kWh', [0])] + building.cooling_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('cooling_demand_kWh', [0])] + building.domestic_hot_water_heat_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('domestic_hot_water_heat_demand_kWh', [0])] + building.appliances_electrical_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('appliances_electrical_demand_kWh', [0])] + building.lighting_electrical_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('lighting_electrical_demand_kWh', [0])] + building.heating_demand[cte.MONTH] = MonthlyValues.get_total_month(building.heating_demand[cte.HOUR]) + building.cooling_demand[cte.MONTH] = MonthlyValues.get_total_month(building.cooling_demand[cte.HOUR]) + building.domestic_hot_water_heat_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.domestic_hot_water_heat_demand[cte.HOUR])) + building.appliances_electrical_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.appliances_electrical_demand[cte.HOUR])) + building.lighting_electrical_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.lighting_electrical_demand[cte.HOUR])) + building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.MONTH])] + building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.MONTH])] + building.domestic_hot_water_heat_demand[cte.YEAR] = [sum(building.domestic_hot_water_heat_demand[cte.MONTH])] + building.appliances_electrical_demand[cte.YEAR] = [sum(building.appliances_electrical_demand[cte.MONTH])] + building.lighting_electrical_demand[cte.YEAR] = [sum(building.lighting_electrical_demand[cte.MONTH])] + + + +enrich_buildings_with_geojson_data (building_type_data, city) +print('test') +for building in city.buildings: + building.energy_systems_archetype_name = 'system 1 electricity pv' + + +EnergySystemsFactory('montreal_custom', city).enrich() +# for building in city.buildings: +# energy_systems = building.energy_systems +# for energy_system in energy_systems: +# generation_units = energy_system.generation_systems +# if cte.HEATING in energy_system.demand_types: +# for generation_unit in generation_units: +# generation_unit.heat_efficiency = 0.96 def to_dict(building, total_floor_area): return { 'roof_area': building.floor_area, 'total_floor_area': total_floor_area, - 'year_of_construction' : building.year_of_construction, - 'type_function':building.function, - 'beam_kWh_per_m2': sum(building.beam[cte.HOUR])/ (3.6e6), - 'diffuse_kWh_per_m2': sum(building.diffuse[cte.HOUR])/ (3.6e6), - 'direct_normal_kWh_per_m2': sum(building.direct_normal[cte.HOUR])/ (3.6e6), - 'average_storey_height_meters': building.average_storey_height, - 'max_height_meters_meters': building.max_height, - 'global_horizontal_kWh_per_m2': sum(building.global_horizontal[cte.HOUR])/ (3.6e6), - 'appliances_peak_load_kW':building.appliances_peak_load[cte.YEAR][0]/ (1e3), - 'domestic_hot_water_peak_load_kW': building.domestic_hot_water_peak_load[cte.YEAR][0]/ (1e3), - 'heating_peak_load_kW': building.heating_peak_load[cte.YEAR][0]/ (1e3), - 'cooling_peak_load_kW': building.cooling_peak_load[cte.YEAR][0]/ (1e3), - 'lighting_peak_load_kW': building.lighting_peak_load[cte.YEAR][0]/ (1e3), - 'heating_demand_kWh_per_m2' : sum(building.heating_demand[cte.HOUR])/ (3.6e6 * total_floor_area), - 'cooling_demand_kWh_per_m2' : sum(building.cooling_demand[cte.HOUR])/ (3.6e6 * total_floor_area), - 'domestic_hot_water_heat_demand_kWh_per_m2': sum(building.domestic_hot_water_heat_demand[cte.HOUR])/ (3.6e6 * total_floor_area), - 'appliances_electrical_demand_kWh_per_m2':sum(building.appliances_electrical_demand[cte.HOUR])/ (3.6e6 * total_floor_area), - 'lighting_electrical_demand_kWh_per_m2': sum(building.lighting_electrical_demand[cte.HOUR])/ (3.6e6 * total_floor_area), - 'heating_demand_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.heating_demand[cte.HOUR]], - 'cooling_demand_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.cooling_demand[cte.HOUR]], - 'domestic_hot_water_heat_demand_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.domestic_hot_water_heat_demand[cte.HOUR]], - 'appliances_electrical_demand_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.appliances_electrical_demand[cte.HOUR]], - 'lighting_electrical_demand_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.lighting_electrical_demand[cte.HOUR]] + 'heating_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.energy_consumption_breakdown[cte.HOUR]], + 'cooling_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.cooling_demand[cte.HOUR]], + 'domestic_hot_water_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.domestic_hot_water_heat_demand[cte.HOUR]], + 'appliances_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.appliances_electrical_demand[cte.HOUR]], + 'lighting_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.lighting_electrical_demand[cte.HOUR]] } buildings_dic={} @@ -82,78 +134,15 @@ for building in city.buildings: total_floor_area = 0 for thermal_zone in building.thermal_zones_from_internal_zones: total_floor_area += thermal_zone.total_floor_area - print(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area)) - building.energy_systems_archetype_name = 'system 1 gas' - buildings_dic[building.name] = to_dict(building,total_floor_area) -print('test') - -""""EXPORTERS""" -import pandas as pd -# Convert the dictionary to a DataFrame -df = pd.DataFrame.from_dict(buildings_dic, orient='index') - -# Export the DataFrame to an Excel file -excel_file_path = r'C:\Users\a_gabald\PycharmProjects\summer_course_2024\out_files\buildings.xlsx' -df.to_excel(excel_file_path, index=True, index_label='Building') - -import json -def make_json_serializable(data): - if isinstance(data, (str, int, float, bool, type(None))): - return data - elif isinstance(data, dict): - return {k: make_json_serializable(v) for k, v in data.items()} - elif isinstance(data, list): - return [make_json_serializable(item) for item in data] - else: - return str(data) # Convert any other type to a string - -# Load the existing GeoJSON file - -with open(geojson_file_path, 'r') as f: - geojson_data = json.load(f) - -# Update the properties of each feature -for feature in geojson_data['features']: - # Attempt to retrieve the building_id from 'id' or 'properties' - building_id = feature.get('id') or feature['properties'].get('id') - - if building_id in buildings_dic: - serializable_properties = make_json_serializable(buildings_dic[building_id]) - feature['properties'].update(serializable_properties) - -# Save the updated GeoJSON to a new file -updated_geojson_file_path = r'C:\Users\a_gabald\PycharmProjects\summer_course_2024\out_files\updated_buildings.geojson' # Replace with your actual path -with open(updated_geojson_file_path, 'w') as f: - json.dump(geojson_data, f, indent=4) - - -# EnergySystemsFactory('montreal_custom', city).enrich() -# print('test') -# for building in city.buildings: -# energy_systems = building.energy_systems -# for energy_system in energy_systems: -# generation_units = energy_system.generation_systems -# if cte.HEATING in energy_system.demand_types: -# for generation_unit in generation_units: -# generation_unit.heat_efficiency = 0.96 -# # for building in city.buildings: -# # building.function = cte.COMMERCIAL -# # -# # ConstructionFactory('nrcan', city).enrich() -# # UsageFactory('nrcan', city).enrich() -# # energy_plus_workflow(city) -# # for building in city.buildings: -# # print(building.heating_demand[cte.YEAR][0] / 3.6e6) -# # print(building.name) -# # total_floor_area = 0 -# # for thermal_zone in building.thermal_zones_from_internal_zones: -# # total_floor_area += thermal_zone.total_floor_area -# # print(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area)) # for building in city.buildings: -# print(building.name) -# print(building.year_of_construction) -# print(building.usages_percentage) \ No newline at end of file +# print(building.heating_demand[cte.YEAR][0] / 3.6e6) +# print(building.name) +# total_floor_area = 0 +# for thermal_zone in building.thermal_zones_from_internal_zones: +# total_floor_area += thermal_zone.total_floor_area +# print(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area)) + diff --git a/main_results_in_geojson.py b/main_results_in_geojson.py deleted file mode 100644 index 33c0dd0f..00000000 --- a/main_results_in_geojson.py +++ /dev/null @@ -1,155 +0,0 @@ -from pathlib import Path -from scripts.ep_workflow import energy_plus_workflow -from hub.helpers.monthly_values import MonthlyValues -from hub.imports.geometry_factory import GeometryFactory -from hub.helpers.dictionaries import Dictionaries -from hub.imports.construction_factory import ConstructionFactory -from hub.imports.usage_factory import UsageFactory -from hub.imports.weather_factory import WeatherFactory -import hub.helpers.constants as cte -from hub.imports.energy_systems_factory import EnergySystemsFactory -from hub.helpers.peak_loads import PeakLoads - -import geopandas as gpd -import json -# Specify the GeoJSON file path -input_files_path = (Path(__file__).parent / 'input_files') -output_path = (Path(__file__).parent / 'out_files').resolve() -output_path.mkdir(parents=True, exist_ok=True) -geojson_file_path_baseline = output_path / 'updated_buildings_with_all_data_baseline.geojson' -geojson_file_path = output_path / 'updated_buildings_with_all_data.geojson' -with open(geojson_file_path , 'r') as f: - building_type_data = json.load(f) -with open(geojson_file_path_baseline, 'r') as f: - building_type_data_baseline = json.load(f) - -# Create city object from GeoJSON file -city = GeometryFactory('geojson', - path=geojson_file_path, - height_field='maximum_roof_height', - year_of_construction_field='year_built', - function_field='building_type', - function_to_hub=Dictionaries().montreal_function_to_hub_function).city -# Enrich city data -ConstructionFactory('nrcan', city).enrich() -UsageFactory('nrcan', city).enrich() -WeatherFactory('epw', city).enrich() - -# #energy plus is not going to be processed here, as demand has been obtained before -# energy_plus_workflow(city) -percentage_data = { - 1646: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2672.550473, "total_floor_area": 26725.50473}, - 1647: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2653.626087, "total_floor_area": 26536.26087}, - 1648: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1056.787496, "total_floor_area": 10567.87496}, - 1649: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1906.620746, "total_floor_area": 19066.20746}, - 1650: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 659.1119416, "total_floor_area": 5272.895533}, - 1651: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1167.208109, "total_floor_area": 9337.664871}, - 1652: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1193.251653, "total_floor_area": 9546.013222}, - 1653: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1491.722543, "total_floor_area": 11933.78035}, - 1654: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1168.005028, "total_floor_area": 9344.040224}, - 1655: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1264.906961, "total_floor_area": 10119.25569}, - 1656: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1281.768818, "total_floor_area": 10254.15054}, - 1657: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 290.3886018, "total_floor_area": 2323.108814}, - 1658: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 847.5095193, "total_floor_area": 6780.076155}, - 1659: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1115.319153, "total_floor_area": 8922.553224}, - 1660: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 469.2918062, "total_floor_area": 3754.33445}, - 1661: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1292.298346, "total_floor_area": 10338.38677}, - 1662: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 625.7828863, "total_floor_area": 5006.263091}, - 1663: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1876.02897, "total_floor_area": 15008.23176}, - 1664: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1118.224781, "total_floor_area": 22364.49562}, - 1665: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 1502.787808, "total_floor_area": 30055.75617}, - 1666: {"type1_%": 0.891045711, "type2_%": 0.108954289, "type3_%": 0, "roof_area": 3038.486076, "total_floor_area": 30384.86076}, - 1667: {"type1_%": 0.8, "type2_%": 0.2, "type3_%": 0, "roof_area": 1343.832818, "total_floor_area": 13438.32818}, - 1668: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 961.0996956, "total_floor_area": 4805.498478}, - 1669: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 489.1282111, "total_floor_area": 1956.512845}, - 1673: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 1693.141465, "total_floor_area": 5079.424396}, - 1674: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 3248.827576, "total_floor_area": 9746.482729}, - 1675: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 4086.842191, "total_floor_area": 12260.52657}, - 1676: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 2786.114146, "total_floor_area": 11144.45658}, - 1677: {"type1_%": 1, "type2_%": 0, "type3_%": 0, "roof_area": 5142.784184, "total_floor_area": 15428.35255}, - 1678: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 6068.664574, "total_floor_area": 18205.99372}, - 1679: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 5646.751407, "total_floor_area": 16940.25422}, - 1680: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 1601.765953, "total_floor_area": 4805.297859}, - 1681: {"type1_%": 0.7, "type2_%": 0.3, "type3_%": 0, "roof_area": 9728.221797, "total_floor_area": 29184.66539}, - 1687: {"type1_%": 0.606611029, "type2_%": 0.28211422, "type3_%": 0.11127475, "roof_area": 4268.608743, "total_floor_area": 59760.52241}, - 1688: {"type1_%": 0.92, "type2_%": 0.08, "type3_%": 0, "roof_area": 2146.654828, "total_floor_area": 38639.7869}, - 1689: {"type1_%": 0.96, "type2_%": 0.04, "type3_%": 0, "roof_area": 2860.270711, "total_floor_area": 57205.41421}, - 1690: {"type1_%": 0.94, "type2_%": 0.06, "type3_%": 0, "roof_area": 2189.732519, "total_floor_area": 28466.52275}, - 1691: {"type1_%": 0.75, "type2_%": 0.25, "type3_%": 0, "roof_area": 3159.077523, "total_floor_area": 31590.77523}, -} - -def enrich_buildings_with_geojson_data (building_type_data, city): - for building in city.buildings: - for idx, feature in enumerate(building_type_data['features']): - if feature['properties']['id'] == str(building.name): - building.heating_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('heating_demand_kWh', [0])] - building.cooling_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('cooling_demand_kWh', [0])] - building.domestic_hot_water_heat_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('domestic_hot_water_heat_demand_kWh', [0])] - building.appliances_electrical_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('appliances_electrical_demand_kWh', [0])] - building.lighting_electrical_demand[cte.HOUR] = [x *1000* cte.WATTS_HOUR_TO_JULES for x in building_type_data['features'][idx]['properties'].get('lighting_electrical_demand_kWh', [0])] - building.heating_demand[cte.MONTH] = MonthlyValues.get_total_month(building.heating_demand[cte.HOUR]) - building.cooling_demand[cte.MONTH] = MonthlyValues.get_total_month(building.cooling_demand[cte.HOUR]) - building.domestic_hot_water_heat_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.domestic_hot_water_heat_demand[cte.HOUR])) - building.appliances_electrical_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.appliances_electrical_demand[cte.HOUR])) - building.lighting_electrical_demand[cte.MONTH] = (MonthlyValues.get_total_month(building.lighting_electrical_demand[cte.HOUR])) - building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.MONTH])] - building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.MONTH])] - building.domestic_hot_water_heat_demand[cte.YEAR] = [sum(building.domestic_hot_water_heat_demand[cte.MONTH])] - building.appliances_electrical_demand[cte.YEAR] = [sum(building.appliances_electrical_demand[cte.MONTH])] - building.lighting_electrical_demand[cte.YEAR] = [sum(building.lighting_electrical_demand[cte.MONTH])] - - - -enrich_buildings_with_geojson_data (building_type_data, city) -# for building in city.buildings: -# monthly_values = PeakLoads().peak_loads_from_hourly(building.lighting_electrical_demand[cte.HOUR]) -# building.lighting_peak_load[cte.MONTH]=[x / cte.WATTS_HOUR_TO_JULES for x in monthly_values] -# building.lighting_peak_load[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES] -# monthly_values = PeakLoads().peak_loads_from_hourly(building.appliances_electrical_demand[cte.HOUR]) -# building.appliances_electrical_demand[cte.MONTH]=[x / cte.WATTS_HOUR_TO_JULES for x in monthly_values] -# building.appliances_electrical_demand[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES] - - -print('test') -for building in city.buildings: - building.energy_systems_archetype_name = 'system 1 gas' - - -EnergySystemsFactory('montreal_custom', city).enrich() -for building in city.buildings: - energy_systems = building.energy_systems - for energy_system in energy_systems: - generation_units = energy_system.generation_systems - if cte.HEATING in energy_system.demand_types: - for generation_unit in generation_units: - generation_unit.heat_efficiency = 0.96 -def to_dict(building, total_floor_area): - return { - 'roof_area': building.floor_area, - 'total_floor_area': total_floor_area, - 'heating_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.energy_consumption_breakdown[cte.HOUR]], - # 'cooling_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.cooling_demand[cte.HOUR]], - # 'domestic_hot_water_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.domestic_hot_water_heat_demand[cte.HOUR]], - # 'appliances_consumption_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.appliances_electrical_demand[cte.HOUR]], - # 'lighting_consumption_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.lighting_electrical_demand[cte.HOUR]] - } -buildings_dic={} - - -for building in city.buildings: - - total_floor_area = 0 - for thermal_zone in building.thermal_zones_from_internal_zones: - total_floor_area += thermal_zone.total_floor_area - print(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area)) - - - -# for building in city.buildings: -# print(building.heating_demand[cte.YEAR][0] / 3.6e6) -# print(building.name) -# total_floor_area = 0 -# for thermal_zone in building.thermal_zones_from_internal_zones: -# total_floor_area += thermal_zone.total_floor_area -# print(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area)) - diff --git a/old_main.py b/old_main.py new file mode 100644 index 00000000..349e9be9 --- /dev/null +++ b/old_main.py @@ -0,0 +1,159 @@ +from pathlib import Path +from scripts.ep_workflow import energy_plus_workflow +from hub.imports.geometry_factory import GeometryFactory +from hub.helpers.dictionaries import Dictionaries +from hub.imports.construction_factory import ConstructionFactory +from hub.imports.usage_factory import UsageFactory +from hub.imports.weather_factory import WeatherFactory +import hub.helpers.constants as cte +from hub.imports.energy_systems_factory import EnergySystemsFactory +import geopandas as gpd +# Specify the GeoJSON file path +input_files_path = (Path(__file__).parent / 'input_files') + +building_type_2_modelling=2 +#'Lachine_New_Developments.geojson' +geojson_file_path = input_files_path / 'Lachine_moved_2024_type.geojson' +if building_type_2_modelling==1: + gdf = gpd.read_file(geojson_file_path) + # Filter gdf when 'building_type_2' is not null + filtered_gdf = gdf[gdf['building_type_2'].notnull()] + output_geojson =input_files_path /'Lachine_moved_2024_type_2.geojson' + geojson_file_path =output_geojson + filtered_gdf.to_file(output_geojson, driver='GeoJSON') + print(f"New GeoJSON saved in: {output_geojson}") +if building_type_2_modelling==2: + gdf = gpd.read_file(geojson_file_path) + # Filter gdf when 'building_type_3' is not null + filtered_gdf = gdf[gdf['building_type_3'].notnull()] + output_geojson =input_files_path /'Lachine_moved_2024_type_3.geojson' + geojson_file_path = output_geojson + filtered_gdf.to_file(output_geojson, driver='GeoJSON') + print(f"New GeoJSON saved in: {output_geojson}") + + +output_path = (Path(__file__).parent / 'out_files').resolve() +output_path.mkdir(parents=True, exist_ok=True) +# Create city object from GeoJSON file +city = GeometryFactory('geojson', + path=geojson_file_path, + height_field='maximum_roof_height', + year_of_construction_field='year_built', + function_field='building_type', + function_to_hub=Dictionaries().montreal_function_to_hub_function).city +# Enrich city data +ConstructionFactory('nrcan', city).enrich() +UsageFactory('nrcan', city).enrich() +WeatherFactory('epw', city).enrich() +energy_plus_workflow(city) +def to_dict(building, total_floor_area): + return { + 'roof_area': building.floor_area, + 'total_floor_area': total_floor_area, + 'year_of_construction' : building.year_of_construction, + 'type_function':building.function, + 'beam_kWh_per_m2': sum(building.beam[cte.HOUR])/ (3.6e6), + 'diffuse_kWh_per_m2': sum(building.diffuse[cte.HOUR])/ (3.6e6), + 'direct_normal_kWh_per_m2': sum(building.direct_normal[cte.HOUR])/ (3.6e6), + 'average_storey_height_meters': building.average_storey_height, + 'max_height_meters_meters': building.max_height, + 'global_horizontal_kWh_per_m2': sum(building.global_horizontal[cte.HOUR])/ (3.6e6), + 'appliances_peak_load_kW':building.appliances_peak_load[cte.YEAR][0]/ (1e3), + 'domestic_hot_water_peak_load_kW': building.domestic_hot_water_peak_load[cte.YEAR][0]/ (1e3), + 'heating_peak_load_kW': building.heating_peak_load[cte.YEAR][0]/ (1e3), + 'cooling_peak_load_kW': building.cooling_peak_load[cte.YEAR][0]/ (1e3), + 'lighting_peak_load_kW': building.lighting_peak_load[cte.YEAR][0]/ (1e3), + 'heating_demand_kWh_per_m2' : sum(building.heating_demand[cte.HOUR])/ (3.6e6 * total_floor_area), + 'cooling_demand_kWh_per_m2' : sum(building.cooling_demand[cte.HOUR])/ (3.6e6 * total_floor_area), + 'domestic_hot_water_heat_demand_kWh_per_m2': sum(building.domestic_hot_water_heat_demand[cte.HOUR])/ (3.6e6 * total_floor_area), + 'appliances_electrical_demand_kWh_per_m2':sum(building.appliances_electrical_demand[cte.HOUR])/ (3.6e6 * total_floor_area), + 'lighting_electrical_demand_kWh_per_m2': sum(building.lighting_electrical_demand[cte.HOUR])/ (3.6e6 * total_floor_area), + 'heating_demand_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.heating_demand[cte.HOUR]], + 'cooling_demand_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.cooling_demand[cte.HOUR]], + 'domestic_hot_water_heat_demand_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.domestic_hot_water_heat_demand[cte.HOUR]], + 'appliances_electrical_demand_kWh':[x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.appliances_electrical_demand[cte.HOUR]], + 'lighting_electrical_demand_kWh': [x / (cte.WATTS_HOUR_TO_JULES * 1000) for x in building.lighting_electrical_demand[cte.HOUR]] + } +buildings_dic={} + + +for building in city.buildings: + + total_floor_area = 0 + for thermal_zone in building.thermal_zones_from_internal_zones: + total_floor_area += thermal_zone.total_floor_area + print(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area)) + building.energy_systems_archetype_name = 'system 1 gas' + buildings_dic[building.name] = to_dict(building,total_floor_area) +print('test') + +""""EXPORTERS""" +import pandas as pd +# Convert the dictionary to a DataFrame +df = pd.DataFrame.from_dict(buildings_dic, orient='index') + +# Export the DataFrame to an Excel file +excel_file_path = r'C:\Users\a_gabald\PycharmProjects\summer_course_2024\out_files\buildings.xlsx' +df.to_excel(excel_file_path, index=True, index_label='Building') + +import json + + +def make_json_serializable(data): + if isinstance(data, (str, int, float, bool, type(None))): + return data + elif isinstance(data, dict): + return {k: make_json_serializable(v) for k, v in data.items()} + elif isinstance(data, list): + return [make_json_serializable(item) for item in data] + else: + return str(data) # Convert any other type to a string + +# Load the existing GeoJSON file + +with open(geojson_file_path, 'r') as f: + geojson_data = json.load(f) + +# Update the properties of each feature +for feature in geojson_data['features']: + # Attempt to retrieve the building_id from 'id' or 'properties' + building_id = feature.get('id') or feature['properties'].get('id') + + if building_id in buildings_dic: + serializable_properties = make_json_serializable(buildings_dic[building_id]) + feature['properties'].update(serializable_properties) + +# Save the updated GeoJSON to a new file +updated_geojson_file_path = r'C:\Users\a_gabald\PycharmProjects\summer_course_2024\out_files\updated_buildings.geojson' # Replace with your actual path +with open(updated_geojson_file_path, 'w') as f: + json.dump(geojson_data, f, indent=4) + + +# EnergySystemsFactory('montreal_custom', city).enrich() +# print('test') +# for building in city.buildings: +# energy_systems = building.energy_systems +# for energy_system in energy_systems: +# generation_units = energy_system.generation_systems +# if cte.HEATING in energy_system.demand_types: +# for generation_unit in generation_units: +# generation_unit.heat_efficiency = 0.96 +# # for building in city.buildings: +# # building.function = cte.COMMERCIAL +# # +# # ConstructionFactory('nrcan', city).enrich() +# # UsageFactory('nrcan', city).enrich() +# # energy_plus_workflow(city) +# # for building in city.buildings: +# # print(building.heating_demand[cte.YEAR][0] / 3.6e6) +# # print(building.name) +# # total_floor_area = 0 +# # for thermal_zone in building.thermal_zones_from_internal_zones: +# # total_floor_area += thermal_zone.total_floor_area +# # print(building.heating_demand[cte.YEAR][0] / (3.6e6 * total_floor_area)) + + +# for building in city.buildings: +# print(building.name) +# print(building.year_of_construction) +# print(building.usages_percentage) \ No newline at end of file