From 355cc6ecdf1a7ab2dde91962f5056cfc1ddbeab8 Mon Sep 17 00:00:00 2001 From: guille Date: Thu, 28 Mar 2024 06:59:57 +0100 Subject: [PATCH] bugfix in idf exporter --- hub/exports/building_energy/idf.py | 96 +++++------------------------- 1 file changed, 14 insertions(+), 82 deletions(-) diff --git a/hub/exports/building_energy/idf.py b/hub/exports/building_energy/idf.py index ee0471ff..cf1646e3 100644 --- a/hub/exports/building_energy/idf.py +++ b/hub/exports/building_energy/idf.py @@ -54,14 +54,6 @@ class Idf: _SIZING_PERIODS = 'SIZINGPERIOD:DESIGNDAY' _LOCATION = 'SITE:LOCATION' _SIMPLE = 'Simple' - _EQUIPMENT_CONNECTIONS = 'ZONEHVAC:EQUIPMENTCONNECTIONS' - _NODE_LIST = 'NODELIST' - _BASEBOARD = 'ZONEHVAC:BASEBOARD:CONVECTIVE:ELECTRIC' - _AIR_TERMINAL_NO_REHEAT = 'AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:NOREHEAT' - _AIR_DISTRIBUTION = 'ZONEHVAC:AIRDISTRIBUTIONUNIT' - _EQUIPMENT_LIST = 'ZONEHVAC:EQUIPMENTLIST' - _SIZING_ZONE = 'SIZING:ZONE' - _DESIGN_SPECIFICATION_OUTDOOR_AIR = 'DESIGNSPECIFICATION:OUTDOORAIR' idf_surfaces = { cte.WALL: 'wall', @@ -125,8 +117,7 @@ class Idf: if levels_of_detail.construction is None: raise AttributeError('Level of detail of construction not assigned') if levels_of_detail.construction < 2: - raise AttributeError( - f'Level of detail of construction = {levels_of_detail.construction}. Required minimum level 2') + raise AttributeError(f'Level of detail of construction = {levels_of_detail.construction}. Required minimum level 2') if levels_of_detail.usage is None: raise AttributeError('Level of detail of usage not assigned') if levels_of_detail.usage < 2: @@ -357,7 +348,7 @@ class Idf: def _add_window_construction_and_material(self, thermal_opening): for window_material in self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]: if window_material['UFactor'] == thermal_opening.overall_u_value and \ - window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value: + window_material['Solar_Heat_Gain_Coefficient'] == thermal_opening.g_value: return order = str(len(self._idf.idfobjects[self._WINDOW_MATERIAL_SIMPLE]) + 1) @@ -390,86 +381,22 @@ class Idf: ) def _add_heating_system(self, thermal_zone, zone_name): - for air_system in self._idf.idfobjects[self._EQUIPMENT_CONNECTIONS]: + for air_system in self._idf.idfobjects[self._IDEAL_LOAD_AIR_SYSTEM]: if air_system.Zone_Name == zone_name: return thermostat = self._add_thermostat(thermal_zone) - self._idf.newidfobject(self._EQUIPMENT_CONNECTIONS, + self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM, Zone_Name=zone_name, - Zone_Conditioning_Equipment_List_Name=f'{zone_name} Equipment List', - Zone_Air_Inlet_Node_or_NodeList_Name=f'{zone_name} Inlet Node List', - Zone_Air_Node_Name=f'Node 1', - Zone_Return_Air_Node_or_NodeList_Name=f'{zone_name} Return Node List') - - def _add_nodelist_system(self, thermal_zone, zone_name): - self._idf.newidfobject(self._NODE_LIST, - Name=f'{zone_name} Inlet Node List', - Node_1_Name='Node 2') - self._idf.newidfobject(self._NODE_LIST, - Name=f'{zone_name} Return Node List', - Node_1_Name='Node 3') - - def _add_baseboard_system(self, thermal_zone, zone_name): - for baseboard in self._idf.idfobjects[self._BASEBOARD]: - if baseboard.Zone_Name == zone_name: - return - self._idf.newidfobject(self._BASEBOARD, Name=f'Elec Baseboard',Availability_Schedule_Name='HVAC AVAIL') - - def _add_air_terminal_system(self, thermal_zone, zone_name): - """for air_terminal in self._idf.idfobjects[self._AIR_TERMINAL_NO_REHEAT]: - if air_terminal.Zone_Name == zone_name: - return""" - self._idf.newidfobject(self._AIR_TERMINAL_NO_REHEAT, Name=f'Diffuser', - Availability_Schedule_Name='HVAC AVAIL', - Air_Inlet_Node_Name='Node 4', - Air_Outlet_Node_Name='Node 2', - Maximum_Air_Flow_Rate='AutoSize') - - def _add_air_distribution_system(self, thermal_zone, zone_name): - for air_distribution in self._idf.idfobjects[self._AIR_DISTRIBUTION]: - if air_distribution.Zone_Name == zone_name: - return - self._idf.newidfobject(self._AIR_DISTRIBUTION, - Name='ADU Diffuser', - Air_Distribution_Unit_Outlet_Node_Name='Node 2', - Air_Terminal_Object_Type='AirTerminal:SingleDuct:ConstantVolume:NoReheat', - Air_Terminal_Name='Diffuser') - - def _add_equipment_list_system(self, thermal_zone, zone_name): - for air_distribution in self._idf.idfobjects[self._EQUIPMENT_LIST]: - if air_distribution.Zone_Name == zone_name: - return - self._idf.newidfobject(self._EQUIPMENT_LIST, - Name=f'{zone_name} Equipment List', - Load_Distribution_Scheme='SequentialLoad', - Zone_Equipment_1_Object_Type='ZoneHVAC:Baseboard:Convective:Electric', - Zone_Equipment_1_Name='Elec Baseboard', - Zone_Equipment_1_Cooling_Sequence='1', - Zone_Equipment_1_Heating_or_NoLoad_Sequence='1', - Zone_Equipment_2_Object_Type='ZoneHVAC:AirDistributionUnit', - Zone_Equipment_2_Name='ADU Diffuser', - Zone_Equipment_2_Cooling_Sequence='2', - Zone_Equipment_2_Heating_or_NoLoad_Sequence='2' - ) - - def _add_sizing_zone(self, thermal_zone, zone_name): - koa=self._idf.newidfobject(self._SIZING_ZONE, - Zone_or_ZoneList_Name=f'{zone_name}', - Zone_Cooling_Design_Supply_Air_Humidity_Ratio='0.0085', - Zone_Heating_Design_Supply_Air_Humidity_Ratio='0.008' - ) - - def _add_outdoor_air_design_specification(self, thermal_zone, zone_name): - self._idf.newidfobject(self._DESIGN_SPECIFICATION_OUTDOOR_AIR, - Name='MidriseApartment Apartment Ventilation', - Outdoor_Air_Method='Sum', - Outdoor_Air_Flow_per_Person='0.0169901079552') + System_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}', + Heating_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}', + Cooling_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}', + Template_Thermostat_Name=thermostat.Name) def _add_occupancy(self, thermal_zone, zone_name): number_of_people = thermal_zone.occupancy.occupancy_density * thermal_zone.total_floor_area fraction_radiant = 0 total_sensible = ( - thermal_zone.occupancy.sensible_radiative_internal_gain + thermal_zone.occupancy.sensible_convective_internal_gain + thermal_zone.occupancy.sensible_radiative_internal_gain + thermal_zone.occupancy.sensible_convective_internal_gain ) if total_sensible != 0: fraction_radiant = thermal_zone.occupancy.sensible_radiative_internal_gain / total_sensible @@ -626,6 +553,10 @@ class Idf: self._add_zone(thermal_zone, building.name) self._add_heating_system(thermal_zone, building.name) self._add_infiltration(thermal_zone, building.name) + self._add_ventilation(thermal_zone, building.name) + self._add_occupancy(thermal_zone, building.name) + self._add_lighting(thermal_zone, building.name) + self._add_appliances(thermal_zone, building.name) self._add_dhw(thermal_zone, building.name) if self._export_type == "Surfaces": if building.name in self._target_buildings or building.name in self._adjacent_buildings: @@ -679,6 +610,7 @@ class Idf: windows_list.append(window) for window in windows_list: self._idf.removeidfobject(window) + self._idf.saveas(str(self._output_file)) return self._idf