mabuseif commited on
Commit
2bca6a4
·
verified ·
1 Parent(s): 83fc946

Update app/component_selection.py

Browse files
Files changed (1) hide show
  1. app/component_selection.py +40 -54
app/component_selection.py CHANGED
@@ -77,7 +77,7 @@ class BuildingComponent:
77
  @dataclass
78
  class Wall(BuildingComponent):
79
  wall_type: str = "Brick"
80
- wall_group: str = "B"
81
  shading_percentage: float = 0.0 # New attribute for shading percentage
82
 
83
  def __post_init__(self):
@@ -227,16 +227,16 @@ class ReferenceData:
227
  "mat_005": {"name": "Wood", "conductivity": 0.15}
228
  },
229
  "wall_types": {
230
- "preset_wall_001": {"id": "preset_wall_001", "name": "Brick Wall (Single Layer)", "component_type": "Wall", "u_value": 2.0, "area": 0.0, "orientation": "North", "wall_type": "Brick", "wall_group": "B", "shading_percentage": 0.0},
231
- "preset_wall_002": {"id": "preset_wall_002", "name": "Insulated Brick Wall", "component_type": "Wall", "u_value": 0.5, "area": 0.0, "orientation": "North", "wall_type": "Insulated Brick", "wall_group": "B", "shading_percentage": 0.0},
232
- "preset_wall_003": {"id": "preset_wall_003", "name": "Concrete Block Wall", "component_type": "Wall", "u_value": 1.8, "area": 0.0, "orientation": "North", "wall_type": "Concrete Block", "wall_group": "C", "shading_percentage": 0.0},
233
- "preset_wall_004": {"id": "preset_wall_004", "name": "Insulated Concrete Wall", "component_type": "Wall", "u_value": 0.4, "area": 0.0, "orientation": "North", "wall_type": "Insulated Concrete", "wall_group": "C", "shading_percentage": 0.0},
234
- "preset_wall_005": {"id": "preset_wall_005", "name": "Timber Frame Wall", "component_type": "Wall", "u_value": 0.3, "area": 0.0, "orientation": "North", "wall_type": "Timber Frame", "wall_group": "D", "shading_percentage": 0.0},
235
- "preset_wall_006": {"id": "preset_wall_006", "name": "Cavity Wall (Brick + Insulation)", "component_type": "Wall", "u_value": 0.6, "area": 0.0, "orientation": "North", "wall_type": "Cavity Brick", "wall_group": "B", "shading_percentage": 0.0},
236
- "preset_wall_007": {"id": "preset_wall_007", "name": "Lightweight Panel Wall", "component_type": "Wall", "u_value": 1.0, "area": 0.0, "orientation": "North", "wall_type": "Lightweight Panel", "wall_group": "E", "shading_percentage": 0.0},
237
- "preset_wall_008": {"id": "preset_wall_008", "name": "Reinforced Concrete Wall", "component_type": "Wall", "u_value": 1.5, "area": 0.0, "orientation": "North", "wall_type": "Reinforced Concrete", "wall_group": "C", "shading_percentage": 0.0},
238
- "preset_wall_009": {"id": "preset_wall_009", "name": "SIP Wall (Structural Insulated Panel)", "component_type": "Wall", "u_value": 0.25, "area": 0.0, "orientation": "North", "wall_type": "SIP", "wall_group": "F", "shading_percentage": 0.0},
239
- "preset_wall_010": {"id": "preset_wall_010", "name": "Custom Wall", "component_type": "Wall", "u_value": 0.5, "area": 0.0, "orientation": "North", "wall_type": "Custom", "wall_group": "G", "shading_percentage": 0.0}
240
  },
