Spaces:
Sleeping
Sleeping
Update app/materials_library.py
Browse files- app/materials_library.py +53 -44
app/materials_library.py
CHANGED
@@ -20,7 +20,7 @@ from typing import Dict, List, Any, Optional, Tuple, Union
|
|
20 |
from enum import Enum
|
21 |
|
22 |
# Import default data and constants from centralized module
|
23 |
-
from app.m_c_data import SAMPLE_MATERIALS, SAMPLE_FENESTRATIONS, DEFAULT_MATERIAL_PROPERTIES, DEFAULT_WINDOW_PROPERTIES
|
24 |
|
25 |
# Configure logging
|
26 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
@@ -255,16 +255,16 @@ def display_materials_page():
|
|
255 |
material_library.library_materials[k] = Material(
|
256 |
name=k,
|
257 |
category=MaterialCategory[category_str],
|
258 |
-
conductivity=m["thermal_properties"]
|
259 |
-
density=m["thermal_properties"]
|
260 |
-
specific_heat=m["thermal_properties"]
|
261 |
-
default_thickness=m["thickness_range"]
|
262 |
-
embodied_carbon=m
|
263 |
absorptivity=m.get("absorptivity", DEFAULT_MATERIAL_PROPERTIES["absorptivity"]),
|
264 |
-
price=m["cost"]
|
265 |
emissivity=m.get("emissivity", DEFAULT_MATERIAL_PROPERTIES["emissivity"]),
|
266 |
is_library=True,
|
267 |
-
u_value=m
|
268 |
)
|
269 |
logger.debug(f"Loaded material: {k}, Category: {m['category']}")
|
270 |
except (KeyError, ValueError) as e:
|
@@ -325,20 +325,32 @@ def initialize_materials_and_fenestrations():
|
|
325 |
}
|
326 |
# Add doors to materials
|
327 |
for k, v in doors.items():
|
328 |
-
|
329 |
-
"
|
330 |
-
|
331 |
-
"
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
logger.info(f"Initialized fenestrations in session state with {len(windows)} fenestrations")
|
343 |
logger.info(f"Moved {len(doors)} doors to materials library")
|
344 |
|
@@ -837,18 +849,15 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
837 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|
838 |
})
|
839 |
is_edit = editor_state.get("is_edit", False)
|
840 |
-
|
|
|
|
|
841 |
name = st.text_input(
|
842 |
"Fenestration Name",
|
843 |
value=form_state.get("name", editor_state.get("name", "")),
|
844 |
help="Unique fenestration identifier",
|
845 |
key="fenestration_name_input"
|
846 |
)
|
847 |
-
filter_category = st.session_state.get("fenestration_filter", "All")
|
848 |
-
default_category = (filter_category if filter_category in FENESTRATION_TYPES
|
849 |
-
else editor_state.get("category", "Window/Skylight"))
|
850 |
-
category_index = (FENESTRATION_TYPES.index(default_category)
|
851 |
-
if default_category in FENESTRATION_TYPES else 0)
|
852 |
category = st.selectbox(
|
853 |
"Category",
|
854 |
FENESTRATION_TYPES,
|
@@ -860,7 +869,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
860 |
"Solar Heat Gain Coefficient (SHGC)",
|
861 |
min_value=0.0,
|
862 |
max_value=1.0,
|
863 |
-
value=form_state.get("shgc", editor_state.get("shgc", 0.
|
864 |
help="Fraction of solar radiation admitted",
|
865 |
key="fenestration_shgc_input"
|
866 |
)
|
@@ -874,16 +883,16 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
874 |
h_o = st.number_input(
|
875 |
"Exterior Surface Conductance (W/m虏路K)",
|
876 |
min_value=0.0,
|
877 |
-
value=form_state.get("h_o", editor_state.get("h_o", DEFAULT_WINDOW_PROPERTIES["h_o"])),
|
878 |
help="Exterior surface heat transfer coefficient",
|
879 |
key="fenestration_h_o_input"
|
880 |
)
|
881 |
|
882 |
if st.form_submit_button("Save Fenestration"):
|
883 |
action_id = str(uuid.uuid4())
|
884 |
-
if st.session_state.fenestration_action.get("
|
885 |
-
st.session_state.fenestration_action = {"action": "save", "id": action_id}
|
886 |
-
st.session_state.
|
887 |
"name": name,
|
888 |
"category": category,
|
889 |
"shgc": shgc,
|
@@ -894,7 +903,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
894 |
st.error("Fenestration name cannot be empty.")
|
895 |
elif (name in st.session_state.project_data["fenestrations"]["project"] or
|
896 |
name in st.session_state.project_data["fenestrations"]["library"]) and (not is_edit or name != original_name):
|
897 |
-
st.error(f"Fenestration '{name}' already exists.")
|
898 |
else:
|
899 |
try:
|
900 |
new_fenestration = GlazingMaterial(
|
@@ -911,17 +920,17 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
911 |
else:
|
912 |
st.session_state.project_data["fenestrations"]["project"][name] = new_fenestration
|
913 |
st.success(f"Fenestration '{name}' added successfully!")
|
914 |
-
st.session_state.
|
915 |
-
st.session_state.
|
916 |
"name": "",
|
917 |
"category": "Window/Skylight",
|
918 |
-
"shgc": 0.7,
|
919 |
"u_value": 5.0,
|
920 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|
921 |
}
|
922 |
-
st.session_state.
|
923 |
st.session_state.rerun_trigger = None
|
924 |
-
st.session_state.
|
925 |
except Exception as e:
|
926 |
st.error(f"Error saving fenestration: {str(e)}")
|
927 |
|
@@ -938,25 +947,25 @@ def get_available_fenestrations():
|
|
938 |
fenestrations = {}
|
939 |
if "fenestrations" in st.session_state.project_data:
|
940 |
fenestrations.update(st.session_state.project_data["fenestrations"]["library"])
|
941 |
-
fenestrations.update(st.session_state.project_data["fenestrations"]["project"])
|
942 |
# Include doors from materials as fenestrations for compatibility
|
943 |
-
if "materials" in st.session_state.project_data:
|
944 |
for k, m in st.session_state.project_data["materials"]["library"].items():
|
945 |
if m.get("category") == "Door":
|
946 |
fenestrations[k] = GlazingMaterial(
|
947 |
name=k,
|
948 |
shgc=0.0,
|
949 |
-
u_value=m
|
950 |
h_o=m.get("h_o", DEFAULT_WINDOW_PROPERTIES["h_o"]),
|
951 |
category="Door",
|
952 |
is_library=True
|
953 |
)
|
954 |
for k, m in st.session_state.project_data["materials"]["project"].items():
|
955 |
-
if m.category == MaterialCategory.DOOR:
|
956 |
fenestrations[k] = GlazingMaterial(
|
957 |
name=k,
|
958 |
shgc=0.0,
|
959 |
-
u_value=m.u_value,
|
960 |
h_o=DEFAULT_WINDOW_PROPERTIES["h_o"],
|
961 |
category="Door",
|
962 |
is_library=False
|
|
|
20 |
from enum import Enum
|
21 |
|
22 |
# Import default data and constants from centralized module
|
23 |
+
from app.m_c_data import SAMPLE_MATERIALS, SAMPLE_FENESTRATIONS, DEFAULT_MATERIAL_PROPERTIES, DEFAULT_WINDOW_PROPERTIES, DEFAULT_DOOR_PROPERTIES
|
24 |
|
25 |
# Configure logging
|
26 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
255 |
material_library.library_materials[k] = Material(
|
256 |
name=k,
|
257 |
category=MaterialCategory[category_str],
|
258 |
+
conductivity=m["thermal_properties"].get("conductivity", 0.0),
|
259 |
+
density=m["thermal_properties"].get("density", 1000.0),
|
260 |
+
specific_heat=m["thermal_properties"].get("specific_heat", 1000.0),
|
261 |
+
default_thickness=m["thickness_range"].get("default", 0.05) if "thickness_range" in m else m.get("default_thickness", 0.05),
|
262 |
+
embodied_carbon=m.get("embodied_carbon", 0.5),
|
263 |
absorptivity=m.get("absorptivity", DEFAULT_MATERIAL_PROPERTIES["absorptivity"]),
|
264 |
+
price=m["cost"].get("material", 50.0),
|
265 |
emissivity=m.get("emissivity", DEFAULT_MATERIAL_PROPERTIES["emissivity"]),
|
266 |
is_library=True,
|
267 |
+
u_value=m.get("performance", {}).get("u_value") if m.get("category") == "Door" else None
|
268 |
)
|
269 |
logger.debug(f"Loaded material: {k}, Category: {m['category']}")
|
270 |
except (KeyError, ValueError) as e:
|
|
|
325 |
}
|
326 |
# Add doors to materials
|
327 |
for k, v in doors.items():
|
328 |
+
try:
|
329 |
+
st.session_state.project_data["materials"]["library"][k] = {
|
330 |
+
"category": "Door",
|
331 |
+
"thermal_properties": {
|
332 |
+
"conductivity": v["thermal_properties"].get("conductivity", 0.0),
|
333 |
+
"density": v["thermal_properties"].get("density", 1000.0),
|
334 |
+
"specific_heat": v["thermal_properties"].get("specific_heat", 1000.0)
|
335 |
+
},
|
336 |
+
"default_thickness": v.get("default_thickness", 0.05),
|
337 |
+
"embodied_carbon": v.get("embodied_carbon", 0.5),
|
338 |
+
"cost": {
|
339 |
+
"material": v["cost"].get("material", 100.0),
|
340 |
+
"labor": v["cost"].get("labor", 30.0),
|
341 |
+
"replacement_years": v["cost"].get("replacement_years", 25)
|
342 |
+
},
|
343 |
+
"absorptivity": v.get("absorptivity", DEFAULT_MATERIAL_PROPERTIES["absorptivity"]),
|
344 |
+
"emissivity": v.get("emissivity", DEFAULT_DOOR_PROPERTIES["emissivity"]),
|
345 |
+
"performance": {
|
346 |
+
"u_value": v["performance"].get("u_value", 5.0)
|
347 |
+
},
|
348 |
+
"description": v.get("description", f"{k} for door applications")
|
349 |
+
}
|
350 |
+
logger.debug(f"Moved door {k} to materials library")
|
351 |
+
except KeyError as e:
|
352 |
+
logger.error(f"Error moving door {k} to materials: Missing key {e}")
|
353 |
+
continue
|
354 |
logger.info(f"Initialized fenestrations in session state with {len(windows)} fenestrations")
|
355 |
logger.info(f"Moved {len(doors)} doors to materials library")
|
356 |
|
|
|
849 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|
850 |
})
|
851 |
is_edit = editor_state.get("is_edit", False)
|
852 |
+
default_category = editor_state.get("category", "Window/Skylight")
|
853 |
+
category_index = (FENESTRATION_TYPES.index(default_category)
|
854 |
+
if default_category in FENESTRATION_TYPES else 0)
|
855 |
name = st.text_input(
|
856 |
"Fenestration Name",
|
857 |
value=form_state.get("name", editor_state.get("name", "")),
|
858 |
help="Unique fenestration identifier",
|
859 |
key="fenestration_name_input"
|
860 |
)
|
|
|
|
|
|
|
|
|
|
|
861 |
category = st.selectbox(
|
862 |
"Category",
|
863 |
FENESTRATION_TYPES,
|
|
|
869 |
"Solar Heat Gain Coefficient (SHGC)",
|
870 |
min_value=0.0,
|
871 |
max_value=1.0,
|
872 |
+
value=form_state.get("shgc", editor_state.get("shgc", 0.0)),
|
873 |
help="Fraction of solar radiation admitted",
|
874 |
key="fenestration_shgc_input"
|
875 |
)
|
|
|
883 |
h_o = st.number_input(
|
884 |
"Exterior Surface Conductance (W/m虏路K)",
|
885 |
min_value=0.0,
|
886 |
+
value=form_state.get("h_o", editor_state.get("h_o", DEFAULT_WINDOW_PROPERTIES["h_o"]))),
|
887 |
help="Exterior surface heat transfer coefficient",
|
888 |
key="fenestration_h_o_input"
|
889 |
)
|
890 |
|
891 |
if st.form_submit_button("Save Fenestration"):
|
892 |
action_id = str(uuid.uuid4())
|
893 |
+
if st.session_state.fenestration_action.get("action_id") != action_id:
|
894 |
+
st.session_state.fenestration_action = {"action": "save", "id": action_id"}
|
895 |
+
st.session_state.fenestrations_form_state = {
|
896 |
"name": name,
|
897 |
"category": category,
|
898 |
"shgc": shgc,
|
|
|
903 |
st.error("Fenestration name cannot be empty.")
|
904 |
elif (name in st.session_state.project_data["fenestrations"]["project"] or
|
905 |
name in st.session_state.project_data["fenestrations"]["library"]) and (not is_edit or name != original_name):
|
906 |
+
st.error(f"Fenestration '{name}'" already exists.")
|
907 |
else:
|
908 |
try:
|
909 |
new_fenestration = GlazingMaterial(
|
|
|
920 |
else:
|
921 |
st.session_state.project_data["fenestrations"]["project"][name] = new_fenestration
|
922 |
st.success(f"Fenestration '{name}' added successfully!")
|
923 |
+
st.session_state.fenestrations_editor = {}
|
924 |
+
st.session_state.fenestrations_form_state = {
|
925 |
"name": "",
|
926 |
"category": "Window/Skylight",
|
927 |
+
"shgc""": 0.7,
|
928 |
"u_value": 5.0,
|
929 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|
930 |
}
|
931 |
+
st.session_state.fenestrations_action = {"action": None, "id": None}
|
932 |
st.session_state.rerun_trigger = None
|
933 |
+
st.session_state.materials_rerun_triggered = True
|
934 |
except Exception as e:
|
935 |
st.error(f"Error saving fenestration: {str(e)}")
|
936 |
|
|
|
947 |
fenestrations = {}
|
948 |
if "fenestrations" in st.session_state.project_data:
|
949 |
fenestrations.update(st.session_state.project_data["fenestrations"]["library"])
|
950 |
+
fenestrations.update(st.session_state.project_data["fenestrations"]["project"]))
|
951 |
# Include doors from materials as fenestrations for compatibility
|
952 |
+
if "materials" in st.session_state.project_data["materials"]:
|
953 |
for k, m in st.session_state.project_data["materials"]["library"].items():
|
954 |
if m.get("category") == "Door":
|
955 |
fenestrations[k] = GlazingMaterial(
|
956 |
name=k,
|
957 |
shgc=0.0,
|
958 |
+
u_value=m.get("performance", {}).get("u_value", 5.0),
|
959 |
h_o=m.get("h_o", DEFAULT_WINDOW_PROPERTIES["h_o"]),
|
960 |
category="Door",
|
961 |
is_library=True
|
962 |
)
|
963 |
for k, m in st.session_state.project_data["materials"]["project"].items():
|
964 |
+
if isinstance(m, Material) and m.category == MaterialCategory.DOOR:
|
965 |
fenestrations[k] = GlazingMaterial(
|
966 |
name=k,
|
967 |
shgc=0.0,
|
968 |
+
u_value=m.u_value if m.u_value is not None else 5.0,
|
969 |
h_o=DEFAULT_WINDOW_PROPERTIES["h_o"],
|
970 |
category="Door",
|
971 |
is_library=False
|