Spaces:
Sleeping
Sleeping
Update app/hvac_loads.py
Browse files- app/hvac_loads.py +145 -93
app/hvac_loads.py
CHANGED
@@ -801,7 +801,15 @@ class TFMCalculations:
|
|
801 |
return final_loads
|
802 |
|
803 |
def make_pie(data: Dict[str, float], title: str) -> px.pie:
|
804 |
-
"""Create a Plotly pie chart from a dictionary of values.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
805 |
fig = px.pie(
|
806 |
names=list(data.keys()),
|
807 |
values=list(data.values()),
|
@@ -811,41 +819,135 @@ def make_pie(data: Dict[str, float], title: str) -> px.pie:
|
|
811 |
fig.update_traces(textinfo='percent+label', hoverinfo='label+percent+value')
|
812 |
return fig
|
813 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
814 |
def display_hvac_results_ui(loads: List[Dict[str, Any]], run_id: str = "default"):
|
815 |
-
"""Display HVAC load results with enhanced UI elements in a two-column format.
|
|
|
|
|
|
|
|
|
|
|
816 |
st.subheader("HVAC Load Results")
|
817 |
|
|
|
|
|
|
|
818 |
# First Row: Equipment Sizing (Two Columns)
|
819 |
col1, col2 = st.columns(2)
|
820 |
with col1:
|
821 |
st.subheader("Cooling Equipment Sizing")
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
st.write(f"**Peak Cooling Load**: {peak_cooling['total_cooling']:.2f} kW")
|
826 |
-
st.write(f"Occurred on: {peak_cooling['month']}/{peak_cooling['day']} at {peak_cooling['hour']}:00")
|
827 |
else:
|
828 |
st.write("**Peak Cooling Load**: 0.00 kW")
|
829 |
|
830 |
with col2:
|
831 |
st.subheader("Heating Equipment Sizing")
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
st.write(f"**Peak Heating Load**: {peak_heating['total_heating']:.2f} kW")
|
836 |
-
st.write(f"Occurred on: {peak_heating['month']}/{peak_heating['day']} at {peak_heating['hour']}:00")
|
837 |
else:
|
838 |
st.write("**Peak Heating Load**: 0.00 kW")
|
839 |
|
840 |
# Second Row: Monthly Loads Graph (Single Column)
|
841 |
st.subheader("Monthly Heating and Cooling Load")
|
842 |
-
monthly_df = pd.DataFrame(loads).groupby("month").agg({
|
843 |
-
"total_cooling": "sum",
|
844 |
-
"total_heating": "sum"
|
845 |
-
}).reset_index()
|
846 |
-
monthly_df = monthly_df.rename(columns={"total_cooling": "Cooling", "total_heating": "Heating"})
|
847 |
fig = px.bar(
|
848 |
-
monthly_df,
|
849 |
x="month",
|
850 |
y=["Cooling", "Heating"],
|
851 |
barmode="group",
|
@@ -854,87 +956,50 @@ def display_hvac_results_ui(loads: List[Dict[str, Any]], run_id: str = "default"
|
|
854 |
fig.update_xaxes(title="Month", tickvals=list(range(1, 13)))
|
855 |
fig.update_yaxes(title="Load (kW)")
|
856 |
st.plotly_chart(fig, use_container_width=True)
|
857 |
-
st.session_state.project_data["hvac_loads"]["monthly_summary"] = monthly_df.to_dict()
|
858 |
|
859 |
# Third Row: Load Breakdown (Two Columns)
|
860 |
col3, col4 = st.columns(2)
|
861 |
with col3:
|
862 |
st.subheader("Cooling Load Breakdown")
|
863 |
-
|
864 |
-
"Conduction": sum(load["conduction_cooling"] for load in cooling_loads),
|
865 |
-
"Solar Gains": sum(load["solar"] for load in cooling_loads),
|
866 |
-
"Internal": sum(load["internal"] for load in cooling_loads),
|
867 |
-
"Ventilation": sum(load["ventilation_cooling"] for load in cooling_loads),
|
868 |
-
"Infiltration": sum(load["infiltration_cooling"] for load in cooling_loads)
|
869 |
-
}
|
870 |
-
cooling_pie = make_pie({k: v for k, v in cooling_breakdown.items() if v > 0}, "Cooling Load Components")
|
871 |
st.plotly_chart(cooling_pie)
|
872 |
-
st.session_state.project_data["hvac_loads"]["cooling"]["charts"]["pie_by_component"] = cooling_breakdown
|
873 |
|
874 |
with col4:
|
875 |
st.subheader("Heating Load Breakdown")
|
876 |
-
|
877 |
-
"Conduction": sum(load["conduction_heating"] for load in heating_loads),
|
878 |
-
"Ventilation": sum(load["ventilation_heating"] for load in heating_loads),
|
879 |
-
"Infiltration": sum(load["infiltration_heating"] for load in heating_loads)
|
880 |
-
}
|
881 |
-
heating_pie = make_pie({k: v for k, v in heating_breakdown.items() if v > 0}, "Heating Load Components")
|
882 |
st.plotly_chart(heating_pie)
|
883 |
-
st.session_state.project_data["hvac_loads"]["heating"]["charts"]["pie_by_component"] = heating_breakdown
|
884 |
|
885 |
# Fourth Row: Heat Gain by Orientation (Two Columns)
|
886 |
col5, col6 = st.columns(2)
|
887 |
with col5:
|
888 |
st.subheader("Cooling Heat Gain by Orientation")
|
889 |
-
|
890 |
-
orientation_conduction = defaultdict(float)
|
891 |
-
for load in cooling_loads:
|
892 |
-
for key, value in load["solar_by_orientation"].items():
|
893 |
-
orientation_solar[key] += value
|
894 |
-
for key, value in load["conduction_by_orientation"].items():
|
895 |
-
orientation_conduction[key] += value
|
896 |
-
orientation_breakdown = {k: orientation_solar[k] + orientation_conduction[k] for k in set(orientation_solar) | set(orientation_conduction)}
|
897 |
-
orientation_pie = make_pie({k: v for k, v in orientation_breakdown.items() if v > 0}, "Cooling Heat Gain by Orientation")
|
898 |
st.plotly_chart(orientation_pie)
|
899 |
-
st.session_state.project_data["hvac_loads"]["cooling"]["charts"]["pie_by_orientation"] =
|
900 |
|
901 |
with col6:
|
902 |
st.subheader("Heating Heat Gain by Orientation")
|
903 |
-
|
904 |
-
for load in heating_loads:
|
905 |
-
for key, value in load["conduction_by_orientation"].items():
|
906 |
-
orientation_conduction[key] += value
|
907 |
-
orientation_breakdown = {k: v for k, v in orientation_conduction.items() if v > 0}
|
908 |
-
orientation_pie = make_pie(orientation_breakdown, "Heating Heat Gain by Orientation")
|
909 |
st.plotly_chart(orientation_pie)
|
910 |
-
st.session_state.project_data["hvac_loads"]["heating"]["charts"]["pie_by_orientation"] =
|
911 |
|
912 |
# Fifth Row: Explore Hourly Loads (Single Column)
|
913 |
st.subheader("Explore Hourly Loads")
|
914 |
-
|
915 |
-
#
|
916 |
-
|
917 |
-
for load in loads:
|
918 |
-
unique_orientations.update(load["solar_by_orientation"].keys())
|
919 |
-
unique_orientations.update(load["conduction_by_orientation"].keys())
|
920 |
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
"
|
925 |
-
|
926 |
-
"
|
927 |
-
|
928 |
-
|
929 |
-
df[f"solar_{orient}"] = df["solar_by_orientation"].apply(lambda x: x.get(orient, 0.0))
|
930 |
-
df[f"conduction_{orient}"] = df["conduction_by_orientation"].apply(lambda x: x.get(orient, 0.0))
|
931 |
-
columns.extend([f"solar_{orient}", f"conduction_{orient}"])
|
932 |
-
|
933 |
-
st.dataframe(df[columns])
|
934 |
-
|
935 |
-
# CSV Export
|
936 |
-
csv = df[columns].to_csv(index=False)
|
937 |
-
st.download_button("Download Hourly Summary as CSV", data=csv, file_name="hourly_loads.csv")
|
938 |
|
939 |
def display_hvac_loads_page():
|
940 |
"""
|
@@ -946,7 +1011,6 @@ def display_hvac_loads_page():
|
|
946 |
st.markdown("Configure and calculate HVAC loads for the building.")
|
947 |
|
948 |
# Generate a unique run ID for this session
|
949 |
-
import uuid
|
950 |
run_id = str(uuid.uuid4())
|
951 |
|
952 |
# Check for existing results
|
@@ -957,7 +1021,6 @@ def display_hvac_loads_page():
|
|
957 |
heating_loads = st.session_state.project_data["hvac_loads"]["heating"].get("hourly", [])
|
958 |
loads.extend(cooling_loads)
|
959 |
loads.extend(heating_loads)
|
960 |
-
# Sort loads by month, day, hour to ensure consistent display
|
961 |
loads = sorted(loads, key=lambda x: (x["month"], x["day"], x["hour"]))
|
962 |
if loads:
|
963 |
st.info("Displaying previously calculated HVAC load results.")
|
@@ -973,7 +1036,7 @@ def display_hvac_loads_page():
|
|
973 |
"Latitude": climate_data.get("location", {}).get("latitude", 0.0),
|
974 |
"Longitude": climate_data.get("location", {}).get("longitude", 0.0),
|
975 |
"Elevation": climate_data.get("location", {}).get("elevation", 0.0),
|
976 |
-
"Time Zone": climate_data.get("location", {}).get("timezone",
|
977 |
"Ground Reflectivity": climate_data.get("ground_reflectivity", 0.2)
|
978 |
}
|
979 |
|
@@ -1200,21 +1263,10 @@ def display_hvac_loads_page():
|
|
1200 |
st.session_state.project_data["hvac_loads"]["cooling"]["charts"] = {}
|
1201 |
st.session_state.project_data["hvac_loads"]["heating"]["charts"] = {}
|
1202 |
|
1203 |
-
# Store breakdown
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
"internal": sum(load["internal"] for load in cooling_loads if load["total_cooling"] > 0),
|
1208 |
-
"ventilation": sum(load["ventilation_cooling"] for load in cooling_loads),
|
1209 |
-
"infiltration": sum(load["infiltration_cooling"] for load in cooling_loads)
|
1210 |
-
}
|
1211 |
-
heating_breakdown = {
|
1212 |
-
"conduction": sum(load["conduction_heating"] for load in heating_loads),
|
1213 |
-
"ventilation": sum(load["ventilation_heating"] for load in heating_loads),
|
1214 |
-
"infiltration": sum(load["infiltration_heating"] for load in heating_loads)
|
1215 |
-
}
|
1216 |
-
st.session_state.project_data["hvac_loads"]["cooling"]["breakdown"] = cooling_breakdown
|
1217 |
-
st.session_state.project_data["hvac_loads"]["heating"]["breakdown"] = heating_breakdown
|
1218 |
|
1219 |
# Display Results UI with unique run_id
|
1220 |
display_hvac_results_ui(loads, run_id=run_id)
|
|
|
801 |
return final_loads
|
802 |
|
803 |
def make_pie(data: Dict[str, float], title: str) -> px.pie:
|
804 |
+
"""Create a Plotly pie chart from a dictionary of values.
|
805 |
+
|
806 |
+
Args:
|
807 |
+
data: Dictionary with keys as labels and values as magnitudes.
|
808 |
+
title: Title for the pie chart.
|
809 |
+
|
810 |
+
Returns:
|
811 |
+
Plotly pie chart figure.
|
812 |
+
"""
|
813 |
fig = px.pie(
|
814 |
names=list(data.keys()),
|
815 |
values=list(data.values()),
|
|
|
819 |
fig.update_traces(textinfo='percent+label', hoverinfo='label+percent+value')
|
820 |
return fig
|
821 |
|
822 |
+
@st.cache_data
|
823 |
+
def compute_chart_data(_loads: List[Dict[str, Any]]) -> Dict[str, Any]:
|
824 |
+
"""Compute and cache chart and breakdown data to avoid recalculation.
|
825 |
+
|
826 |
+
Args:
|
827 |
+
_loads: List of dictionaries containing HVAC load data.
|
828 |
+
|
829 |
+
Returns:
|
830 |
+
Dictionary containing precomputed data for charts and breakdowns.
|
831 |
+
"""
|
832 |
+
cooling_loads = [load for load in _loads if load["total_cooling"] > 0]
|
833 |
+
heating_loads = [load for load in _loads if load["total_heating"] > 0]
|
834 |
+
|
835 |
+
# Monthly summary
|
836 |
+
monthly_df = pd.DataFrame(_loads).groupby("month").agg({
|
837 |
+
"total_cooling": "sum",
|
838 |
+
"total_heating": "sum"
|
839 |
+
}).reset_index()
|
840 |
+
monthly_df = monthly_df.rename(columns={"total_cooling": "Cooling", "total_heating": "Heating"})
|
841 |
+
|
842 |
+
# Cooling breakdown
|
843 |
+
cooling_breakdown = {
|
844 |
+
"Conduction": sum(load["conduction_cooling"] for load in cooling_loads),
|
845 |
+
"Solar Gains": sum(load["solar"] for load in cooling_loads),
|
846 |
+
"Internal": sum(load["internal"] for load in cooling_loads),
|
847 |
+
"Ventilation": sum(load["ventilation_cooling"] for load in cooling_loads),
|
848 |
+
"Infiltration": sum(load["infiltration_cooling"] for load in cooling_loads)
|
849 |
+
}
|
850 |
+
|
851 |
+
# Heating breakdown
|
852 |
+
heating_breakdown = {
|
853 |
+
"Conduction": sum(load["conduction_heating"] for load in heating_loads),
|
854 |
+
"Ventilation": sum(load["ventilation_heating"] for load in heating_loads),
|
855 |
+
"Infiltration": sum(load["infiltration_heating"] for load in heating_loads)
|
856 |
+
}
|
857 |
+
|
858 |
+
# Orientation breakdowns
|
859 |
+
orientation_solar = defaultdict(float)
|
860 |
+
orientation_conduction_cooling = defaultdict(float)
|
861 |
+
orientation_conduction_heating = defaultdict(float)
|
862 |
+
for load in cooling_loads:
|
863 |
+
for key, value in load["solar_by_orientation"].items():
|
864 |
+
orientation_solar[key] += value
|
865 |
+
for key, value in load["conduction_by_orientation"].items():
|
866 |
+
orientation_conduction_cooling[key] += value
|
867 |
+
for load in heating_loads:
|
868 |
+
for key, value in load["conduction_by_orientation"].items():
|
869 |
+
orientation_conduction_heating[key] += value
|
870 |
+
cooling_orientation_breakdown = {k: orientation_solar[k] + orientation_conduction_cooling[k] for k in set(orientation_solar) | set(orientation_conduction_cooling)}
|
871 |
+
heating_orientation_breakdown = {k: v for k, v in orientation_conduction_heating.items() if v > 0}
|
872 |
+
|
873 |
+
# Peak loads
|
874 |
+
peak_cooling = max(cooling_loads, key=lambda x: x["total_cooling"]) if cooling_loads else None
|
875 |
+
peak_heating = max(heating_loads, key=lambda x: x["total_heating"]) if heating_loads else None
|
876 |
+
|
877 |
+
return {
|
878 |
+
"monthly_df": monthly_df,
|
879 |
+
"cooling_breakdown": cooling_breakdown,
|
880 |
+
"heating_breakdown": heating_breakdown,
|
881 |
+
"cooling_orientation_breakdown": cooling_orientation_breakdown,
|
882 |
+
"heating_orientation_breakdown": heating_orientation_breakdown,
|
883 |
+
"peak_cooling": peak_cooling,
|
884 |
+
"peak_heating": peak_heating
|
885 |
+
}
|
886 |
+
|
887 |
+
@st.cache_data
|
888 |
+
def compute_table_data(_loads: List[Dict[str, Any]]) -> pd.DataFrame:
|
889 |
+
"""Compute and cache DataFrame for hourly loads table.
|
890 |
+
|
891 |
+
Args:
|
892 |
+
_loads: List of dictionaries containing HVAC load data.
|
893 |
+
|
894 |
+
Returns:
|
895 |
+
Pandas DataFrame with hourly load data and orientation columns.
|
896 |
+
"""
|
897 |
+
df = pd.DataFrame(_loads)
|
898 |
+
unique_orientations = set()
|
899 |
+
for load in _loads:
|
900 |
+
unique_orientations.update(load["solar_by_orientation"].keys())
|
901 |
+
unique_orientations.update(load["conduction_by_orientation"].keys())
|
902 |
+
|
903 |
+
columns = [
|
904 |
+
"month", "day", "hour",
|
905 |
+
"total_cooling", "total_heating",
|
906 |
+
"conduction_cooling", "solar", "internal",
|
907 |
+
"ventilation_cooling", "infiltration_cooling",
|
908 |
+
"ventilation_heating", "infiltration_heating"
|
909 |
+
]
|
910 |
+
for orient in sorted(unique_orientations):
|
911 |
+
df[f"solar_{orient}"] = df["solar_by_orientation"].apply(lambda x: x.get(orient, 0.0))
|
912 |
+
df[f"conduction_{orient}"] = df["conduction_by_orientation"].apply(lambda x: x.get(orient, 0.0))
|
913 |
+
columns.extend([f"solar_{orient}", f"conduction_{orient}"])
|
914 |
+
|
915 |
+
return df[columns]
|
916 |
+
|
917 |
def display_hvac_results_ui(loads: List[Dict[str, Any]], run_id: str = "default"):
|
918 |
+
"""Display HVAC load results with enhanced UI elements in a two-column format.
|
919 |
+
|
920 |
+
Args:
|
921 |
+
loads: List of dictionaries containing HVAC load data.
|
922 |
+
run_id: Unique identifier for the simulation run to ensure unique widget keys.
|
923 |
+
"""
|
924 |
st.subheader("HVAC Load Results")
|
925 |
|
926 |
+
# Compute cached data
|
927 |
+
chart_data = compute_chart_data(loads)
|
928 |
+
|
929 |
# First Row: Equipment Sizing (Two Columns)
|
930 |
col1, col2 = st.columns(2)
|
931 |
with col1:
|
932 |
st.subheader("Cooling Equipment Sizing")
|
933 |
+
if chart_data["peak_cooling"]:
|
934 |
+
st.write(f"**Peak Cooling Load**: {chart_data['peak_cooling']['total_cooling']:.2f} kW")
|
935 |
+
st.write(f"Occurred on: {chart_data['peak_cooling']['month']}/{chart_data['peak_cooling']['day']} at {chart_data['peak_cooling']['hour']}:00")
|
|
|
|
|
936 |
else:
|
937 |
st.write("**Peak Cooling Load**: 0.00 kW")
|
938 |
|
939 |
with col2:
|
940 |
st.subheader("Heating Equipment Sizing")
|
941 |
+
if chart_data["peak_heating"]:
|
942 |
+
st.write(f"**Peak Heating Load**: {chart_data['peak_heating']['total_heating']:.2f} kW")
|
943 |
+
st.write(f"Occurred on: {chart_data['peak_heating']['month']}/{chart_data['peak_heating']['day']} at {chart_data['peak_cooling']['hour']}:00")
|
|
|
|
|
944 |
else:
|
945 |
st.write("**Peak Heating Load**: 0.00 kW")
|
946 |
|
947 |
# Second Row: Monthly Loads Graph (Single Column)
|
948 |
st.subheader("Monthly Heating and Cooling Load")
|
|
|
|
|
|
|
|
|
|
|
949 |
fig = px.bar(
|
950 |
+
chart_data["monthly_df"],
|
951 |
x="month",
|
952 |
y=["Cooling", "Heating"],
|
953 |
barmode="group",
|
|
|
956 |
fig.update_xaxes(title="Month", tickvals=list(range(1, 13)))
|
957 |
fig.update_yaxes(title="Load (kW)")
|
958 |
st.plotly_chart(fig, use_container_width=True)
|
959 |
+
st.session_state.project_data["hvac_loads"]["monthly_summary"] = chart_data["monthly_df"].to_dict()
|
960 |
|
961 |
# Third Row: Load Breakdown (Two Columns)
|
962 |
col3, col4 = st.columns(2)
|
963 |
with col3:
|
964 |
st.subheader("Cooling Load Breakdown")
|
965 |
+
cooling_pie = make_pie({k: v for k, v in chart_data["cooling_breakdown"].items() if v > 0}, "Cooling Load Components")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
966 |
st.plotly_chart(cooling_pie)
|
967 |
+
st.session_state.project_data["hvac_loads"]["cooling"]["charts"]["pie_by_component"] = chart_data["cooling_breakdown"]
|
968 |
|
969 |
with col4:
|
970 |
st.subheader("Heating Load Breakdown")
|
971 |
+
heating_pie = make_pie({k: v for k, v in chart_data["heating_breakdown"].items() if v > 0}, "Heating Load Components")
|
|
|
|
|
|
|
|
|
|
|
972 |
st.plotly_chart(heating_pie)
|
973 |
+
st.session_state.project_data["hvac_loads"]["heating"]["charts"]["pie_by_component"] = chart_data["heating_breakdown"]
|
974 |
|
975 |
# Fourth Row: Heat Gain by Orientation (Two Columns)
|
976 |
col5, col6 = st.columns(2)
|
977 |
with col5:
|
978 |
st.subheader("Cooling Heat Gain by Orientation")
|
979 |
+
orientation_pie = make_pie({k: v for k, v in chart_data["cooling_orientation_breakdown"].items() if v > 0}, "Cooling Heat Gain by Orientation")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
980 |
st.plotly_chart(orientation_pie)
|
981 |
+
st.session_state.project_data["hvac_loads"]["cooling"]["charts"]["pie_by_orientation"] = chart_data["cooling_orientation_breakdown"]
|
982 |
|
983 |
with col6:
|
984 |
st.subheader("Heating Heat Gain by Orientation")
|
985 |
+
orientation_pie = make_pie(chart_data["heating_orientation_breakdown"], "Heating Heat Gain by Orientation")
|
|
|
|
|
|
|
|
|
|
|
986 |
st.plotly_chart(orientation_pie)
|
987 |
+
st.session_state.project_data["hvac_loads"]["heating"]["charts"]["pie_by_orientation"] = chart_data["heating_orientation_breakdown"]
|
988 |
|
989 |
# Fifth Row: Explore Hourly Loads (Single Column)
|
990 |
st.subheader("Explore Hourly Loads")
|
991 |
+
table_df = compute_table_data(loads)
|
992 |
+
# Limit to first 100 rows to improve performance
|
993 |
+
st.dataframe(table_df.head(100))
|
|
|
|
|
|
|
994 |
|
995 |
+
# CSV Export with unique key
|
996 |
+
csv = table_df.to_csv(index=False)
|
997 |
+
st.download_button(
|
998 |
+
label="Download Hourly Summary as CSV",
|
999 |
+
data=csv,
|
1000 |
+
file_name="hourly_loads.csv",
|
1001 |
+
key=f"download_hvac_loads_{run_id}"
|
1002 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1003 |
|
1004 |
def display_hvac_loads_page():
|
1005 |
"""
|
|
|
1011 |
st.markdown("Configure and calculate HVAC loads for the building.")
|
1012 |
|
1013 |
# Generate a unique run ID for this session
|
|
|
1014 |
run_id = str(uuid.uuid4())
|
1015 |
|
1016 |
# Check for existing results
|
|
|
1021 |
heating_loads = st.session_state.project_data["hvac_loads"]["heating"].get("hourly", [])
|
1022 |
loads.extend(cooling_loads)
|
1023 |
loads.extend(heating_loads)
|
|
|
1024 |
loads = sorted(loads, key=lambda x: (x["month"], x["day"], x["hour"]))
|
1025 |
if loads:
|
1026 |
st.info("Displaying previously calculated HVAC load results.")
|
|
|
1036 |
"Latitude": climate_data.get("location", {}).get("latitude", 0.0),
|
1037 |
"Longitude": climate_data.get("location", {}).get("longitude", 0.0),
|
1038 |
"Elevation": climate_data.get("location", {}).get("elevation", 0.0),
|
1039 |
+
"Time Zone": climate_data.get("location", {}).get("timezone", 0.0),
|
1040 |
"Ground Reflectivity": climate_data.get("ground_reflectivity", 0.2)
|
1041 |
}
|
1042 |
|
|
|
1263 |
st.session_state.project_data["hvac_loads"]["cooling"]["charts"] = {}
|
1264 |
st.session_state.project_data["hvac_loads"]["heating"]["charts"] = {}
|
1265 |
|
1266 |
+
# Store breakdown (cached function handles this, but store for consistency)
|
1267 |
+
chart_data = compute_chart_data(loads)
|
1268 |
+
st.session_state.project_data["hvac_loads"]["cooling"]["breakdown"] = chart_data["cooling_breakdown"]
|
1269 |
+
st.session_state.project_data["hvac_loads"]["heating"]["breakdown"] = chart_data["heating_breakdown"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1270 |
|
1271 |
# Display Results UI with unique run_id
|
1272 |
display_hvac_results_ui(loads, run_id=run_id)
|