Coverage for teaser/examples/e9_building_data_import_from_excel.py: 0%

216 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-04-29 16:01 +0000

1# -*- coding: utf-8 -*- 

2# @Author: Martin Raetz 

3# @Date: 2019-02-19 18:41:56 

4# @Last Modified by: Martin Rätz 

5# @Last Modified time: 29.11.2019 

6 

7""" 

8This script demonstrates how a building can be generated by importing building 

9data from excel. 

10An appropriate example file with some building data is imported from 

11examplefiles/ExcelBuildingData_Sample.xlsx. 

12 

13In the excel every room is listed by its own, via a custom defined zoning 

14algorithm these rooms are combined to zones. 

15The user needs to adjust the zoning to his needs. 

16See # Block: Zoning methodologies (define your zoning function here) 

17 

18Limitations and assumptions: 

19- Outer and inner wall area depend on the calculations done in the excel 

20- Ground floor area is only as big the respective net area of the heated room 

21volume (NetArea) 

22- Floor area is only as big the respective net area of the heated room volume 

23(NetArea) 

24- Rooftop area is only as big the respective net area of the heated room 

25volume (NetArea) 

26- Rooftops are flat and not tilted, see "RooftopTilt" 

27- Ceiling area is only as big the respective net area of the heated room 

28volume (NetArea) 

29- Ceiling, floor and inner walls are only respected by half their area, 

30since they belong half to the respective 

31and half to the adjacent zone 

32- Orientations are clockwise in degree, 0° is directed north 

33 

34-respective construction types have to be added to the TypeBuildingElements.json 

35-respective UsageTypes for Zones have to be added to the UseConditions.json 

36-excel file format has to be as shown in the "ExcelBuildingData_Sample.xlsx" 

37 

38Information about the required excel format: 

39#Documentation in progress! 

40-yellowed columns are necessary input to teaser -> don´t change column 

41header, keep value names consistent. 

42-non yellowed columns may either not be used or be used for your zoning 

43algorithm 

44-Under the cell ‚Usage type‘ you will see some cells that are blank but have 

45their row filled. 

46It means the blank cell actually belongs to the Usage type above but in that 

47specific row we filled the characteristics 

48of the window/wall of a different orientation of the same exact room. That 

49means every row is either a new room or a 

50new orientation of that room. A room might have two outer walls in two 

51different orientation so for each outer wall, 

52a an extra row defining the respective orientation is added 

53-The entries in the excel sheet must be consistent for python being able to 

54convert it. 

55-If an inner wall is reaching inside a room but is not the limit of the room, 

56it should be accounted with 2x the area 

57""" 

58 

59import os 

60import warnings 

61import shutil 

62import pandas as pd 

63import numpy as np 

64from teaser.project import Project 

65from teaser.logic.buildingobjects.building import Building 

66from teaser.logic.buildingobjects.thermalzone import ThermalZone 

67from teaser.logic.buildingobjects.useconditions import UseConditions 

68from teaser.logic.buildingobjects.buildingphysics.outerwall import OuterWall 

69from teaser.logic.buildingobjects.buildingphysics.floor import Floor 

70from teaser.logic.buildingobjects.buildingphysics.rooftop import Rooftop 

71from teaser.logic.buildingobjects.buildingphysics.groundfloor import GroundFloor 

72from teaser.logic.buildingobjects.buildingphysics.ceiling import Ceiling 

73from teaser.logic.buildingobjects.buildingphysics.window import Window 

74from teaser.logic.buildingobjects.buildingphysics.innerwall import InnerWall 

75 

76 

77def import_data(path=None, sheet_names=None): 

78 """ 

79 Import data from the building data excel file and perform some 

80 preprocessing for nan and empty cells. 

81 If several sheets are imported, the data is concatenated to one dataframe 

82 

83 Parameters 

84 ---------- 

85 path: str 

86 path to the excel file that should be imported 

87 sheet_names: list or str 

88 sheets of excel that should be imported 

89 """ 

90 

91 # process an import of a single sheet as well as several sheets, 

92 # which will be concatenated with an continuous index 

