"""Markdown-Reporterzeugung fuer die Waermerueckgewinnung-Auslegung. Einziger oeffentlicher Einstiegspunkt: report_md(e, cfg, quelldateien). """ from __future__ import annotations import datetime def _h2(title: str) -> list[str]: return ["", f"## {title}", ""] def _h3(title: str) -> list[str]: return [f"### {title}", ""] def _tbl_header(cols: list[str]) -> list[str]: return [" | ".join(cols), " | ".join(["---"] * len(cols))] def _code(lines: list[str]) -> list[str]: return ["```"] + lines + ["```", ""] def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str: """Vollstaendiger Markdown-Report: je Block Voraussetzungen → Formeln → Ergebnisse.""" q = e["milch_kuehllast_kWh_tag"] wp = e["waermepumpe"] sp = e["speicher"] pv = e["pv"] netz = e["netzbezug"] bat = e["batterie"] hh = e["haushalte"] m_cfg = cfg["milch"] wp_cfg = cfg["waermepumpe"] pcm_cfg = cfg["pcm"] abh_cfg = cfg["abholung"] pv_cfg = cfg["pv"] bat_cfg = cfg["batterie"] hh_cfg = cfg["haushalt"] z = abh_cfg["zyklus_tage"] milch = e["eingang"]["milch_l_tag"] ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") L = [] L.append("# Auslegung Waermerueckgewinnung Milchkuehlung") L.append("") L.append(f"**Erstellt:** {ts}") if quelldateien: L.append(f"**Konfiguration:** {', '.join(quelldateien)}") # ── Milchkühllast ──────────────────────────────────────────────── L.extend(_h2("Milchkuehllast")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| Milchmenge | {milch:.0f} L/Tag |") L.append(f"| Eingangstemperatur | {m_cfg['temp_ein_C']:.0f} C (Eutertemperatur) |") L.append(f"| Ausgangstemperatur | {m_cfg['temp_aus_C']:.0f} C (Lagertemperatur) |") L.append(f"| Dichte | {m_cfg['dichte_kg_pro_L']:.2f} kg/L |") L.append(f"| Spez. Waerme | {m_cfg['spez_waerme_kJ_pro_kgK']:.3f} kJ/(kg·K) |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "Q = V × ρ × c × ΔT / 3600 [kWh/Tag]", " = (Milchmenge × Dichte) × spez_Waerme × (T_ein − T_aus) / 3600", "", f" = ({milch:.0f} L/Tag × {m_cfg['dichte_kg_pro_L']:.2f} kg/L)" f" × {m_cfg['spez_waerme_kJ_pro_kgK']:.3f} kJ/(kg·K)" f" × ({m_cfg['temp_ein_C']:.0f} − {m_cfg['temp_aus_C']:.0f}) K / 3600", f" = {q:.1f} kWh/Tag", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kenngroesse", "Wert"])) L.append(f"| Taegl. Kuehllast | **{q:.1f} kWh/Tag** |") # ── Wärmepumpe ─────────────────────────────────────────────────── L.extend(_h2("Waermepumpe")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| COP (Coefficient of Performance) | {wp_cfg['cop']:.2f} |") L.append(f"| Laufzeit | {wp_cfg['laufzeit_h_pro_tag']:.0f} h/Tag |") L.append(f"| Kuehllast (aus Milchblock) | {q:.1f} kWh/Tag |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "Leistungsauslegung aus Kuehllast und Laufzeit:", " P_Kaelte = Q_Tag / Laufzeit [kW] (Verdampfer)", " P_Heiz = P_Kaelte × COP / (COP − 1) [kW] (Kondensator)", " P_el = P_Kaelte / (COP − 1) [kW] (Antrieb)", "", "Tageswerte:", " W_el = P_el × Laufzeit [kWh/Tag]", " Q_Speicher = P_Heiz × Laufzeit [kWh/Tag]", "", f" P_Kaelte = {q:.1f} / {wp_cfg['laufzeit_h_pro_tag']:.0f}" f" = {wp['kaelteleistung_kW']:.1f} kW", f" P_Heiz = {wp['kaelteleistung_kW']:.1f}" f" × {wp_cfg['cop']:.2f} / ({wp_cfg['cop']:.2f} − 1)" f" = {wp['heizleistung_kW']:.1f} kW", f" P_el = {wp['kaelteleistung_kW']:.1f}" f" / ({wp_cfg['cop']:.2f} − 1)" f" = {wp['elektrische_leistung_kW']:.1f} kW", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kenngroesse", "Wert"])) L.append(f"| Kaelteleistung (Verdampfer) | {wp['kaelteleistung_kW']:.1f} kW |") L.append(f"| Heizleistung (Kondensator) | {wp['heizleistung_kW']:.1f} kW |") L.append(f"| el. Leistung | {wp['elektrische_leistung_kW']:.1f} kW |") L.append(f"| Strombedarf | **{wp['strom_kWh_tag']:.1f} kWh/Tag** |") L.append(f"| Waerme in den Speicher | **{wp['speicher_kWh_tag']:.1f} kWh/Tag** |") # ── PV-Anlage ──────────────────────────────────────────────────── L.extend(_h2("PV-Anlage (Jahresbilanz)")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| Strombedarf WP (aus WP-Block) | {wp['strom_kWh_tag']:.1f} kWh/Tag |") L.append(f"| Spez. Jahresertrag | {pv_cfg['spez_ertrag_kWh_pro_kWp_jahr']} kWh/(kWp·a) |") L.append(f"| Dachflaeche je kWp | {pv_cfg['flaeche_m2_pro_kWp']:.1f} m2/kWp |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "Jahresbedarf = W_el_Tag × 365 [kWh/a]", "kWp = Jahresbedarf / spez_Ertrag [kWp]", "Flaeche = kWp × Flaeche_je_kWp [m²]", "", f"kWp = {pv['jahresbedarf_kWh']:.0f} kWh/a" f" / {pv_cfg['spez_ertrag_kWh_pro_kWp_jahr']} kWh/(kWp·a)" f" = {pv['kWp']:.1f} kWp", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kenngroesse", "Wert"])) L.append(f"| Jahresstrombedarf WP | {pv['jahresbedarf_kWh']:.0f} kWh/a |") L.append(f"| PV-Leistung | **{pv['kWp']:.1f} kWp** |") L.append(f"| Dachflaeche | **{pv['flaeche_m2']:.0f} m2** |") # ── Netzbezug ──────────────────────────────────────────────────── L.extend(_h2("Netzbezug (Wintermonate, Monatsbilanz)")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| PV-Leistung (aus PV-Block) | {pv['kWp']:.1f} kWp |") L.append(f"| Strombedarf WP | {wp['strom_kWh_tag']:.1f} kWh/Tag |") L.append(f"| Monatsprofil | Jan {pv_cfg['monatsertrag_kWh_pro_kWp']['Jan']}," f" Feb {pv_cfg['monatsertrag_kWh_pro_kWp']['Feb']}," f" ... Dez {pv_cfg['monatsertrag_kWh_pro_kWp']['Dez']} kWh/kWp |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "je Monat (n = Tage im Monat):", " PV_Monat = kWp × Monatsertrag_kWh_pro_kWp [kWh]", " Bedarf_Monat = W_el_Tag × n [kWh]", " Zukauf = max(0, Bedarf_Monat − PV_Monat) [kWh]", " Ueberschuss = max(0, PV_Monat − Bedarf_Monat) [kWh]", "", "Jahreswerte:", " Netzbezug = Σ Zukauf [kWh/a]", " Anteil = Netzbezug / Jahresbedarf [%]", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kenngroesse", "Wert"])) L.append(f"| Netzbezug | **{netz['netzbezug_kWh']:.0f} kWh/a = {netz['netzbezug_anteil']*100:.0f} %** |") L.append(f"| Sommerueberschuss | {netz['ueberschuss_kWh']:.0f} kWh/a |") L.append("") L.append("#### Monatsbilanz") L.append("") L.extend(_tbl_header(["Monat", "Bedarf kWh", "PV kWh", "Zukauf kWh"])) for monat, werte in netz["monate"].items(): L.append(f"| {monat} | {werte['bedarf_kWh']:.0f} | {werte['pv_kWh']:.0f}" f" | {werte['zukauf_kWh']:.0f} |") # ── Batterie ───────────────────────────────────────────────────── L.extend(_h2("Batterie (Tag-/Nacht-Ueberbrueckung)")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| Strombedarf WP | {wp['strom_kWh_tag']:.1f} kWh/Tag |") L.append(f"| Direkt-PV-Stunden (WP laeuft direkt aus PV) | {bat_cfg['direkt_pv_stunden']:.0f} h/Tag |") L.append(f"| Nutzbarer Anteil (Entladetiefe LFP) | {bat_cfg['nutzbar_anteil']*100:.0f} % |") L.append(f"| Reservefaktor | {bat_cfg['reserve_faktor']:.1f} |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "Pufferbedarf = W_el × (24 − Direkt_PV_h) / 24 [kWh]", " (Anteil des Tages ohne direkten PV-Strom)", "C_nutzbar = Pufferbedarf × Reservefaktor [kWh]", "C_nominal = C_nutzbar / Entladetiefe_DoD [kWh]", "", f"Pufferbedarf = {wp['strom_kWh_tag']:.1f}" f" × (24 − {bat_cfg['direkt_pv_stunden']:.0f}) / 24" f" = {wp['strom_kWh_tag'] * (24 - bat_cfg['direkt_pv_stunden']) / 24:.1f} kWh", f"C_nutzbar = … × {bat_cfg['reserve_faktor']:.1f}" f" = {bat['nutzbar_kWh']:.1f} kWh", f"C_nominal = {bat['nutzbar_kWh']:.1f}" f" / {bat_cfg['nutzbar_anteil']:.1f}" f" = {bat['nominal_kWh']:.1f} kWh", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kenngroesse", "Wert"])) L.append(f"| Nutzbare Kapazitaet | {bat['nutzbar_kWh']:.1f} kWh |") L.append(f"| Nennkapazitaet | **{bat['nominal_kWh']:.1f} kWh** |") # ── Latentspeicher ─────────────────────────────────────────────── passt = "ja" if sp["passt_in_einen_lkw"] else "NEIN - mehrere Behaelter noetig" L.extend(_h2(f"Latentspeicher ({pcm_cfg['name']})")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| PCM | {pcm_cfg['name']} |") L.append(f"| Schmelzpunkt | {pcm_cfg['schmelzpunkt_C']:.0f} C |") L.append(f"| Latentwaerme | {pcm_cfg['latentwaerme_kJ_pro_kg']:.0f} kJ/kg |") L.append(f"| Dichte | {pcm_cfg['dichte_kg_pro_L']:.1f} kg/L |") L.append(f"| Modus | {pcm_cfg['modus']} |") if pcm_cfg["modus"] == "latent_plus_hub": L.append(f"| Ladetemperatur | {pcm_cfg['ladetemp_C']:.0f} C |") L.append(f"| Entladetemperatur | {pcm_cfg['entladetemp_C']:.0f} C |") L.append(f"| cp fluessig | {pcm_cfg['cp_fluessig_kJ_pro_kgK']:.1f} kJ/(kg·K) |") L.append(f"| cp fest | {pcm_cfg['cp_fest_kJ_pro_kgK']:.1f} kJ/(kg·K) |") L.append(f"| Abholzyklus | {z} Tage |") L.append(f"| LKW-Nutzlast | {abh_cfg['lkw_nutzlast_kg']:,} kg |") L.append(f"| LKW-Volumen | {abh_cfg['lkw_volumen_m3']} m3 |") L.append(f"| Waerme je Tag (aus WP-Block) | {wp['speicher_kWh_tag']:.1f} kWh/Tag |") L.append("") L.extend(_h3("Formeln")) if pcm_cfg["modus"] == "latent_plus_hub": dt_uh = max(0.0, pcm_cfg["ladetemp_C"] - pcm_cfg["schmelzpunkt_C"]) dt_uk = max(0.0, pcm_cfg["schmelzpunkt_C"] - pcm_cfg["entladetemp_C"]) e_kj = (pcm_cfg["latentwaerme_kJ_pro_kg"] + pcm_cfg["cp_fluessig_kJ_pro_kgK"] * dt_uh + pcm_cfg["cp_fest_kJ_pro_kgK"] * dt_uk) L.extend(_code([ "Energiedichte (Modus latent_plus_hub):", " E = (L + cp_fl · ΔT_üh + cp_fest · ΔT_uk) / 3600 [kWh/kg]", " mit ΔT_üh = max(0, T_Lade − T_Schmelz) (Ueberhitzung, fluessig)", " ΔT_uk = max(0, T_Schmelz − T_Entlade) (Unterkuehlung, fest)", "", f" ΔT_üh = max(0, {pcm_cfg['ladetemp_C']:.0f} − {pcm_cfg['schmelzpunkt_C']:.0f})" f" = {dt_uh:.0f} K", f" ΔT_uk = max(0, {pcm_cfg['schmelzpunkt_C']:.0f} − {pcm_cfg['entladetemp_C']:.0f})" f" = {dt_uk:.0f} K", f" E = ({pcm_cfg['latentwaerme_kJ_pro_kg']:.0f}" f" + {pcm_cfg['cp_fluessig_kJ_pro_kgK']:.1f}·{dt_uh:.0f}" f" + {pcm_cfg['cp_fest_kJ_pro_kgK']:.1f}·{dt_uk:.0f}) / 3600" f" = {e_kj:.1f} / 3600" f" = {sp['energiedichte_kWh_pro_kg']*1000:.1f} Wh/kg", "", "Speichergroesse:", " E_Zyklus = Q_Speicher_Tag × Zyklus [kWh]", " m = E_Zyklus / E [kg]", " V = m / (ρ × 1000) [m³]", "", f" E_Zyklus = {wp['speicher_kWh_tag']:.1f} kWh/Tag × {z} Tage" f" = {sp['energie_pro_zyklus_kWh']:.0f} kWh", f" m = {sp['energie_pro_zyklus_kWh']:.0f}" f" / {sp['energiedichte_kWh_pro_kg']:.4f}" f" = {sp['masse_kg']:.0f} kg", f" V = {sp['masse_kg']:.0f}" f" / ({pcm_cfg['dichte_kg_pro_L']:.1f} × 1000)" f" = {sp['volumen_m3']:.1f} m³", ])) else: L.extend(_code([ "Energiedichte (Modus latent_only):", " E = L / 3600 [kWh/kg]", "", "Speichergroesse:", " E_Zyklus = Q_Speicher_Tag × Zyklus [kWh]", " m = E_Zyklus / E [kg]", " V = m / (ρ × 1000) [m³]", "", f" E_Zyklus = {wp['speicher_kWh_tag']:.1f} × {z}" f" = {sp['energie_pro_zyklus_kWh']:.0f} kWh", f" m = {sp['energie_pro_zyklus_kWh']:.0f}" f" / {sp['energiedichte_kWh_pro_kg']:.4f}" f" = {sp['masse_kg']:.0f} kg", f" V = {sp['masse_kg']:.0f}" f" / ({pcm_cfg['dichte_kg_pro_L']:.1f} × 1000)" f" = {sp['volumen_m3']:.1f} m³", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kenngroesse", "Wert"])) L.append(f"| Energiedichte | {sp['energiedichte_kWh_pro_kg']*1000:.1f} Wh/kg |") L.append(f"| Energie je Zyklus ({z} Tage) | {sp['energie_pro_zyklus_kWh']:.0f} kWh |") L.append(f"| Masse | **{sp['masse_kg']:.0f} kg** |") L.append(f"| Volumen | **{sp['volumen_m3']:.1f} m3** |") L.append(f"| LKW-Auslastung Gewicht | {sp['auslastung_gewicht']*100:.0f} % |") L.append(f"| LKW-Auslastung Volumen | {sp['auslastung_volumen']*100:.0f} % |") L.append(f"| Bindende Grenze | {sp['bindende_grenze']} |") L.append(f"| Passt in einen LKW | {passt} |") L.append(f"| Voller LKW nach | {sp['voller_lkw_tausch_tage']:.1f} Tagen |") L.append(f"| Energieinhalt voller LKW | {sp['voller_lkw_energie_kWh']:.0f} kWh |") if sp.get("empf_zyklus_tage") is not None: L.append("") L.append(f"**empfohlene Zyklenzahl = {sp['empf_zyklus_tage']} Tage**" f" (ergibt ≥ 90 % LKW-Auslastung)") # ── Haushalte ──────────────────────────────────────────────────── L.extend(_h2(f"Versorgte Haushalte" f" ({hh_cfg['erwachsene']} Erw. + {hh_cfg['kinder']} Kinder)")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| Erwachsene je Haushalt | {hh_cfg['erwachsene']} |") L.append(f"| Kinder je Haushalt | {hh_cfg['kinder']} |") L.append(f"| WW-Bedarf Erwachsener | {hh_cfg['ww_erwachsener_kWh_tag']:.1f} kWh/Tag |") L.append(f"| WW-Bedarf Kind | {hh_cfg['ww_kind_kWh_tag']:.1f} kWh/Tag |") L.append(f"| Heizbedarf Winter | {hh_cfg['heizbedarf_winter_kWh_tag']:.0f} kWh/Tag/HH |") L.append(f"| Waerme je Tag (aus WP-Block) | {wp['speicher_kWh_tag']:.1f} kWh/Tag |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "WW_je_HH = n_Erw × WW_Erw + n_Kind × WW_Kind [kWh/Tag]", "HH_WW = Q_Speicher / WW_je_HH [Haushalte, ganzjaehrig]", "HH_Winter = Q_Speicher / (WW_je_HH + Heiz_Winter) [Haushalte, Winter]", "", f"WW_je_HH = {hh_cfg['erwachsene']} × {hh_cfg['ww_erwachsener_kWh_tag']:.1f}" f" + {hh_cfg['kinder']} × {hh_cfg['ww_kind_kWh_tag']:.1f}" f" = {hh['ww_pro_haushalt_kWh_tag']:.1f} kWh/Tag", f"HH_WW = {wp['speicher_kWh_tag']:.1f}" f" / {hh['ww_pro_haushalt_kWh_tag']:.1f}" f" = {hh['haushalte_warmwasser']:.1f} HH", f"HH_Winter = {wp['speicher_kWh_tag']:.1f}" f" / {hh['winter_pro_haushalt_kWh_tag']:.1f}" f" = {hh['haushalte_winter']:.1f} HH", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kenngroesse", "Wert"])) L.append(f"| WW-Bedarf je Haushalt | {hh['ww_pro_haushalt_kWh_tag']:.1f} kWh/Tag |") L.append(f"| Winterbedarf je Haushalt (Heiz+WW) | {hh['winter_pro_haushalt_kWh_tag']:.1f} kWh/Tag |") L.append(f"| Versorgte HH (Warmwasser, ganzjaehrig) | **{hh['haushalte_warmwasser']:.1f}** |") L.append(f"| Versorgte HH (Heizung + WW, Winter) | **{hh['haushalte_winter']:.1f}** |") # ── Wert beim Käufer ───────────────────────────────────────────── bk = e.get("brennstoffkosten") if bk and bk["vergleich"]: L.extend(_h2("Wert der Waerme beim Kaeufer (Ersatzkosten fossil/Holz)")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Brennstoff", "Preis ct/kWh", "Kesselwirkungsgrad"])) for b in cfg.get("brennstoffe", []): L.append(f"| {b['name']} | {b['preis_ct_kWh']:.1f} | {b['wirkungsgrad']*100:.0f} % |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "Nutzwaermekosten = Preis_ct_kWh / Wirkungsgrad [ct/kWh]", "EUR_je_LKW = E_LKW_kWh × Nutzwaermekosten / 100 [EUR]", "EUR_je_Jahr = E_Jahr_kWh × Nutzwaermekosten / 100 [EUR/a]", ])) L.extend(_h3("Ergebnisse")) L.append(f"Bewertet: voller LKW **{bk['energie_lkw_kWh']:.0f} kWh**," f" Jahreserzeugung **{bk['energie_jahr_kWh']:.0f} kWh/a**") L.append("") L.extend(_tbl_header(["Brennstoff", "ct/kWh (Nutzw.)", "EUR/LKW", "EUR/Jahr"])) for v in bk["vergleich"]: L.append(f"| {v['name']} | {v['nutzwaerme_ct_kWh']:.1f} |" f" {v['eur_pro_lkw']:.0f} | {v['eur_pro_jahr']:.0f} |") # ── Gestehungskosten Anbieter ──────────────────────────────────── ak = e.get("anbieter") if ak: inv = cfg["anbieter"]["invest"] ci = ak["container_invest"] sd = ak["kosten_strom_detail"] L.extend(_h2("Waerme-Gestehungskosten Anbieter")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| Transport je Fuhre | {cfg['anbieter']['transport_eur_pro_fuhre']:.0f} EUR |") L.append(f"| Netzstrompreis | {cfg['anbieter']['netzstrompreis_ct_kWh']:.0f} ct/kWh |") L.append(f"| PV-Gestehungskosten (LCOE) | {cfg['anbieter']['pv_gestehung_ct_kWh']:.0f} ct/kWh |") L.append(f"| Wartung pauschal | {cfg['anbieter']['wartung_eur_pro_jahr']:.0f} EUR/a |") L.append(f"| PV-Invest | {inv['pv_eur_pro_kWp']} EUR/kWp," f" {inv['pv_nutzungsdauer_jahre']} J Nutzung |") L.append(f"| Batterie-Invest | {inv['batterie_eur_pro_kWh']} EUR/kWh," f" {inv['batterie_nutzungsdauer_jahre']} J |") L.append(f"| WP-Invest | {inv['waermepumpe_eur']:,} EUR," f" {inv['waermepumpe_nutzungsdauer_jahre']} J |") L.append(f"| Speicher-Invest | {ci['anzahl_module']} Module," f" {inv['speicher_nutzungsdauer_jahre']} J Nutzung |") if ak["eh_da"]: L.append("| ~~Kapital PV~~ | *eh-da: bereits vorhanden, entfaellt* |") L.append("| ~~Kapital WP~~ | *eh-da: bereits vorhanden, entfaellt* |") if ak["driver"]: L.append(f"| Fahrerabzug | {ak['fahrer_abzug_eur_pro_fuhre']:.0f} EUR/Fuhre" f" (--driver: Betreiber oder Landwirt faehrt selbst) |") L.append("") L.append("**Aufschluesselung Speicher-Invest**") L.append("") L.extend(_tbl_header(["Komponente", "EUR (alle Module)"])) L.append(f"| PCM ({sp['masse_kg']:.0f} kg × {ci['anzahl_module']} Module)" f" | {ci['pcm_eur']:,.0f} |") L.append(f"| Behaelter (isoliert, LKW-tauglich) | {ci['behaelter_eur']:,.0f} |") L.append(f"| Waermetauscher + Hydraulik | {ci['wt_hydraulik_eur']:,.0f} |") L.append(f"| Elektronik / Regelung | {ci['elektronik_eur']:,.0f} |") L.append(f"| Montage + Inbetriebnahme | {ci['montage_eur']:,.0f} |") L.append(f"| **Gesamt** | **{ci['gesamt_eur']:,.0f}** |") L.append(f"| entspricht | {ci['eur_pro_kwh_kapazitaet']:.0f} EUR/kWh Speicherkapazitaet |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "Kapital_X = Invest_X / Nutzungsdauer_X [EUR/a] (lineare AfA)", "Kosten_Transport = Fuhren_Jahr × Kosten_je_Fuhre [EUR/a]", "Kosten_Strom = kWh_Netz × p_Netz + kWh_PV × p_LCOE [EUR/a]", "Jahreskosten = Σ(alle Kostenblöcke) [EUR/a]", "", "Gestehungskosten = Jahreskosten / Energie_Jahr × 100 [ct/kWh]", "", f"Gestehungskosten = {ak['jahreskosten_eur']:.0f} EUR/a" f" / {ak['energie_jahr_kWh']:.0f} kWh/a × 100" f" = {ak['gestehungskosten_ct_kWh']:.1f} ct/kWh", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header(["Kostenblock", "EUR/Jahr"])) L.append(f"| Transport ({ak['fuhren_jahr']:.0f} Fuhren/a)" f" | {ak['kosten_transport_eur']:.0f} |") L.append(f"| WP-Strom ({sd['netz_kWh']:.0f} kWh Netz" f" + {sd['pv_kWh']:.0f} kWh PV-Eigen) | {ak['kosten_strom_eur']:.0f} |") L.append(f"| Wartung | {ak['kosten_wartung_eur']:.0f} |") L.append(f"| Kapital PV ({pv['kWp']:.1f} kWp) | {ak['kapital_pv_eur']:.0f} |") L.append(f"| Kapital Batterie ({bat['nominal_kWh']:.0f} kWh)" f" | {ak['kapital_batterie_eur']:.0f} |") L.append(f"| Kapital Waermepumpe | {ak['kapital_waermepumpe_eur']:.0f} |") L.append(f"| Kapital Speicher ({ci['anzahl_module']} Module)" f" | {ak['kapital_speicher_eur']:.0f} |") L.append(f"| **Jahreskosten gesamt** | **{ak['jahreskosten_eur']:.0f}** |") L.append("") L.append(f"**Jahreserzeugung:** {ak['energie_jahr_kWh']:.0f} kWh/a") L.append("") L.append(f"**Mindestverkaufspreis: {ak['gestehungskosten_ct_kWh']:.1f} ct/kWh**") # ── Marge ──────────────────────────────────────────────────── if ak["marge"]: L.extend(_h2("Marge gegen Ersatzbrennstoff")) L.extend(_h3("Voraussetzungen")) L.extend(_tbl_header(["Parameter", "Wert"])) L.append(f"| Mindestverkaufspreis (aus Gestehungskosten)" f" | {ak['gestehungskosten_ct_kWh']:.1f} ct/kWh |") for m in ak["marge"]: L.append(f"| Nutzwaerme {m['name']} | {m['nutzwaerme_ct_kWh']:.1f} ct/kWh |") L.append("") L.extend(_h3("Formeln")) L.extend(_code([ "Marge_ct = Nutzwaerme_Brennstoff − Gestehungskosten [ct/kWh]", " Positiv = System kostendeckend gegenueber diesem Brennstoff", "Marge_EUR = Marge_ct × Energie_Jahr / 100 [EUR/a]", ])) L.extend(_h3("Ergebnisse")) L.extend(_tbl_header( ["Brennstoff", "ct/kWh (Nutzw.)", "Marge ct/kWh", "Marge EUR/Jahr"])) for m in ak["marge"]: L.append(f"| {m['name']} | {m['nutzwaerme_ct_kWh']:.1f} |" f" {m['marge_ct_kWh']:+.1f} | {m['marge_eur_jahr']:+.0f} |") return "\n".join(L)