schalter --eh-da und --driver dazu
This commit is contained in:
+180
-8
@@ -20,8 +20,12 @@ def _tbl_header(cols: list[str]) -> list[str]:
|
||||
" | ".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 erst Voraussetzungen, dann Ergebnisse."""
|
||||
"""Vollstaendiger Markdown-Report: je Block Voraussetzungen → Formeln → Ergebnisse."""
|
||||
q = e["milch_kuehllast_kWh_tag"]
|
||||
wp = e["waermepumpe"]
|
||||
sp = e["speicher"]
|
||||
@@ -57,6 +61,16 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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** |")
|
||||
@@ -69,6 +83,26 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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 |")
|
||||
@@ -85,6 +119,16 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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 |")
|
||||
@@ -101,6 +145,18 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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} %** |")
|
||||
@@ -122,6 +178,22 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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 |")
|
||||
@@ -147,6 +219,62 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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 |")
|
||||
@@ -159,6 +287,10 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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"
|
||||
@@ -172,6 +304,22 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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 |")
|
||||
@@ -188,8 +336,12 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
for b in cfg.get("brennstoffe", []):
|
||||
L.append(f"| {b['name']} | {b['preis_ct_kWh']:.1f} | {b['wirkungsgrad']*100:.0f} % |")
|
||||
L.append("")
|
||||
L.append("*Nutzwaermekosten = Brennstoffpreis ÷ Kesselwirkungsgrad*")
|
||||
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**")
|
||||
@@ -220,6 +372,12 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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("")
|
||||
@@ -233,8 +391,19 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
L.append(f"| **Gesamt** | **{ci['gesamt_eur']:,.0f}** |")
|
||||
L.append(f"| entspricht | {ci['eur_pro_kwh_kapazitaet']:.0f} EUR/kWh Speicherkapazitaet |")
|
||||
L.append("")
|
||||
L.append("*Abschreibung: linear, kein Kapitalzins.*")
|
||||
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)"
|
||||
@@ -264,10 +433,13 @@ def report_md(e: dict, cfg: dict, quelldateien: list[str] | None = None) -> str:
|
||||
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.append("Marge = Nutzwaermekosten Brennstoff − Mindestverkaufspreis."
|
||||
" Positiv = System kostendeckend.")
|
||||
L.append("")
|
||||
L.extend(_tbl_header(
|
||||
["Brennstoff", "ct/kWh (Nutzw.)", "Marge ct/kWh", "Marge EUR/Jahr"]))
|
||||
for m in ak["marge"]:
|
||||
|
||||
Reference in New Issue
Block a user