93 if type(sheet_names) == list: 

94 data = pd.DataFrame() 

95 _data = pd.read_excel(io=path, sheet_name=sheet_names, header=0, index_col=None) 

96 for sheet in sheet_names: 

97 data = data.append(_data[sheet], sort=False) 

98 data = data.reset_index(drop=False) 

99 data["index"] = data["index"] + 2 # sync the index with the excel index 

100 else: 

101 data = pd.read_excel(io=path, sheet_name=sheet_names, header=0, index_col=0) 

102 

103 # Cut of leading or tailing white spaces from any string in the dataframe 

104 data = data.applymap(lambda x: x.strip() if type(x) is str else x) 

105 

106 # Convert every N/A, nan, empty strings and strings called N/a, n/A, NAN, 

107 # nan, na, Na, nA or NA to np.nan 

108 data = data.replace( 

109 ["", "N/a", "n/A", "NAN", "nan", "na", "Na", "nA", "NA"], np.nan, regex=False 

110 ) 

111 data = data.fillna(np.nan) 

112 

113 return data 

114 

115 

116def get_list_of_present_entries(list_): 

117 """ 

118 Extracts a list of all in the list available entries, discarding "None" 

119 and "nan" entries 

120 

121 Parameters 

122 ---------- 

123 list_: list 

124 list that shall be processed 

125 """ 

126 

127 _List = [] 

128 for x in list_: 

129 if x not in _List: 

130 if not None: 

131 if not pd.isna(x): 

132 _List.append(x) 

133 return _List 

134 

135 

136# Block: Zoning methodologies (define your zoning function here) 

137# ------------------------------------------------------------- 

138def zoning_example(data): 

139 """ 

140 This is an example on how the rooms of a building could be aggregated to 

141 zones. 

142 

143 In this example the UsageType has to be empty in the case that the 

144 respective line does not represent another 

145 room but a different orientated wall or window belonging to a room that 

146 is already declared once in the excel file. 

147 

148 Parameters 

149 ---------- 

150 data: pandas.dataframe 

151 The data which shall be zoned 

152 return data: pandas.dataframe 

153 The zoning should return the imported dataset with an additional 

154 column called "Zone" which inhibits the 

155 information to which zone the respective room shall be part of, 

156 and also a column called "UsageType_Teaser" which stores the 

157 in UsageType of each row. 

158 UsageType must be available in the UseConditions.json. 

159 """ 

160 

161 # account all outer walls not adjacent to the ambient to the entity 

162 # "inner wall" 

163 # !right now the wall construction of the added wall is not respected, 

164 # the same wall construction as regular 

165 # inner wall is set 

166 for index, line in data.iterrows(): 

167 if not pd.isna(line["WallAdjacentTo"]): 

168 data.loc[index, "InnerWallArea[m²]"] = ( 

169 data.loc[index, "OuterWallArea[m²]"] 

170 + data.loc[index, "WindowArea[m²]"] 

171 + data.loc[index, "InnerWallArea[m²]"] 

172 ) 

173 data.loc[index, "WindowOrientation[°]"] = np.NaN 

174 data.loc[index, "WindowArea[m²]"] = np.NaN 

175 data.loc[index, "WindowConstruction"] = np.NaN 

176 data.loc[index, "OuterWallOrientation[°]"] = np.NaN 

177 data.loc[index, "OuterWallArea[m²]"] = np.NaN 

178 data.loc[index, "OuterWallConstruction"] = np.NaN 

179 

180 # make all rooms that belong to a certain room have the same room identifier 

181 _list = [] 

182 for index, line in data.iterrows(): 

183 if pd.isna(line["BelongsToIdentifier"]): 

184 _list.append(line["RoomIdentifier"]) 

185 else: 

186 _list.append(line["BelongsToIdentifier"]) 

187 data["RoomCluster"] = _list 

188 

189 # check for lines in which the net area is zero, marking an second wall 

190 # or window 

191 # element for the respective room, and in which there is still stated a 

192 # UsageType which is wrong 

193 # and should be changed in the file 

194 for i, row in data.iterrows(): 

