mabuseif commited on
Commit
d00cdea
·
verified ·
1 Parent(s): 9f2e218

Update app/intro.py

Browse files
Files changed (1) hide show
  1. app/intro.py +155 -33
app/intro.py CHANGED
@@ -76,9 +76,6 @@ def display_about_section():
76
 
77
  Beta Version 0.4.1 (2025)
78
  """)
79
-
80
- # Add Deakin University logo or other relevant images if available
81
- # st.image("path_to_logo.png", width=200)
82
 
83
  def display_instructions_section():
84
  """Display instructions on how to use the application."""
@@ -115,9 +112,6 @@ def display_instructions_section():
115
  * **Sol-Air Temperature**: For solar radiation effects on opaque surfaces
116
  * **Dynamic Solar Heat Gain**: For fenestration with angle-dependent properties
117
  """)
118
-
119
- # Add any diagrams or flowcharts if available
120
- # st.image("path_to_flowchart.png", width=600)
121
 
122
  def display_project_management_section():
123
  """Display project management options (new, import, export)."""
@@ -159,21 +153,61 @@ def start_new_project():
159
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
160
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
161
 
162
- # Reset project data to default values
163
  st.session_state.project_data = {
164
  "project_name": "",
165
  "building_info": {
166
  "project_name": "",
167
  "floor_area": 100.0,
168
  "building_height": 3.0,
169
- "indoor_design_temp": 24.0,
170
- "indoor_design_rh": 50.0,
171
- "ventilation_rate": 0.1,
172
- "orientation_angle": 0.0,
173
- "operation_hours": 8,
174
- "building_type": "Office"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  },
176
- "climate_data": {},
177
  "materials": {
178
  "library": {},
179
  "project": {}
@@ -191,27 +225,74 @@ def start_new_project():
191
  "roofs": [],
192
  "floors": [],
193
  "windows": [],
194
- "doors": [],
195
  "skylights": []
196
  },
197
  "internal_loads": {
 
198
  "people": [],
199
- "lighting": {},
200
- "equipment": {}
 
 
 
 
 
 
 
 
 
201
  },
202
  "hvac_loads": {
203
  "cooling": {
204
  "hourly": [],
205
- "peak": 0,
206
  "summary_tables": {},
207
- "charts": {}
 
 
 
 
 
 
 
 
 
 
 
 
208
  },
209
  "heating": {
210
  "hourly": [],
211
- "peak": 0,
212
  "summary_tables": {},
213
- "charts": {}
214
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  },
216
  "building_energy": {
217
  "hvac_type": "",
@@ -235,12 +316,14 @@ def start_new_project():
235
  "embodied_energy": {
236
  "total_embodied_carbon_kgco2e": 0,
237
  "breakdown_by_component": {},
238
- "charts": {}
 
239
  },
240
  "materials_cost": {
241
  "total_cost_usd": 0,
242
  "breakdown_by_component": {},
243
- "charts": {}
 
244
  }
245
  }
246
 
@@ -275,6 +358,12 @@ def load_project(uploaded_file) -> bool:
275
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
276
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
277
 
 
 
 
 
 
 
278
  # Update session state with the loaded project data
279
  st.session_state.project_data = project_data
280
 
@@ -297,6 +386,7 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
297
  """
298
  # Check for required top-level keys
299
  required_keys = [
 
300
  "building_info",
301
  "climate_data",
302
  "materials",
@@ -304,7 +394,11 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
304
  "constructions",
305
  "components",
306
  "internal_loads",
 
307
  "hvac_loads",
 
 
 
308
  "building_energy",
309
  "renewable_energy",
310
  "embodied_energy",
@@ -321,11 +415,12 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
321
  "project_name",
322
  "floor_area",
323
  "building_height",
324
- "indoor_design_temp",
325
- "indoor_design_rh",
326
- "orientation_angle",
327
- "operation_hours",
328
- "building_type"
 
329
  ]
330
 
331
  for key in building_info_keys:
@@ -333,8 +428,26 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
333
  logger.error(f"Missing required key in building_info: {key}")
334
  return False
335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  # Check components structure
337
- component_types = ["walls", "roofs", "floors", "windows", "doors", "skylights"]
338
  for component_type in component_types:
339
  if component_type not in project_data["components"]:
340
  logger.error(f"Missing component type in components: {component_type}")
@@ -351,11 +464,20 @@ def validate_project_data(project_data: Dict[str, Any]) -> bool:
351
  def export_project():
352
  """Export the current project as a downloadable JSON file."""
353
  try:
 
 
 
 
 
 
 
 
 
354
  # Convert project data to JSON
355
- project_json = json.dumps(st.session_state.project_data, indent=2)
356
 
357
  # Generate filename based on project name
358
- project_name = st.session_state.project_data.get("project_name", "unnamed_project")
359
  safe_project_name = "".join(c if c.isalnum() else "_" for c in project_name)
360
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
361
  filename = f"{safe_project_name}_{timestamp}.json"
@@ -390,4 +512,4 @@ def get_download_link(data, filename, link_text):
390
  """
391
  b64 = base64.b64encode(data.encode()).decode()
392
  href = f'<a href="data:application/json;base64,{b64}" download="{filename}">{link_text}</a>'
393
- return href
 
76
 
77
  Beta Version 0.4.1 (2025)
78
  """)
 
 
 
79
 
80
  def display_instructions_section():
81
  """Display instructions on how to use the application."""
 
112
  * **Sol-Air Temperature**: For solar radiation effects on opaque surfaces
113
  * **Dynamic Solar Heat Gain**: For fenestration with angle-dependent properties
114
  """)
 
 
 
115
 
116
  def display_project_management_section():
117
  """Display project management options (new, import, export)."""
 
153
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
154
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
155
 
156
+ # Reset project data to match main.py structure
157
  st.session_state.project_data = {
158
  "project_name": "",
159
  "building_info": {
160
  "project_name": "",
161
  "floor_area": 100.0,
162
  "building_height": 3.0,
163
+ "building_type": "Office",
164
+ "summer_indoor_design_temp": 24.0,
165
+ "summer_indoor_design_rh": 50.0,
166
+ "winter_indoor_design_temp": 20.0,
167
+ "winter_indoor_design_rh": 50.0,
168
+ "orientation_angle": 0.0
169
+ },
170
+ "climate_data": {
171
+ "id": "",
172
+ "location": {
173
+ "city": "",
174
+ "state_province": "",
175
+ "country": "",
176
+ "source": "",
177
+ "wmo": "",
178
+ "latitude": 0.0,
179
+ "longitude": 0.0,
180
+ "timezone": 0.0,
181
+ "elevation": 0.0
182
+ },
183
+ "design_conditions": {
184
+ "winter_design_temp": 0.0,
185
+ "summer_design_temp_db": 30.0,
186
+ "summer_design_temp_wb": 25.0,
187
+ "heating_degree_days": 0,
188
+ "cooling_degree_days": 0,
189
+ "monthly_average_temps": [20.0] * 12,
190
+ "monthly_average_radiation": [150.0] * 12,
191
+ "summer_daily_range": 8.0,
192
+ "wind_speed": 3.0,
193
+ "pressure": 101325.0
194
+ },
195
+ "climate_zone": "",
196
+ "hourly_data": [],
197
+ "epw_filename": "",
198
+ "typical_extreme_periods": {
199
+ "summer_extreme": {"start": {"month": 7, "day": 1}, "end": {"month": 7, "day": 7}},
200
+ "summer_typical": {"start": {"month": 6, "day": 1}, "end": {"month": 6, "day": 7}},
201
+ "winter_extreme": {"start": {"month": 1, "day": 1}, "end": {"month": 1, "day": 7}},
202
+ "winter_typical": {"start": {"month": 12, "day": 1}, "end": {"month": 12, "day": 7}}
203
+ },
204
+ "ground_temperatures": {
205
+ "0.5": [20.0] * 12,
206
+ "2": [18.0] * 12,
207
+ "4": [16.0] * 12
208
+ },
209
+ "ground_reflectivity": 0.2
210
  },
 
211
  "materials": {
212
  "library": {},
213
  "project": {}
 
225
  "roofs": [],
226
  "floors": [],
227
  "windows": [],
 
228
  "skylights": []
229
  },
230
  "internal_loads": {
231
+ "schedules": {},
232
  "people": [],
233
+ "lighting": [],
234
+ "equipment": [],
235
+ "ventilation": [],
236
+ "infiltration": []
237
+ },
238
+ "internal_loads_conditions": {
239
+ "air_velocity": 0.1,
240
+ "lighting_convective_fraction": 0.5,
241
+ "lighting_radiative_fraction": 0.5,
242
+ "equipment_convective_fraction": 0.5,
243
+ "equipment_radiative_fraction": 0.5
244
  },
245
  "hvac_loads": {
246
  "cooling": {
247
  "hourly": [],
248
+ "peak": 0.0,
249
  "summary_tables": {},
250
+ "charts": {
251
+ "pie_by_component": {},
252
+ "pie_by_orientation": {}
253
+ },
254
+ "breakdown": {
255
+ "conduction": 0.0,
256
+ "solar": 0.0,
257
+ "internal": 0.0,
258
+ "ventilation_sensible": 0.0,
259
+ "ventilation_latent": 0.0,
260
+ "infiltration_sensible": 0.0,
261
+ "infiltration_latent": 0.0
262
+ }
263
  },
264
  "heating": {
265
  "hourly": [],
266
+ "peak": 0.0,
267
  "summary_tables": {},
268
+ "charts": {
269
+ "pie_by_component": {},
270
+ "pie_by_orientation": {}
271
+ },
272
+ "breakdown": {
273
+ "conduction": 0.0,
274
+ "ventilation": 0.0,
275
+ "infiltration": 0.0
276
+ }
277
+ },
278
+ "monthly_summary": {}
279
+ },
280
+ "hvac_settings": {
281
+ "operating_hours": [{"start": 8, "end": 18}],
282
+ "system_type": "Default"
283
+ },
284
+ "sim_period": {
285
+ "type": "Full Year",
286
+ "start_date": datetime(2025, 1, 1),
287
+ "end_date": datetime(2025, 12, 31),
288
+ "base_temp": 18.3
289
+ },
290
+ "indoor_conditions": {
291
+ "type": "Fixed Setpoints",
292
+ "cooling_setpoint": {"temperature": 24.0, "rh": 50.0},
293
+ "heating_setpoint": {"temperature": 20.0, "rh": 50.0},
294
+ "adaptive_acceptability": "90",
295
+ "schedule": []
296
  },
297
  "building_energy": {
298
  "hvac_type": "",
 
316
  "embodied_energy": {
317
  "total_embodied_carbon_kgco2e": 0,
318
  "breakdown_by_component": {},
319
+ "charts": {},
320
+ "material_inventory": []
321
  },
322
  "materials_cost": {
323
  "total_cost_usd": 0,
324
  "breakdown_by_component": {},
325
+ "charts": {},
326
+ "material_inventory": []
327
  }
328
  }
329
 
 
358
  backup_timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
359
  st.session_state.project_data_backup[backup_timestamp] = st.session_state.project_data.copy()
360
 
361
+ # Convert datetime strings back to datetime objects if necessary
362
+ if project_data.get("sim_period", {}).get("start_date"):
363
+ project_data["sim_period"]["start_date"] = datetime.fromisoformat(project_data["sim_period"]["start_date"])
364
+ if project_data.get("sim_period", {}).get("end_date"):
365
+ project_data["sim_period"]["end_date"] = datetime.fromisoformat(project_data["sim_period"]["end_date"])
366
+
367
  # Update session state with the loaded project data
368
  st.session_state.project_data = project_data
369
 
 
386
  """
387
  # Check for required top-level keys
388
  required_keys = [
389
+ "project_name",
390
  "building_info",
391
  "climate_data",
392
  "materials",
 
394
  "constructions",
395
  "components",
396
  "internal_loads",
397
+ "internal_loads_conditions",
398
  "hvac_loads",
399
+ "hvac_settings",
400
+ "sim_period",
401
+ "indoor_conditions",
402
  "building_energy",
403
  "renewable_energy",
404
  "embodied_energy",
 
415
  "project_name",
416
  "floor_area",
417
  "building_height",
418
+ "building_type",
419
+ "summer_indoor_design_temp",
420
+ "summer_indoor_design_rh",
421
+ "winter_indoor_design_temp",
422
+ "winter_indoor_design_rh",
423
+ "orientation_angle"
424
  ]
425
 
426
  for key in building_info_keys:
 
428
  logger.error(f"Missing required key in building_info: {key}")
429
  return False
430
 
431
+ # Check climate_data structure
432
+ climate_data_keys = [
433
+ "id",
434
+ "location",
435
+ "design_conditions",
436
+ "climate_zone",
437
+ "hourly_data",
438
+ "epw_filename",
439
+ "typical_extreme_periods",
440
+ "ground_temperatures",
441
+ "ground_reflectivity"
442
+ ]
443
+
444
+ for key in climate_data_keys:
445
+ if key not in project_data["climate_data"]:
446
+ logger.error(f"Missing required key in climate_data: {key}")
447
+ return False
448
+
449
  # Check components structure
450
+ component_types = ["walls", "roofs", "floors", "windows", "skylights"]
451
  for component_type in component_types:
452
  if component_type not in project_data["components"]:
453
  logger.error(f"Missing component type in components: {component_type}")
 
464
  def export_project():
465
  """Export the current project as a downloadable JSON file."""
466
  try:
467
+ # Create a deep copy of project data to avoid modifying session state
468
+ project_data = st.session_state.project_data.copy()
469
+
470
+ # Convert datetime objects to ISO format strings for JSON serialization
471
+ if project_data.get("sim_period", {}).get("start_date"):
472
+ project_data["sim_period"]["start_date"] = project_data["sim_period"]["start_date"].isoformat()
473
+ if project_data.get("sim_period", {}).get("end_date"):
474
+ project_data["sim_period"]["end_date"] = project_data["sim_period"]["end_date"].isoformat()
475
+
476
  # Convert project data to JSON
477
+ project_json = json.dumps(project_data, indent=2)
478
 
479
  # Generate filename based on project name
480
+ project_name = project_data.get("project_name", "unnamed_project")
481
  safe_project_name = "".join(c if c.isalnum() else "_" for c in project_name)
482
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
483
  filename = f"{safe_project_name}_{timestamp}.json"
 
512
  """
513
  b64 = base64.b64encode(data.encode()).decode()
514
  href = f'<a href="data:application/json;base64,{b64}" download="{filename}">{link_text}</a>'
515
+ return href