KliWinBa-WebTool_2.0 / logic /tmpa1i6jrn3
Tobi-ewl's picture
Initial push
0399906 verified
# Description: Finding the right heating system for a building based on the energy demand, the age of the building and the size of the building.
import pandas as pd
import os
import streamlit as st
from data_utils.loader import load_heatingsystem_csv
from utils.misc import parsefloat, apply_technology_name_language
def determine_heatingsystem_filename(scenario_id):
return f"Szen{scenario_id}_Heizsystem.csv"
def determine_building_state(energy_demand):
energy_demand = float(energy_demand)
if 0 <= energy_demand <= 100:
return "NB"
elif 100 < energy_demand <= 200:
return "ABsaniert"
else:
return "ABunsaniert"
def find_suitable_heating_systems(
energy_demand, year_built, area, scenario_id="A", heat_load_user=None, building_state="ABsaniert"
):
filename = determine_heatingsystem_filename(scenario_id)
df = load_heatingsystem_csv(filename)
df["Effizienz"] = df[f"Effizienz_{building_state}"]
relevant_columns = [
'Heizsystem', 'Leistung (kW)', 'Investitionskosten (€)', 'Betriebsjahre', 'Effizienz',
'Emissionen (kg_CO2/kWh)', 'Preisänderungsfaktor Inv', 'Betriebskosten (€/kWh)', 'Preisänderungsfaktor Bedarf',
'Fixkosten O+M (€/kW)', 'Preisänderungsrate O+M', 'Emissionsänderungsfaktor', 'Förderung'
]
df = df[relevant_columns]
df.columns = [
"Name", "Leistung", "Investitionskosten", "Betriebsdauer", "Effizienz", "Emissionen",
"Preisänderungsfaktor_Inv", "Betriebskosten", "Preisänderungsfaktor_Bedarf",
"Fixkosten_O+M", "Preisänderungsfaktor_O+M", "Emissionsänderungsfaktor", "Förderung"
]
# Berechnung Heizlast
if heat_load_user is not None:
heat_load = float(heat_load_user)
else:
heat_load = calc_heat_load(area, energy_demand)
# ACHTUNG: Jetzt die neuen Namen verwenden!
df['Leistung'] = pd.to_numeric(df['Leistung'], errors='coerce')
df = df.dropna(subset=['Leistung'])
df = df[df['Leistung'] >= heat_load]
# ... wie gehabt weiter (jetzt mit neuen Namen!)
df_result = df.loc[df.groupby('Name')['Leistung'].idxmin()]
heizsystem_reihenfolge = [
'Luft-Wasser Wärmepumpe', 'Wasser-Wasser Wärmepumpe',
'Sole-Wasser Wärmepumpe', 'Hybrid-Wärmepumpe', 'Pelletheizung', 'Holzhackschnitzelheizung',
'Wasserstoffheizung', 'Gasheizung', 'Ölheizung'
]
df_result['Name'] = pd.Categorical(df_result['Name'], categories=heizsystem_reihenfolge, ordered=True)
df_result = df_result.sort_values(by='Name')
return df_result
# VDI 2067, Blatt 2:
full_load_hours_SFH = 2100
full_load_hours_MFH = 2000
def calc_heat_load(area, energy_demand):
total_energy_demand = energy_demand*area
# Differentiate between SFH and MFH. We use 400 m² as the threshold. Could be changed or even interpolated.
if area < 400:
full_load_hours = full_load_hours_SFH
else:
full_load_hours = full_load_hours_MFH
heat_load = total_energy_demand / full_load_hours
return heat_load
def load_or_calculate_heating_systems(
submitted, specific_energy_demand, year_built, floor_area, scenario_id,
interest_rate, observation_period, emission_price_change_factor, emission_cost, ui, heat_load_user, building_state):
if submitted or st.session_state.df_heizsysteme is None:
try:
df = find_suitable_heating_systems(specific_energy_demand, year_built, floor_area, scenario_id, heat_load_user, building_state)
if df.empty:
st.error(ui["output"]["no_systems_found"])
st.stop()
df.columns = [
"Name", "Leistung", "Investitionskosten", "Betriebsdauer", "Effizienz", "Emissionen",
"Preisänderungsfaktor_Inv", "Betriebskosten", "Preisänderungsfaktor_Bedarf",
"Fixkosten_O+M", "Preisänderungsfaktor_O+M", "Emissionsänderungsfaktor", "Förderung"
]
df = apply_technology_name_language(df,ui)
for col in df.columns[2:]:
df[col] = df[col].astype(str).str.replace(",", ".").str.replace("|", ".")
df[col] = pd.to_numeric(df[col], errors='coerce')
st.session_state.df_heizsysteme = df.copy()
st.session_state.user_values = {}
st.session_state.input_values = {
"floor_area": floor_area,
"year_built": year_built,
"specific_energy_demand": specific_energy_demand,
"interest_rate": interest_rate,
"observation_period": observation_period,
"emission_price_change_factor": emission_price_change_factor,
"emission_cost": emission_cost
}
except Exception as e:
st.error(ui["output"]["system_selection_error"].format(error=e))
st.stop()
else:
df = st.session_state.df_heizsysteme.copy()
inputs = st.session_state.input_values
floor_area = inputs["floor_area"]
year_built = inputs["year_built"]
specific_energy_demand = inputs["specific_energy_demand"]
interest_rate = inputs["interest_rate"]
observation_period = inputs["observation_period"]
emission_price_change_factor = inputs["emission_price_change_factor"]
emission_cost = inputs["emission_cost"]
return df, floor_area, year_built, specific_energy_demand, interest_rate, observation_period, emission_price_change_factor, emission_cost
def generate_preview_df(df_input_row, scenario_id):
try:
# Zugriff jetzt mit festen internen Spaltennamen, NICHT über ui["batch"]["columns"]
floor_area = parsefloat(df_input_row["floor_area"])
year_built = int(df_input_row["year_built"])
total_demand = parsefloat(df_input_row.get("heat_demand", ""))
specific_demand = parsefloat(df_input_row.get("specific_demand", ""))
# Heizwärmebedarf berechnen
if total_demand and total_demand > 0 and floor_area and floor_area > 0:
demand_specific = total_demand / floor_area
elif specific_demand and specific_demand > 0:
demand_specific = specific_demand
else:
raise ValueError("preview_error: Angaben zum Wärmebedarf fehlen oder ungültig.")
# Heizsysteme auswählen
df = find_suitable_heating_systems(demand_specific, year_built, floor_area, scenario_id)
# Spalten für Heizsystem-DF fixieren (interne Namen)
df.columns = [
"Name", "Leistung", "Investitionskosten", "Betriebsdauer", "Effizienz", "Emissionen",
"Preisänderungsfaktor_Inv", "Betriebskosten", "Preisänderungsfaktor_Bedarf",
"Fixkosten_O+M", "Preisänderungsfaktor_O+M", "Emissionsänderungsfaktor", "Förderung"
]
# Numerische Spalten bereinigen
for col in df.columns[2:]:
df[col] = df[col].astype(str).str.replace(",", ".").str.replace("|", ".")
df[col] = pd.to_numeric(df[col], errors="coerce")
return df
except Exception as e:
raise RuntimeError(str(e))
def prepare_heating_system_df(specific_energy_demand, year_built, floor_area, scen_id, heat_load_user=None):
df = find_suitable_heating_systems(specific_energy_demand, year_built, floor_area, scen_id, heat_load_user=heat_load_user)
df.columns = [
"Name", "Leistung", "Investitionskosten", "Betriebsdauer", "Effizienz", "Emissionen",
"Preisänderungsfaktor_Inv", "Betriebskosten", "Preisänderungsfaktor_Bedarf",
"Fixkosten_O+M", "Preisänderungsfaktor_O+M", "Emissionsänderungsfaktor", "Förderung"
]
for col in df.columns[2:]:
df[col] = df[col].astype(str).str.replace(",", ".").str.replace("|", ".")
df[col] = pd.to_numeric(df[col], errors='coerce')
return df