195 if (row["NetArea[m²]"] == 0 or row["NetArea[m²]"] == np.nan) and not pd.isna( 

196 row["UsageType"] 

197 ): 

198 warnings.warn( 

199 "In line %s the net area is zero, marking an second wall or " 

200 "window element for the respective room, " 

201 "and in which there is still stated a UsageType which is " 

202 "wrong and should be changed in the file" % i 

203 ) 

204 

205 # make all rooms of the cluster having the usage type of the main usage type 

206 _groups = data.groupby(["RoomCluster"]) 

207 for index, cluster in _groups: 

208 count = 0 

209 for line in cluster.iterrows(): 

210 if pd.isna(line[1]["BelongsToIdentifier"]) and not pd.isna( 

211 line[1]["UsageType"] 

212 ): 

213 main_usage = line[1]["UsageType"] 

214 for i, row in data.iterrows(): 

215 if row["RoomCluster"] == line[1]["RoomCluster"]: 

216 data.loc[i, "RoomClusterUsage"] = main_usage 

217 count += 1 

218 if count != 1: 

219 warnings.warn( 

220 "This cluster has more than one main usage type or none, " 

221 "check your excel file for mistakes! \n" 

222 "Common mistakes: \n" 

223 "-NetArea of a wall is not equal to 0 \n" 

224 "-UsageType of a wall is not empty \n" 

225 "Explanation: Rooms may have outer walls/windows on different orientations.\n" 

226 "Every row with an empty slot in the column UsageType, " 

227 "marks another direction of an outer wall and/or" 

228 "window entity of the same room.\n" 

229 "The connection of the same room is realised by an " 

230 "RoomIdentifier equal to the respective " 

231 "BelongsToIdentifier. \n Cluster = %s" % cluster 

232 ) 

233 

234 # name usage types after usage types available in the json 

235 usage_to_json_usage = { 

236 "IsolationRoom": "Bed room", 

237 "PatientRoom": "Bed room", 

238 "Aisle": "Corridors in the general care area", 

239 "Technical room": "Stock, technical equipment, archives", 

240 "Washing": "WC and sanitary rooms in non-residential buildings", 

241 "Stairway": "Corridors in the general care area", 

242 "WC": "WC and sanitary rooms in non-residential buildings", 

243 "Storage": "Stock, technical equipment, archives", 

244 "Lounge": "Meeting, Conference, seminar", 

245 "Office": "Meeting, Conference, seminar", 

246 "Treatment room": "Examination- or treatment room", 

247 "StorageChemical": "Stock, technical equipment, archives", 

248 "EquipmentServiceAndRinse": "WC and sanitary rooms in non-residential buildings", 

249 } 

250 

251 # rename all zone names from the excel to the according zone name which 

252 # is in the UseConditions.json files 

253 usages = get_list_of_present_entries(data["RoomClusterUsage"]) 

254 data["UsageType_Teaser"] = "" 

255 for usage in usages: 

256 data["UsageType_Teaser"] = np.where( 

257 data["RoomClusterUsage"] == usage, 

258 usage_to_json_usage[usage], 

259 data["UsageType_Teaser"], 

260 ) 

261 

262 # name the column where the zones are defined "Zone" 

263 data["Zone"] = data["UsageType_Teaser"] 

264 

265 return data 

266 

267 

268# ------------------------------------------------------------- 

269def import_building_from_excel( 

270 project, building_name, construction_age, path_to_excel, sheet_names 

271): 

272 """ 

273 Import building data from excel, convert it via the respective zoning and feed it to teasers logic classes. 

274 Pay attention to hard coded parts, which are marked. 

275 

276 Parameters 

277 ---------- 

278 project: Project() 

279 TEASER instance of Project 

280 building_name: str 

281 name of building to be set in the project 

282 construction_age: int [y] 

283 construction age of the building 

284 path_to_excel: str 

285 path to excel file to be imported 

286 sheet_names: str or list 

287 sheet names which shall be imported 

288 return data: pandas.DataFrame 

289 zoned DataFrame which is finally used to parametrize the teaser classes 

290 return project: Project() 

291 TEASER instance of Project filled with the imported building data 

292 """ 

