Spaces:
Sleeping
Sleeping
Update app/component_selection.py
Browse files- app/component_selection.py +35 -10
app/component_selection.py
CHANGED
|
@@ -422,17 +422,23 @@ class ComponentSelectionInterface:
|
|
| 422 |
|
| 423 |
elif wall_method == "File Upload":
|
| 424 |
st.info("Upload a CSV or Excel file with columns: Name, Area (m²), U-Value (W/m²·K), Orientation, Wall Type, Wall Group, Shading (%)")
|
| 425 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
required_cols = ["Name", "Area (m²)", "U-Value (W/m²·K)", "Orientation", "Wall Type", "Wall Group", "Shading (%)"]
|
|
|
|
| 427 |
if uploaded_file and st.button("Process File"):
|
| 428 |
try:
|
| 429 |
if uploaded_file.name.endswith('.csv'):
|
| 430 |
-
# Try multiple encodings to handle potential issues
|
| 431 |
encodings = ['utf-8', 'latin1', 'windows-1252']
|
| 432 |
df = None
|
| 433 |
for encoding in encodings:
|
| 434 |
try:
|
| 435 |
-
uploaded_file.seek(0)
|
| 436 |
df = pd.read_csv(uploaded_file, encoding=encoding)
|
| 437 |
break
|
| 438 |
except UnicodeDecodeError:
|
|
@@ -444,7 +450,6 @@ class ComponentSelectionInterface:
|
|
| 444 |
|
| 445 |
# Normalize column names
|
| 446 |
df.columns = [col.strip() for col in df.columns]
|
| 447 |
-
# Map "Group" to "Wall Group" if present
|
| 448 |
if "Group" in df.columns and "Wall Group" not in df.columns:
|
| 449 |
df.rename(columns={"Group": "Wall Group"}, inplace=True)
|
| 450 |
if not all(col in df.columns for col in required_cols):
|
|
@@ -468,9 +473,12 @@ class ComponentSelectionInterface:
|
|
| 468 |
except ValueError as e:
|
| 469 |
st.error(f"Error in row: {row['Name']} - {str(e)}")
|
| 470 |
st.success("Walls uploaded and overwritten successfully!")
|
| 471 |
-
|
|
|
|
|
|
|
| 472 |
except Exception as e:
|
| 473 |
st.error(f"Error processing file: {str(e)}")
|
|
|
|
| 474 |
# Provide a downloadable template
|
| 475 |
template_df = pd.DataFrame(columns=required_cols)
|
| 476 |
buffer = io.BytesIO()
|
|
@@ -596,7 +604,7 @@ class ComponentSelectionInterface:
|
|
| 596 |
for comp in components:
|
| 597 |
row = {"Name": comp.name, "Area (m²)": comp.area, "U-Value (W/m²·K)": comp.u_value, "Orientation": comp.orientation.value, "ID": comp.id}
|
| 598 |
if component_type == ComponentType.WALL:
|
| 599 |
-
row.update({"Wall Type": comp.wall_type, "Wall Group": comp.wall_group, "Shading (%)": comp.shading_percentage
|
| 600 |
elif component_type == ComponentType.ROOF:
|
| 601 |
row.update({"Roof Type": comp.roof_type, "Roof Group": comp.roof_group})
|
| 602 |
elif component_type == ComponentType.FLOOR:
|
|
@@ -612,9 +620,25 @@ class ComponentSelectionInterface:
|
|
| 612 |
display_cols = [col for col in df.columns if col != "ID"]
|
| 613 |
|
| 614 |
if component_type == ComponentType.WALL:
|
| 615 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 616 |
for i, row in df.iterrows():
|
| 617 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 618 |
if not row["ID"].startswith("preset_"):
|
| 619 |
self.component_library.remove_component(row["ID"])
|
| 620 |
session_state.components['walls'] = [c for c in components if c.id != row["ID"]]
|
|
@@ -622,8 +646,9 @@ class ComponentSelectionInterface:
|
|
| 622 |
st.rerun()
|
| 623 |
else:
|
| 624 |
st.warning("Cannot delete preset components.")
|
| 625 |
-
|
| 626 |
-
|
|
|
|
| 627 |
csv_buffer = io.BytesIO()
|
| 628 |
csv_df.to_csv(csv_buffer, index=False, encoding='utf-8')
|
| 629 |
st.download_button(label="Download Walls Table", data=csv_buffer.getvalue(), file_name="walls_table.csv", mime="text/csv")
|
|
|
|
| 422 |
|
| 423 |
elif wall_method == "File Upload":
|
| 424 |
st.info("Upload a CSV or Excel file with columns: Name, Area (m²), U-Value (W/m²·K), Orientation, Wall Type, Wall Group, Shading (%)")
|
| 425 |
+
# Use a unique key for the file uploader to allow clearing
|
| 426 |
+
if "file_uploaded" not in session_state:
|
| 427 |
+
session_state.file_uploaded = False
|
| 428 |
+
if "uploaded_file_key" not in session_state:
|
| 429 |
+
session_state.uploaded_file_key = 0
|
| 430 |
+
|
| 431 |
+
uploaded_file = st.file_uploader("Upload Walls File", type=["csv", "xlsx"], key=f"wall_upload_{session_state.uploaded_file_key}")
|
| 432 |
required_cols = ["Name", "Area (m²)", "U-Value (W/m²·K)", "Orientation", "Wall Type", "Wall Group", "Shading (%)"]
|
| 433 |
+
|
| 434 |
if uploaded_file and st.button("Process File"):
|
| 435 |
try:
|
| 436 |
if uploaded_file.name.endswith('.csv'):
|
|
|
|
| 437 |
encodings = ['utf-8', 'latin1', 'windows-1252']
|
| 438 |
df = None
|
| 439 |
for encoding in encodings:
|
| 440 |
try:
|
| 441 |
+
uploaded_file.seek(0)
|
| 442 |
df = pd.read_csv(uploaded_file, encoding=encoding)
|
| 443 |
break
|
| 444 |
except UnicodeDecodeError:
|
|
|
|
| 450 |
|
| 451 |
# Normalize column names
|
| 452 |
df.columns = [col.strip() for col in df.columns]
|
|
|
|
| 453 |
if "Group" in df.columns and "Wall Group" not in df.columns:
|
| 454 |
df.rename(columns={"Group": "Wall Group"}, inplace=True)
|
| 455 |
if not all(col in df.columns for col in required_cols):
|
|
|
|
| 473 |
except ValueError as e:
|
| 474 |
st.error(f"Error in row: {row['Name']} - {str(e)}")
|
| 475 |
st.success("Walls uploaded and overwritten successfully!")
|
| 476 |
+
# Clear the file uploader by incrementing the key
|
| 477 |
+
session_state.uploaded_file_key += 1
|
| 478 |
+
session_state.file_uploaded = True
|
| 479 |
except Exception as e:
|
| 480 |
st.error(f"Error processing file: {str(e)}")
|
| 481 |
+
|
| 482 |
# Provide a downloadable template
|
| 483 |
template_df = pd.DataFrame(columns=required_cols)
|
| 484 |
buffer = io.BytesIO()
|
|
|
|
| 604 |
for comp in components:
|
| 605 |
row = {"Name": comp.name, "Area (m²)": comp.area, "U-Value (W/m²·K)": comp.u_value, "Orientation": comp.orientation.value, "ID": comp.id}
|
| 606 |
if component_type == ComponentType.WALL:
|
| 607 |
+
row.update({"Wall Type": comp.wall_type, "Wall Group": comp.wall_group, "Shading (%)": comp.shading_percentage})
|
| 608 |
elif component_type == ComponentType.ROOF:
|
| 609 |
row.update({"Roof Type": comp.roof_type, "Roof Group": comp.roof_group})
|
| 610 |
elif component_type == ComponentType.FLOOR:
|
|
|
|
| 620 |
display_cols = [col for col in df.columns if col != "ID"]
|
| 621 |
|
| 622 |
if component_type == ComponentType.WALL:
|
| 623 |
+
# Custom table rendering for walls with delete button in the row
|
| 624 |
+
st.write("### Walls Table")
|
| 625 |
+
# Display headers
|
| 626 |
+
headers = ["Name", "Area (m²)", "U-Value (W/m²·K)", "Orientation", "Wall Type", "Wall Group", "Shading (%)", "Delete"]
|
| 627 |
+
cols = st.columns([1, 1, 1, 1, 1, 1, 1, 1])
|
| 628 |
+
for i, header in enumerate(headers):
|
| 629 |
+
cols[i].write(f"**{header}**")
|
| 630 |
+
|
| 631 |
+
# Display rows
|
| 632 |
for i, row in df.iterrows():
|
| 633 |
+
cols = st.columns([1, 1, 1, 1, 1, 1, 1, 1])
|
| 634 |
+
cols[0].write(row["Name"])
|
| 635 |
+
cols[1].write(row["Area (m²)"])
|
| 636 |
+
cols[2].write(row["U-Value (W/m²·K)"])
|
| 637 |
+
cols[3].write(row["Orientation"])
|
| 638 |
+
cols[4].write(row["Wall Type"])
|
| 639 |
+
cols[5].write(row["Wall Group"])
|
| 640 |
+
cols[6].write(row["Shading (%)"])
|
| 641 |
+
if cols[7].button("Delete", key=f"delete_{row['ID']}"):
|
| 642 |
if not row["ID"].startswith("preset_"):
|
| 643 |
self.component_library.remove_component(row["ID"])
|
| 644 |
session_state.components['walls'] = [c for c in components if c.id != row["ID"]]
|
|
|
|
| 646 |
st.rerun()
|
| 647 |
else:
|
| 648 |
st.warning("Cannot delete preset components.")
|
| 649 |
+
|
| 650 |
+
# Download walls table (excluding Delete column)
|
| 651 |
+
csv_df = df[["Name", "Area (m²)", "U-Value (W/m²·K)", "Orientation", "Wall Type", "Wall Group", "Shading (%)"]]
|
| 652 |
csv_buffer = io.BytesIO()
|
| 653 |
csv_df.to_csv(csv_buffer, index=False, encoding='utf-8')
|
| 654 |
st.download_button(label="Download Walls Table", data=csv_buffer.getvalue(), file_name="walls_table.csv", mime="text/csv")
|