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 from pathlib import Path import subprocess from hub.imports.results_factory import ResultFactory from hub.imports.energy_systems_factory import EnergySystemsFactory from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory import hub.helpers.constants as cte from hub.exports.exports_factory import ExportsFactory from scripts.solar_angles import CitySolarAngles from scripts.radiation_tilted import RadiationTilted 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) energy_plus_output_path = output_path / 'energy_plus_outputs' energy_plus_output_path.mkdir(parents=True, exist_ok=True) simulation_results_path = (Path(__file__).parent / 'out_files' / 'simulation_results').resolve() simulation_results_path.mkdir(parents=True, exist_ok=True) sra_output_path = output_path / 'sra_outputs' sra_output_path.mkdir(parents=True, exist_ok=True) cost_analysis_output_path = output_path / 'cost_analysis' cost_analysis_output_path.mkdir(parents=True, exist_ok=True) #%%----------------------------------------------- #"""add geojson paths and create city for Baseline""" #%% # ----------------------------------------------- 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_baseline, 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) #%%----------------------------------------------- # """SRA""" #%% # ----------------------------------------------- ExportsFactory('sra', city, sra_output_path).export() sra_path = (sra_output_path / f'{city.name}_sra.xml').resolve() subprocess.run(['sra', str(sra_path)]) ResultFactory('sra', city, sra_output_path).enrich() solar_angles = CitySolarAngles(city.name, city.latitude, city.longitude, tilt_angle=45, surface_azimuth_angle=180).calculate for building in city.buildings: ghi = [x / cte.WATTS_HOUR_TO_JULES for x in building.roofs[0].global_irradiance[cte.HOUR]] RadiationTilted(building, solar_angles, tilt_angle=45, ghi=ghi).enrich() # building_names = [] # for building in city.buildings: # building_names.append(building.name) # # df = pd.DataFrame(columns=building_names) # df1 = pd.DataFrame(columns=building_names) # print('test') # for building in city.buildings: # # if building.name in selected_buildings_list: # df[f'{building.name}'] = building.roofs[0].global_irradiance[cte.HOUR] # df1[f'{building.name}'] = building.roofs[0].global_irradiance_tilted[cte.HOUR] # # df.to_csv('solar_radiation_horizontal_selected_buildings.csv') # df1.to_csv('solar_radiation_tilted_selected_buildings.csv') #%% # ----------------------------------------------- #"""Enrich city with geojson file data""" #%% # ----------------------------------------------- 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') #%%----------------------------------------------- # """ADD energy systems""" #%% # ----------------------------------------------- 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, '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 # 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: # building.energy_systems_archetype_name = 'PV+4Pipe+DHW' # EnergySystemsFactory('montreal_future', city).enrich() # for building in city.buildings: # EnergySystemsSimulationFactory('archetype13', building=building, output_path=simulation_results_path).enrich()