293 

294 def warn_constructiontype(element): 

295 """Generic warning function""" 

296 if element.construction_data is None: 

297 warnings.warn( 

298 'In zone "%s" the %s construction "%s" could not be loaded from the TypeBuildingElements.json, ' 

299 "an error will occur due to missing data for calculation." 

300 "Check for spelling and the correct combination of building age and construction type." 

301 "Here is the list of faulty entries:\n%s" 

302 "\nThese entries can easily be found checking the stated index in the produced ZonedInput.xlsx" 

303 % ( 

304 group["Zone"].iloc[0], 

305 element.name, 

306 group["OuterWallConstruction"].iloc[0], 

307 group, 

308 ) 

309 ) 

310 

311 bldg = Building(parent=project) 

312 bldg.name = building_name 

313 bldg.year_of_construction = construction_age 

314 bldg.internal_gains_mode = 3 # HardCodedInput 

315 bldg.with_ahu = True # HardCodedInput 

316 if bldg.with_ahu is True: 

317 bldg.central_ahu.heat_recovery = True # HardCodedInput 

318 bldg.central_ahu.efficiency_recovery = 0.35 # HardCodedInput 

319 bldg.central_ahu.temperature_profile = 24 * [273.15 + 18] # HardCodedInput 

320 bldg.central_ahu.min_relative_humidity_profile = 24 * [0] # HardCodedInput 

321 bldg.central_ahu.max_relative_humidity_profile = 24 * [1] # HardCodedInput 

322 bldg.central_ahu.v_flow_profile = 24 * [1] # HardCodedInput 

323 

324 # Parameters that need hard coding in teasers logic classes 

325 # 1. "use_set_back" needs hard coding at aixlib.py in the init; defines 

326 # if the in the useconditions stated 

327 # heating_time with the respective set_back_temp should be applied. 

328 # use_set_back = false -> all hours of the day 

329 # have same set_temp_heat actual value: use_set_back = Check your current version! 

330 # !This may has been resolved with the last changes in the development 

331 

332 # Parameters to be set for each and every zone (#HardCodedInput) 

333 # ----------------------------- 

334 out_wall_tilt = 90 

335 window_tilt = 90 

336 ground_floor_tilt = 0 

337 floor_tilt = 0 

338 ceiling_tilt = 0 

339 rooftop_tilt = 0 

340 ground_floor_orientation = -2 

341 floor_orientation = -2 

342 rooftop_orientation = -1 

343 ceiling_orientation = -1 

344 # ----------------------------- 

345 

346 # load_building_data from excel_to_pandas DataFrame: 

347 data = import_data(path_to_excel, sheet_names) 

348 

349 # informative print 

350 usage_types = get_list_of_present_entries(data["UsageType"]) 

351 print("List of present usage_types in the original Data set: \n%s" % usage_types) 

352 

353 # define the zoning methodology/function 

354 data = zoning_example(data) 

355 

356 # informative print 

357 usage_types = get_list_of_present_entries(data["Zone"]) 

358 print("List of zones after the zoning is applied: \n%s" % usage_types) 

359 

360 # aggregate all rooms of each zone and for each set general parameter, 

361 # boundary conditions 

362 # and parameter regarding the building physics 

363 zones = data.groupby(["Zone"]) 

364 for name, zone in zones: 

365 

366 # Block: Thermal zone (general parameter) 

367 tz = ThermalZone(parent=bldg) 

368 tz.name = str(name) 

369 tz.area = np.nansum(zone["NetArea[m²]"]) 

370 # room vice calculation of volume plus summing those 

371 tz.volume = np.nansum( 

372 np.array(zone["NetArea[m²]"]) * np.array(zone["HeatedRoomHeight[m]"]) 

373 ) 

374 

375 # Block: Boundary Conditions 

376 # load UsageOperationTime, Lighting, RoomClimate and InternalGains 

377 # from the "UseCondition.json" 

378 tz.use_conditions = UseConditions(parent=tz) 

379 tz.use_conditions.load_use_conditions( 

380 zone["UsageType_Teaser"].iloc[0], project.data 

381 ) 