241
  "roof_types": {
242
  "preset_roof_001": {"id": "preset_roof_001", "name": "Concrete Roof", "component_type": "Roof", "u_value": 0.3, "area": 0.0, "orientation": "Horizontal", "roof_type": "Concrete", "roof_group": "C"}
@@ -371,8 +371,7 @@ class ComponentSelectionInterface:
371
  if components:
372
  st.subheader(f"Existing {type_name.capitalize()} Components")
373
  self._display_components_table(session_state, component_type, components)
374
- else:
375
- st.info(f"No {type_name} components defined yet.")
376
 
377
  def _display_add_wall_form(self, session_state: Any) -> None:
378
  # Wall-specific form with manual entry and Excel upload options
@@ -380,6 +379,9 @@ class ComponentSelectionInterface:
380
  wall_method = st.radio("Add Wall Method", ["Manual Entry", "Excel Upload"])
381
 
382
  if wall_method == "Manual Entry":
 
 
 
383
  with st.form("add_wall_form"):
384
  col1, col2 = st.columns(2)
385
  with col1:
@@ -391,14 +393,12 @@ class ComponentSelectionInterface:
391
  wall_options = {comp.name: comp for comp in preset_walls}
392
  selected_wall = st.selectbox("Select Wall Type", options=list(wall_options.keys()))
393
  component = wall_options[selected_wall]
394
- if selected_wall == "Custom Wall":
395
- u_value = st.number_input("U-Value (W/m²·K)", min_value=0.0, max_value=9.0, value=0.5, step=0.01)
396
- else:
397
- u_value = st.number_input("U-Value (W/m²·K)", value=component.u_value, disabled=True)
398
- shading_percentage = st.number_input("Shading Percentage (%)", min_value=0.0, max_value=100.0, value=0.0, step=5.0)
399
 
400
  submitted = st.form_submit_button("Add Wall")
401
- if submitted:
402
  if not name:
403
  st.error("Wall name is required!")
404
  elif area <= 0:
@@ -409,19 +409,24 @@ class ComponentSelectionInterface:
409
  new_wall = Wall(
410
  id=str(uuid.uuid4()), name=name, u_value=u_value, area=area,
411
  orientation=Orientation(orientation), wall_type=component.wall_type,
412
- wall_group=component.wall_group, shading_percentage=shading_percentage
413
  )
414
  self.component_library.add_component(new_wall)
415
  session_state.components['walls'].append(new_wall)
416
  st.success(f"Added {new_wall.name}")
 
417
  st.rerun()
 
 
 
 
418
 
419
  elif wall_method == "Excel Upload":
420
  st.info("Upload an Excel file with columns: Name, Area (m²), U-Value (W/m²·K), Orientation, Wall Type, Wall Group, Shading (%)")
421
  uploaded_file = st.file_uploader("Upload Walls Excel", type=["xlsx"], key="wall_upload")
 
422
  if uploaded_file and st.button("Process Excel"):
423
  df = pd.read_excel(uploaded_file)
424
- required_cols = ["Name", "Area (m²)", "U-Value (W/m²·K)", "Orientation", "Wall Type", "Wall Group", "Shading (%)"]
425
  if not all(col in df.columns for col in required_cols):
426
  st.error("Excel file must contain all required columns!")
427
  else:
@@ -430,7 +435,7 @@ class ComponentSelectionInterface:
430
  new_wall = Wall(
431
  id=str(uuid.uuid4()), name=row["Name"], u_value=row["U-Value (W/m²·K)"],
432
  area=row["Area (m²)"], orientation=Orientation(row["Orientation"]),
433
- wall_type=row["Wall Type"], wall_group=row["Wall Group"],
434
  shading_percentage=row["Shading (%)"]
435
  )
436
  self.component_library.add_component(new_wall)
@@ -579,47 +584,28 @@ class ComponentSelectionInterface:
579
 
580
  df = pd.DataFrame(data)
581
  display_cols = [col for col in df.columns if col != "ID"]
 
582
 
583
- if component_type == ComponentType.WALL:
584
- # Custom table rendering for walls with delete button next to each row
585
- st.write("Walls Table:")
586
- for i, row in df.iterrows():
587
- cols = st.columns([2, 1, 1, 1, 1, 1, 1, 1])
588
- cols[0].write(row["Name"])
589
- cols[1].write(row["Area (m²)"])
590
- cols[2].write(row["U-Value (W/m²·K)"])
591
- cols[3].write(row["Orientation"])
592
- cols[4].write(row["Wall Type"])
593
- cols[5].write(row["Wall Group"])
594
- cols[6].write(row["Shading (%)"])
595
- if cols[7].button("Delete", key=f"delete_{row['ID']}"):
596
  if not row["ID"].startswith("preset_"):
597
  self.component_library.remove_component(row["ID"])
598
- session_state.components['walls'] = [c for c in components if c.id != row["ID"]]
599
  st.success(f"Deleted {row['Name']}")
600
  st.rerun()
601
  else:
602
  st.warning("Cannot delete preset components.")
603
- # Download walls table as CSV
 
604
  csv = df[display_cols].to_csv(index=False)
605
  st.download_button(label="Download Walls Table", data=csv, file_name="walls_table.csv", mime="text/csv")
606
- else:
607
- st.dataframe(df[display_cols], use_container_width=True)
608
- for i, row in df.iterrows():
609
- col1, col2 = st.columns(2)
610
- with col1:
611
- if st.button("Edit", key=f"edit_{row['ID']}"):
612
- session_state[f"edit_{type_name}"] = row["ID"]
613
- st .rerun()
614
- with col2:
615
- if st.button("Delete", key=f"delete_{row['ID']}"):
616
- if not row["ID"].startswith("preset_"):
617
- self.component_library.remove_component(row["ID"])
618
- session_state.components[type_name + 's'] = [c for c in components if c.id != row["ID"]]
619
- st.success(f"Deleted {row['Name']}")
620
- st.rerun()
621
- else:
622
- st.warning("Cannot delete preset components.")
623
 
624
  if f"edit_{type_name}" in session_state and component_type != ComponentType.WALL:
625
  self._display_edit_component_form(session_state, component_type, session_state[f"edit_{type_name}"])
 
77
  @dataclass
78
  class Wall(BuildingComponent):
79
  wall_type: str = "Brick"
80
+ wall_group: str = "Wall" # Changed from B/C to Wall for visualization
81
  shading_percentage: float = 0.0 # New attribute for shading percentage
82
 
83
  def __post_init__(self):
 
227
  "mat_005": {"name": "Wood", "conductivity": 0.15}
228
  },
