Spaces:
Sleeping
Sleeping
Update app/materials_library.py
Browse files- app/materials_library.py +30 -23
app/materials_library.py
CHANGED
@@ -368,17 +368,18 @@ def display_materials_page():
|
|
368 |
if "fenestration_action" not in st.session_state:
|
369 |
st.session_state.fenestration_action = {"action": None, "id": None}
|
370 |
|
371 |
-
# Process
|
372 |
-
|
373 |
action = st.session_state.action_queue.pop(0)
|
|
|
374 |
if action["type"] == "page_change":
|
375 |
st.session_state.current_page = action["page"]
|
376 |
-
st.rerun
|
377 |
elif action["type"] == "material_action":
|
378 |
handle_material_action(action)
|
379 |
elif action["type"] == "fenestration_action":
|
380 |
handle_fenestration_action(action)
|
381 |
-
|
382 |
|
383 |
# Apply custom CSS for button styling
|
384 |
st.markdown("""
|
@@ -419,6 +420,7 @@ def display_materials_page():
|
|
419 |
|
420 |
def handle_material_action(action: Dict[str, Any]):
|
421 |
"""Handle material-related actions."""
|
|
|
422 |
if action["action"] == "preview":
|
423 |
material = action["material"]
|
424 |
name = action["name"]
|
@@ -451,6 +453,7 @@ def handle_material_action(action: Dict[str, Any]):
|
|
451 |
"emissivity": float(material["emissivity"]),
|
452 |
"colour": material["colour"]
|
453 |
}
|
|
|
454 |
elif action["action"] == "copy":
|
455 |
name = action["name"]
|
456 |
material = action["material"]
|
@@ -495,6 +498,7 @@ def handle_material_action(action: Dict[str, Any]):
|
|
495 |
"emissivity": float(material["emissivity"]),
|
496 |
"colour": material["colour"]
|
497 |
}
|
|
|
498 |
elif action["action"] == "delete":
|
499 |
name = action["name"]
|
500 |
is_in_use = check_material_in_use(name)
|
@@ -507,6 +511,7 @@ def handle_material_action(action: Dict[str, Any]):
|
|
507 |
|
508 |
def handle_fenestration_action(action: Dict[str, Any]):
|
509 |
"""Handle fenestration-related actions."""
|
|
|
510 |
if action["action"] == "preview":
|
511 |
fenestration = action["fenestration"]
|
512 |
name = action["name"]
|
@@ -533,6 +538,7 @@ def handle_fenestration_action(action: Dict[str, Any]):
|
|
533 |
"embodied_carbon": float(fenestration["embodied_carbon"]),
|
534 |
"cost": float(fenestration["cost"])
|
535 |
}
|
|
|
536 |
elif action["action"] == "copy":
|
537 |
name = action["name"]
|
538 |
fenestration = action["fenestration"]
|
@@ -571,6 +577,7 @@ def handle_fenestration_action(action: Dict[str, Any]):
|
|
571 |
"embodied_carbon": float(fenestration["embodied_carbon"]),
|
572 |
"cost": float(fenestration["cost"])
|
573 |
}
|
|
|
574 |
elif action["action"] == "delete":
|
575 |
name = action["name"]
|
576 |
is_in_use = check_fenestration_in_use(name)
|
@@ -715,8 +722,8 @@ def display_materials_tab():
|
|
715 |
"U-Value (W/m虏路K)": u_value
|
716 |
})
|
717 |
df = pd.DataFrame(data)
|
|
|
718 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
719 |
-
st.session_state.project_data["materials"]["table"] = df
|
720 |
else:
|
721 |
st.info("No project materials to display.")
|
722 |
|
@@ -844,8 +851,8 @@ def display_fenestrations_tab():
|
|
844 |
"Cost (USD/m虏)": props["cost"]
|
845 |
})
|
846 |
df = pd.DataFrame(data)
|
|
|
847 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
848 |
-
st.session_state.project_data["fenestrations"]["table"] = df
|
849 |
else:
|
850 |
st.info("No project fenestrations to display.")
|
851 |
|
@@ -1120,11 +1127,11 @@ def display_material_editor():
|
|
1120 |
st.success(f"Material '{name}' added to your project.")
|
1121 |
logger.info(f"Added new material '{name}' to project")
|
1122 |
reset_material_editor()
|
1123 |
-
|
1124 |
|
1125 |
if clear_button:
|
1126 |
reset_material_editor()
|
1127 |
-
|
1128 |
|
1129 |
def display_fenestration_editor():
|
1130 |
"""Display the fenestration editor form."""
|
@@ -1257,7 +1264,7 @@ def display_fenestration_editor():
|
|
1257 |
"embodied_carbon": embodied_carbon,
|
1258 |
"cost": cost
|
1259 |
}
|
1260 |
-
if
|
1261 |
original_name = editor_state["original_name"]
|
1262 |
if original_name != name:
|
1263 |
del st.session_state.project_data["fenestrations"]["project"][original_name]
|
@@ -1269,11 +1276,11 @@ def display_fenestration_editor():
|
|
1269 |
st.success(f"Fenestration '{name}' added to your project.")
|
1270 |
logger.info(f"Added new fenestration '{name}' to project")
|
1271 |
reset_fenestration_editor()
|
1272 |
-
|
1273 |
|
1274 |
if clear_button:
|
1275 |
reset_fenestration_editor()
|
1276 |
-
|
1277 |
|
1278 |
def validate_material(
|
1279 |
name: str, category: str, thermal_conductivity: float, density: float,
|
@@ -1324,8 +1331,8 @@ def validate_material(
|
|
1324 |
colour_ranges = {
|
1325 |
"Light": (0.30, 0.50),
|
1326 |
"Medium": (0.60, 0.70),
|
1327 |
-
"Dark": (0.
|
1328 |
-
"Reflective": (0.
|
1329 |
}
|
1330 |
min_abs, max_abs = colour_ranges[colour]
|
1331 |
if not (min_abs <= absorptivity <= max_abs):
|
@@ -1358,7 +1365,7 @@ def validate_fenestration(
|
|
1358 |
return False, "SHGC must be between 0 and 1."
|
1359 |
|
1360 |
if visible_trans < 0 or visible_trans > 1:
|
1361 |
-
return False, "Visible
|
1362 |
|
1363 |
if thickness <= 0:
|
1364 |
return False, "Thickness must be greater than zero."
|
@@ -1371,8 +1378,8 @@ def validate_fenestration(
|
|
1371 |
|
1372 |
return True, ""
|
1373 |
|
1374 |
-
def
|
1375 |
-
"""Reset the material editor and form state."""
|
1376 |
st.session_state.material_form_state = {
|
1377 |
"name": "",
|
1378 |
"category": MATERIAL_CATEGORIES[0],
|
@@ -1452,15 +1459,15 @@ def display_materials_help():
|
|
1452 |
|
1453 |
**Materials Tab:**
|
1454 |
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
|
1459 |
**Fenestrations Tab:**
|
1460 |
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
|
1465 |
**Key Properties:**
|
1466 |
|
@@ -1468,7 +1475,7 @@ def display_materials_help():
|
|
1468 |
* **Density (kg/m鲁)**: Mass per unit volume.
|
1469 |
* **Specific Heat (J/kg路K)**: Energy required to raise the temperature of 1 kg by 1 K. Higher values indicate better thermal mass.
|
1470 |
* **Thermal Mass (J/m虏路K)**: Areal heat capacity (density 脳 specific heat 脳 thickness).
|
1471 |
-
* **U-Value (W/m虏路K)**: Overall heat transfer coefficient, accounting for material
|
1472 |
* **SHGC**: Solar Heat Gain Coefficient (0-1). Fraction of incident solar radiation that enters through a fenestration.
|
1473 |
* **Visible Transmittance**: Fraction of visible light that passes through a fenestration.
|
1474 |
* **Embodied Carbon**: Carbon emissions associated with material production, measured in kg CO鈧俥 per unit volume or area.
|
|
|
368 |
if "fenestration_action" not in st.session_state:
|
369 |
st.session_state.fenestration_action = {"action": None, "id": None}
|
370 |
|
371 |
+
# Process all actions in the queue without immediate rerun
|
372 |
+
while st.session_state.action_queue:
|
373 |
action = st.session_state.action_queue.pop(0)
|
374 |
+
logger.info(f"Processing action: {action}")
|
375 |
if action["type"] == "page_change":
|
376 |
st.session_state.current_page = action["page"]
|
377 |
+
st.session_state.module_rerun_flags["materials"] = True # Request rerun via main.py
|
378 |
elif action["type"] == "material_action":
|
379 |
handle_material_action(action)
|
380 |
elif action["type"] == "fenestration_action":
|
381 |
handle_fenestration_action(action)
|
382 |
+
# No rerun here to allow UI to update naturally
|
383 |
|
384 |
# Apply custom CSS for button styling
|
385 |
st.markdown("""
|
|
|
420 |
|
421 |
def handle_material_action(action: Dict[str, Any]):
|
422 |
"""Handle material-related actions."""
|
423 |
+
logger.info(f"Handling material action: {action}")
|
424 |
if action["action"] == "preview":
|
425 |
material = action["material"]
|
426 |
name = action["name"]
|
|
|
453 |
"emissivity": float(material["emissivity"]),
|
454 |
"colour": material["colour"]
|
455 |
}
|
456 |
+
logger.info(f"Previewed material '{name}'")
|
457 |
elif action["action"] == "copy":
|
458 |
name = action["name"]
|
459 |
material = action["material"]
|
|
|
498 |
"emissivity": float(material["emissivity"]),
|
499 |
"colour": material["colour"]
|
500 |
}
|
501 |
+
logger.info(f"Editing material '{name}'")
|
502 |
elif action["action"] == "delete":
|
503 |
name = action["name"]
|
504 |
is_in_use = check_material_in_use(name)
|
|
|
511 |
|
512 |
def handle_fenestration_action(action: Dict[str, Any]):
|
513 |
"""Handle fenestration-related actions."""
|
514 |
+
logger.info(f"Handling fenestration action: {action}")
|
515 |
if action["action"] == "preview":
|
516 |
fenestration = action["fenestration"]
|
517 |
name = action["name"]
|
|
|
538 |
"embodied_carbon": float(fenestration["embodied_carbon"]),
|
539 |
"cost": float(fenestration["cost"])
|
540 |
}
|
541 |
+
logger.info(f"Previewed fenestration '{name}'")
|
542 |
elif action["action"] == "copy":
|
543 |
name = action["name"]
|
544 |
fenestration = action["fenestration"]
|
|
|
577 |
"embodied_carbon": float(fenestration["embodied_carbon"]),
|
578 |
"cost": float(fenestration["cost"])
|
579 |
}
|
580 |
+
logger.info(f"Editing fenestration '{name}'")
|
581 |
elif action["action"] == "delete":
|
582 |
name = action["name"]
|
583 |
is_in_use = check_fenestration_in_use(name)
|
|
|
722 |
"U-Value (W/m虏路K)": u_value
|
723 |
})
|
724 |
df = pd.DataFrame(data)
|
725 |
+
st.session_state.project_data["materials"]["table"] = df # Update table before rendering
|
726 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
|
|
727 |
else:
|
728 |
st.info("No project materials to display.")
|
729 |
|
|
|
851 |
"Cost (USD/m虏)": props["cost"]
|
852 |
})
|
853 |
df = pd.DataFrame(data)
|
854 |
+
st.session_state.project_data["fenestrations"]["table"] = df # Update table before rendering
|
855 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
|
|
856 |
else:
|
857 |
st.info("No project fenestrations to display.")
|
858 |
|
|
|
1127 |
st.success(f"Material '{name}' added to your project.")
|
1128 |
logger.info(f"Added new material '{name}' to project")
|
1129 |
reset_material_editor()
|
1130 |
+
# Removed refresh action to allow natural re-render
|
1131 |
|
1132 |
if clear_button:
|
1133 |
reset_material_editor()
|
1134 |
+
# Removed refresh action to allow natural re-render
|
1135 |
|
1136 |
def display_fenestration_editor():
|
1137 |
"""Display the fenestration editor form."""
|
|
|
1264 |
"embodied_carbon": embodied_carbon,
|
1265 |
"cost": cost
|
1266 |
}
|
1267 |
+
if editorpiel["edit_mode"]:
|
1268 |
original_name = editor_state["original_name"]
|
1269 |
if original_name != name:
|
1270 |
del st.session_state.project_data["fenestrations"]["project"][original_name]
|
|
|
1276 |
st.success(f"Fenestration '{name}' added to your project.")
|
1277 |
logger.info(f"Added new fenestration '{name}' to project")
|
1278 |
reset_fenestration_editor()
|
1279 |
+
# Removed refresh action to allow natural re-render
|
1280 |
|
1281 |
if clear_button:
|
1282 |
reset_fenestration_editor()
|
1283 |
+
# Removed refresh action to allow natural re-render
|
1284 |
|
1285 |
def validate_material(
|
1286 |
name: str, category: str, thermal_conductivity: float, density: float,
|
|
|
1331 |
colour_ranges = {
|
1332 |
"Light": (0.30, 0.50),
|
1333 |
"Medium": (0.60, 0.70),
|
1334 |
+
"Dark": (0.95),
|
1335 |
+
"Reflective": (0.20)
|
1336 |
}
|
1337 |
min_abs, max_abs = colour_ranges[colour]
|
1338 |
if not (min_abs <= absorptivity <= max_abs):
|
|
|
1365 |
return False, "SHGC must be between 0 and 1."
|
1366 |
|
1367 |
if visible_trans < 0 or visible_trans > 1:
|
1368 |
+
return False, "Visible transmittence must be between {0} and {1}."
|
1369 |
|
1370 |
if thickness <= 0:
|
1371 |
return False, "Thickness must be greater than zero."
|
|
|
1378 |
|
1379 |
return True, ""
|
1380 |
|
1381 |
+
def reset_materials_editor():
|
1382 |
+
"""Reset the material editor and reset form state."""
|
1383 |
st.session_state.material_form_state = {
|
1384 |
"name": "",
|
1385 |
"category": MATERIAL_CATEGORIES[0],
|
|
|
1459 |
|
1460 |
**Materials Tab:**
|
1461 |
|
1462 |
+
- **Library Materials**: Pre-defined materials with standard thermal properties. Use 'Preview' to view details or 'Copy' to add to your project.
|
1463 |
+
- **Project Materials**: Materials you've added to your project. Use 'Edit' to modify or 'Delete' to remove.
|
1464 |
+
- **Material Editor/Creator**: Create new materials or edit existing project materials. Library materials can only be previewed.
|
1465 |
|
1466 |
**Fenestrations Tab:**
|
1467 |
|
1468 |
+
- **Library Fenestrations**: Pre-defined windows, doors, and skylights. Use 'Preview' to view details or 'Copy' to add to your project.
|
1469 |
+
- **Project Fenestrations**: Fenestrations you've added to your project. Use 'Edit' to modify or 'Delete' to remove.
|
1470 |
+
- **Fenestration Editor/Creator**: Create new fenestrations or edit existing project fenestrations. Library fenestrations can only be previewed.
|
1471 |
|
1472 |
**Key Properties:**
|
1473 |
|
|
|
1475 |
* **Density (kg/m鲁)**: Mass per unit volume.
|
1476 |
* **Specific Heat (J/kg路K)**: Energy required to raise the temperature of 1 kg by 1 K. Higher values indicate better thermal mass.
|
1477 |
* **Thermal Mass (J/m虏路K)**: Areal heat capacity (density 脳 specific heat 脳 thickness).
|
1478 |
+
* **U-Value (W/m虏路K)**: Overall heat transfer coefficient, accounting for material{eq surfaces resistances. Lower values indicate better insulation.
|
1479 |
* **SHGC**: Solar Heat Gain Coefficient (0-1). Fraction of incident solar radiation that enters through a fenestration.
|
1480 |
* **Visible Transmittance**: Fraction of visible light that passes through a fenestration.
|
1481 |
* **Embodied Carbon**: Carbon emissions associated with material production, measured in kg CO鈧俥 per unit volume or area.
|