382 

383 # Block: Building Physics 

384 # Grouping by orientation and construction type 

385 # aggregating and feeding to the teaser logic classes 

386 grouped = zone.groupby(["OuterWallOrientation[°]", "OuterWallConstruction"]) 

387 for name, group in grouped: 

388 # looping through a groupby object automatically discards the 

389 # groups where one of the attributes is nan 

390 # additionally check for strings, since the value must be of type 

391 # int or float 

392 if not isinstance(group["OuterWallOrientation[°]"].iloc[0], str): 

393 if ( 

394 np.nansum(group["OuterWallArea[m²]"]) > 0 

395 ): # only create element if it has an area 

396 out_wall = OuterWall(parent=tz) 

397 out_wall.name = ( 

398 "outer_wall_" 

399 + str(int(group["OuterWallOrientation[°]"].iloc[0])) 

400 + "_" 

401 + str(group["OuterWallConstruction"].iloc[0]) 

402 ) 

403 out_wall.area = np.nansum(group["OuterWallArea[m²]"]) 

404 out_wall.tilt = out_wall_tilt 

405 out_wall.orientation = group["OuterWallOrientation[°]"].iloc[0] 

406 # load wall properties from "TypeBuildingElements.json" 

407 out_wall.load_type_element( 

408 year=bldg.year_of_construction, 

409 construction=group["OuterWallConstruction"].iloc[0], 

410 ) 

411 warn_constructiontype(out_wall) 

412 else: 

413 warnings.warn( 

414 'In zone "%s" the OuterWallOrientation "%s" is ' 

415 "neither float nor int, " 

416 "hence this building element is not added.\nHere is the " 

417 "list of faulty entries:\n%s" 

418 "\n These entries can easily be found checking the stated " 

419 "index in the produced ZonedInput.xlsx" 

420 % ( 

421 group["Zone"].iloc[0], 

422 group["OuterWallOrientation[°]"].iloc[0], 

423 group, 

424 ) 

425 ) 

426 

427 grouped = zone.groupby(["WindowOrientation[°]", "WindowConstruction"]) 

428 for name, group in grouped: 

429 # looping through a groupby object automatically discards the 

430 # groups where one of the attributes is nan 

431 # additionally check for strings, since the value must be of type 

432 # int or float 

433 if not isinstance(group["WindowOrientation[°]"].iloc[0], str): 

434 if ( 

435 np.nansum(group["WindowArea[m²]"]) > 0 

436 ): # only create element if it has an area 

437 window = Window(parent=tz) 

438 window.name = ( 

439 "window_" 

440 + str(int(group["WindowOrientation[°]"].iloc[0])) 

441 + "_" 

442 + str(group["WindowConstruction"].iloc[0]) 

443 ) 

444 window.area = np.nansum(group["WindowArea[m²]"]) 

445 window.tilt = window_tilt 

446 window.orientation = group["WindowOrientation[°]"].iloc[0] 

447 # load wall properties from "TypeBuildingElements.json" 

448 window.load_type_element( 

449 year=bldg.year_of_construction, 

450 construction=group["WindowConstruction"].iloc[0], 

451 ) 

452 warn_constructiontype(window) 

453 else: 

454 warnings.warn( 

455 'In zone "%s" the window orientation "%s" is neither ' 

456 "float nor int, " 

457 "hence this building element is not added. Here is the " 

458 "list of faulty entries:\n%s" 

459 "\nThese entries can easily be found checking the stated " 

460 "index in the produced ZonedInput.xlsx" 

461 % ( 

462 group["Zone"].iloc[0], 

463 group["WindowOrientation[°]"].iloc[0], 

464 group, 

465 ) 

466 ) 

467 

468 grouped = zone.groupby(["IsGroundFloor", "FloorConstruction"]) 

469 for name, group in grouped: 

470 if np.nansum(group["NetArea[m²]"]) != 0: # to avoid devision by 0 

471 if group["IsGroundFloor"].iloc[0] == 1: 

472 ground_floor = GroundFloor(parent=tz) 