229
  "wall_types": {
230
+ "preset_wall_001": {"id": "preset_wall_001", "name": "Brick Wall (Single Layer) (U-value: 2.0 W/m²·K)", "component_type": "Wall", "u_value": 2.0, "area": 0.0, "orientation": "North", "wall_type": "Brick", "wall_group": "Wall", "shading_percentage": 0.0},
231
+ "preset_wall_002": {"id": "preset_wall_002", "name": "Insulated Brick Wall (U-value: 0.5 W/m²·K)", "component_type": "Wall", "u_value": 0.5, "area": 0.0, "orientation": "North", "wall_type": "Insulated Brick", "wall_group": "Wall", "shading_percentage": 0.0},
232
+ "preset_wall_003": {"id": "preset_wall_003", "name": "Concrete Block Wall (U-value: 1.8 W/m²·K)", "component_type": "Wall", "u_value": 1.8, "area": 0.0, "orientation": "North", "wall_type": "Concrete Block", "wall_group": "Wall", "shading_percentage": 0.0},
233
+ "preset_wall_004": {"id": "preset_wall_004", "name": "Insulated Concrete Wall (U-value: 0.4 W/m²·K)", "component_type": "Wall", "u_value": 0.4, "area": 0.0, "orientation": "North", "wall_type": "Insulated Concrete", "wall_group": "Wall", "shading_percentage": 0.0},
234
+ "preset_wall_005": {"id": "preset_wall_005", "name": "Timber Frame Wall (U-value: 0.3 W/m²·K)", "component_type": "Wall", "u_value": 0.3, "area": 0.0, "orientation": "North", "wall_type": "Timber Frame", "wall_group": "Wall", "shading_percentage": 0.0},
235
+ "preset_wall_006": {"id": "preset_wall_006", "name": "Cavity Wall (Brick + Insulation) (U-value: 0.6 W/m²·K)", "component_type": "Wall", "u_value": 0.6, "area": 0.0, "orientation": "North", "wall_type": "Cavity Brick", "wall_group": "Wall", "shading_percentage": 0.0},
236
+ "preset_wall_007": {"id": "preset_wall_007", "name": "Lightweight Panel Wall (U-value: 1.0 W/m²·K)", "component_type": "Wall", "u_value": 1.0, "area": 0.0, "orientation": "North", "wall_type": "Lightweight Panel", "wall_group": "Wall", "shading_percentage": 0.0},
237
+ "preset_wall_008": {"id": "preset_wall_008", "name": "Reinforced Concrete Wall (U-value: 1.5 W/m²·K)", "component_type": "Wall", "u_value": 1.5, "area": 0.0, "orientation": "North", "wall_type": "Reinforced Concrete", "wall_group": "Wall", "shading_percentage": 0.0},
238
+ "preset_wall_009": {"id": "preset_wall_009", "name": "SIP Wall (Structural Insulated Panel) (U-value: 0.25 W/m²·K)", "component_type": "Wall", "u_value": 0.25, "area": 0.0, "orientation": "North", "wall_type": "SIP", "wall_group": "Wall", "shading_percentage": 0.0},
239
+ "preset_wall_010": {"id": "preset_wall_010", "name": "Custom Wall (U-value: 0.5 W/m²·K)", "component_type": "Wall", "u_value": 0.5, "area": 0.0, "orientation": "North", "wall_type": "Custom", "wall_group": "Wall", "shading_percentage": 0.0}
240
  },
