Spaces:
Sleeping
Sleeping
Update app/materials_library.py
Browse files- app/materials_library.py +57 -33
app/materials_library.py
CHANGED
@@ -76,11 +76,12 @@ class Material:
|
|
76 |
return self.conductivity / self.default_thickness if self.default_thickness > 0 else 0.0
|
77 |
|
78 |
class GlazingMaterial:
|
79 |
-
def __init__(self, name: str, shgc: float, u_value: float, h_o: float, is_library: bool = True):
|
80 |
self.name = name
|
81 |
self.shgc = shgc
|
82 |
self.u_value = u_value
|
83 |
self.h_o = h_o
|
|
|
84 |
self.is_library = is_library
|
85 |
|
86 |
class MaterialLibrary:
|
@@ -113,6 +114,7 @@ class MaterialLibrary:
|
|
113 |
data = [
|
114 |
{
|
115 |
"Name": g.name,
|
|
|
116 |
"SHGC": g.shgc,
|
117 |
"U-Value (W/m虏路K)": g.u_value,
|
118 |
"Exterior Conductance (W/m虏路K)": g.h_o
|
@@ -227,9 +229,13 @@ def display_materials_page():
|
|
227 |
material_library.library_materials = {}
|
228 |
for k, m in st.session_state.project_data["materials"]["library"].items():
|
229 |
try:
|
|
|
|
|
|
|
|
|
230 |
material_library.library_materials[k] = Material(
|
231 |
name=k,
|
232 |
-
category=MaterialCategory
|
233 |
conductivity=m["thermal_properties"]["conductivity"],
|
234 |
density=m["thermal_properties"]["density"],
|
235 |
specific_heat=m["thermal_properties"]["specific_heat"],
|
@@ -248,14 +254,16 @@ def display_materials_page():
|
|
248 |
material_library.library_glazing_materials = {}
|
249 |
for k, f in st.session_state.project_data["fenestrations"]["library"].items():
|
250 |
try:
|
|
|
251 |
material_library.library_glazing_materials[k] = GlazingMaterial(
|
252 |
name=k,
|
253 |
shgc=f["performance"]["shgc"],
|
254 |
u_value=f["performance"]["u_value"],
|
255 |
h_o=f.get("h_o", DEFAULT_WINDOW_PROPERTIES["h_o"]),
|
|
|
256 |
is_library=True
|
257 |
)
|
258 |
-
logger.debug(f"Loaded fenestration: {k}, Type: {f['type']}")
|
259 |
except KeyError as e:
|
260 |
logger.error(f"Error processing fenestration {k}: Missing key {e}")
|
261 |
continue
|
@@ -285,13 +293,13 @@ def initialize_materials_and_fenestrations():
|
|
285 |
"library": dict(SAMPLE_MATERIALS),
|
286 |
"project": {}
|
287 |
}
|
288 |
-
logger.info("Initialized materials in session state with SAMPLE_MATERIALS")
|
289 |
if "fenestrations" not in st.session_state.project_data:
|
290 |
st.session_state.project_data["fenestrations"] = {
|
291 |
"library": dict(SAMPLE_FENESTRATIONS),
|
292 |
"project": {}
|
293 |
}
|
294 |
-
logger.info("Initialized fenestrations in session state with SAMPLE_FENESTRATIONS")
|
295 |
|
296 |
def display_materials_tab(material_library: MaterialLibrary):
|
297 |
"""Display the materials tab content with two-column layout."""
|
@@ -307,6 +315,11 @@ def display_materials_tab(material_library: MaterialLibrary):
|
|
307 |
library_materials = list(material_library.library_materials.values())
|
308 |
if not library_materials:
|
309 |
st.warning("No library materials loaded. Check data initialization.")
|
|
|
|
|
|
|
|
|
|
|
310 |
if category == "None":
|
311 |
library_materials = []
|
312 |
elif category != "All":
|
@@ -567,7 +580,7 @@ def display_materials_tab(material_library: MaterialLibrary):
|
|
567 |
try:
|
568 |
new_material = Material(
|
569 |
name=name,
|
570 |
-
category=MaterialCategory
|
571 |
conductivity=conductivity,
|
572 |
density=density,
|
573 |
specific_heat=specific_heat,
|
@@ -578,7 +591,7 @@ def display_materials_tab(material_library: MaterialLibrary):
|
|
578 |
emissivity=emissivity,
|
579 |
is_library=False
|
580 |
)
|
581 |
-
if is_edit and editor_state.get("edit_source") == "project"
|
582 |
success, message = material_library.edit_project_material(
|
583 |
original_name, new_material, st.session_state.project_data["materials"]["project"], st.session_state.get("components", {})
|
584 |
)
|
@@ -620,14 +633,14 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
620 |
library_fenestrations = list(material_library.library_glazing_materials.values())
|
621 |
if not library_fenestrations:
|
622 |
st.warning("No library fenestrations loaded. Check data initialization.")
|
|
|
|
|
|
|
|
|
623 |
if fenestration_filter == "None":
|
624 |
library_fenestrations = []
|
625 |
elif fenestration_filter != "All":
|
626 |
-
|
627 |
-
library_fenestrations = [
|
628 |
-
f for f in library_fenestrations
|
629 |
-
if st.session_state.project_data["fenestrations"]["library"][f.name]["type"] == fen_type
|
630 |
-
]
|
631 |
cols = st.columns([2, 1, 1, 1, 1])
|
632 |
cols[0].write("**Name**")
|
633 |
cols[1].write("**SHGC**")
|
@@ -644,6 +657,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
644 |
st.session_state.rerun_trigger = f"preview_fen_{fenestration.name}"
|
645 |
st.session_state.fenestration_editor = {
|
646 |
"name": fenestration.name,
|
|
|
647 |
"shgc": fenestration.shgc,
|
648 |
"u_value": fenestration.u_value,
|
649 |
"h_o": fenestration.h_o,
|
@@ -652,6 +666,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
652 |
}
|
653 |
st.session_state.fenestration_form_state = {
|
654 |
"name": fenestration.name,
|
|
|
655 |
"shgc": fenestration.shgc,
|
656 |
"u_value": fenestration.u_value,
|
657 |
"h_o": fenestration.h_o
|
@@ -668,6 +683,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
668 |
shgc=fenestration.shgc,
|
669 |
u_value=fenestration.u_value,
|
670 |
h_o=fenestration.h_o,
|
|
|
671 |
is_library=False
|
672 |
)
|
673 |
st.session_state.project_data["fenestrations"]["project"][new_name] = new_fenestration
|
@@ -693,6 +709,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
693 |
st.session_state.rerun_trigger = f"edit_fen_{fenestration.name}"
|
694 |
st.session_state.fenestration_editor = {
|
695 |
"name": fenestration.name,
|
|
|
696 |
"shgc": fenestration.shgc,
|
697 |
"u_value": fenestration.u_value,
|
698 |
"h_o": fenestration.h_o,
|
@@ -702,6 +719,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
702 |
}
|
703 |
st.session_state.fenestration_form_state = {
|
704 |
"name": fenestration.name,
|
|
|
705 |
"shgc": fenestration.shgc,
|
706 |
"u_value": fenestration.u_value,
|
707 |
"h_o": fenestration.h_o
|
@@ -722,10 +740,13 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
722 |
if st.session_state.project_data["fenestrations"]["project"]:
|
723 |
try:
|
724 |
fenestration_df = material_library.to_dataframe("glazing", project_glazing_materials=st.session_state.project_data["fenestrations"]["project"])
|
725 |
-
if fenestration_df.empty:
|
|
|
|
|
726 |
fenestration_data = [
|
727 |
{
|
728 |
"Name": f.name,
|
|
|
729 |
"SHGC": f.shgc,
|
730 |
"U-Value (W/m虏路K)": f.u_value,
|
731 |
"Exterior Conductance (W/m虏路K)": f.h_o
|
@@ -733,26 +754,13 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
733 |
for f in st.session_state.project_data["fenestrations"]["project"].values()
|
734 |
]
|
735 |
fenestration_df = pd.DataFrame(fenestration_data)
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
except Exception as e:
|
741 |
-
|
742 |
-
|
743 |
-
"Name": f.name,
|
744 |
-
"SHGC": f.shgc,
|
745 |
-
"U-Value (W/m虏路K)": f.u_value,
|
746 |
-
"Exterior Conductance (W/m虏路K)": f.h_o
|
747 |
-
}
|
748 |
-
for f in st.session_state.project_data["fenestrations"]["project"].values()
|
749 |
-
]
|
750 |
-
fenestration_df = pd.DataFrame(fenestration_data)
|
751 |
-
if not fenestration_df.empty:
|
752 |
-
st.dataframe(fenestration_df, use_container_width=True)
|
753 |
-
else:
|
754 |
-
st.error(f"Error displaying project fenestrations: {str(e)}")
|
755 |
-
st.write("No project fenestrations to display.")
|
756 |
else:
|
757 |
st.write("No project fenestrations to display.")
|
758 |
|
@@ -763,6 +771,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
763 |
editor_state = st.session_state.get("fenestration_editor", {})
|
764 |
form_state = st.session_state.get("fenestration_form_state", {
|
765 |
"name": "",
|
|
|
766 |
"shgc": 0.7,
|
767 |
"u_value": 5.0,
|
768 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|
@@ -775,6 +784,18 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
775 |
help="Unique fenestration identifier",
|
776 |
key="fenestration_name_input"
|
777 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
778 |
shgc = st.number_input(
|
779 |
"Solar Heat Gain Coefficient (SHGC)",
|
780 |
min_value=0.0,
|
@@ -804,6 +825,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
804 |
st.session_state.fenestration_action = {"action": "save", "id": action_id}
|
805 |
st.session_state.fenestration_form_state = {
|
806 |
"name": name,
|
|
|
807 |
"shgc": shgc,
|
808 |
"u_value": u_value,
|
809 |
"h_o": h_o
|
@@ -820,9 +842,10 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
820 |
shgc=shgc,
|
821 |
u_value=u_value,
|
822 |
h_o=h_o,
|
|
|
823 |
is_library=False
|
824 |
)
|
825 |
-
if is_edit and editor_state.get("edit_source") == "project"
|
826 |
st.session_state.project_data["fenestrations"]["project"][original_name] = new_fenestration
|
827 |
st.success(f"Fenestration '{name}' updated successfully!")
|
828 |
else:
|
@@ -831,6 +854,7 @@ def display_fenestrations_tab(material_library: MaterialLibrary):
|
|
831 |
st.session_state.fenestration_editor = {}
|
832 |
st.session_state.fenestration_form_state = {
|
833 |
"name": "",
|
|
|
834 |
"shgc": 0.7,
|
835 |
"u_value": 5.0,
|
836 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|
|
|
76 |
return self.conductivity / self.default_thickness if self.default_thickness > 0 else 0.0
|
77 |
|
78 |
class GlazingMaterial:
|
79 |
+
def __init__(self, name: str, shgc: float, u_value: float, h_o: float, category: str, is_library: bool = True):
|
80 |
self.name = name
|
81 |
self.shgc = shgc
|
82 |
self.u_value = u_value
|
83 |
self.h_o = h_o
|
84 |
+
self.category = category
|
85 |
self.is_library = is_library
|
86 |
|
87 |
class MaterialLibrary:
|
|
|
114 |
data = [
|
115 |
{
|
116 |
"Name": g.name,
|
117 |
+
"Category": g.category,
|
118 |
"SHGC": g.shgc,
|
119 |
"U-Value (W/m虏路K)": g.u_value,
|
120 |
"Exterior Conductance (W/m虏路K)": g.h_o
|
|
|
229 |
material_library.library_materials = {}
|
230 |
for k, m in st.session_state.project_data["materials"]["library"].items():
|
231 |
try:
|
232 |
+
category_str = m["category"].upper().replace("-", "_")
|
233 |
+
if category_str not in MaterialCategory.__members__:
|
234 |
+
logger.error(f"Invalid category for material {k}: {category_str}")
|
235 |
+
continue
|
236 |
material_library.library_materials[k] = Material(
|
237 |
name=k,
|
238 |
+
category=MaterialCategory[category_str],
|
239 |
conductivity=m["thermal_properties"]["conductivity"],
|
240 |
density=m["thermal_properties"]["density"],
|
241 |
specific_heat=m["thermal_properties"]["specific_heat"],
|
|
|
254 |
material_library.library_glazing_materials = {}
|
255 |
for k, f in st.session_state.project_data["fenestrations"]["library"].items():
|
256 |
try:
|
257 |
+
category = "Window/Skylight" if f["type"] == "window" else "Door"
|
258 |
material_library.library_glazing_materials[k] = GlazingMaterial(
|
259 |
name=k,
|
260 |
shgc=f["performance"]["shgc"],
|
261 |
u_value=f["performance"]["u_value"],
|
262 |
h_o=f.get("h_o", DEFAULT_WINDOW_PROPERTIES["h_o"]),
|
263 |
+
category=category,
|
264 |
is_library=True
|
265 |
)
|
266 |
+
logger.debug(f"Loaded fenestration: {k}, Type: {f['type']}, Category: {category}")
|
267 |
except KeyError as e:
|
268 |
logger.error(f"Error processing fenestration {k}: Missing key {e}")
|
269 |
continue
|
|
|
293 |
"library": dict(SAMPLE_MATERIALS),
|
294 |
"project": {}
|
295 |
}
|
296 |
+
logger.info(f"Initialized materials in session state with {len(SAMPLE_MATERIALS)} materials")
|
297 |
if "fenestrations" not in st.session_state.project_data:
|
298 |
st.session_state.project_data["fenestrations"] = {
|
299 |
"library": dict(SAMPLE_FENESTRATIONS),
|
300 |
"project": {}
|
301 |
}
|
302 |
+
logger.info(f"Initialized fenestrations in session state with {len(SAMPLE_FENESTRATIONS)} fenestrations")
|
303 |
|
304 |
def display_materials_tab(material_library: MaterialLibrary):
|
305 |
"""Display the materials tab content with two-column layout."""
|
|
|
315 |
library_materials = list(material_library.library_materials.values())
|
316 |
if not library_materials:
|
317 |
st.warning("No library materials loaded. Check data initialization.")
|
318 |
+
# Fallback: Display raw material names from session state
|
319 |
+
raw_materials = st.session_state.project_data["materials"]["library"]
|
320 |
+
if raw_materials:
|
321 |
+
st.write("Raw material names available in session state:")
|
322 |
+
st.write(list(raw_materials.keys()))
|
323 |
if category == "None":
|
324 |
library_materials = []
|
325 |
elif category != "All":
|
|
|
580 |
try:
|
581 |
new_material = Material(
|
582 |
name=name,
|
583 |
+
category=MaterialCategory[category.upper().replace("-", "_")],
|
584 |
conductivity=conductivity,
|
585 |
density=density,
|
586 |
specific_heat=specific_heat,
|
|
|
591 |
emissivity=emissivity,
|
592 |
is_library=False
|
593 |
)
|
594 |
+
if is_edit and editor_state.get("edit_source") == "project":
|
595 |
success, message = material_library.edit_project_material(
|
596 |
original_name, new_material, st.session_state.project_data["materials"]["project"], st.session_state.get("components", {})
|
597 |
)
|
|
|
633 |
library_fenestrations = list(material_library.library_glazing_materials.values())
|
634 |
if not library_fenestrations:
|
635 |
st.warning("No library fenestrations loaded. Check data initialization.")
|
636 |
+
raw_fenestrations = st.session_state.project_data["fenestrations"]["library"]
|
637 |
+
if raw_fenestrations:
|
638 |
+
st.write("Raw fenestration names available in session state:")
|
639 |
+
st.write(list(raw_fenestrations.keys()))
|
640 |
if fenestration_filter == "None":
|
641 |
library_fenestrations = []
|
642 |
elif fenestration_filter != "All":
|
643 |
+
library_fenestrations = [f for f in library_fenestrations if f.category == fenestration_filter]
|
|
|
|
|
|
|
|
|
644 |
cols = st.columns([2, 1, 1, 1, 1])
|
645 |
cols[0].write("**Name**")
|
646 |
cols[1].write("**SHGC**")
|
|
|
657 |
st.session_state.rerun_trigger = f"preview_fen_{fenestration.name}"
|
658 |
st.session_state.fenestration_editor = {
|
659 |
"name": fenestration.name,
|
660 |
+
"category": fenestration.category,
|
661 |
"shgc": fenestration.shgc,
|
662 |
"u_value": fenestration.u_value,
|
663 |
"h_o": fenestration.h_o,
|
|
|
666 |
}
|
667 |
st.session_state.fenestration_form_state = {
|
668 |
"name": fenestration.name,
|
669 |
+
"category": fenestration.category,
|
670 |
"shgc": fenestration.shgc,
|
671 |
"u_value": fenestration.u_value,
|
672 |
"h_o": fenestration.h_o
|
|
|
683 |
shgc=fenestration.shgc,
|
684 |
u_value=fenestration.u_value,
|
685 |
h_o=fenestration.h_o,
|
686 |
+
category=fenestration.category,
|
687 |
is_library=False
|
688 |
)
|
689 |
st.session_state.project_data["fenestrations"]["project"][new_name] = new_fenestration
|
|
|
709 |
st.session_state.rerun_trigger = f"edit_fen_{fenestration.name}"
|
710 |
st.session_state.fenestration_editor = {
|
711 |
"name": fenestration.name,
|
712 |
+
"category": fenestration.category,
|
713 |
"shgc": fenestration.shgc,
|
714 |
"u_value": fenestration.u_value,
|
715 |
"h_o": fenestration.h_o,
|
|
|
719 |
}
|
720 |
st.session_state.fenestration_form_state = {
|
721 |
"name": fenestration.name,
|
722 |
+
"category": fenestration.category,
|
723 |
"shgc": fenestration.shgc,
|
724 |
"u_value": fenestration.u_value,
|
725 |
"h_o": fenestration.h_o
|
|
|
740 |
if st.session_state.project_data["fenestrations"]["project"]:
|
741 |
try:
|
742 |
fenestration_df = material_library.to_dataframe("glazing", project_glazing_materials=st.session_state.project_data["fenestrations"]["project"])
|
743 |
+
if not fenestration_df.empty:
|
744 |
+
st.dataframe(fenestration_df, use_container_width=True)
|
745 |
+
else:
|
746 |
fenestration_data = [
|
747 |
{
|
748 |
"Name": f.name,
|
749 |
+
"Category": f.category,
|
750 |
"SHGC": f.shgc,
|
751 |
"U-Value (W/m虏路K)": f.u_value,
|
752 |
"Exterior Conductance (W/m虏路K)": f.h_o
|
|
|
754 |
for f in st.session_state.project_data["fenestrations"]["project"].values()
|
755 |
]
|
756 |
fenestration_df = pd.DataFrame(fenestration_data)
|
757 |
+
if not fenestration_df.empty:
|
758 |
+
st.dataframe(fenestration_df, use_container_width=True)
|
759 |
+
else:
|
760 |
+
st.write("No project fenestrations to display.")
|
761 |
except Exception as e:
|
762 |
+
st.error(f"Error displaying project fenestrations: {str(e)}")
|
763 |
+
st.write("No project fenestrations to display.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
764 |
else:
|
765 |
st.write("No project fenestrations to display.")
|
766 |
|
|
|
771 |
editor_state = st.session_state.get("fenestration_editor", {})
|
772 |
form_state = st.session_state.get("fenestration_form_state", {
|
773 |
"name": "",
|
774 |
+
"category": "Window/Skylight",
|
775 |
"shgc": 0.7,
|
776 |
"u_value": 5.0,
|
777 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|
|
|
784 |
help="Unique fenestration identifier",
|
785 |
key="fenestration_name_input"
|
786 |
)
|
787 |
+
filter_category = st.session_state.get("fenestration_filter", "All")
|
788 |
+
default_category = (filter_category if filter_category in FENESTRATION_TYPES
|
789 |
+
else editor_state.get("category", "Window/Skylight"))
|
790 |
+
category_index = (FENESTRATION_TYPES.index(default_category)
|
791 |
+
if default_category in FENESTRATION_TYPES else 0)
|
792 |
+
category = st.selectbox(
|
793 |
+
"Category",
|
794 |
+
FENESTRATION_TYPES,
|
795 |
+
index=category_index,
|
796 |
+
help="Fenestration type (Window/Skylight or Door)",
|
797 |
+
key="fenestration_category_input"
|
798 |
+
)
|
799 |
shgc = st.number_input(
|
800 |
"Solar Heat Gain Coefficient (SHGC)",
|
801 |
min_value=0.0,
|
|
|
825 |
st.session_state.fenestration_action = {"action": "save", "id": action_id}
|
826 |
st.session_state.fenestration_form_state = {
|
827 |
"name": name,
|
828 |
+
"category": category,
|
829 |
"shgc": shgc,
|
830 |
"u_value": u_value,
|
831 |
"h_o": h_o
|
|
|
842 |
shgc=shgc,
|
843 |
u_value=u_value,
|
844 |
h_o=h_o,
|
845 |
+
category=category,
|
846 |
is_library=False
|
847 |
)
|
848 |
+
if is_edit and editor_state.get("edit_source") == "project":
|
849 |
st.session_state.project_data["fenestrations"]["project"][original_name] = new_fenestration
|
850 |
st.success(f"Fenestration '{name}' updated successfully!")
|
851 |
else:
|
|
|
854 |
st.session_state.fenestration_editor = {}
|
855 |
st.session_state.fenestration_form_state = {
|
856 |
"name": "",
|
857 |
+
"category": "Window/Skylight",
|
858 |
"shgc": 0.7,
|
859 |
"u_value": 5.0,
|
860 |
"h_o": DEFAULT_WINDOW_PROPERTIES["h_o"]
|