473 ground_floor.name = "ground_floor" + str( 

474 group["FloorConstruction"].iloc[0] 

475 ) 

476 ground_floor.area = np.nansum(group["NetArea[m²]"]) 

477 ground_floor.tilt = ground_floor_tilt 

478 ground_floor.orientation = ground_floor_orientation 

479 # load wall properties from "TypeBuildingElements.json" 

480 ground_floor.load_type_element( 

481 year=bldg.year_of_construction, 

482 construction=group["FloorConstruction"].iloc[0], 

483 ) 

484 warn_constructiontype(ground_floor) 

485 elif group["IsGroundFloor"].iloc[0] == 0: 

486 floor = Floor(parent=tz) 

487 floor.name = "floor" + str(group["FloorConstruction"].iloc[0]) 

488 floor.area = np.nansum(group["NetArea[m²]"]) / 2 # only half of 

489 # the floor belongs to this story 

490 floor.tilt = floor_tilt 

491 floor.orientation = floor_orientation 

492 # load wall properties from "TypeBuildingElements.json" 

493 floor.load_type_element( 

494 year=bldg.year_of_construction, 

495 construction=group["FloorConstruction"].iloc[0], 

496 ) 

497 warn_constructiontype(floor) 

498 else: 

499 warnings.warn( 

500 "Values for IsGroundFloor have to be either 0 or 1, " 

501 "for no or yes respectively" 

502 ) 

503 else: 

504 warnings.warn( 

505 'zone "%s" with IsGroundFloor "%s" and construction ' 

506 'type "%s" ' 

507 "has no floor nor groundfloor, since the area equals 0." 

508 % ( 

509 group["Zone"].iloc[0], 

510 group["IsGroundFloor"].iloc[0], 

511 group["FloorConstruction"].iloc[0], 

512 ) 

513 ) 

514 

515 grouped = zone.groupby(["IsRooftop", "CeilingConstruction"]) 

516 for name, group in grouped: 

517 if np.nansum(group["NetArea[m²]"]) != 0: # to avoid devision by 0 

518 if group["IsRooftop"].iloc[0] == 1: 

519 rooftop = Rooftop(parent=tz) 

520 rooftop.name = "rooftop" + str(group["CeilingConstruction"].iloc[0]) 

521 rooftop.area = np.nansum( 

522 group["NetArea[m²]"] 

523 ) # sum up area of respective 

524 # rooftop parts 

525 rooftop.tilt = rooftop_tilt 

526 rooftop.orientation = rooftop_orientation 

527 # load wall properties from "TypeBuildingElements.json" 

528 rooftop.load_type_element( 

529 year=bldg.year_of_construction, 

530 construction=group["CeilingConstruction"].iloc[0], 

531 ) 

532 warn_constructiontype(rooftop) 

533 elif group["IsRooftop"].iloc[0] == 0: 

534 ceiling = Ceiling(parent=tz) 

535 ceiling.name = "ceiling" + str(group["CeilingConstruction"].iloc[0]) 

536 ceiling.area = np.nansum(group["NetArea[m²]"]) / 2 # only half 

537 # of the ceiling belongs to a story, 

538 # the other half to the above 

539 ceiling.tilt = ceiling_tilt 

540 ceiling.orientation = ceiling_orientation 

541 # load wall properties from "TypeBuildingElements.json" 

542 ceiling.load_type_element( 

543 year=bldg.year_of_construction, 

544 construction=group["CeilingConstruction"].iloc[0], 

545 ) 

546 warn_constructiontype(ceiling) 

547 else: 

548 warnings.warn( 

549 "Values for IsRooftop have to be either 0 or 1, " 

550 "for no or yes respectively" 

551 ) 

552 else: 

553 warnings.warn( 

554 'zone "%s" with IsRooftop "%s" and construction type ' 

555 '"%s" ' 

556 "has no ceiling nor rooftop, since the area equals 0." 

557 % ( 

558 group["Zone"].iloc[0], 

559 group["IsRooftop"].iloc[0], 

560 group["CeilingConstruction"].iloc[0], 

561 ) 

562 ) 

563 

