Spaces:
Sleeping
Sleeping
Update app/hvac_loads.py
Browse files- app/hvac_loads.py +44 -127
app/hvac_loads.py
CHANGED
@@ -685,12 +685,10 @@ class TFMCalculations:
|
|
685 |
@staticmethod
|
686 |
def filter_hourly_data(hourly_data: List[Dict], sim_period: Dict, climate_data: Dict) -> List[Dict]:
|
687 |
"""Filter hourly data based on simulation period, ignoring year."""
|
688 |
-
|
689 |
-
if sim_type == "Full Year":
|
690 |
return hourly_data
|
691 |
filtered_data = []
|
692 |
-
|
693 |
-
if sim_type == "From Date to Date":
|
694 |
start_month = sim_period["start_date"].month
|
695 |
start_day = sim_period["start_date"].day
|
696 |
end_month = sim_period["end_date"].month
|
@@ -700,31 +698,12 @@ class TFMCalculations:
|
|
700 |
if (month > start_month or (month == start_month and day >= start_day)) and \
|
701 |
(month < end_month or (month == end_month and day <= end_day)):
|
702 |
filtered_data.append(data)
|
703 |
-
|
704 |
-
|
705 |
-
base_temp = sim_period.get("base_temp", 18.3 if sim_type == "Heating Only" else 23.9)
|
706 |
for data in hourly_data:
|
707 |
temp = data["dry_bulb"]
|
708 |
-
if (
|
709 |
-
(sim_type == "Cooling Only" and temp > base_temp):
|
710 |
filtered_data.append(data)
|
711 |
-
|
712 |
-
elif sim_type in ["Summer Extreme", "Summer Typical", "Winter Extreme", "Winter Typical"]:
|
713 |
-
period_key = sim_type.lower().replace(" ", "_")
|
714 |
-
period = climate_data.get("typical_extreme_periods", {}).get(period_key, {})
|
715 |
-
if not period:
|
716 |
-
logger.warning(f"No data found for {sim_type} in typical_extreme_periods.")
|
717 |
-
return []
|
718 |
-
start_month = period["start"]["month"]
|
719 |
-
start_day = period["start"]["day"]
|
720 |
-
end_month = period["end"]["month"]
|
721 |
-
end_day = period["end"]["day"]
|
722 |
-
for data in hourly_data:
|
723 |
-
month, day = data["month"], data["day"]
|
724 |
-
if (month > start_month or (month == start_month and day >= start_day)) and \
|
725 |
-
(month < end_month or (month == end_month and day <= end_day)):
|
726 |
-
filtered_data.append(data)
|
727 |
-
|
728 |
return filtered_data
|
729 |
|
730 |
@staticmethod
|
@@ -858,116 +837,24 @@ class TFMCalculations:
|
|
858 |
def display_hvac_loads_page():
|
859 |
"""
|
860 |
Display the HVAC Loads page in the Streamlit application.
|
861 |
-
Allows users to configure
|
862 |
calculates HVAC loads using TFMCalculations, and displays results.
|
863 |
"""
|
864 |
try:
|
865 |
st.header("HVAC Loads")
|
866 |
st.markdown("Configure and calculate HVAC loads for the building.")
|
867 |
|
868 |
-
# Location Information
|
869 |
-
st.subheader("Location Information")
|
870 |
-
climate_data = st.session_state.project_data["climate_data"]
|
871 |
-
location_data = {
|
872 |
-
"Country": climate_data.get("location", {}).get("country", ""),
|
873 |
-
"City": climate_data.get("location", {}).get("city", ""),
|
874 |
-
"State/Province": climate_data.get("location", {}).get("state_province", ""),
|
875 |
-
"Latitude": climate_data.get("latitude", 0.0),
|
876 |
-
"Longitude": climate_data.get("longitude", 0.0),
|
877 |
-
"Elevation": climate_data.get("elevation", 0.0),
|
878 |
-
"Time Zone": climate_data.get("timezone", 0.0),
|
879 |
-
"Ground Reflectivity": climate_data.get("ground_reflectivity", 0.2)
|
880 |
-
}
|
881 |
-
|
882 |
-
# Create two rows with four columns each
|
883 |
-
col1, col2, col3, col4 = st.columns(4)
|
884 |
-
with col1:
|
885 |
-
country = st.text_input("Country", value=location_data["Country"], key="hvac_country")
|
886 |
-
with col2:
|
887 |
-
city = st.text_input("City", value=location_data["City"], key="hvac_city")
|
888 |
-
with col3:
|
889 |
-
state_province = st.text_input("State/Province", value=location_data["State/Province"], key="hvac_state_province")
|
890 |
-
with col4:
|
891 |
-
latitude = st.number_input(
|
892 |
-
"Latitude (°)",
|
893 |
-
min_value=-90.0,
|
894 |
-
max_value=90.0,
|
895 |
-
value=location_data["Latitude"],
|
896 |
-
step=0.1,
|
897 |
-
key="hvac_latitude"
|
898 |
-
)
|
899 |
-
|
900 |
-
col5, col6, col7, col8 = st.columns(4)
|
901 |
-
with col5:
|
902 |
-
longitude = st.number_input(
|
903 |
-
"Longitude (°)",
|
904 |
-
min_value=-180.0,
|
905 |
-
max_value=180.0,
|
906 |
-
value=location_data["Longitude"],
|
907 |
-
step=0.1,
|
908 |
-
key="hvac_longitude"
|
909 |
-
)
|
910 |
-
with col6:
|
911 |
-
elevation = st.number_input(
|
912 |
-
"Elevation (m)",
|
913 |
-
min_value=0.0,
|
914 |
-
max_value=10000.0,
|
915 |
-
value=location_data["Elevation"],
|
916 |
-
step=1.0,
|
917 |
-
key="hvac_elevation"
|
918 |
-
)
|
919 |
-
with col7:
|
920 |
-
timezone = st.number_input(
|
921 |
-
"Time Zone (UTC offset)",
|
922 |
-
min_value=-12.0,
|
923 |
-
max_value=14.0,
|
924 |
-
value=location_data["Time Zone"],
|
925 |
-
step=0.5,
|
926 |
-
key="hvac_timezone"
|
927 |
-
)
|
928 |
-
with col8:
|
929 |
-
ground_reflectivity = st.number_input(
|
930 |
-
"Ground Reflectivity",
|
931 |
-
min_value=0.0,
|
932 |
-
max_value=1.0,
|
933 |
-
value=location_data["Ground Reflectivity"],
|
934 |
-
step=0.01,
|
935 |
-
key="hvac_ground_reflectivity"
|
936 |
-
)
|
937 |
-
|
938 |
-
if st.button("Save Location"):
|
939 |
-
st.session_state.project_data["climate_data"]["location"].update({
|
940 |
-
"country": country,
|
941 |
-
"city": city,
|
942 |
-
"state_province": state_province
|
943 |
-
})
|
944 |
-
st.session_state.project_data["climate_data"].update({
|
945 |
-
"latitude": latitude,
|
946 |
-
"longitude": longitude,
|
947 |
-
"elevation": elevation,
|
948 |
-
"timezone": timezone,
|
949 |
-
"ground_reflectivity": ground_reflectivity
|
950 |
-
})
|
951 |
-
st.success("Location information saved successfully.")
|
952 |
-
logger.info("Location information updated in session state")
|
953 |
-
|
954 |
# Simulation Period Configuration
|
955 |
st.subheader("Simulation Period")
|
956 |
sim_type = st.selectbox(
|
957 |
"Simulation Type",
|
958 |
-
["Full Year", "From
|
959 |
-
"Summer Extreme", "Summer Typical", "Winter Extreme", "Winter Typical"],
|
960 |
key="hvac_sim_type",
|
961 |
-
index=["Full Year", "From
|
962 |
-
"Summer Extreme", "Summer Typical", "Winter Extreme", "Winter Typical"].index(
|
963 |
-
st.session_state.project_data["sim_period"]["type"]
|
964 |
-
) if st.session_state.project_data["sim_period"]["type"] in
|
965 |
-
["Full Year", "From Date to Date", "Heating Only", "Cooling Only",
|
966 |
-
"Summer Extreme", "Summer Typical", "Winter Extreme", "Winter Typical"] else 0
|
967 |
)
|
968 |
st.session_state.project_data["sim_period"]["type"] = sim_type
|
969 |
|
970 |
-
if sim_type == "From
|
971 |
col1, col2 = st.columns(2)
|
972 |
with col1:
|
973 |
start_date = st.date_input(
|
@@ -983,18 +870,18 @@ def display_hvac_loads_page():
|
|
983 |
)
|
984 |
st.session_state.project_data["sim_period"]["start_date"] = start_date
|
985 |
st.session_state.project_data["sim_period"]["end_date"] = end_date
|
986 |
-
elif sim_type in ["
|
987 |
base_temp = st.number_input(
|
988 |
"Base Temperature (°C)",
|
989 |
min_value=0.0,
|
990 |
max_value=40.0,
|
991 |
-
value=st.session_state.project_data["sim_period"]
|
992 |
step=0.1,
|
993 |
key="hvac_base_temp"
|
994 |
)
|
995 |
st.session_state.project_data["sim_period"]["base_temp"] = base_temp
|
996 |
|
997 |
-
# Indoor Conditions Configuration
|
998 |
st.subheader("Indoor Conditions")
|
999 |
indoor_type = st.selectbox(
|
1000 |
"Indoor Conditions Type",
|
@@ -1057,7 +944,37 @@ def display_hvac_loads_page():
|
|
1057 |
)
|
1058 |
st.session_state.project_data["indoor_conditions"]["adaptive_acceptability"] = acceptability
|
1059 |
|
1060 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1061 |
if st.button("Calculate HVAC Loads"):
|
1062 |
try:
|
1063 |
components = st.session_state.project_data["components"]
|
@@ -1087,7 +1004,7 @@ def display_hvac_loads_page():
|
|
1087 |
hvac_settings=hvac_settings
|
1088 |
)
|
1089 |
|
1090 |
-
# Update session state with results
|
1091 |
cooling_loads = [load for load in loads if load["total_cooling"] > 0]
|
1092 |
heating_loads = [load for load in loads if load["total_heating"] > 0]
|
1093 |
st.session_state.project_data["hvac_loads"]["cooling"]["hourly"] = cooling_loads
|
|
|
685 |
@staticmethod
|
686 |
def filter_hourly_data(hourly_data: List[Dict], sim_period: Dict, climate_data: Dict) -> List[Dict]:
|
687 |
"""Filter hourly data based on simulation period, ignoring year."""
|
688 |
+
if sim_period["type"] == "Full Year":
|
|
|
689 |
return hourly_data
|
690 |
filtered_data = []
|
691 |
+
if sim_period["type"] == "From-to":
|
|
|
692 |
start_month = sim_period["start_date"].month
|
693 |
start_day = sim_period["start_date"].day
|
694 |
end_month = sim_period["end_date"].month
|
|
|
698 |
if (month > start_month or (month == start_month and day >= start_day)) and \
|
699 |
(month < end_month or (month == end_month and day <= end_day)):
|
700 |
filtered_data.append(data)
|
701 |
+
elif sim_period["type"] in ["HDD", "CDD"]:
|
702 |
+
base_temp = sim_period.get("base_temp", 18.3 if sim_period["type"] == "HDD" else 23.9)
|
|
|
703 |
for data in hourly_data:
|
704 |
temp = data["dry_bulb"]
|
705 |
+
if (sim_period["type"] == "HDD" and temp < base_temp) or (sim_period["type"] == "CDD" and temp > base_temp):
|
|
|
706 |
filtered_data.append(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
707 |
return filtered_data
|
708 |
|
709 |
@staticmethod
|
|
|
837 |
def display_hvac_loads_page():
|
838 |
"""
|
839 |
Display the HVAC Loads page in the Streamlit application.
|
840 |
+
Allows users to configure simulation period, indoor conditions, and HVAC settings,
|
841 |
calculates HVAC loads using TFMCalculations, and displays results.
|
842 |
"""
|
843 |
try:
|
844 |
st.header("HVAC Loads")
|
845 |
st.markdown("Configure and calculate HVAC loads for the building.")
|
846 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
# Simulation Period Configuration
|
848 |
st.subheader("Simulation Period")
|
849 |
sim_type = st.selectbox(
|
850 |
"Simulation Type",
|
851 |
+
["Full Year", "From-to", "HDD", "CDD"],
|
|
|
852 |
key="hvac_sim_type",
|
853 |
+
index=["Full Year", "From-to", "HDD", "CDD"].index(st.session_state.project_data["sim_period"]["type"])
|
|
|
|
|
|
|
|
|
|
|
854 |
)
|
855 |
st.session_state.project_data["sim_period"]["type"] = sim_type
|
856 |
|
857 |
+
if sim_type == "From-to":
|
858 |
col1, col2 = st.columns(2)
|
859 |
with col1:
|
860 |
start_date = st.date_input(
|
|
|
870 |
)
|
871 |
st.session_state.project_data["sim_period"]["start_date"] = start_date
|
872 |
st.session_state.project_data["sim_period"]["end_date"] = end_date
|
873 |
+
elif sim_type in ["HDD", "CDD"]:
|
874 |
base_temp = st.number_input(
|
875 |
"Base Temperature (°C)",
|
876 |
min_value=0.0,
|
877 |
max_value=40.0,
|
878 |
+
value=st.session_state.project_data["sim_period"]["base_temp"],
|
879 |
step=0.1,
|
880 |
key="hvac_base_temp"
|
881 |
)
|
882 |
st.session_state.project_data["sim_period"]["base_temp"] = base_temp
|
883 |
|
884 |
+
# Indoor Conditions Configuration
|
885 |
st.subheader("Indoor Conditions")
|
886 |
indoor_type = st.selectbox(
|
887 |
"Indoor Conditions Type",
|
|
|
944 |
)
|
945 |
st.session_state.project_data["indoor_conditions"]["adaptive_acceptability"] = acceptability
|
946 |
|
947 |
+
# HVAC Settings Configuration
|
948 |
+
st.subheader("HVAC Settings")
|
949 |
+
col1, col2 = st.columns(2)
|
950 |
+
with col1:
|
951 |
+
start_hour = st.number_input(
|
952 |
+
"Operating Start Hour",
|
953 |
+
min_value=0,
|
954 |
+
max_value=23,
|
955 |
+
value=st.session_state.project_data["hvac_settings"]["operating_hours"][0]["start"],
|
956 |
+
step=1,
|
957 |
+
key="hvac_start_hour"
|
958 |
+
)
|
959 |
+
with col2:
|
960 |
+
end_hour = st.number_input(
|
961 |
+
"Operating End Hour",
|
962 |
+
min_value=0,
|
963 |
+
max_value=23,
|
964 |
+
value=st.session_state.project_data["hvac_settings"]["operating_hours"][0]["end"],
|
965 |
+
step=1,
|
966 |
+
key="hvac_end_hour"
|
967 |
+
)
|
968 |
+
system_type = st.selectbox(
|
969 |
+
"HVAC System Type",
|
970 |
+
["Default", "VAV", "CAV", "VRF"],
|
971 |
+
key="hvac_system_type",
|
972 |
+
index=["Default", "VAV", "CAV", "VRF"].index(st.session_state.project_data["hvac_settings"]["system_type"])
|
973 |
+
)
|
974 |
+
st.session_state.project_data["hvac_settings"]["operating_hours"] = [{"start": start_hour, "end": end_hour}]
|
975 |
+
st.session_state.project_data["hvac_settings"]["system_type"] = system_type
|
976 |
+
|
977 |
+
# Calculate HVAC Loads
|
978 |
if st.button("Calculate HVAC Loads"):
|
979 |
try:
|
980 |
components = st.session_state.project_data["components"]
|
|
|
1004 |
hvac_settings=hvac_settings
|
1005 |
)
|
1006 |
|
1007 |
+
# Update session state with results
|
1008 |
cooling_loads = [load for load in loads if load["total_cooling"] > 0]
|
1009 |
heating_loads = [load for load in loads if load["total_heating"] > 0]
|
1010 |
st.session_state.project_data["hvac_loads"]["cooling"]["hourly"] = cooling_loads
|