Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
0c74ff26e7 | |||
7fbc199479 | |||
a6f9425068 | |||
39951a76a9 | |||
0015a3efd7 | |||
32ed8671d8 | |||
6ab8d88173 | |||
bc5f4f842c | |||
60f329ef4f | |||
c6acddc1e8 | |||
ffabcb29f6 | |||
42b1d363a6 | |||
201d9ed7f2 | |||
e544eb2ed5 | |||
8ea416dd6c |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -10,3 +10,4 @@
|
|||
**/__pycache__/
|
||||
**/.idea/
|
||||
cerc_hub.egg-info
|
||||
dist
|
|
@ -190,7 +190,7 @@ class ComnetCatalog(Catalog):
|
|||
schedules_key = {}
|
||||
for j in range(0, number_usage_types-1):
|
||||
usage_parameters = _extracted_data.iloc[j]
|
||||
usage_type = usage_parameters[0]
|
||||
usage_type = usage_parameters.iloc[0]
|
||||
lighting_data[usage_type] = usage_parameters[1:6].values.tolist()
|
||||
plug_loads_data[usage_type] = usage_parameters[8:13].values.tolist()
|
||||
occupancy_data[usage_type] = usage_parameters[17:20].values.tolist()
|
||||
|
|
|
@ -359,6 +359,8 @@ class City:
|
|||
Get city latitude in degrees
|
||||
:return: None or float
|
||||
"""
|
||||
if self._latitude is None:
|
||||
return self._get_location().climate_reference_city_latitude
|
||||
return self._latitude
|
||||
|
||||
@latitude.setter
|
||||
|
@ -376,6 +378,8 @@ class City:
|
|||
Get city longitude in degrees
|
||||
:return: None or float
|
||||
"""
|
||||
if self._longitude is None:
|
||||
return self._get_location().climate_reference_city_longitude
|
||||
return self._longitude
|
||||
|
||||
@longitude.setter
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,157 +0,0 @@
|
|||
! Minimal.idf
|
||||
! Basic file description: This is a minimal configuration necessary to run.
|
||||
! Highlights: Illustrates minimal items necessary to perform run.
|
||||
! BUILDING, SURFACEGEOMETRY, LOCATION and DESIGNDAY (or RUNPERIOD) are the absolute minimal required input objects.
|
||||
! TIME STEP IN HOUR is included so as to not get warning error.
|
||||
! Including two design days, Run Control object and RunPeriod to facilitate use.
|
||||
! Although not incredibly useful, this could be used as a weather/solar calculator.
|
||||
! Simulation Location/Run: Denver is included. Any could be used.
|
||||
! Building: None.
|
||||
!
|
||||
! Internal gains description: None.
|
||||
!
|
||||
! HVAC: None.
|
||||
!
|
||||
|
||||
Version,9.5;
|
||||
|
||||
Timestep,4;
|
||||
|
||||
Building,
|
||||
None, !- Name
|
||||
0.0000000E+00, !- North Axis {deg}
|
||||
Suburbs, !- Terrain
|
||||
0.04, !- Loads Convergence Tolerance Value {W}
|
||||
0.40, !- Temperature Convergence Tolerance Value {deltaC}
|
||||
FullInteriorAndExterior, !- Solar Distribution
|
||||
25, !- Maximum Number of Warmup Days
|
||||
6; !- Minimum Number of Warmup Days
|
||||
|
||||
GlobalGeometryRules,
|
||||
UpperLeftCorner, !- Starting Vertex Position
|
||||
CounterClockWise, !- Vertex Entry Direction
|
||||
World; !- Coordinate System
|
||||
|
||||
Site:Location,
|
||||
DENVER_STAPLETON_CO_USA_WMO_724690, !- Name
|
||||
39.77, !- Latitude {deg}
|
||||
-104.87, !- Longitude {deg}
|
||||
-7.00, !- Time Zone {hr}
|
||||
1611.00; !- Elevation {m}
|
||||
|
||||
! DENVER_STAPLETON_CO_USA Annual Heating Design Conditions Wind Speed=2.3m/s Wind Dir=180
|
||||
! Coldest Month=December
|
||||
! DENVER_STAPLETON_CO_USA Annual Heating 99.6%, MaxDB=-20°C
|
||||
|
||||
SizingPeriod:DesignDay,
|
||||
DENVER_STAPLETON Ann Htg 99.6% Condns DB, !- Name
|
||||
12, !- Month
|
||||
21, !- Day of Month
|
||||
WinterDesignDay, !- Day Type
|
||||
-20, !- Maximum Dry-Bulb Temperature {C}
|
||||
0.0, !- Daily Dry-Bulb Temperature Range {deltaC}
|
||||
, !- Dry-Bulb Temperature Range Modifier Type
|
||||
, !- Dry-Bulb Temperature Range Modifier Day Schedule Name
|
||||
Wetbulb, !- Humidity Condition Type
|
||||
-20, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C}
|
||||
, !- Humidity Condition Day Schedule Name
|
||||
, !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir}
|
||||
, !- Enthalpy at Maximum Dry-Bulb {J/kg}
|
||||
, !- Daily Wet-Bulb Temperature Range {deltaC}
|
||||
83411., !- Barometric Pressure {Pa}
|
||||
2.3, !- Wind Speed {m/s}
|
||||
180, !- Wind Direction {deg}
|
||||
No, !- Rain Indicator
|
||||
No, !- Snow Indicator
|
||||
No, !- Daylight Saving Time Indicator
|
||||
ASHRAEClearSky, !- Solar Model Indicator
|
||||
, !- Beam Solar Day Schedule Name
|
||||
, !- Diffuse Solar Day Schedule Name
|
||||
, !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless}
|
||||
, !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless}
|
||||
0.00; !- Sky Clearness
|
||||
|
||||
! DENVER_STAPLETON Annual Cooling Design Conditions Wind Speed=4m/s Wind Dir=120
|
||||
! Hottest Month=July
|
||||
! DENVER_STAPLETON_CO_USA Annual Cooling (DB=>MWB) .4%, MaxDB=34.1°C MWB=15.8°C
|
||||
|
||||
SizingPeriod:DesignDay,
|
||||
DENVER_STAPLETON Ann Clg .4% Condns DB=>MWB, !- Name
|
||||
7, !- Month
|
||||
21, !- Day of Month
|
||||
SummerDesignDay, !- Day Type
|
||||
34.1, !- Maximum Dry-Bulb Temperature {C}
|
||||
15.2, !- Daily Dry-Bulb Temperature Range {deltaC}
|
||||
, !- Dry-Bulb Temperature Range Modifier Type
|
||||
, !- Dry-Bulb Temperature Range Modifier Day Schedule Name
|
||||
Wetbulb, !- Humidity Condition Type
|
||||
15.8, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C}
|
||||
, !- Humidity Condition Day Schedule Name
|
||||
, !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir}
|
||||
, !- Enthalpy at Maximum Dry-Bulb {J/kg}
|
||||
, !- Daily Wet-Bulb Temperature Range {deltaC}
|
||||
83411., !- Barometric Pressure {Pa}
|
||||
4, !- Wind Speed {m/s}
|
||||
120, !- Wind Direction {deg}
|
||||
No, !- Rain Indicator
|
||||
No, !- Snow Indicator
|
||||
No, !- Daylight Saving Time Indicator
|
||||
ASHRAEClearSky, !- Solar Model Indicator
|
||||
, !- Beam Solar Day Schedule Name
|
||||
, !- Diffuse Solar Day Schedule Name
|
||||
, !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless}
|
||||
, !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless}
|
||||
1.00; !- Sky Clearness
|
||||
|
||||
RunPeriod,
|
||||
Run Period 1, !- Name
|
||||
1, !- Begin Month
|
||||
1, !- Begin Day of Month
|
||||
, !- Begin Year
|
||||
12, !- End Month
|
||||
31, !- End Day of Month
|
||||
, !- End Year
|
||||
Tuesday, !- Day of Week for Start Day
|
||||
Yes, !- Use Weather File Holidays and Special Days
|
||||
Yes, !- Use Weather File Daylight Saving Period
|
||||
No, !- Apply Weekend Holiday Rule
|
||||
Yes, !- Use Weather File Rain Indicators
|
||||
Yes; !- Use Weather File Snow Indicators
|
||||
|
||||
SimulationControl,
|
||||
No, !- Do Zone Sizing Calculation
|
||||
No, !- Do System Sizing Calculation
|
||||
No, !- Do Plant Sizing Calculation
|
||||
No, !- Run Simulation for Sizing Periods
|
||||
Yes, !- Run Simulation for Weather File Run Periods
|
||||
No, !- Do HVAC Sizing Simulation for Sizing Periods
|
||||
1; !- Maximum Number of HVAC Sizing Simulation Passes
|
||||
|
||||
Output:Table:SummaryReports, AnnualBuildingUtilityPerformanceSummary,
|
||||
DemandEndUseComponentsSummary,
|
||||
SensibleHeatGainSummary,
|
||||
InputVerificationandResultsSummary,
|
||||
AdaptiveComfortSummary,
|
||||
Standard62.1Summary,
|
||||
ClimaticDataSummary,
|
||||
EquipmentSummary,
|
||||
EnvelopeSummary,
|
||||
LightingSummary,
|
||||
HVACSizingSummary,
|
||||
SystemSummary,
|
||||
ComponentSizingSummary,
|
||||
OutdoorAirSummary,
|
||||
ObjectCountSummary,
|
||||
EndUseEnergyConsumptionOtherFuelsMonthly,
|
||||
PeakEnergyEndUseOtherFuelsMonthly;
|
||||
|
||||
|
||||
OutputControl:Table:Style, CommaAndHTML,JtoKWH;
|
||||
|
||||
Output:Meter,DISTRICTHEATING:Facility,hourly;
|
||||
Output:Meter,DISTRICTCOOLING:Facility,hourly;
|
||||
Output:Meter,InteriorEquipment:Electricity,hourly;
|
||||
Output:Meter,InteriorLights:Electricity,hourly;
|
||||
|
||||
OutputControl:IlluminanceMap:Style,
|
||||
Comma; !- Column separator
|
317
hub/exports/building_energy/trnsys.py
Normal file
317
hub/exports/building_energy/trnsys.py
Normal file
|
@ -0,0 +1,317 @@
|
|||
"""
|
||||
export a city into B18 (TRNSYS 18) format
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
import json
|
||||
import math
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from urllib.error import URLError
|
||||
from urllib.request import urlopen
|
||||
|
||||
import pytz
|
||||
from timezonefinder import TimezoneFinder
|
||||
|
||||
from hub.version import __version__
|
||||
import hub.helpers.constants as cte
|
||||
|
||||
|
||||
class Trnsys:
|
||||
"""
|
||||
TRNSYS class
|
||||
"""
|
||||
|
||||
def __init__(self, city, path, target_buildings=None):
|
||||
self._city = city
|
||||
self._path = path
|
||||
self._buildings = self._city.buildings
|
||||
self._tf = TimezoneFinder()
|
||||
|
||||
if target_buildings is not None:
|
||||
buildings = []
|
||||
for building in target_buildings:
|
||||
buildings.append(self._city.city_object(building))
|
||||
self._buildings = buildings
|
||||
print("trnsys constructor completed")
|
||||
self.export()
|
||||
|
||||
def _header(self, f, building):
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Cerc Hub {__version__}\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('* Building descriptions file TRNSYS\n')
|
||||
location = (
|
||||
self._city.latitude, self._city.longitude
|
||||
)
|
||||
f.write(f'* Export: {self._city.location.city} {self._city.location.country} {location}\n')
|
||||
f.write(f'* For building: {building.name}')
|
||||
if building.aliases is not None:
|
||||
f.write(f' {building.aliases})')
|
||||
f.write('\n')
|
||||
f.write(f'* Total floors: {building.storeys_above_ground}\n')
|
||||
f.write(f'* Year build: {building.year_of_construction}\n')
|
||||
f.write('***************************************\n')
|
||||
|
||||
def _properties(self, f):
|
||||
latitude = self._city.latitude
|
||||
longitude = self._city.longitude
|
||||
utc_offset = datetime.now(
|
||||
pytz.timezone(self._tf.timezone_at(lng=longitude, lat=latitude))
|
||||
).utcoffset().total_seconds()/60/60
|
||||
elevation = 200
|
||||
try:
|
||||
elevation = json.loads(
|
||||
urlopen(f'https://api.open-elevation.com/api/v1/lookup?locations={latitude},{longitude}').read()
|
||||
)['results'][0]['elevation']
|
||||
except URLError:
|
||||
pass
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Properties\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('PROPERTIES\n')
|
||||
# todo: from where does this values come from?
|
||||
f.write(f' DENSITY=1.204 : CAPACITY=1.012 : PRESSURE=101325.000 : HVAPOR=2454.0 : SIGMA=2.041e-007 : RTEMP=293.15\n')
|
||||
f.write('* Convective heat transfer coefficient calculation\n')
|
||||
f.write(' KFLOORUP=7.2 : EFLOORUP=0.31 : KFLOORDOWN=3.888 : EFLOORDOWN=0.31\n')
|
||||
f.write(' KCEILUP=7.2 : ECEILUP=0.31 : KCEILDOWN=3.888 : ECEILDOWN=0.31\n')
|
||||
f.write(' KVERTICAL=5.76 : EVERTICAL=0.3\n')
|
||||
f.write('* Radiance parameters\n')
|
||||
f.write(' SCENE_ROTATION_ANGLE=0 : GROUND_IDS= : GROUND_REFLECTANCE=0.2 : SHADER_REFLECTANCE=0\n')
|
||||
f.write(f' CALC_MODE=RAD : LATITUDE={latitude} : LONGITUDE={longitude} : TIME_ZONE={utc_offset} : SITE_ELEVATION={elevation}\n')
|
||||
f.write(' AB=5 : AD=1000 : AS=20 : AR=300 : AA=0.1\n')
|
||||
f.write(' LR=6 : ST=0.15 : SJ=1 : LW=0.004 : DJ=0 : DS=0.2 : DR=2 : DP=512\n')
|
||||
f.write('* Comfort parameters\n')
|
||||
f.write(' DIAM-SENSOR=0.07 : EPS-SENSOR=0.82 : REFL-SENSOR=0.47 : ELV_AIRSPEED1=0.3 : ELV_AIRSPEED2=0.7 : ELV_AIRSPEED3=1.2\n')
|
||||
f.write('* Other parameters\n')
|
||||
f.write(' FSCAL_TREGENZA=MEDIUM : SHM_MODE=0 : SURFGRID=0.2\n')
|
||||
f.write('* Daylight parameters\n')
|
||||
f.write(' UDIMIN=100 : UDIMAX=2000 : DAMIN=300\n')
|
||||
|
||||
@staticmethod
|
||||
def _types(f, building):
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Types\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Layers\n')
|
||||
f.write('***************************************\n')
|
||||
layers = {}
|
||||
|
||||
for thermal_zone in building.thermal_zones_from_internal_zones:
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
for layer in thermal_boundary.layers:
|
||||
capacity = 0
|
||||
conductivity = 0
|
||||
density = 0
|
||||
if layer.thermal_absorptance is not None:
|
||||
capacity = layer.thermal_absorptance
|
||||
if layer.conductivity is not None:
|
||||
conductivity = layer.conductivity
|
||||
if layer.density is not None:
|
||||
density = layer.density
|
||||
|
||||
layers[layer.material_name] = {
|
||||
'conductivity': conductivity,
|
||||
'capacity': capacity, # todo: transform units
|
||||
'density': density,
|
||||
'pert': '0',
|
||||
'penrt': '0'
|
||||
}
|
||||
f.write('PROPERTIES\n')
|
||||
for name, values in layers.items():
|
||||
f.write(f'LAYER {name.replace(" ", "_").upper()}\n')
|
||||
for attribute, value in values.items():
|
||||
f.write(f'{attribute.upper()}=\t{value}\t')
|
||||
f.write('\n')
|
||||
|
||||
@staticmethod
|
||||
def _inputs(f):
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Inputs\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('INPUTS TGROUND TBOUNDARY SHADE_CLOSE SHADE_OPEN MAX_ISHADE MAX_ESHADE\n')
|
||||
f.write('INPUTS_DESCRIPTION\n')
|
||||
f.write('TGROUND : C : Ground Temperature (boundary temperature used for floors adjacent to the ground)\n')
|
||||
f.write('TBOUNDARY : C : Boundary Temperature (boundary temperature used for boundary floors, walls, ceilings)\n')
|
||||
f.write('SHADE_CLOSE : kJ/hr.m^2 : threshold of total radiation on facade where shading device is activated\n')
|
||||
f.write('SHADE_OPEN : kJ/hr.m^2 : threshold of total radiation on facade where shading device is deactivated\n')
|
||||
f.write('MAX_ISHADE : any : max shading factor of internal shading\n')
|
||||
f.write('MAX_ESHADE : any : max shading factor of external shading\n')
|
||||
|
||||
@staticmethod
|
||||
def _add_schedule(f, schedule, name):
|
||||
if schedule.time_step is cte.HOUR:
|
||||
for day_type in schedule.day_types:
|
||||
f.write(f'{name} {day_type.upper()}\n')
|
||||
hours = 'HOURS= '
|
||||
values = 'VALUES= '
|
||||
previous = math.inf
|
||||
for hour, value in enumerate(schedule.values):
|
||||
if previous != value:
|
||||
hours = f'{hours} {hour}.000'
|
||||
values = f'{values} {value}'
|
||||
previous = value
|
||||
f.write(f'{hours} 24.0\n')
|
||||
f.write(f'{values} {schedule.values[0]}\n')
|
||||
|
||||
@staticmethod
|
||||
def _schedules(f, building):
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Schedules\n')
|
||||
f.write('***************************************\n')
|
||||
for thermal_zone in building.thermal_zones_from_internal_zones:
|
||||
for usage in thermal_zone.usages:
|
||||
for schedule in usage.occupancy.occupancy_schedules:
|
||||
Trnsys._add_schedule(f, schedule, 'SCHEDULE OCCUPANCY')
|
||||
for schedule in usage.lighting.schedules:
|
||||
Trnsys._add_schedule(f, schedule, 'SCHEDULE LIGHTING ')
|
||||
|
||||
@staticmethod
|
||||
def _constructions(f, building):
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Construction\n')
|
||||
f.write('***************************************\n')
|
||||
constructions = {}
|
||||
for thermal_zone in building.thermal_zones_from_internal_zones:
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
constructions[thermal_boundary.construction_name] = {
|
||||
'layers': '',
|
||||
'thickness': '',
|
||||
'absortance-front': thermal_boundary.layers[0].solar_absorptance,
|
||||
'absortance-back': thermal_boundary.layers[-1].solar_absorptance,
|
||||
'resistance-front': 1 - thermal_boundary.layers[0].thermal_absorptance,
|
||||
'resistance-back': 1 - thermal_boundary.layers[-1].thermal_absorptance,
|
||||
'he': thermal_boundary.he,
|
||||
'hi': thermal_boundary.hi
|
||||
}
|
||||
for layer in thermal_boundary.layers:
|
||||
constructions[thermal_boundary.construction_name]['layers'] = f'{constructions[thermal_boundary.construction_name]["layers"]} {layer.material_name.replace(" ", "_").upper()} '
|
||||
constructions[thermal_boundary.construction_name]['thickness'] = f'{constructions[thermal_boundary.construction_name]["thickness"]} {layer.thickness} '
|
||||
for name, values in constructions.items():
|
||||
f.write(f'CONSTRUCTION {name.replace(" ", "_").upper()}\n')
|
||||
f.write(f'LAYERS = {values["layers"]}\n')
|
||||
f.write(f'THICKNESS = {values["thickness"]}\n')
|
||||
f.write(f'ABS-FRONT = {values["absortance-front"]} : ABS-BACK = {values["absortance-back"]}\n')
|
||||
f.write(f'EPS-FRONT = {values["resistance-front"]} : EPS-BACK = {values["resistance-back"]}\n')
|
||||
f.write(f'HFRONT = {values["he"]} : HBACK = {values["hi"]}\n')
|
||||
f.write('\n')
|
||||
|
||||
@staticmethod
|
||||
def _windows(f, building):
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Windows\n')
|
||||
f.write('***************************************\n')
|
||||
windows = {}
|
||||
for thermal_zone in building.thermal_zones_from_internal_zones:
|
||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||
polygon = thermal_boundary.parent_surface.solid_polygon
|
||||
min_z = math.inf
|
||||
max_z = -math.inf
|
||||
Z = 2
|
||||
for point in polygon.points:
|
||||
min_z = min(min_z, point.coordinates[Z])
|
||||
max_z = max(max_z, point.coordinates[Z])
|
||||
height = max_z - min_z
|
||||
if height == 0:
|
||||
height = 1
|
||||
|
||||
for opening_id, thermal_opening in enumerate(thermal_boundary.thermal_openings):
|
||||
absortance = 0.6
|
||||
if thermal_opening.conductivity is not None:
|
||||
absortance = 1 - thermal_opening.conductivity
|
||||
windows[f'{thermal_opening.construction_name}'] = {
|
||||
'window_id': opening_id,
|
||||
'hi': thermal_opening.hi,
|
||||
'he': thermal_opening.he,
|
||||
'slope': -999,
|
||||
'space_id': 3,
|
||||
'width': thermal_opening.area / height, # todo: this is just an estimation as the surfaces may not be squares.
|
||||
'height': height,
|
||||
'frame_f': 0,
|
||||
'frame_u': thermal_opening.overall_u_value,
|
||||
'abs_frame': absortance,
|
||||
'ri_shade': 0,
|
||||
're_shade': 0,
|
||||
're_fli_shade': 0.5,
|
||||
're_flo_shade': 0.5,
|
||||
'cci_shade': 0.5,
|
||||
'eps_frame': 0.9,
|
||||
'epsi_shade': 0.9,
|
||||
'it_shade_close': 0,
|
||||
'it_shade_open': 0,
|
||||
'flow_to_air_node': 1,
|
||||
'pert': 0,
|
||||
'penrt': 0,
|
||||
'rad_material': 'undefined',
|
||||
'rad_material_shd1': 'undefined'
|
||||
}
|
||||
for name, values in windows.items():
|
||||
f.write(f'WINDOW {name.replace(" ", "_").upper()}\n')
|
||||
f.write(f' WINID={values["window_id"]} :')
|
||||
f.write(f' HINSIDE={values["hi"]} :')
|
||||
f.write(f' HOUTSIDE={values["he"]} :')
|
||||
f.write(f' SLOPE={values["slope"]} :')
|
||||
f.write(f' SPACID={values["space_id"]} :')
|
||||
f.write(f' WWID={values["width"]} :')
|
||||
f.write(f' WHEIG={values["height"]} :')
|
||||
f.write(f' FFRAME={values["frame_f"]} :')
|
||||
f.write(f' UFRAME={values["frame_u"]} :')
|
||||
f.write(f' ABSFRAME={values["abs_frame"]} :')
|
||||
f.write(f' RISHADE={values["ri_shade"]} :')
|
||||
f.write(f' RESHADE={values["re_shade"]} :')
|
||||
f.write(f' REFLISHADE={values["re_fli_shade"]} :')
|
||||
f.write(f' REFLOSHADE={values["re_flo_shade"]} :')
|
||||
f.write(f' CCISHADE={values["cci_shade"]} :')
|
||||
f.write(f' EPSFRAME={values["eps_frame"]} :')
|
||||
f.write(f' EPSIFRAME={values["epsi_shade"]} :')
|
||||
f.write(f' ITSHADECLOSE={values["it_shade_close"]} :')
|
||||
f.write(f' ITSHADEOPEN={values["it_shade_open"]} :')
|
||||
f.write(f' FLOWTOAIRNODE={values["flow_to_air_node"]} :')
|
||||
f.write(f' PERT={values["pert"]} :')
|
||||
f.write(f' PENRT={values["penrt"]} :')
|
||||
f.write(f' RADMATERIAL={values["rad_material"]} :')
|
||||
f.write(f' RADMATERIAL_SHD1={values["rad_material_shd1"]}\n')
|
||||
|
||||
@staticmethod
|
||||
def _empty_sections(f):
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Gains / Losses\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Confort\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Infiltration\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Ventilation\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Cooling\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Heating\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Daylight control\n')
|
||||
f.write('***************************************\n')
|
||||
f.write('***************************************\n')
|
||||
f.write(f'* Confort\n')
|
||||
f.write('***************************************\n')
|
||||
|
||||
def export(self):
|
||||
for building in self._buildings:
|
||||
path = Path(self._path / f'{building.name}.b18')
|
||||
with open(path, 'w', encoding='utf-8') as f:
|
||||
print(path)
|
||||
self._header(f, building)
|
||||
self._properties(f)
|
||||
Trnsys._types(f, building)
|
||||
Trnsys._inputs(f)
|
||||
Trnsys._schedules(f, building)
|
||||
Trnsys._constructions(f, building)
|
||||
Trnsys._windows(f, building)
|
||||
Trnsys._empty_sections(f)
|
||||
|
||||
|
|
@ -12,6 +12,7 @@ import requests
|
|||
from hub.exports.building_energy.energy_ade import EnergyAde
|
||||
from hub.exports.building_energy.idf import Idf
|
||||
from hub.exports.building_energy.insel.insel_monthly_energy_balance import InselMonthlyEnergyBalance
|
||||
from hub.exports.building_energy.trnsys import Trnsys
|
||||
from hub.helpers.utils import validate_import_export_type
|
||||
from hub.imports.weather.helpers.weather import Weather as wh
|
||||
|
||||
|
@ -60,6 +61,17 @@ class EnergyBuildingsExportsFactory:
|
|||
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path,
|
||||
target_buildings=self._target_buildings)
|
||||
|
||||
@property
|
||||
def _trnsys(self):
|
||||
"""
|
||||
Export the city to TRNSYS 18 format
|
||||
|
||||
Currently only b18 files will be generated
|
||||
|
||||
:return: None
|
||||
"""
|
||||
return Trnsys(self._city, self._path, target_buildings=self._target_buildings)
|
||||
|
||||
@property
|
||||
def _insel_monthly_energy_balance(self):
|
||||
"""
|
||||
|
|
|
@ -24,3 +24,4 @@ triangle
|
|||
psycopg2-binary
|
||||
Pillow
|
||||
pathlib
|
||||
timezonefinder
|
|
@ -147,3 +147,22 @@ class TestExports(TestCase):
|
|||
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
||||
except Exception:
|
||||
self.fail("Idf ExportsFactory raised ExceptionType unexpectedly!")
|
||||
|
||||
def test_trnsys_export(self):
|
||||
"""
|
||||
export to Trnsys
|
||||
"""
|
||||
file = 'test.geojson'
|
||||
file_path = (self._example_path / file).resolve()
|
||||
city = GeometryFactory('geojson',
|
||||
path=file_path,
|
||||
height_field='citygml_me',
|
||||
year_of_construction_field='ANNEE_CONS',
|
||||
function_field='CODE_UTILI',
|
||||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
|
||||
self.assertIsNotNone(city, 'city is none')
|
||||
ConstructionFactory('nrcan', city).enrich()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
EnergyBuildingsExportsFactory('trnsys', city, self._output_path).export()
|
||||
|
|
Loading…
Reference in New Issue
Block a user