564 grouped = zone.groupby(["InnerWallConstruction"]) 

565 for name, group in grouped: 

566 if np.nansum(group["InnerWallArea[m²]"]) != 0: # to avoid devision by 0 

567 in_wall = InnerWall(parent=tz) 

568 in_wall.name = "inner_wall" + str( 

569 group["InnerWallConstruction"].iloc[0] 

570 ) 

571 in_wall.area = np.nansum(group["InnerWallArea[m²]"]) / 2 # only 

572 # half of the wall belongs to each room, 

573 # the other half to the adjacent 

574 # load wall properties from "TypeBuildingElements.json" 

575 in_wall.load_type_element( 

576 year=bldg.year_of_construction, 

577 construction=group["InnerWallConstruction"].iloc[0], 

578 ) 

579 warn_constructiontype(in_wall) 

580 else: 

581 warnings.warn( 

582 'zone "%s" with inner wall construction "%s" has no ' 

583 "inner walls, since area = 0." 

584 % (group["Zone"].iloc[0], group["InnerWallConstructio" "n"].iloc[0]) 

585 ) 

586 

587 # Block: AHU and infiltration #Attention hard coding 

588 # set the supply volume flow of the AHU per zone 

589 ahu_dict = { 

590 "Bedroom": [15.778, 15.778], 

591 "Corridorsinthegeneralcarearea": [5.2941, 5.2941], 

592 "Examinationortreatmentroom": [15.743, 15.743], 

593 "MeetingConferenceseminar": [16.036, 16.036], 

594 "Stocktechnicalequipmentarchives": [20.484, 20.484], 

595 "WCandsanitaryroomsinnonresidentialbuildings": [27.692, 27.692], 

596 } 

597 _i = 0 

598 for key in ahu_dict: 

599 if tz.name == key: 

600 tz.use_conditions.min_ahu = ahu_dict[key][0] 

601 tz.use_conditions.max_ahu = ahu_dict[key][1] 

602 _i = 1 

603 if _i == 0: 

604 warnings.warn( 

605 "The zone %s could not be found in your ahu_dict. Hence, " 

606 "no AHU flow is defined. The default value is " 

607 "0 (min_ahu = 0; max_ahu=0" % tz.name 

608 ) 

609 

610 return project, data 

611 

612 

613if __name__ == "__main__": 

614 result_path = os.path.dirname(__file__) 

615 

616 prj = Project() 

617 prj.name = "BuildingGeneratedviaExcelImport" 

618 prj.data.load_uc_binding() 

619 prj.weather_file_path = os.path.join( 

620 os.path.dirname(os.path.dirname(__file__)), 

621 "data", 

622 "input", 

623 "inputdata", 

624 "weatherdata", 

625 "DEU_BW_Mannheim_107290_TRY2010_12_Jahr_BBSR.mos", 

626 ) 

627 prj.modelica_info.weekday = 0 # 0-Monday, 6-Sunday 

628 prj.modelica_info.simulation_start = 0 # start time for simulation 

629 

630 PathToExcel = os.path.join( 

631 os.path.dirname(__file__), "examplefiles", "ExcelBuildingData_Sample.xlsx" 

632 ) 

633 prj, Data = import_building_from_excel( 

634 prj, "ExampleImport", 2000, PathToExcel, sheet_names=["ImportSheet1"] 

635 ) 

636 

637 prj.modelica_info.current_solver = "dassl" 

638 prj.calc_all_buildings(raise_errors=True) 

639 

640 # Hard coding 

641 # for zones: zone.model_attr.cool_load = -5000 or -zone.model_attr.heat_load 

642 

643 prj.export_aixlib(internal_id=None, path=result_path) 

644 

645 # if wished, export the zoned DataFrame which is finally used to 

646 # parametrize the teaser classes 

647 Data.to_excel(os.path.join(result_path, prj.name, "ZonedInput.xlsx")) 

648 # if wished, save the current python script to the results folder to 

649 # track the used parameters and reproduce results 

650 shutil.copy(__file__, os.path.join(result_path, prj.name)) 

651 

652 print("%s: That's it :)" % prj.name)