Spaces:
Sleeping
Sleeping
Upload main.py
Browse files
main.py
ADDED
@@ -0,0 +1,544 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
HVAC Load Calculator - Main Module
|
3 |
+
|
4 |
+
This is the main module for the HVAC Load Calculator application. It serves as the central
|
5 |
+
orchestrator for the application, handling navigation between different modules and managing
|
6 |
+
the overall application flow.
|
7 |
+
|
8 |
+
Developed by: Dr Majed Abuseif, Deakin University
|
9 |
+
© 2025
|
10 |
+
"""
|
11 |
+
|
12 |
+
import streamlit as st
|
13 |
+
import logging
|
14 |
+
import os
|
15 |
+
import sys
|
16 |
+
from typing import Dict, List, Any, Optional, Tuple
|
17 |
+
|
18 |
+
# Configure logging
|
19 |
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
20 |
+
logger = logging.getLogger(__name__)
|
21 |
+
|
22 |
+
# Add the current directory to the path so we can import our modules
|
23 |
+
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
24 |
+
|
25 |
+
# Import modules as they are developed
|
26 |
+
from intro import display_intro_page
|
27 |
+
from building_information import display_building_info_page
|
28 |
+
from climate_data import display_climate_page
|
29 |
+
from materials_library import display_materials_page
|
30 |
+
from construction import display_construction_page
|
31 |
+
from components import display_components_page
|
32 |
+
from data.internal_loads import display_internal_loads_page
|
33 |
+
from hvac_loads import display_hvac_loads_page
|
34 |
+
from building_energy import display_building_energy_page
|
35 |
+
from renewable_energy import display_renewable_energy_page
|
36 |
+
from embodied_energy import display_embodied_energy_page
|
37 |
+
from materials_cost import display_materials_cost_page
|
38 |
+
|
39 |
+
class HVACApp:
|
40 |
+
"""
|
41 |
+
Main class for the HVAC Load Calculator application.
|
42 |
+
Handles navigation, session state initialization, and module integration.
|
43 |
+
"""
|
44 |
+
|
45 |
+
def __init__(self):
|
46 |
+
"""
|
47 |
+
Initialize the HVAC Load Calculator application.
|
48 |
+
Sets up the page configuration and initializes session state if needed.
|
49 |
+
"""
|
50 |
+
# Configure the Streamlit page
|
51 |
+
st.set_page_config(
|
52 |
+
page_title="HVAC Load Calculator",
|
53 |
+
page_icon="🌡️",
|
54 |
+
layout="wide",
|
55 |
+
initial_sidebar_state="expanded"
|
56 |
+
)
|
57 |
+
|
58 |
+
# Initialize session state if it doesn't exist
|
59 |
+
self._initialize_session_state()
|
60 |
+
|
61 |
+
# Set up the application layout
|
62 |
+
self.setup_layout()
|
63 |
+
|
64 |
+
def _initialize_session_state(self):
|
65 |
+
"""
|
66 |
+
Initialize the session state structure if it doesn't exist.
|
67 |
+
This creates the basic structure for storing all application data.
|
68 |
+
"""
|
69 |
+
# Initialize current page if not set
|
70 |
+
if 'current_page' not in st.session_state:
|
71 |
+
st.session_state.current_page = "Intro"
|
72 |
+
|
73 |
+
# Initialize project data structure if not set
|
74 |
+
if 'project_data' not in st.session_state:
|
75 |
+
st.session_state.project_data = {
|
76 |
+
"project_name": "",
|
77 |
+
"building_info": {
|
78 |
+
"project_name": "",
|
79 |
+
"floor_area": 100.0,
|
80 |
+
"building_height": 3.0,
|
81 |
+
"indoor_design_temp": 24.0,
|
82 |
+
"indoor_design_rh": 50.0,
|
83 |
+
"ventilation_rate": 0.1,
|
84 |
+
"orientation_angle": 0.0,
|
85 |
+
"operation_hours": 8,
|
86 |
+
"building_type": "Office"
|
87 |
+
},
|
88 |
+
"climate_data": {},
|
89 |
+
"materials": {
|
90 |
+
"library": {},
|
91 |
+
"project": {}
|
92 |
+
},
|
93 |
+
"fenestrations": {
|
94 |
+
"library": {},
|
95 |
+
"project": {}
|
96 |
+
},
|
97 |
+
"constructions": {
|
98 |
+
"library": {},
|
99 |
+
"project": {}
|
100 |
+
},
|
101 |
+
"components": {
|
102 |
+
"walls": [],
|
103 |
+
"roofs": [],
|
104 |
+
"floors": [],
|
105 |
+
"windows": [],
|
106 |
+
"doors": [],
|
107 |
+
"skylights": []
|
108 |
+
},
|
109 |
+
"internal_loads": {
|
110 |
+
"people": [],
|
111 |
+
"lighting": {},
|
112 |
+
"equipment": {}
|
113 |
+
},
|
114 |
+
"hvac_loads": {
|
115 |
+
"cooling": {
|
116 |
+
"hourly": [],
|
117 |
+
"peak": 0,
|
118 |
+
"summary_tables": {},
|
119 |
+
"charts": {}
|
120 |
+
},
|
121 |
+
"heating": {
|
122 |
+
"hourly": [],
|
123 |
+
"peak": 0,
|
124 |
+
"summary_tables": {},
|
125 |
+
"charts": {}
|
126 |
+
}
|
127 |
+
},
|
128 |
+
"building_energy": {
|
129 |
+
"hvac_type": "",
|
130 |
+
"cop": 0.0,
|
131 |
+
"energy_consumption": {
|
132 |
+
"cooling": 0,
|
133 |
+
"heating": 0,
|
134 |
+
"lighting": 0,
|
135 |
+
"equipment": 0,
|
136 |
+
"total": 0
|
137 |
+
},
|
138 |
+
"charts": {}
|
139 |
+
},
|
140 |
+
"renewable_energy": {
|
141 |
+
"pv_system_size_kw": 0,
|
142 |
+
"pv_generation_kwh": 0,
|
143 |
+
"net_energy_kwh": 0,
|
144 |
+
"zero_energy_status": "",
|
145 |
+
"charts": {}
|
146 |
+
},
|
147 |
+
"embodied_energy": {
|
148 |
+
"total_embodied_carbon_kgco2e": 0,
|
149 |
+
"breakdown_by_component": {},
|
150 |
+
"charts": {}
|
151 |
+
},
|
152 |
+
"materials_cost": {
|
153 |
+
"total_cost_usd": 0,
|
154 |
+
"breakdown_by_component": {},
|
155 |
+
"charts": {}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
# Initialize UI state variables
|
160 |
+
if 'debug_mode' not in st.session_state:
|
161 |
+
st.session_state.debug_mode = False
|
162 |
+
|
163 |
+
if 'rerun_pending' not in st.session_state:
|
164 |
+
st.session_state.rerun_pending = False
|
165 |
+
|
166 |
+
def setup_layout(self):
|
167 |
+
"""
|
168 |
+
Set up the main application layout with sidebar navigation and main content area.
|
169 |
+
"""
|
170 |
+
# Create the sidebar
|
171 |
+
st.sidebar.title("HVAC Load Calculator")
|
172 |
+
st.sidebar.markdown("---")
|
173 |
+
|
174 |
+
# Navigation section in sidebar
|
175 |
+
st.sidebar.subheader("Navigation")
|
176 |
+
|
177 |
+
# Define all available pages
|
178 |
+
pages = [
|
179 |
+
"Intro",
|
180 |
+
"Building Information",
|
181 |
+
"Climate Data",
|
182 |
+
"Material Library",
|
183 |
+
"Construction",
|
184 |
+
"Building Components",
|
185 |
+
"Internal Loads",
|
186 |
+
"HVAC Loads",
|
187 |
+
"Building Energy",
|
188 |
+
"Renewable Energy",
|
189 |
+
"Embodied Energy",
|
190 |
+
"Materials Cost"
|
191 |
+
]
|
192 |
+
|
193 |
+
# Create the navigation radio buttons
|
194 |
+
selected_page = st.sidebar.radio(
|
195 |
+
"Go to",
|
196 |
+
pages,
|
197 |
+
index=pages.index(st.session_state.current_page)
|
198 |
+
)
|
199 |
+
|
200 |
+
# Update the current page if changed
|
201 |
+
if selected_page != st.session_state.current_page:
|
202 |
+
st.session_state.current_page = selected_page
|
203 |
+
# Clear any temporary form states when changing pages
|
204 |
+
for key in list(st.session_state.keys()):
|
205 |
+
if key.endswith("_form_state") or key.endswith("_editor"):
|
206 |
+
st.session_state.pop(key, None)
|
207 |
+
|
208 |
+
# Add application info to sidebar
|
209 |
+
st.sidebar.markdown("---")
|
210 |
+
st.sidebar.info(
|
211 |
+
"HVAC Load Calculator v3.0.0\n\n"
|
212 |
+
"Based on ASHRAE CTF/TFM methods\n\n"
|
213 |
+
"Developed by: Dr Majed Abuseif\n\n"
|
214 |
+
"School of Architecture and Built Environment\n\n"
|
215 |
+
"Deakin University\n\n"
|
216 |
+
"© 2025"
|
217 |
+
)
|
218 |
+
|
219 |
+
# Add help section to sidebar
|
220 |
+
st.sidebar.markdown("### Help")
|
221 |
+
st.sidebar.write("Learn about CTF/TFM methods:")
|
222 |
+
st.sidebar.markdown("[ASHRAE Handbook](https://www.ashrae.org/technical-resources/bookstore/handbook)")
|
223 |
+
|
224 |
+
# Debug mode toggle (for development)
|
225 |
+
if st.sidebar.checkbox("Debug Mode", value=st.session_state.debug_mode):
|
226 |
+
st.session_state.debug_mode = True
|
227 |
+
else:
|
228 |
+
st.session_state.debug_mode = False
|
229 |
+
|
230 |
+
# Display the selected page content
|
231 |
+
self.display_page(st.session_state.current_page)
|
232 |
+
|
233 |
+
# Handle any pending reruns (for form submissions that need to refresh)
|
234 |
+
if st.session_state.rerun_pending:
|
235 |
+
st.session_state.rerun_pending = False
|
236 |
+
st.rerun()
|
237 |
+
|
238 |
+
def display_page(self, page: str):
|
239 |
+
"""
|
240 |
+
Display the content for the selected page by calling the appropriate module function.
|
241 |
+
|
242 |
+
Args:
|
243 |
+
page: The name of the page to display
|
244 |
+
"""
|
245 |
+
if page == "Intro":
|
246 |
+
# Call the implemented intro module
|
247 |
+
display_intro_page()
|
248 |
+
elif page == "Building Information":
|
249 |
+
# Call the implemented building information module
|
250 |
+
display_building_info_page()
|
251 |
+
elif page == "Climate Data":
|
252 |
+
# Call the implemented climate data module
|
253 |
+
display_climate_page()
|
254 |
+
elif page == "Material Library":
|
255 |
+
# Call the implemented material library module
|
256 |
+
display_materials_page()
|
257 |
+
elif page == "Construction":
|
258 |
+
# Call the implemented construction module
|
259 |
+
display_construction_page()
|
260 |
+
elif page == "Building Components":
|
261 |
+
# Call the implemented components module
|
262 |
+
display_components_page()
|
263 |
+
elif page == "Internal Loads":
|
264 |
+
# Call the implemented internal loads module
|
265 |
+
display_internal_loads_page()
|
266 |
+
elif page == "HVAC Loads":
|
267 |
+
# Call the implemented HVAC loads module
|
268 |
+
display_hvac_loads_page()
|
269 |
+
elif page == "Building Energy":
|
270 |
+
# Call the implemented building energy module
|
271 |
+
display_building_energy_page()
|
272 |
+
elif page == "Renewable Energy":
|
273 |
+
# Call the implemented renewable energy module
|
274 |
+
display_renewable_energy_page()
|
275 |
+
elif page == "Embodied Energy":
|
276 |
+
# Call the implemented embodied energy module
|
277 |
+
display_embodied_energy_page()
|
278 |
+
elif page == "Materials Cost":
|
279 |
+
# Call the implemented materials cost module
|
280 |
+
display_materials_cost_page()
|
281 |
+
else:
|
282 |
+
st.error(f"Unknown page: {page}")
|
283 |
+
|
284 |
+
# Placeholder display methods until actual modules are implemented
|
285 |
+
def _display_intro_placeholder(self):
|
286 |
+
st.info("This is a placeholder for the Intro module. The actual module will be implemented in Stage 2.")
|
287 |
+
st.markdown("""
|
288 |
+
### About
|
289 |
+
The HVAC Load Calculator is a tool for calculating heating and cooling loads for buildings.
|
290 |
+
|
291 |
+
### Features
|
292 |
+
- Building information input
|
293 |
+
- Climate data selection
|
294 |
+
- Material and construction library
|
295 |
+
- Component definition
|
296 |
+
- Internal loads calculation
|
297 |
+
- HVAC load calculation using CTF/TFM methods
|
298 |
+
- Building energy consumption estimation
|
299 |
+
- Renewable energy sizing
|
300 |
+
- Embodied energy calculation
|
301 |
+
- Materials cost estimation
|
302 |
+
|
303 |
+
### Project Management
|
304 |
+
""")
|
305 |
+
|
306 |
+
col1, col2, col3 = st.columns(3)
|
307 |
+
with col1:
|
308 |
+
st.button("Start New Project")
|
309 |
+
with col2:
|
310 |
+
st.file_uploader("Import Project", type=["json"])
|
311 |
+
with col3:
|
312 |
+
st.button("Export Project")
|
313 |
+
|
314 |
+
def _display_building_info_placeholder(self):
|
315 |
+
st.info("This is a placeholder for the Building Information module. The actual module will be implemented in Stage 3.")
|
316 |
+
|
317 |
+
with st.form("building_info_form_placeholder"):
|
318 |
+
st.text_input("Project Name", value=st.session_state.project_data["building_info"]["project_name"])
|
319 |
+
st.number_input("Floor Area (square meters)", value=st.session_state.project_data["building_info"]["floor_area"])
|
320 |
+
st.number_input("Building Height (meters)", value=st.session_state.project_data["building_info"]["building_height"])
|
321 |
+
st.number_input("Indoor Design Temperature (°C)", value=st.session_state.project_data["building_info"]["indoor_design_temp"])
|
322 |
+
st.number_input("Indoor Design Relative Humidity (%)", value=st.session_state.project_data["building_info"]["indoor_design_rh"])
|
323 |
+
st.slider("Orientation Angle (°)", min_value=-180, max_value=180, value=int(st.session_state.project_data["building_info"]["orientation_angle"]))
|
324 |
+
st.slider("Operation Hours (hours/day)", min_value=0, max_value=24, value=st.session_state.project_data["building_info"]["operation_hours"])
|
325 |
+
st.selectbox("Building Type", ["Office", "Classroom", "Retail", "Restaurant", "Hotel", "Hospital", "Residential"])
|
326 |
+
|
327 |
+
st.form_submit_button("Save")
|
328 |
+
|
329 |
+
st.button("Continue to Climate Data")
|
330 |
+
|
331 |
+
def _display_climate_data_placeholder(self):
|
332 |
+
st.info("This is a placeholder for the Climate Data module. The actual module will be implemented in Stage 4.")
|
333 |
+
|
334 |
+
st.file_uploader("Upload EPW File", type=["epw"])
|
335 |
+
|
336 |
+
st.markdown("### Climate Data Summary")
|
337 |
+
st.markdown("Location: Not selected")
|
338 |
+
st.markdown("Climate Zone: Not available")
|
339 |
+
st.markdown("Design Temperatures: Not available")
|
340 |
+
|
341 |
+
col1, col2 = st.columns(2)
|
342 |
+
with col1:
|
343 |
+
st.button("Back to Building Information")
|
344 |
+
with col2:
|
345 |
+
st.button("Continue to Material Library")
|
346 |
+
|
347 |
+
def _display_material_library_placeholder(self):
|
348 |
+
st.info("This is a placeholder for the Material Library module. The actual module will be implemented in Stage 5.")
|
349 |
+
|
350 |
+
tab1, tab2 = st.tabs(["Materials", "Fenestrations"])
|
351 |
+
|
352 |
+
with tab1:
|
353 |
+
st.markdown("### Library Materials")
|
354 |
+
st.markdown("Material list will appear here")
|
355 |
+
|
356 |
+
st.markdown("### Project Materials")
|
357 |
+
st.markdown("User-defined materials will appear here")
|
358 |
+
|
359 |
+
st.markdown("### Material Editor")
|
360 |
+
st.text_input("Material Name")
|
361 |
+
st.selectbox("Category", ["Finishing Materials", "Structural Materials", "Sub-Structural Materials", "Insulation"])
|
362 |
+
st.number_input("Thermal Conductivity (W/m·K)", min_value=0.01, value=0.1)
|
363 |
+
st.button("Save Material")
|
364 |
+
|
365 |
+
with tab2:
|
366 |
+
st.markdown("### Library Fenestrations")
|
367 |
+
st.markdown("Fenestration list will appear here")
|
368 |
+
|
369 |
+
st.markdown("### Project Fenestrations")
|
370 |
+
st.markdown("User-defined fenestrations will appear here")
|
371 |
+
|
372 |
+
st.markdown("### Fenestration Editor")
|
373 |
+
st.text_input("Fenestration Name")
|
374 |
+
st.number_input("U-Value (W/m²·K)", min_value=0.1, value=2.8)
|
375 |
+
st.number_input("SHGC", min_value=0.0, max_value=1.0, value=0.7)
|
376 |
+
st.button("Save Fenestration")
|
377 |
+
|
378 |
+
col1, col2 = st.columns(2)
|
379 |
+
with col1:
|
380 |
+
st.button("Back to Climate Data")
|
381 |
+
with col2:
|
382 |
+
st.button("Continue to Construction")
|
383 |
+
|
384 |
+
def _display_construction_placeholder(self):
|
385 |
+
st.info("This is a placeholder for the Construction module. The actual module will be implemented in Stage 6.")
|
386 |
+
|
387 |
+
st.markdown("### Library Constructions")
|
388 |
+
st.markdown("Construction list will appear here")
|
389 |
+
|
390 |
+
st.markdown("### Project Constructions")
|
391 |
+
st.markdown("User-defined constructions will appear here")
|
392 |
+
|
393 |
+
st.markdown("### Construction Editor")
|
394 |
+
st.text_input("Construction Name")
|
395 |
+
st.selectbox("Component Type", ["Wall", "Roof", "Floor"])
|
396 |
+
st.markdown("Layer editor will appear here")
|
397 |
+
st.button("Save Construction")
|
398 |
+
|
399 |
+
col1, col2 = st.columns(2)
|
400 |
+
with col1:
|
401 |
+
st.button("Back to Material Library")
|
402 |
+
with col2:
|
403 |
+
st.button("Continue to Building Components")
|
404 |
+
|
405 |
+
def _display_components_placeholder(self):
|
406 |
+
st.info("This is a placeholder for the Building Components module. The actual module will be implemented in Stage 7.")
|
407 |
+
|
408 |
+
tabs = st.tabs(["Walls", "Roofs", "Floors", "Windows", "Doors", "Skylights"])
|
409 |
+
|
410 |
+
for i, tab in enumerate(tabs):
|
411 |
+
with tab:
|
412 |
+
st.markdown(f"### {['Walls', 'Roofs', 'Floors', 'Windows', 'Doors', 'Skylights'][i]}")
|
413 |
+
st.markdown("Component list will appear here")
|
414 |
+
st.button(f"Add New {['Wall', 'Roof', 'Floor', 'Window', 'Door', 'Skylight'][i]}")
|
415 |
+
|
416 |
+
col1, col2 = st.columns(2)
|
417 |
+
with col1:
|
418 |
+
st.button("Back to Construction")
|
419 |
+
with col2:
|
420 |
+
st.button("Continue to Internal Loads")
|
421 |
+
|
422 |
+
def _display_internal_loads_placeholder(self):
|
423 |
+
st.info("This is a placeholder for the Internal Loads module. The actual module will be implemented in Stage 8.")
|
424 |
+
|
425 |
+
tabs = st.tabs(["People", "Lighting", "Equipment"])
|
426 |
+
|
427 |
+
with tabs[0]:
|
428 |
+
st.number_input("Number of People", min_value=1, value=10)
|
429 |
+
st.selectbox("Activity Level", ["Seated, at Rest", "Light Office Work", "Standing, Light Work"])
|
430 |
+
|
431 |
+
with tabs[1]:
|
432 |
+
st.number_input("Lighting Power Density (W/m²)", min_value=0.0, value=10.0)
|
433 |
+
st.selectbox("Fixture Type", ["LED", "Fluorescent", "Incandescent"])
|
434 |
+
|
435 |
+
with tabs[2]:
|
436 |
+
st.number_input("Equipment Power Density (W/m²)", min_value=0.0, value=15.0)
|
437 |
+
|
438 |
+
col1, col2 = st.columns(2)
|
439 |
+
with col1:
|
440 |
+
st.button("Back to Building Components")
|
441 |
+
with col2:
|
442 |
+
st.button("Continue to HVAC Loads")
|
443 |
+
|
444 |
+
def _display_hvac_loads_placeholder(self):
|
445 |
+
st.info("This is a placeholder for the HVAC Loads module. The actual module will be implemented in Stage 9.")
|
446 |
+
|
447 |
+
st.button("Calculate HVAC Loads")
|
448 |
+
|
449 |
+
st.markdown("### Results")
|
450 |
+
st.markdown("Peak Cooling Load: Not calculated")
|
451 |
+
st.markdown("Peak Heating Load: Not calculated")
|
452 |
+
|
453 |
+
st.markdown("### Load Breakdown")
|
454 |
+
st.markdown("Charts will appear here")
|
455 |
+
|
456 |
+
col1, col2 = st.columns(2)
|
457 |
+
with col1:
|
458 |
+
st.button("Back to Internal Loads")
|
459 |
+
with col2:
|
460 |
+
st.button("Continue to Building Energy")
|
461 |
+
|
462 |
+
def _display_building_energy_placeholder(self):
|
463 |
+
st.info("This is a placeholder for the Building Energy module. The actual module will be implemented in Stage 10.")
|
464 |
+
|
465 |
+
st.selectbox("HVAC System Type", ["Heat Pump", "Boiler + Chiller", "VRF", "Other"])
|
466 |
+
st.number_input("COP/Efficiency", min_value=0.1, value=3.5)
|
467 |
+
st.button("Calculate Energy Consumption")
|
468 |
+
|
469 |
+
st.markdown("### Results")
|
470 |
+
st.markdown("Total Annual Energy Consumption: Not calculated")
|
471 |
+
|
472 |
+
st.markdown("### Energy Breakdown")
|
473 |
+
st.markdown("Charts will appear here")
|
474 |
+
|
475 |
+
col1, col2 = st.columns(2)
|
476 |
+
with col1:
|
477 |
+
st.button("Back to HVAC Loads")
|
478 |
+
with col2:
|
479 |
+
st.button("Continue to Renewable Energy")
|
480 |
+
|
481 |
+
def _display_renewable_energy_placeholder(self):
|
482 |
+
st.info("This is a placeholder for the Renewable Energy module. The actual module will be implemented in Stage 11.")
|
483 |
+
|
484 |
+
st.markdown("### PV System Sizing")
|
485 |
+
st.markdown("Required PV System Size for Net-Zero: Not calculated")
|
486 |
+
st.number_input("Custom PV System Size (kWp)", min_value=0.0, value=10.0)
|
487 |
+
st.button("Calculate PV Generation")
|
488 |
+
|
489 |
+
st.markdown("### Results")
|
490 |
+
st.markdown("Annual PV Generation: Not calculated")
|
491 |
+
st.markdown("Net Energy Consumption: Not calculated")
|
492 |
+
st.markdown("Zero Energy Status: Not calculated")
|
493 |
+
|
494 |
+
st.markdown("### Energy Balance")
|
495 |
+
st.markdown("Charts will appear here")
|
496 |
+
|
497 |
+
col1, col2 = st.columns(2)
|
498 |
+
with col1:
|
499 |
+
st.button("Back to Building Energy")
|
500 |
+
with col2:
|
501 |
+
st.button("Continue to Embodied Energy")
|
502 |
+
|
503 |
+
def _display_embodied_energy_placeholder(self):
|
504 |
+
st.info("This is a placeholder for the Embodied Energy module. The actual module will be implemented in Stage 12.")
|
505 |
+
|
506 |
+
st.button("Calculate Embodied Carbon")
|
507 |
+
|
508 |
+
st.markdown("### Results")
|
509 |
+
st.markdown("Total Embodied Carbon: Not calculated")
|
510 |
+
|
511 |
+
st.markdown("### Carbon Breakdown")
|
512 |
+
st.markdown("Charts will appear here")
|
513 |
+
|
514 |
+
col1, col2 = st.columns(2)
|
515 |
+
with col1:
|
516 |
+
st.button("Back to Renewable Energy")
|
517 |
+
with col2:
|
518 |
+
st.button("Continue to Materials Cost")
|
519 |
+
|
520 |
+
def _display_materials_cost_placeholder(self):
|
521 |
+
st.info("This is a placeholder for the Materials Cost module. The actual module will be implemented in Stage 13.")
|
522 |
+
|
523 |
+
st.button("Calculate Material Cost")
|
524 |
+
|
525 |
+
st.markdown("### Results")
|
526 |
+
st.markdown("Total Material Cost: Not calculated")
|
527 |
+
|
528 |
+
st.markdown("### Cost Breakdown")
|
529 |
+
st.markdown("Charts will appear here")
|
530 |
+
|
531 |
+
st.button("Back to Embodied Energy")
|
532 |
+
|
533 |
+
|
534 |
+
# Main entry point
|
535 |
+
if __name__ == "__main__":
|
536 |
+
try:
|
537 |
+
app = HVACApp()
|
538 |
+
except Exception as e:
|
539 |
+
st.error(f"An error occurred: {str(e)}")
|
540 |
+
logger.exception("Application error")
|
541 |
+
|
542 |
+
|
543 |
+
sys.path.append(os.path.join(os.path.dirname(__file__), 'data'))
|
544 |
+
|