Spaces:
Sleeping
Sleeping
Update app/materials_library.py
Browse files- app/materials_library.py +94 -89
app/materials_library.py
CHANGED
@@ -56,7 +56,7 @@ DEFAULT_MATERIALS = {
|
|
56 |
"density": 1920.0,
|
57 |
"specific_heat": 840.0,
|
58 |
"default_thickness": 0.1,
|
59 |
-
"embodied_carbon": 240,
|
60 |
"cost": 180.0,
|
61 |
"absorptivity": 0.65,
|
62 |
"emissivity": 0.90,
|
@@ -345,12 +345,13 @@ def categorize_thermal_mass(thermal_mass: float) -> str:
|
|
345 |
else:
|
346 |
return "High"
|
347 |
|
348 |
-
def get_stable_button_key(prefix: str, name: str, action: str) -> str:
|
349 |
-
"""Generate a stable button key based on prefix, name, and
|
350 |
import hashlib
|
351 |
-
|
|
|
352 |
hash_key = hashlib.md5(key_string.encode()).hexdigest()[:8]
|
353 |
-
return f"{prefix}_{action}_{hash_key}"
|
354 |
|
355 |
def display_materials_page():
|
356 |
"""
|
@@ -478,14 +479,14 @@ def display_materials_tab():
|
|
478 |
st.session_state.material_form_state = {
|
479 |
"name": name,
|
480 |
"category": material["category"],
|
481 |
-
"thermal_conductivity": material["thermal_conductivity"],
|
482 |
-
"density": material["density"],
|
483 |
-
"specific_heat": material["specific_heat"],
|
484 |
-
"default_thickness": material["default_thickness"],
|
485 |
-
"embodied_carbon": material["embodied_carbon"],
|
486 |
-
"cost": material["cost"],
|
487 |
-
"absorptivity": material["absorptivity"],
|
488 |
-
"emissivity": material["emissivity"],
|
489 |
"colour": material["colour"]
|
490 |
}
|
491 |
st.session_state.active_tab = "Materials"
|
@@ -558,14 +559,14 @@ def display_materials_tab():
|
|
558 |
st.session_state.material_form_state = {
|
559 |
"name": name,
|
560 |
"category": material["category"],
|
561 |
-
"thermal_conductivity": material["thermal_conductivity"],
|
562 |
-
"density": material["density"],
|
563 |
-
"specific_heat": material["specific_heat"],
|
564 |
-
"default_thickness": material["default_thickness"],
|
565 |
-
"embodied_carbon": material["embodied_carbon"],
|
566 |
-
"cost": material["cost"],
|
567 |
-
"absorptivity": material["absorptivity"],
|
568 |
-
"emissivity": material["emissivity"],
|
569 |
"colour": material["colour"]
|
570 |
}
|
571 |
st.session_state.active_tab = "Materials"
|
@@ -674,12 +675,12 @@ def display_fenestrations_tab():
|
|
674 |
st.session_state.fenestration_form_state = {
|
675 |
"name": name,
|
676 |
"type": fenestration["type"],
|
677 |
-
"u_value": fenestration["u_value"],
|
678 |
-
"shgc": fenestration["shgc"],
|
679 |
-
"visible_trans": fenestration["visible_transmittance"],
|
680 |
-
"thickness": fenestration["thickness"],
|
681 |
-
"embodied_carbon": fenestration["embodied_carbon"],
|
682 |
-
"cost": fenestration["cost"]
|
683 |
}
|
684 |
st.session_state.active_tab = "Fenestrations"
|
685 |
st.session_state.rerun_pending = True
|
@@ -745,12 +746,12 @@ def display_fenestrations_tab():
|
|
745 |
st.session_state.fenestration_form_state = {
|
746 |
"name": name,
|
747 |
"type": fenestration["type"],
|
748 |
-
"u_value": fenestration["u_value"],
|
749 |
-
"shgc": fenestration["shgc"],
|
750 |
-
"visible_trans": fenestration["visible_transmittance"],
|
751 |
-
"thickness": fenestration["thickness"],
|
752 |
-
"embodied_carbon": fenestration["embodied_carbon"],
|
753 |
-
"cost": fenestration["cost"]
|
754 |
}
|
755 |
st.session_state.active_tab = "Fenestrations"
|
756 |
st.session_state.rerun_pending = True
|
@@ -758,13 +759,13 @@ def display_fenestrations_tab():
|
|
758 |
if cols[4].button("Delete", key=delete_key):
|
759 |
is_in_use = check_fenestration_in_use(name)
|
760 |
if is_in_use:
|
761 |
-
st.error(f"Cannot delete
|
762 |
else:
|
763 |
del st.session_state.project_data["fenestrations"]["project"][name]
|
764 |
st.success(f"Fenestration '{name}' deleted from project.")
|
765 |
-
|
766 |
st.session_state.rerun_pending = True
|
767 |
-
|
768 |
else:
|
769 |
st.info("No project fenestrations in the selected type.")
|
770 |
|
@@ -778,7 +779,7 @@ def display_fenestrations_tab():
|
|
778 |
"Type": props["type"],
|
779 |
"U-Value (W/m虏路K)": props["u_value"],
|
780 |
"SHGC": props["shgc"],
|
781 |
-
"
|
782 |
"Thickness (m)": props["thickness"],
|
783 |
"Embodied Carbon (kg/m虏)": props["embodied_carbon"],
|
784 |
"Cost (USD/m虏)": props["cost"]
|
@@ -814,7 +815,7 @@ def initialize_materials():
|
|
814 |
"specific_heat": 1000.0,
|
815 |
"default_thickness": 0.05,
|
816 |
"embodied_carbon": 100.0,
|
817 |
-
"cost": 100.
|
818 |
"absorptivity": 0.60,
|
819 |
"emissivity": 0.90,
|
820 |
"colour": "Medium",
|
@@ -831,10 +832,10 @@ def initialize_materials():
|
|
831 |
"density": 1000.0,
|
832 |
"specific_heat": 1000.0,
|
833 |
"default_thickness": 0.05,
|
834 |
-
"embodied_carbon":
|
835 |
-
"cost":
|
836 |
-
"absorptivity": 0.
|
837 |
-
"emissivity":
|
838 |
"colour": "Medium"
|
839 |
}
|
840 |
|
@@ -850,7 +851,7 @@ def initialize_fenestrations():
|
|
850 |
if not st.session_state.project_data["fenestrations"]["library"]:
|
851 |
st.session_state.project_data["fenestrations"]["library"] = DEFAULT_FENESTRATIONS.copy()
|
852 |
|
853 |
-
if "
|
854 |
st.session_state.fenestration_editor = {
|
855 |
"name": "",
|
856 |
"type": FENESTRATION_TYPES[0],
|
@@ -873,8 +874,8 @@ def initialize_fenestrations():
|
|
873 |
"shgc": 0.7,
|
874 |
"visible_trans": 0.8,
|
875 |
"thickness": 0.024,
|
876 |
-
"embodied_carbon":
|
877 |
-
"cost":
|
878 |
}
|
879 |
|
880 |
def display_material_editor():
|
@@ -907,7 +908,7 @@ def display_material_editor():
|
|
907 |
"Thermal Conductivity (W/m路K)",
|
908 |
min_value=0.001,
|
909 |
max_value=1000.0,
|
910 |
-
value=float(form_state.get("thermal_conductivity", editor_state
|
911 |
format="%.3f",
|
912 |
help="Thermal conductivity in W/m路K. Lower values indicate better insulation.",
|
913 |
disabled=is_library
|
@@ -917,7 +918,7 @@ def display_material_editor():
|
|
917 |
"Density (kg/m鲁)",
|
918 |
min_value=1.0,
|
919 |
max_value=20000.0,
|
920 |
-
value=float(form_state.get("density", editor_state
|
921 |
format="%.1f",
|
922 |
help="Material density in kg/m鲁.",
|
923 |
disabled=is_library
|
@@ -928,7 +929,7 @@ def display_material_editor():
|
|
928 |
"Specific Heat (J/kg路K)",
|
929 |
min_value=100.0,
|
930 |
max_value=10000.0,
|
931 |
-
value=float(form_state.get("specific_heat", editor_state
|
932 |
format="%.1f",
|
933 |
help="Specific heat capacity in J/kg路K. Higher values indicate better thermal mass.",
|
934 |
disabled=is_library
|
@@ -938,7 +939,7 @@ def display_material_editor():
|
|
938 |
"Thickness (m)",
|
939 |
min_value=0.001,
|
940 |
max_value=0.5,
|
941 |
-
value=float(form_state.get("default_thickness", editor_state
|
942 |
format="%.3f",
|
943 |
help="Thickness for this material in meters.",
|
944 |
disabled=is_library
|
@@ -948,7 +949,7 @@ def display_material_editor():
|
|
948 |
"Absorptivity",
|
949 |
min_value=0.0,
|
950 |
max_value=1.0,
|
951 |
-
value=float(form_state.get("absorptivity", editor_state
|
952 |
format="%.2f",
|
953 |
help="Solar radiation absorbed (0-1).",
|
954 |
disabled=is_library
|
@@ -961,14 +962,14 @@ def display_material_editor():
|
|
961 |
"Emissivity",
|
962 |
min_value=0.0,
|
963 |
max_value=1.0,
|
964 |
-
value=float(form_state.get("emissivity", editor_state
|
965 |
format="%.2f",
|
966 |
help="Ratio of radiation emitted (0-1).",
|
967 |
disabled=is_library
|
968 |
)
|
969 |
|
970 |
with col2:
|
971 |
-
colour_index = COLOUR_CATEGORIES.index(form_state.get("colour", editor_state
|
972 |
colour = st.selectbox(
|
973 |
"Colour Category",
|
974 |
COLOUR_CATEGORIES,
|
@@ -985,7 +986,7 @@ def display_material_editor():
|
|
985 |
"Embodied Carbon (kg CO鈧俥/m鲁)",
|
986 |
min_value=0.0,
|
987 |
max_value=10000.0,
|
988 |
-
value=float(form_state.get("embodied_carbon", editor_state.get("embodied_carbon",
|
989 |
format="%.1f",
|
990 |
help="Embodied carbon in kg CO鈧俥 per cubic meter.",
|
991 |
disabled=is_library
|
@@ -996,7 +997,7 @@ def display_material_editor():
|
|
996 |
"Cost (USD/m鲁)",
|
997 |
min_value=0.0,
|
998 |
max_value=10000.0,
|
999 |
-
value=float(form_state.get("cost", editor_state.get("cost",
|
1000 |
format="%.1f",
|
1001 |
help="Material cost in USD per cubic meter.",
|
1002 |
disabled=is_library
|
@@ -1096,9 +1097,9 @@ def display_fenestration_editor():
|
|
1096 |
"U-Value (W/m虏路K)",
|
1097 |
min_value=0.1,
|
1098 |
max_value=10.0,
|
1099 |
-
value=float(form_state.get("u_value", editor_state.get("u_value",
|
1100 |
format="%.2f",
|
1101 |
-
help="U-value in W/m虏路K.
|
1102 |
disabled=is_library
|
1103 |
)
|
1104 |
|
@@ -1107,7 +1108,7 @@ def display_fenestration_editor():
|
|
1107 |
"Solar Heat Gain Coefficient (SHGC)",
|
1108 |
min_value=0.0,
|
1109 |
max_value=1.0,
|
1110 |
-
value=float(form_state.get("shgc", editor_state.get("shgc",
|
1111 |
format="%.2f",
|
1112 |
help="Solar Heat Gain Coefficient (0-1).",
|
1113 |
disabled=is_library
|
@@ -1117,7 +1118,7 @@ def display_fenestration_editor():
|
|
1117 |
"Visible Transmittance",
|
1118 |
min_value=0.0,
|
1119 |
max_value=1.0,
|
1120 |
-
value=float(form_state.get("visible_trans", editor_state.get("visible_trans",
|
1121 |
format="%.2f",
|
1122 |
help="Visible light transmission (0-1).",
|
1123 |
disabled=is_library
|
@@ -1127,7 +1128,7 @@ def display_fenestration_editor():
|
|
1127 |
"Thickness (m)",
|
1128 |
min_value=0.001,
|
1129 |
max_value=0.1,
|
1130 |
-
value=float(form_state.get("thickness", editor_state.get("thickness",
|
1131 |
format="%.3f",
|
1132 |
help="Thickness in meters.",
|
1133 |
disabled=is_library
|
@@ -1142,7 +1143,7 @@ def display_fenestration_editor():
|
|
1142 |
"Embodied Carbon (kg CO鈧俥/m虏)",
|
1143 |
min_value=0.0,
|
1144 |
max_value=5000.0,
|
1145 |
-
value=float(form_state.get("embodied_carbon", editor_state.get("embodied_carbon",
|
1146 |
format="%.1f",
|
1147 |
help="Embodied carbon in kg CO鈧俥/m虏.",
|
1148 |
disabled=is_library
|
@@ -1153,7 +1154,7 @@ def display_fenestration_editor():
|
|
1153 |
"Cost (USD/m虏)",
|
1154 |
min_value=0.0,
|
1155 |
max_value=5000.0,
|
1156 |
-
value=float(form_state.get("cost", editor_state.get("cost",
|
1157 |
format="%.1f",
|
1158 |
help="Fenestration cost in USD/m虏.",
|
1159 |
disabled=is_library
|
@@ -1199,7 +1200,7 @@ def display_fenestration_editor():
|
|
1199 |
}
|
1200 |
if editor_state["edit_mode"]:
|
1201 |
original_name = editor_state["original_name"]
|
1202 |
-
if original_name !=
|
1203 |
del st.session_state.project_data["fenestrations"]["project"][original_name]
|
1204 |
st.session_state.project_data["fenestrations"]["project"][name] = fenestration_data
|
1205 |
st.success(f"Fenestration '{name}' updated successfully.")
|
@@ -1280,7 +1281,8 @@ def validate_fenestration(
|
|
1280 |
) -> Tuple[bool, str]:
|
1281 |
"""
|
1282 |
Validate fenestration inputs.
|
1283 |
-
Returns (success, message) tuple.
|
|
|
1284 |
if not name or name.strip() == "":
|
1285 |
return False, "Fenestration name is required."
|
1286 |
|
@@ -1319,24 +1321,24 @@ def reset_material_editor():
|
|
1319 |
"density": 1000.0,
|
1320 |
"specific_heat": 1000.0,
|
1321 |
"default_thickness": 0.05,
|
1322 |
-
"embodied_carbon":
|
1323 |
-
"cost":
|
1324 |
"absorptivity": 0.60,
|
1325 |
-
"emissivity":
|
1326 |
-
"colour": ""
|
1327 |
}
|
1328 |
st.session_state.material_editor = {
|
1329 |
"name": "",
|
1330 |
"category": MATERIAL_CATEGORIES[0],
|
1331 |
-
"thermal_conductivity":
|
1332 |
-
"density":
|
1333 |
-
"specific_heat":
|
1334 |
-
"default_thickness":
|
1335 |
-
"embodied_carbon":
|
1336 |
-
"cost":
|
1337 |
-
"absorptivity":
|
1338 |
-
"emissivity":
|
1339 |
-
"colour": "",
|
1340 |
"edit_mode": False,
|
1341 |
"original_name": "",
|
1342 |
"is_library": False
|
@@ -1349,22 +1351,25 @@ def reset_fenestration_editor():
|
|
1349 |
st.session_state.fenestration_form_state = {
|
1350 |
"name": "",
|
1351 |
"type": FENESTRATION_TYPES[0],
|
1352 |
-
"u_value":
|
1353 |
-
"shgc":
|
1354 |
-
"visible_trans":
|
1355 |
-
"thickness":
|
1356 |
-
"embodied_carbon":
|
1357 |
-
"cost":
|
1358 |
}
|
1359 |
-
st.session_state.
|
1360 |
"name": "",
|
1361 |
"type": FENESTRATION_TYPES[0],
|
1362 |
-
"u_value":
|
1363 |
-
"shgc":
|
1364 |
-
"visible_trans":
|
1365 |
-
"thickness":
|
1366 |
-
"embodied_carbon":
|
1367 |
-
"cost":
|
|
|
|
|
|
|
1368 |
}
|
1369 |
st.session_state.fenestration_action = {"action": None, "id": None}
|
1370 |
st.session_state.rerun_trigger = None
|
|
|
56 |
"density": 1920.0,
|
57 |
"specific_heat": 840.0,
|
58 |
"default_thickness": 0.1,
|
59 |
+
"embodied_carbon": 240.0,
|
60 |
"cost": 180.0,
|
61 |
"absorptivity": 0.65,
|
62 |
"emissivity": 0.90,
|
|
|
345 |
else:
|
346 |
return "High"
|
347 |
|
348 |
+
def get_stable_button_key(prefix: str, name: str, action: str, unique_id: str = None) -> str:
|
349 |
+
"""Generate a stable button key based on prefix, name, action, and optional unique identifier."""
|
350 |
import hashlib
|
351 |
+
unique_id = unique_id or str(uuid.uuid4())[:8] # Generate unique ID if not provided
|
352 |
+
key_string = f"{prefix}_{name}_{action}_{unique_id}"
|
353 |
hash_key = hashlib.md5(key_string.encode()).hexdigest()[:8]
|
354 |
+
return f"{prefix}_{action}_{name}_{hash_key}"
|
355 |
|
356 |
def display_materials_page():
|
357 |
"""
|
|
|
479 |
st.session_state.material_form_state = {
|
480 |
"name": name,
|
481 |
"category": material["category"],
|
482 |
+
"thermal_conductivity": float(material["thermal_conductivity"]),
|
483 |
+
"density": float(material["density"]),
|
484 |
+
"specific_heat": float(material["specific_heat"]),
|
485 |
+
"default_thickness": float(material["default_thickness"]),
|
486 |
+
"embodied_carbon": float(material["embodied_carbon"]),
|
487 |
+
"cost": float(material["cost"]),
|
488 |
+
"absorptivity": float(material["absorptivity"]),
|
489 |
+
"emissivity": float(material["emissivity"]),
|
490 |
"colour": material["colour"]
|
491 |
}
|
492 |
st.session_state.active_tab = "Materials"
|
|
|
559 |
st.session_state.material_form_state = {
|
560 |
"name": name,
|
561 |
"category": material["category"],
|
562 |
+
"thermal_conductivity": float(material["thermal_conductivity"]),
|
563 |
+
"density": float(material["density"]),
|
564 |
+
"specific_heat": float(material["specific_heat"]),
|
565 |
+
"default_thickness": float(material["default_thickness"]),
|
566 |
+
"embodied_carbon": float(material["embodied_carbon"]),
|
567 |
+
"cost": float(material["cost"]),
|
568 |
+
"absorptivity": float(material["absorptivity"]),
|
569 |
+
"emissivity": float(material["emissivity"]),
|
570 |
"colour": material["colour"]
|
571 |
}
|
572 |
st.session_state.active_tab = "Materials"
|
|
|
675 |
st.session_state.fenestration_form_state = {
|
676 |
"name": name,
|
677 |
"type": fenestration["type"],
|
678 |
+
"u_value": float(fenestration["u_value"]),
|
679 |
+
"shgc": float(fenestration["shgc"]),
|
680 |
+
"visible_trans": float(fenestration["visible_transmittance"]),
|
681 |
+
"thickness": float(fenestration["thickness"]),
|
682 |
+
"embodied_carbon": float(fenestration["embodied_carbon"]),
|
683 |
+
"cost": float(fenestration["cost"])
|
684 |
}
|
685 |
st.session_state.active_tab = "Fenestrations"
|
686 |
st.session_state.rerun_pending = True
|
|
|
746 |
st.session_state.fenestration_form_state = {
|
747 |
"name": name,
|
748 |
"type": fenestration["type"],
|
749 |
+
"u_value": float(fenestration["u_value"]),
|
750 |
+
"shgc": float(fenestration["shgc"]),
|
751 |
+
"visible_trans": float(fenestration["visible_transmittance"]),
|
752 |
+
"thickness": float(fenestration["thickness"]),
|
753 |
+
"embodied_carbon": float(fenestration["embodied_carbon"]),
|
754 |
+
"cost": float(fenestration["cost"])
|
755 |
}
|
756 |
st.session_state.active_tab = "Fenestrations"
|
757 |
st.session_state.rerun_pending = True
|
|
|
759 |
if cols[4].button("Delete", key=delete_key):
|
760 |
is_in_use = check_fenestration_in_use(name)
|
761 |
if is_in_use:
|
762 |
+
st.error(f"Cannot delete fenestration '{name}' because it is in use in components.")
|
763 |
else:
|
764 |
del st.session_state.project_data["fenestrations"]["project"][name]
|
765 |
st.success(f"Fenestration '{name}' deleted from project.")
|
766 |
+
logger.info(f"Deleted fenestration '{name}' from project")
|
767 |
st.session_state.rerun_pending = True
|
768 |
+
|
769 |
else:
|
770 |
st.info("No project fenestrations in the selected type.")
|
771 |
|
|
|
779 |
"Type": props["type"],
|
780 |
"U-Value (W/m虏路K)": props["u_value"],
|
781 |
"SHGC": props["shgc"],
|
782 |
+
"Visible Transmittance": props["visible_transmittance"],
|
783 |
"Thickness (m)": props["thickness"],
|
784 |
"Embodied Carbon (kg/m虏)": props["embodied_carbon"],
|
785 |
"Cost (USD/m虏)": props["cost"]
|
|
|
815 |
"specific_heat": 1000.0,
|
816 |
"default_thickness": 0.05,
|
817 |
"embodied_carbon": 100.0,
|
818 |
+
"cost": 100.0,
|
819 |
"absorptivity": 0.60,
|
820 |
"emissivity": 0.90,
|
821 |
"colour": "Medium",
|
|
|
832 |
"density": 1000.0,
|
833 |
"specific_heat": 1000.0,
|
834 |
"default_thickness": 0.05,
|
835 |
+
"embodied_carbon": 100.0,
|
836 |
+
"cost": 100.0,
|
837 |
+
"absorptivity": 0.60,
|
838 |
+
"emissivity": 0.90,
|
839 |
"colour": "Medium"
|
840 |
}
|
841 |
|
|
|
851 |
if not st.session_state.project_data["fenestrations"]["library"]:
|
852 |
st.session_state.project_data["fenestrations"]["library"] = DEFAULT_FENESTRATIONS.copy()
|
853 |
|
854 |
+
if "fenestration_editor" not in st.session_state:
|
855 |
st.session_state.fenestration_editor = {
|
856 |
"name": "",
|
857 |
"type": FENESTRATION_TYPES[0],
|
|
|
874 |
"shgc": 0.7,
|
875 |
"visible_trans": 0.8,
|
876 |
"thickness": 0.024,
|
877 |
+
"embodied_carbon": 900.0,
|
878 |
+
"cost": 200.0
|
879 |
}
|
880 |
|
881 |
def display_material_editor():
|
|
|
908 |
"Thermal Conductivity (W/m路K)",
|
909 |
min_value=0.001,
|
910 |
max_value=1000.0,
|
911 |
+
value=float(form_state.get("thermal_conductivity", editor_state.get("thermal_conductivity", 0.5))),
|
912 |
format="%.3f",
|
913 |
help="Thermal conductivity in W/m路K. Lower values indicate better insulation.",
|
914 |
disabled=is_library
|
|
|
918 |
"Density (kg/m鲁)",
|
919 |
min_value=1.0,
|
920 |
max_value=20000.0,
|
921 |
+
value=float(form_state.get("density", editor_state.get("density", 1000.0))),
|
922 |
format="%.1f",
|
923 |
help="Material density in kg/m鲁.",
|
924 |
disabled=is_library
|
|
|
929 |
"Specific Heat (J/kg路K)",
|
930 |
min_value=100.0,
|
931 |
max_value=10000.0,
|
932 |
+
value=float(form_state.get("specific_heat", editor_state.get("specific_heat", 1000.0))),
|
933 |
format="%.1f",
|
934 |
help="Specific heat capacity in J/kg路K. Higher values indicate better thermal mass.",
|
935 |
disabled=is_library
|
|
|
939 |
"Thickness (m)",
|
940 |
min_value=0.001,
|
941 |
max_value=0.5,
|
942 |
+
value=float(form_state.get("default_thickness", editor_state.get("default_thickness", 0.05))),
|
943 |
format="%.3f",
|
944 |
help="Thickness for this material in meters.",
|
945 |
disabled=is_library
|
|
|
949 |
"Absorptivity",
|
950 |
min_value=0.0,
|
951 |
max_value=1.0,
|
952 |
+
value=float(form_state.get("absorptivity", editor_state.get("absorptivity", 0.60))),
|
953 |
format="%.2f",
|
954 |
help="Solar radiation absorbed (0-1).",
|
955 |
disabled=is_library
|
|
|
962 |
"Emissivity",
|
963 |
min_value=0.0,
|
964 |
max_value=1.0,
|
965 |
+
value=float(form_state.get("emissivity", editor_state.get("emissivity", 0.90))),
|
966 |
format="%.2f",
|
967 |
help="Ratio of radiation emitted (0-1).",
|
968 |
disabled=is_library
|
969 |
)
|
970 |
|
971 |
with col2:
|
972 |
+
colour_index = COLOUR_CATEGORIES.index(form_state.get("colour", editor_state.get("colour", "Medium"))) if form_state.get("colour", editor_state.get("colour", "Medium")) in COLOUR_CATEGORIES else 0
|
973 |
colour = st.selectbox(
|
974 |
"Colour Category",
|
975 |
COLOUR_CATEGORIES,
|
|
|
986 |
"Embodied Carbon (kg CO鈧俥/m鲁)",
|
987 |
min_value=0.0,
|
988 |
max_value=10000.0,
|
989 |
+
value=float(form_state.get("embodied_carbon", editor_state.get("embodied_carbon", 100.0))),
|
990 |
format="%.1f",
|
991 |
help="Embodied carbon in kg CO鈧俥 per cubic meter.",
|
992 |
disabled=is_library
|
|
|
997 |
"Cost (USD/m鲁)",
|
998 |
min_value=0.0,
|
999 |
max_value=10000.0,
|
1000 |
+
value=float(form_state.get("cost", editor_state.get("cost", 100.0))),
|
1001 |
format="%.1f",
|
1002 |
help="Material cost in USD per cubic meter.",
|
1003 |
disabled=is_library
|
|
|
1097 |
"U-Value (W/m虏路K)",
|
1098 |
min_value=0.1,
|
1099 |
max_value=10.0,
|
1100 |
+
value=float(form_state.get("u_value", editor_state.get("u_value", 2.8))),
|
1101 |
format="%.2f",
|
1102 |
+
help="U-value in W/m虏路K.",
|
1103 |
disabled=is_library
|
1104 |
)
|
1105 |
|
|
|
1108 |
"Solar Heat Gain Coefficient (SHGC)",
|
1109 |
min_value=0.0,
|
1110 |
max_value=1.0,
|
1111 |
+
value=float(form_state.get("shgc", editor_state.get("shgc", 0.7))),
|
1112 |
format="%.2f",
|
1113 |
help="Solar Heat Gain Coefficient (0-1).",
|
1114 |
disabled=is_library
|
|
|
1118 |
"Visible Transmittance",
|
1119 |
min_value=0.0,
|
1120 |
max_value=1.0,
|
1121 |
+
value=float(form_state.get("visible_trans", editor_state.get("visible_trans", 0.8))),
|
1122 |
format="%.2f",
|
1123 |
help="Visible light transmission (0-1).",
|
1124 |
disabled=is_library
|
|
|
1128 |
"Thickness (m)",
|
1129 |
min_value=0.001,
|
1130 |
max_value=0.1,
|
1131 |
+
value=float(form_state.get("thickness", editor_state.get("thickness", 0.024))),
|
1132 |
format="%.3f",
|
1133 |
help="Thickness in meters.",
|
1134 |
disabled=is_library
|
|
|
1143 |
"Embodied Carbon (kg CO鈧俥/m虏)",
|
1144 |
min_value=0.0,
|
1145 |
max_value=5000.0,
|
1146 |
+
value=float(form_state.get("embodied_carbon", editor_state.get("embodied_carbon", 900.0))),
|
1147 |
format="%.1f",
|
1148 |
help="Embodied carbon in kg CO鈧俥/m虏.",
|
1149 |
disabled=is_library
|
|
|
1154 |
"Cost (USD/m虏)",
|
1155 |
min_value=0.0,
|
1156 |
max_value=5000.0,
|
1157 |
+
value=float(form_state.get("cost", editor_state.get("cost", 200.0))),
|
1158 |
format="%.1f",
|
1159 |
help="Fenestration cost in USD/m虏.",
|
1160 |
disabled=is_library
|
|
|
1200 |
}
|
1201 |
if editor_state["edit_mode"]:
|
1202 |
original_name = editor_state["original_name"]
|
1203 |
+
if original_name != name:
|
1204 |
del st.session_state.project_data["fenestrations"]["project"][original_name]
|
1205 |
st.session_state.project_data["fenestrations"]["project"][name] = fenestration_data
|
1206 |
st.success(f"Fenestration '{name}' updated successfully.")
|
|
|
1281 |
) -> Tuple[bool, str]:
|
1282 |
"""
|
1283 |
Validate fenestration inputs.
|
1284 |
+
Returns (success, message) tuple.
|
1285 |
+
"""
|
1286 |
if not name or name.strip() == "":
|
1287 |
return False, "Fenestration name is required."
|
1288 |
|
|
|
1321 |
"density": 1000.0,
|
1322 |
"specific_heat": 1000.0,
|
1323 |
"default_thickness": 0.05,
|
1324 |
+
"embodied_carbon": 100.0,
|
1325 |
+
"cost": 100.0,
|
1326 |
"absorptivity": 0.60,
|
1327 |
+
"emissivity": 0.90,
|
1328 |
+
"colour": "Medium"
|
1329 |
}
|
1330 |
st.session_state.material_editor = {
|
1331 |
"name": "",
|
1332 |
"category": MATERIAL_CATEGORIES[0],
|
1333 |
+
"thermal_conductivity": 0.5,
|
1334 |
+
"density": 1000.0,
|
1335 |
+
"specific_heat": 1000.0,
|
1336 |
+
"default_thickness": 0.05,
|
1337 |
+
"embodied_carbon": 100.0,
|
1338 |
+
"cost": 100.0,
|
1339 |
+
"absorptivity": 0.60,
|
1340 |
+
"emissivity": 0.90,
|
1341 |
+
"colour": "Medium",
|
1342 |
"edit_mode": False,
|
1343 |
"original_name": "",
|
1344 |
"is_library": False
|
|
|
1351 |
st.session_state.fenestration_form_state = {
|
1352 |
"name": "",
|
1353 |
"type": FENESTRATION_TYPES[0],
|
1354 |
+
"u_value": 2.8,
|
1355 |
+
"shgc": 0.7,
|
1356 |
+
"visible_trans": 0.8,
|
1357 |
+
"thickness": 0.024,
|
1358 |
+
"embodied_carbon": 900.0,
|
1359 |
+
"cost": 200.0
|
1360 |
}
|
1361 |
+
st.session_state.fenestration_editor = {
|
1362 |
"name": "",
|
1363 |
"type": FENESTRATION_TYPES[0],
|
1364 |
+
"u_value": 2.8,
|
1365 |
+
"shgc": 0.7,
|
1366 |
+
"visible_trans": 0.8,
|
1367 |
+
"thickness": 0.024,
|
1368 |
+
"embodied_carbon": 900.0,
|
1369 |
+
"cost": 200.0,
|
1370 |
+
"edit_mode": False,
|
1371 |
+
"original_name": "",
|
1372 |
+
"is_library": False
|
1373 |
}
|
1374 |
st.session_state.fenestration_action = {"action": None, "id": None}
|
1375 |
st.session_state.rerun_trigger = None
|