|
|
""" |
|
|
Main application module for HVAC Load Calculator. |
|
|
This module integrates all components and provides the main Streamlit interface. |
|
|
""" |
|
|
|
|
|
import streamlit as st |
|
|
import pandas as pd |
|
|
import numpy as np |
|
|
import os |
|
|
import datetime |
|
|
from models.building import Building, CoolingLoadResult |
|
|
from views.building_info_form import display_building_info_form |
|
|
from views.internal_loads_form import display_internal_loads_form |
|
|
from views.enhanced_results_display import display_enhanced_results |
|
|
from controllers.building_manager import BuildingManager |
|
|
from controllers.enhanced_cooling_load_calculator import calculate_cooling_load |
|
|
from controllers.monthly_breakdown import calculate_monthly_breakdown |
|
|
from utils.data_io import display_export_options, display_import_options |
|
|
|
|
|
|
|
|
st.set_page_config( |
|
|
page_title="Enhanced HVAC Load Calculator", |
|
|
page_icon="❄️", |
|
|
layout="wide", |
|
|
initial_sidebar_state="expanded" |
|
|
) |
|
|
|
|
|
|
|
|
if 'building' not in st.session_state: |
|
|
st.session_state.building = None |
|
|
|
|
|
if 'result' not in st.session_state: |
|
|
st.session_state.result = None |
|
|
|
|
|
if 'monthly_breakdown' not in st.session_state: |
|
|
st.session_state.monthly_breakdown = None |
|
|
|
|
|
if 'show_comparison' not in st.session_state: |
|
|
st.session_state.show_comparison = False |
|
|
|
|
|
|
|
|
building_manager = BuildingManager() |
|
|
|
|
|
|
|
|
st.title("Enhanced HVAC Load Calculator") |
|
|
|
|
|
|
|
|
with st.sidebar: |
|
|
st.header("Navigation") |
|
|
|
|
|
|
|
|
page = st.radio( |
|
|
"Select Page", |
|
|
["Building Information", "Internal Loads", "Results", "Building Manager", "Import/Export"] |
|
|
) |
|
|
|
|
|
|
|
|
st.header("Building Management") |
|
|
|
|
|
|
|
|
if st.button("Create New Building"): |
|
|
st.session_state.building = Building() |
|
|
st.session_state.result = None |
|
|
st.session_state.monthly_breakdown = None |
|
|
st.success("New building created") |
|
|
|
|
|
|
|
|
if st.session_state.building: |
|
|
if st.button("Save Current Building"): |
|
|
if building_manager.add_building(st.session_state.building): |
|
|
st.success(f"Building {st.session_state.building.settings.name} saved") |
|
|
else: |
|
|
if st.checkbox(f"Update existing building {st.session_state.building.settings.name}?"): |
|
|
if building_manager.update_building(st.session_state.building): |
|
|
st.success(f"Building {st.session_state.building.settings.name} updated") |
|
|
else: |
|
|
st.error(f"Failed to update building {st.session_state.building.settings.name}") |
|
|
|
|
|
|
|
|
if building_manager.get_buildings(): |
|
|
st.header("Load Building") |
|
|
|
|
|
building_names = list(building_manager.get_buildings().keys()) |
|
|
selected_building = st.selectbox("Select Building", building_names) |
|
|
|
|
|
if st.button("Load Selected Building"): |
|
|
st.session_state.building = building_manager.get_buildings()[selected_building] |
|
|
|
|
|
|
|
|
if selected_building in building_manager.get_results(): |
|
|
st.session_state.result = building_manager.get_results()[selected_building] |
|
|
else: |
|
|
st.session_state.result = None |
|
|
|
|
|
|
|
|
if selected_building in building_manager.get_monthly_breakdowns(): |
|
|
st.session_state.monthly_breakdown = building_manager.get_monthly_breakdowns()[selected_building] |
|
|
else: |
|
|
st.session_state.monthly_breakdown = None |
|
|
|
|
|
st.success(f"Building {selected_building} loaded") |
|
|
|
|
|
|
|
|
if len(building_manager.get_buildings()) >= 2: |
|
|
st.header("Compare Buildings") |
|
|
|
|
|
if st.button("Compare Buildings"): |
|
|
st.session_state.show_comparison = True |
|
|
|
|
|
|
|
|
st.header("About") |
|
|
st.write("Enhanced HVAC Load Calculator v2.0") |
|
|
st.write("Based on ASHRAE cooling load calculation methods") |
|
|
st.write("© 2025 HVAC Engineering") |
|
|
|
|
|
|
|
|
if st.session_state.show_comparison: |
|
|
|
|
|
st.header("Building Comparison") |
|
|
|
|
|
|
|
|
buildings = building_manager.get_buildings() |
|
|
results = building_manager.get_results() |
|
|
monthly_breakdowns = building_manager.get_monthly_breakdowns() |
|
|
|
|
|
missing_results = [name for name in buildings if name not in results] |
|
|
if missing_results: |
|
|
st.warning(f"Missing results for buildings: {', '.join(missing_results)}. Please calculate these buildings first.") |
|
|
|
|
|
|
|
|
if st.button("Calculate Missing Results"): |
|
|
with st.spinner("Calculating missing results..."): |
|
|
for name in missing_results: |
|
|
building_manager.calculate_building(name) |
|
|
st.success("All calculations completed") |
|
|
|
|
|
|
|
|
if st.button("Exit Comparison Mode"): |
|
|
st.session_state.show_comparison = False |
|
|
st.experimental_rerun() |
|
|
else: |
|
|
|
|
|
building_manager.display_building_comparison() |
|
|
|
|
|
|
|
|
if st.button("Exit Comparison Mode"): |
|
|
st.session_state.show_comparison = False |
|
|
st.experimental_rerun() |
|
|
elif page == "Building Information": |
|
|
|
|
|
st.header("Building Information") |
|
|
|
|
|
if st.session_state.building is None: |
|
|
st.info("No building loaded. Create a new building or load an existing one.") |
|
|
else: |
|
|
display_building_info_form(st.session_state.building) |
|
|
elif page == "Internal Loads": |
|
|
|
|
|
st.header("Internal Loads") |
|
|
|
|
|
if st.session_state.building is None: |
|
|
st.info("No building loaded. Create a new building or load an existing one.") |
|
|
else: |
|
|
display_internal_loads_form(st.session_state.building) |
|
|
elif page == "Results": |
|
|
|
|
|
st.header("Calculation Results") |
|
|
|
|
|
if st.session_state.building is None: |
|
|
st.info("No building loaded. Create a new building or load an existing one.") |
|
|
else: |
|
|
|
|
|
if st.button("Calculate Cooling Load"): |
|
|
with st.spinner("Calculating cooling load..."): |
|
|
|
|
|
st.session_state.result = calculate_cooling_load(st.session_state.building) |
|
|
|
|
|
|
|
|
st.session_state.monthly_breakdown = calculate_monthly_breakdown(st.session_state.building) |
|
|
|
|
|
st.success("Calculation completed") |
|
|
|
|
|
|
|
|
if st.session_state.result: |
|
|
display_enhanced_results(st.session_state.result, st.session_state.building, st.session_state.monthly_breakdown) |
|
|
else: |
|
|
st.info("No calculation results available. Click 'Calculate Cooling Load' to perform calculation.") |
|
|
elif page == "Building Manager": |
|
|
|
|
|
building_manager.display_building_manager() |
|
|
|
|
|
|
|
|
building_manager.display_building_list() |
|
|
elif page == "Import/Export": |
|
|
|
|
|
st.header("Import/Export") |
|
|
|
|
|
|
|
|
import_export_tabs = st.tabs(["Export", "Import"]) |
|
|
|
|
|
with import_export_tabs[0]: |
|
|
|
|
|
st.subheader("Export Options") |
|
|
|
|
|
if st.session_state.building is None: |
|
|
st.info("No building loaded. Create a new building or load an existing one.") |
|
|
elif st.session_state.result is None: |
|
|
st.info("No calculation results available. Calculate cooling load first.") |
|
|
else: |
|
|
display_export_options(st.session_state.building, st.session_state.result, st.session_state.monthly_breakdown) |
|
|
|
|
|
with import_export_tabs[1]: |
|
|
|
|
|
st.subheader("Import Options") |
|
|
|
|
|
import_result = display_import_options() |
|
|
|
|
|
if import_result: |
|
|
building, result, monthly_breakdown = import_result |
|
|
|
|
|
|
|
|
st.session_state.building = building |
|
|
st.session_state.result = result |
|
|
st.session_state.monthly_breakdown = monthly_breakdown |
|
|
|
|
|
st.success(f"Successfully imported building: {building.settings.name}") |
|
|
|
|
|
|
|
|
st.markdown("---") |
|
|
st.write("Enhanced HVAC Load Calculator | Developed with Streamlit") |
|
|
|