mabuseif commited on
Commit
96af459
·
verified ·
1 Parent(s): 9f07b4c

Update app/intro.py

Browse files
Files changed (1) hide show
  1. app/intro.py +77 -203
app/intro.py CHANGED
@@ -16,7 +16,6 @@ import io
16
  import logging
17
  from datetime import datetime
18
  from typing import Dict, Any, Optional
19
- from app.m_c_data import SAMPLE_MATERIALS, SAMPLE_FENESTRATIONS, SAMPLE_CONSTRUCTIONS
20
 
21
  # Configure logging
22
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@@ -51,31 +50,36 @@ def display_about_section():
51
  st.markdown("""
52
  ### Overview
53
 
54
- BuildSustain is a comprehensive tool for calculating heating and cooling loads for buildings
55
- using the ASHRAE Transfer Function Method (TFM) and Conduction Transfer Function (CTF) approaches.
 
 
56
 
57
- ### Features
58
 
59
- * **Building Information**: Define basic building parameters
60
- * **Climate Data**: Import EPW weather files for location-specific calculations
61
- * **Material Library**: Access and customize building materials and fenestrations
62
- * **Construction Library**: Create and manage multi-layer constructions
63
- * **Building Components**: Define walls, roofs, floors, windows, doors, and skylights
64
- * **Internal Loads**: Account for people, lighting, and equipment heat gains
65
- * **HVAC Loads**: Calculate cooling and heating loads using ASHRAE methods
66
- * **Building Energy**: Estimate energy consumption based on HVAC system efficiency
67
- * **Renewable Energy**: Size PV systems for net-zero energy goals
68
- * **Embodied Energy**: Calculate the embodied carbon of building materials
69
- * **Materials Cost**: Estimate construction material costs
 
70
 
71
  ### Development
72
 
73
- This app was developed by Dr. Majed Abuseif at Deakin University’s School of Architecture and Built Environment.
74
- It is a powerful tool for students and professionals, enabling precise building sustainability calculations with a focus on climate change projections and sustainable design.
75
 
76
  ### Version
77
 
78
  Beta Version 0.4.1 (2025)
 
 
79
  """)
80
 
81
  def display_instructions_section():
@@ -85,33 +89,38 @@ def display_instructions_section():
85
  st.markdown("""
86
  ### Getting Started
87
 
88
- 1. **Create a New Project**: Start by entering basic building information
89
- 2. **Import Climate Data**: Upload an EPW file or select from available locations
90
- 3. **Define Materials**: Use the library or create custom materials
91
- 4. **Create Constructions**: Define wall, roof, and floor assemblies
92
- 5. **Add Building Components**: Specify the building envelope components
93
- 6. **Define Internal Loads**: Add occupancy, lighting, and equipment
94
- 7. **Calculate Loads**: Generate cooling and heating load results
95
- 8. **Explore Additional Analyses**: Energy consumption, renewable energy, embodied carbon, and cost
96
 
97
- ### Navigation
 
 
 
 
 
 
 
98
 
99
- Use the sidebar to navigate between different sections of the application. You can go back to previous
100
- sections at any time to modify inputs.
101
 
102
- ### Saving Your Work
 
 
103
 
104
- Use the Project Management tab to save your project as a JSON file that can be imported later to
105
- continue your work.
106
 
107
- ### Calculation Methods
 
 
 
108
 
109
- BuildSustain uses the following ASHRAE-approved methods:
110
 
111
- * **Conduction Transfer Function (CTF)**: For transient heat transfer through opaque surfaces
112
- * **Transfer Function Method (TFM)**: For calculating cooling and heating loads
113
- * **Sol-Air Temperature**: For solar radiation effects on opaque surfaces
114
- * **Dynamic Solar Heat Gain**: For fenestration with angle-dependent properties
 
115
  """)
116
 
117
  def display_project_management_section():
@@ -144,7 +153,7 @@ def display_project_management_section():
144
  st.warning("Please enter a project name in the Building Information section before exporting.")
145
 
146
  def start_new_project():
147
- """Initialize a new project by resetting project-specific data while preserving library data."""
148
  # Keep a backup of the current project data in case user wants to recover
149
  if 'project_data_backup' not in st.session_state:
150
  st.session_state.project_data_backup = {}
@@ -154,78 +163,31 @@ def start_new_project():
154
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
155
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
156
 