241
  "roof_types": {
242
  "preset_roof_001": {"id": "preset_roof_001", "name": "Concrete Roof", "component_type": "Roof", "u_value": 0.3, "area": 0.0, "orientation": "Horizontal", "roof_type": "Concrete", "roof_group": "C"}
 
371
  if components:
372
  st.subheader(f"Existing {type_name.capitalize()} Components")
373
  self._display_components_table(session_state, component_type, components)
374
+ # Removed the misplaced Download Walls Table button from here
 
375
 
376
  def _display_add_wall_form(self, session_state: Any) -> None:
377
  # Wall-specific form with manual entry and Excel upload options
 
379
  wall_method = st.radio("Add Wall Method", ["Manual Entry", "Excel Upload"])
380
 
381
  if wall_method == "Manual Entry":
382
+ if "add_wall_submitted" not in session_state:
383
+ session_state.add_wall_submitted = False
384
+
385
  with st.form("add_wall_form"):
386
  col1, col2 = st.columns(2)
387
  with col1:
 
393
  wall_options = {comp.name: comp for comp in preset_walls}
394
  selected_wall = st.selectbox("Select Wall Type", options=list(wall_options.keys()))
395
  component = wall_options[selected_wall]
396
+ # Allow editing U-value for all wall types
397
+ u_value = st.number_input("U-Value (W/m²·K)", min_value=0.0, max_value=9.0, value=component.u_value, step=0.01)
398
+ shading_percentage = st.slider("Shading Percentage (%)", min_value=0.0, max_value=100.0, value=0.0, step=5.0)
 
 
399
 
400
  submitted = st.form_submit_button("Add Wall")
401
+ if submitted and not session_state.add_wall_submitted:
402
  if not name:
403
  st.error("Wall name is required!")
404
  elif area <= 0:
 
409
  new_wall = Wall(
410
  id=str(uuid.uuid4()), name=name, u_value=u_value, area=area,
411
  orientation=Orientation(orientation), wall_type=component.wall_type,
412
+ wall_group="Wall", shading_percentage=shading_percentage
413
  )
414
  self.component_library.add_component(new_wall)
415
  session_state.components['walls'].append(new_wall)
416
  st.success(f"Added {new_wall.name}")
417
+ session_state.add_wall_submitted = True # Prevent infinite addition
418
  st.rerun()
419
+
420
+ # Reset the flag after submission
421
+ if session_state.add_wall_submitted:
422
+ session_state.add_wall_submitted = False
423
 
424
  elif wall_method == "Excel Upload":
425
  st.info("Upload an Excel file with columns: Name, Area (m²), U-Value (W/m²·K), Orientation, Wall Type, Wall Group, Shading (%)")
426
  uploaded_file = st.file_uploader("Upload Walls Excel", type=["xlsx"], key="wall_upload")
427
+ required_cols = ["Name", "Area (m²)", "U-Value (W/m²·K)", "Orientation", "Wall Type", "Wall Group", "Shading (%)"] # Defined before use
428
  if uploaded_file and st.button("Process Excel"):
429
  df = pd.read_excel(uploaded_file)
 
430
  if not all(col in df.columns for col in required_cols):
431
  st.error("Excel file must contain all required columns!")
432
  else:
 
435
  new_wall = Wall(
436
  id=str(uuid.uuid4()), name=row["Name"], u_value=row["U-Value (W/m²·K)"],
437
  area=row["Area (m²)"], orientation=Orientation(row["Orientation"]),
438
+ wall_type=row["Wall Type"], wall_group="Wall",
439
  shading_percentage=row["Shading (%)"]
440
  )
441
  self.component_library.add_component(new_wall)
 
584
 
585
  df = pd.DataFrame(data)
586
  display_cols = [col for col in df.columns if col != "ID"]
587
+ st.dataframe(df[display_cols], use_container_width=True)
588
 
589
+ for i, row in df.iterrows():
590
+ col1, col2 = st.columns(2)
591
+ if component_type != ComponentType.WALL: # Edit button only for non-wall components
592
+ with col1:
593
+ if st.button("Edit", key=f"edit_{row['ID']}"):
594
+ session_state[f"edit_{type_name}"] = row["ID"]
595
+ st.rerun()
596
+ with col2:
597
+ if st.button("Delete", key=f"delete_{row['ID']}"):
 
 
 
 
598
  if not row["ID"].startswith("preset_"):
599
  self.component_library.remove_component(row["ID"])
600
+ session_state.components[type_name + 's'] = [c for c in components if c.id != row["ID"]]
601
  st.success(f"Deleted {row['Name']}")
602
  st.rerun()
603
  else:
604
  st.warning("Cannot delete preset components.")
605
+
606
+ if component_type == ComponentType.WALL:
607
  csv = df[display_cols].to_csv(index=False)
608
  st.download_button(label="Download Walls Table", data=csv, file_name="walls_table.csv", mime="text/csv")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
 
610
  if f"edit_{type_name}" in session_state and component_type != ComponentType.WALL:
611
  self._display_edit_component_form(session_state, component_type, session_state[f"edit_{type_name}"])