157
- # Preserve library data from current session state or initialize with defaults
158
- library_data = {
159
- "materials": st.session_state.project_data.get("materials", {}).get("library", dict(SAMPLE_MATERIALS)),
160
- "fenestrations": st.session_state.project_data.get("fenestrations", {}).get("library", dict(SAMPLE_FENESTRATIONS)),
161
- "constructions": st.session_state.project_data.get("constructions", {}).get("library", dict(SAMPLE_CONSTRUCTIONS))
162
- }
163
-
164
- # Reset project data to match main.py structure
165
  st.session_state.project_data = {
166
  "project_name": "",
167
  "building_info": {
168
  "project_name": "",
169
  "floor_area": 100.0,
170
  "building_height": 3.0,
171
- "building_type": "Office",
172
- "summer_indoor_design_temp": 24.0,
173
- "summer_indoor_design_rh": 50.0,
174
- "winter_indoor_design_temp": 20.0,
175
- "winter_indoor_design_rh": 50.0,
176
- "orientation_angle": 0.0
177
- },
178
- "climate_data": {
179
- "id": "",
180
- "location": {
181
- "city": "",
182
- "state_province": "",
183
- "country": "",
184
- "source": "",
185
- "wmo": "",
186
- "latitude": 0.0,
187
- "longitude": 0.0,
188
- "timezone": 0.0,
189
- "elevation": 0.0
190
- },
191
- "design_conditions": {
192
- "winter_design_temp": 0.0,
193
- "summer_design_temp_db": 30.0,
194
- "summer_design_temp_wb": 25.0,
195
- "heating_degree_days": 0,
196
- "cooling_degree_days": 0,
197
- "monthly_average_temps": [20.0] * 12,
198
- "monthly_average_radiation": [150.0] * 12,
199
- "summer_daily_range": 8.0,
200
- "wind_speed": 3.0,
201
- "pressure": 101325.0
202
- },
203
- "climate_zone": "",
204
- "hourly_data": [],
205
- "epw_filename": "",
206
- "typical_extreme_periods": {
207
- "summer_extreme": {"start": {"month": 7, "day": 1}, "end": {"month": 7, "day": 7}},
208
- "summer_typical": {"start": {"month": 6, "day": 1}, "end": {"month": 6, "day": 7}},
209
- "winter_extreme": {"start": {"month": 1, "day": 1}, "end": {"month": 1, "day": 7}},
210
- "winter_typical": {"start": {"month": 12, "day": 1}, "end": {"month": 12, "day": 7}}
211
- },
212
- "ground_temperatures": {
213
- "0.5": [20.0] * 12,
214
- "2": [18.0] * 12,
215
- "4": [16.0] * 12
216
- },
217
- "ground_reflectivity": 0.2
218
  },
 
219
  "materials": {
220
- "library": library_data["materials"],
221
  "project": {}
222
  },
223
  "fenestrations": {
224
- "library": library_data["fenestrations"],
225
  "project": {}
226
  },
227
  "constructions": {
228
- "library": library_data["constructions"],
229
  "project": {}
230
  },
231
  "components": {
@@ -233,74 +195,27 @@ def start_new_project():
233
  "roofs": [],
234
  "floors": [],
235
  "windows": [],
 
236
  "skylights": []
237
  },
238
  "internal_loads": {
239
- "schedules": {},
240
  "people": [],
241
- "lighting": [],
242
- "equipment": [],
243
- "ventilation": [],
244
- "infiltration": []
245
- },
246
- "internal_loads_conditions": {
247
- "air_velocity": 0.1,
248
- "lighting_convective_fraction": 0.5,
249
- "lighting_radiative_fraction": 0.5,
250
- "equipment_convective_fraction": 0.5,
251
- "equipment_radiative_fraction": 0.5
252
  },
253
  "hvac_loads": {
254
  "cooling": {
255
  "hourly": [],
256
- "peak": 0.0,
257
  "summary_tables": {},
258
- "charts": {
259
- "pie_by_component": {},
260
- "pie_by_orientation": {}
261
- },
262
- "breakdown": {
263
- "conduction": 0.0,
264
- "solar": 0.0,
265
- "internal": 0.0,
266
- "ventilation_sensible": 0.0,
267
- "ventilation_latent": 0.0,
268
- "infiltration_sensible": 0.0,
269
- "infiltration_latent": 0.0
270
- }
271
  },
272
  "heating": {
273
  "hourly": [],
274
- "peak": 0.0,
275
  "summary_tables": {},
276
- "charts": {
277
- "pie_by_component": {},
278
- "pie_by_orientation": {}
279
- },
280
- "breakdown": {
281
- "conduction": 0.0,
282
- "ventilation": 0.0,
283
- "infiltration": 0.0
284
- }
285
- },
286
- "monthly_summary": {}
287
- },
288
- "hvac_settings": {
289
- "operating_hours": [{"start": 8, "end": 18}],
290
- "system_type": "Default"
291
- },
292
- "sim_period": {
293
- "type": "Full Year",
294
- "start_date": datetime(2025, 1, 1),
295
- "end_date": datetime(2025, 12, 31),
296
- "base_temp": 18.3
297
- },
298
- "indoor_conditions": {
299
- "type": "Fixed Setpoints",
300
- "cooling_setpoint": {"temperature": 24.0, "rh": 50.0},
301
- "heating_setpoint": {"temperature": 20.0, "rh": 50.0},
302
- "adaptive_acceptability": "90",
303
- "schedule": []
304
  },
305
  "building_energy": {
306
  "hvac_type": "",
@@ -324,18 +239,16 @@ def start_new_project():
324
  "embodied_energy": {
325
  "total_embodied_carbon_kgco2e": 0,
326
  "breakdown_by_component": {},
327
- "charts": {},
328
- "material_inventory": []
329
  },
330
  "materials_cost": {
331
  "total_cost_usd": 0,
332
  "breakdown_by_component": {},
333
- "charts": {},
334
- "material_inventory": []
335
  }
336
  }
337
 
338
- logger.info("New project initialized with preserved library data")
339
 
340
  def load_project(uploaded_file) -> bool:
341
  """
@@ -366,12 +279,6 @@ def load_project(uploaded_file) -> bool:
366
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
367
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
368
 
369
- # Convert datetime strings back to datetime objects if necessary
370
- if project_data.get("sim_period", {}).get("start_date"):
371
- project_data["sim_period"]["start_date"] = datetime.fromisoformat(project_data["sim_period"]["start_date"])
372
- if project_data.get("sim_period", {}).get("end_date"):
373
- project_data["sim_period"]["end_date"] = datetime.fromisoformat(project_data["sim_period"]["end_date"])
374
-
375
  # Update session state with the loaded project data
376
  st.session_state.project_data = project_data
377
 
@@ -394,7 +301,6 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
394
  """
395
  # Check for required top-level keys
396
  required_keys = [
397
- "project_name",
398
  "building_info",
399
  "climate_data",
400
  "materials",
@@ -402,11 +308,7 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
402
  "constructions",
403
  "components",
404
  "internal_loads",
405
- "internal_loads_conditions",
406
  "hvac_loads",
407
- "hvac_settings",
408
- "sim_period",
409
- "indoor_conditions",
410
  "building_energy",
411
  "renewable_energy",
412
  "embodied_energy",
@@ -423,12 +325,11 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
423
  "project_name",
424
  "floor_area",
425
  "building_height",
426
- "building_type",
427
- "summer_indoor_design_temp",
428
- "summer_indoor_design_rh",
429
- "winter_indoor_design_temp",
430
- "winter_indoor_design_rh",
431
- "orientation_angle"
432
  ]
433
 
434
  for key in building_info_keys:
@@ -436,26 +337,8 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
436
  logger.error(f"Missing required key in building_info: {key}")
437
  return False
438
 
439
- # Check climate_data structure
440
- climate_data_keys = [
441
- "id",
442
- "location",
443
- "design_conditions",
444
- "climate_zone",
445
- "hourly_data",
446
- "epw_filename",
447
- "typical_extreme_periods",
448
- "ground_temperatures",
449
- "ground_reflectivity"
450
- ]
451
-
452
- for key in climate_data_keys:
453
- if key not in project_data["climate_data"]:
454
- logger.error(f"Missing required key in climate_data: {key}")
455
- return False
456
-
457
  # Check components structure
458
- component_types = ["walls", "roofs", "floors", "windows", "skylights"]
459
  for component_type in component_types:
460
  if component_type not in project_data["components"]:
461
  logger.error(f"Missing component type in components: {component_type}")
@@ -472,20 +355,11 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
472
  def export_project():
473
  """Export the current project as a downloadable JSON file."""
474
  try:
475
- # Create a deep copy of project data to avoid modifying session state
476
- project_data = st.session_state.project_data.copy()
477
-
478
- # Convert datetime objects to ISO format strings for JSON serialization
479
- if project_data.get("sim_period", {}).get("start_date"):
480
- project_data["sim_period"]["start_date"] = project_data["sim_period"]["start_date"].isoformat()
481
- if project_data.get("sim_period", {}).get("end_date"):
482
- project_data["sim_period"]["end_date"] = project_data["sim_period"]["end_date"].isoformat()
483
-
484
  # Convert project data to JSON
485
- project_json = json.dumps(project_data, indent=2)
486
 
487
  # Generate filename based on project name
488
- project_name = project_data.get("project_name", "unnamed_project")
489
  safe_project_name = "".join(c if c.isalnum() else "_" for c in project_name)
490
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
491
  filename = f"{safe_project_name}_{timestamp}.json"
 
16
  import logging
17
  from datetime import datetime
18
  from typing import Dict, Any, Optional
 
19
 
20
  # Configure logging
21
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
50
  st.markdown("""
51
  ### Overview
52
 
53
+ BuildSustain is a web-based tool developed by Dr. Majed Abuseif at Deakin University’s School of
54
+ Architecture and Built Environment. It enables students and professionals to perform energy
55
+ simulations, calculate heating and cooling loads using ASHRAE-standard methods, and analyze
56
+ embodied energy and material costs for sustainable building design.
57
 
58
+ ### Purpose
59
 
60
+ Designed as a learning platform, BuildSustain helps users understand building physics, apply
61
+ industry-standard calculations, and explore sustainable design strategies. It bridges theoretical
62
+ concepts with practical applications, preparing users for careers in architecture, engineering,
63
+ and sustainability.
64
+
65
+ ### Key Features
66
+
67
+ - **Energy Simulations**: Calculate HVAC loads using ASHRAE Transfer Function Method (TFM) and
68
+ Conduction Transfer Function (CTF).
69
+ - **Sustainability Analysis**: Estimate embodied carbon, renewable energy options, and material costs.
70
+ - **Climate Resilience**: Model future climate scenarios with RCP projections.
71
+ - **User-Friendly Interface**: Intuitive navigation for students to experiment with design parameters.
72
 
73
  ### Development
74
 
75
+ Created by Dr. Majed Abuseif, BuildSustain is a powerful educational tool for precise sustainability
76
+ calculations, focusing on climate change resilience and energy-efficient design.
77
 
78
  ### Version
79
 
80
  Beta Version 0.4.1 (2025)
81
+
82
+ For detailed guidance, refer to the [BuildSustain Student User Guide](BuildSustain_Student_User_Guide.markdown).
83
  """)
84
 
85
  def display_instructions_section():
 
89
  st.markdown("""
90
  ### Getting Started
91
 
92
+ BuildSustain is a step-by-step tool for sustainable building design. Follow the sidebar navigation
93
+ to progress through the modules in order:
 
 
 
 
 
 
94
 
95
+ 1. **Start a Project**: Use the Project Management tab to create a new project or import an existing one.
96
+ 2. **Enter Building Information**: Define project name, building type, dimensions, and indoor conditions.
97
+ 3. **Manage Climate Data**: Upload an EPW file or select a future climate projection.
98
+ 4. **Define Materials and Fenestrations**: Use or customize material and window properties.
99
+ 5. **Create Constructions**: Build multi-layer assemblies for walls, roofs, and floors.
100
+ 6. **Add Building Components**: Specify envelope elements like walls, windows, and skylights.
101
+ 7. **Set Internal Loads**: Define occupant, lighting, and equipment heat gains with schedules.
102
+ 8. **Calculate HVAC Loads**: Run simulations to analyze heating and cooling requirements.
103
 
104
+ ### Navigation
 
105
 
106
+ - Use the sidebar to access modules (e.g., Building Information, HVAC Loads).
107
+ - Follow “Back” and “Continue” buttons to move sequentially.
108
+ - Save progress using the Project Management tab (export as JSON).
109
 
110
+ ### Learning Tips
 
111
 
112
+ - Experiment with inputs (e.g., insulation thickness, window SHGC) to see their impact on energy loads.
113
+ - Review the [BuildSustain Student User Guide](BuildSustain_Student_User_Guide.markdown) for detailed
114
+ steps and equations.
115
+ - Use the ASHRAE Handbook link in the sidebar for reference.
116
 
117
+ ### Key Methods
118
 
119
+ BuildSustain uses ASHRAE-approved methods:
120
+ - **Conduction Transfer Function (CTF)**: For heat transfer through opaque surfaces.
121
+ - **Transfer Function Method (TFM)**: For HVAC load calculations.
122
+ - **Solar Heat Gain**: For dynamic fenestration analysis.
123
+ - **Adaptive Comfort**: For energy-efficient indoor condition settings.
124
  """)
125
 
126
  def display_project_management_section():
 
153
  st.warning("Please enter a project name in the Building Information section before exporting.")
154
 
155
  def start_new_project():
156
+ """Initialize a new project by resetting the project_data in session state."""
157
  # Keep a backup of the current project data in case user wants to recover
158
  if 'project_data_backup' not in st.session_state:
159
  st.session_state.project_data_backup = {}
 
163
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
164
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
165
 
166
+ # Reset project data to default values
 
 
 
 
 
 
 
167
  st.session_state.project_data = {
168
  "project_name": "",
169
  "building_info": {
170
  "project_name": "",
171
  "floor_area": 100.0,
172
  "building_height": 3.0,
173
+ "indoor_design_temp": 24.0,
174
+ "indoor_design_rh": 50.0,
175
+ "ventilation_rate": 0.1,
176
+ "orientation_angle": 0.0,
177
+ "operation_hours": 8,
178
+ "building_type": "Office"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  },
180
+ "climate_data": {},
181
  "materials": {
182
+ "library": {},
183
  "project": {}
184
  },
185
  "fenestrations": {
186
+ "library": {},
187
  "project": {}
188
  },
189
  "constructions": {
190
+ "library": {},
191
  "project": {}
192
  },
193
  "components": {
 
195
  "roofs": [],
196
  "floors": [],
197
  "windows": [],
198
+ "doors": [],
199
  "skylights": []
200
  },
201
  "internal_loads": {
 
202
  "people": [],
203
+ "lighting": {},
204
+ "equipment": {}
 
 
 
 
 
 
 
 
 
205
  },
206
  "hvac_loads": {
207
  "cooling": {
208
  "hourly": [],
209
+ "peak": 0,
210
  "summary_tables": {},
211
+ "charts": {}
 
 
 
 
 
 
 
 
 
 
 
 
212
  },
213
  "heating": {
214
  "hourly": [],
215
+ "peak": 0,
216
  "summary_tables": {},
217
+ "charts": {}
218
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  },
220
  "building_energy": {
221
  "hvac_type": "",
 
239
  "embodied_energy": {
240
  "total_embodied_carbon_kgco2e": 0,
241
  "breakdown_by_component": {},
242
+ "charts": {}
 
243
  },
244
  "materials_cost": {
245
  "total_cost_usd": 0,
246
  "breakdown_by_component": {},
247
+ "charts": {}
 
248
  }
249
  }
250
 
251
+ logger.info("New project initialized")
252
 
253
  def load_project(uploaded_file) -> bool:
254
  """
 
279
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
280
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
281
 
 
 
 
 
 
 
282
  # Update session state with the loaded project data
283
  st.session_state.project_data = project_data
284
 
 
301
  """
302
  # Check for required top-level keys
303
  required_keys = [
 
304
  "building_info",
305
  "climate_data",
306
  "materials",
 
308
  "constructions",
309
  "components",
310
  "internal_loads",
 
311
  "hvac_loads",
 
 
 
312
  "building_energy",
313
  "renewable_energy",
314
  "embodied_energy",
 
325
  "project_name",
326
  "floor_area",
327
  "building_height",
328
+ "indoor_design_temp",
329
+ "indoor_design_rh",
330
+ "orientation_angle",
331
+ "operation_hours",
332
+ "building_type"
 
333
  ]
334
 
335
  for key in building_info_keys:
 
337
  logger.error(f"Missing required key in building_info: {key}")
338
  return False
339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  # Check components structure
341
+ component_types = ["walls", "roofs", "floors", "windows", "doors", "skylights"]
342
  for component_type in component_types:
343
  if component_type not in project_data["components"]:
344
  logger.error(f"Missing component type in components: {component_type}")
 
355
  def export_project():
356
  """Export the current project as a downloadable JSON file."""
357
  try:
 
 
 
 
 
 
 
 
 
358
  # Convert project data to JSON
359
+ project_json = json.dumps(st.session_state.project_data, indent=2)
360
 
361
  # Generate filename based on project name
362
+ project_name = st.session_state.project_data.get("project_name", "unnamed_project")
363
  safe_project_name = "".join(c if c.isalnum() else "_" for c in project_name)
364
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
365
  filename = f"{safe_project_name}_{timestamp}.json"