[[Uebersicht|← Zurück zur Homepage]]
# Batterien-Ladepreis-Buchhaltung
> [!info] Kurzfassung
> Berechnet für jede Marstek-Batterie fortlaufend, zu welchem Durchschnittspreis die aktuell gespeicherte Energie tatsächlich eingekauft wurde. **Status:** Buchhaltung ✅ aktiv & verifiziert — die darauf aufbauende Entscheidungslogik ist noch **offen** (siehe [Offener nächster Schritt](#offener-nächster-schritt)).
## Zweck
Für jede der drei Marstek-Batterien (MTV01/02/03) wird laufend eine **Kostenbasis** der gespeicherten Energie geführt: zu welchem tatsächlichen Durchschnittspreis (ct/kWh) wurde der aktuelle Bestand geladen. Dabei zählt nur der **Netzbezug-Anteil** einer Ladung als Kosten — PV-geladene Energie ist kostenlos.
Aktuell läuft ausschließlich diese Buchhaltung. Der ermittelte `ladepreis_durchschnitt` soll später zwei Entscheidungen unterstützen:
1. **Nächster Ladezyklus:** Lohnt sich Nachladen zum aktuellen Preis, oder ist der Bestand ohnehin schon günstiger?
2. **Laufende Verbrauchsdeckung (Haupt-Anwendungsfall):** Soll der aktuelle Hausverbrauch aus dem **Netz** oder aus der **Batterie** gedeckt werden? Dazu wird der aktuelle Netzpreis mit dem `ladepreis_durchschnitt` verglichen. Im Unterschied zur bestehenden [[04 Akku-Lade-Sperre|Akku-Lade-Sperre]] — die rein preisniveau-basiert und ladepreisunabhängig arbeitet — berücksichtigt diese Entscheidung den tatsächlichen Einkaufspreis des Bestands statt nur das Tibber-Preisniveau.
**Abgrenzung zur [[04 Akku-Lade-Sperre|Akku-Lade-Sperre]]:** Dort gilt der Break-Even-Ladepreis bewusst **nicht** als Preis-Floor fürs Entladen (Ladekosten sind sunk cost). Diese neue Buchhaltung widerspricht dem nicht — sie macht nur den tatsächlichen Einkaufspreis sichtbar, greift aber (noch) nicht in die Lade-/Entladeentscheidung ein.
**Design-Grundsatz:** Bewusst unabhängig von der Omnibattery-Integration (Drittanbieter-Code) — nutzt ausschließlich native `marstek_modbus`-Sensoren und den rohen Smartmeter, keine `sensor.marstek_venus_system_*`- oder `number.omnibattery_*`-Entities.
## Konfiguration
- **Automation:** `automations.yaml`, ID `1783000000001`, Alias „Ladebetrag-Buchhaltung Batterien", `mode: queued` (max. 10)
- **Helfer:** `ladezyklus_input_number.yaml` (neu, per `input_number: !include` in `configuration.yaml` eingebunden) → `input_number.mtv01/02/03_ladebetrag` (Einheit ct, min 0, max 500)
- **Template-Sensoren:** `template_sensors.yaml` → `sensor.mtv01/02/03_ladepreis_durchschnitt` (ct/kWh)
- **Init-Script:** `scripts.yaml` → `script.ladebetrag_initialisieren` (einmalig auszuführen, überschreibt vorhandene Werte)
- **HA-Zugriff:** über Samba-Share `\\192.168.2.154\config` (siehe [[project_ha_claude_mcp]] in Claude-Memory)
## Sensoren
| Sensor | Bedeutung |
|---|---|
| `sensor.mtv0X_ac_power` | AC-Momentanleistung je Batterie (W, negativ = Ladung, positiv = Entladung) |
| `sensor.mtv0X_total_charging_energy` / `_discharging_energy` | Kumulative Lade-/Entladeenergie je Batterie (kWh), löst die Automation aus |
| `sensor.mtv0X_stored_energy` | Aktuell gespeicherte Energie je Batterie (kWh), live vom Gerät — dient direkt als Nenner, kein eigener Zähler |
| `sensor.electricity_arenberger_str_230a_gesamtleistung` | Momentanleistung Netzbezug gesamt Haus (roher inexogy-Smartmeter, wird bei PV-Export negativ) |
| `sensor.daheim_aktueller_strompreis` | Tibber-Live-Preis (ct/kWh) |
## Formel
Bei jeder Änderung von `total_charging_energy` oder `total_discharging_energy` einer Batterie:
1. `P_charge_i = max(0, −ac_power_i)` für alle drei Batterien
2. `grid_power = max(0, Gesamtleistung)` (Export/negative Werte zählen als 0 Netzbezug)
3. `grid_charge_gesamt = min(Σ P_charge_i, grid_power)`
4. `grid_fraction = grid_charge_gesamt / Σ P_charge_i` (0 falls Ladeleistung insgesamt 0) — **gleicher Faktor für alle drei Batterien**, angewandt auf die jeweils eigene Energie-Zuwachs-Delta
**Bei Ladung:**
`ladebetrag_i += Δcharge_i × grid_fraction × aktueller_preis`
**Bei Entladung:**
`avg_price_i = ladebetrag_i / stored_energy_i` (0 falls stored_energy ≤ 0)
`ladebetrag_i = max(0, ladebetrag_i − Δdischarge_i × avg_price_i)`
→ Der Durchschnittspreis (`ladepreis_durchschnitt = ladebetrag / stored_energy`) bleibt bei reiner Entnahme **unverändert** (Lagerbuchhaltungs-Prinzip: FIFO-artiger gewichteter Durchschnitt statt Einzelposten).
## Design-Entscheidungen
- **Pro Batterie getrennt**, nicht aggregiert — ermöglicht später individuelle Lade-/Entladesteuerung je Batterie.
- **kWh-Seite:** Live-Sensor `stored_energy` statt eigenem Zähler — selbstkorrigierend, da das Gerät bei Balancing/Vollladung neu kalibriert; eine eigene Mitzählung würde mit der Zeit driften.
- **Nur der Betrag (ct) wird persistiert**, als `input_number` — überlebt HA-Neustarts nativ (Restore-State), ohne zusätzlichen Mechanismus.
- **Startwert:** `stored_energy (aktuell) × aktueller Tibber-Preis` — neutrale Annahme "als wäre der Bestand heute geladen worden", da die Vorgeschichte unbekannt ist.
- **Kein fixer Tages-Cutoff** in diesem Schritt — die Buchhaltung läuft kontinuierlich; ein Cutoff kann bei Bedarf in der späteren Entscheidungslogik ergänzt werden.
## Verifikation (2026-07-12)
Live beobachtet während eines laufenden Ladevorgangs von MTV01 (~987 W Ladeleistung, aber nur ~20 W Netzbezug — überwiegend PV):
- Ladeenergie stieg um 0,01 kWh → `ladebetrag` stieg nur um **0,0059 ct** (nicht um den vollen Betrag) — Netz/PV-Trennung funktioniert korrekt
- `ladepreis_durchschnitt` neu berechnet: 57,043 ct / 3,43 kWh = **16,63 ct/kWh** — rechnerisch stimmig
- Init-Werte korrekt gesetzt (z. B. MTV01: 3,379 kWh × 16,88 ct = 57,04 ct)
Der Entlade-Pfad nutzt denselben Codepfad, war zum Zeitpunkt der Doku aber noch nicht durch einen echten Entladevorgang live bestätigt (alle drei Batterien luden gerade).
## Bekannte Einschränkung
`grid_fraction` ist eine Näherung auf Basis der Momentanleistung zum Zeitpunkt des Trigger-Events, nicht eine echte Integration über das Intervall — bei schnell schwankender PV-Einstrahlung zwischen zwei Trigger-Events kann der zugeordnete Netzanteil leicht von der tatsächlichen Energie abweichen. Bei der üblichen Update-Frequenz der Energiezähler (im Minutenbereich) ist die Abweichung klein.
## Offener nächster Schritt
Entscheidungslogik, noch nicht spezifiziert. Zwei Anwendungsfälle (siehe Zweck):
- Vergleich `ladepreis_durchschnitt` mit dem erwarteten Preis des nächsten Ladezyklus, um zu entscheiden ob Nachladen sich lohnt.
- Vergleich `ladepreis_durchschnitt` mit dem aktuellen Netzpreis, um laufend zu entscheiden ob der Hausverbrauch aus Netz oder Batterie gedeckt wird — vermutlich als Ergänzung/Ersatz der reinen Preisniveau-Logik in der [[04 Akku-Lade-Sperre|Akku-Lade-Sperre]].
## Tags
`#homeassistant` `#marstek` `#automation` `#tibber` `#ladepreis` `#buchhaltung`
---
## Versionshistorie
| Version | Datum/Uhrzeit | Änderung |
|---|---|---|
| v1.0 | 2026-07-12 13:30 | Erstversion: Helper, Template-Sensoren, Automation und Init-Script angelegt, live verifiziert |
| v1.1 | 2026-07-12 13:45 | Zweck präzisiert: Ladepreis dient nicht nur der Ladezyklus-Entscheidung, sondern vor allem der laufenden Entscheidung Netzbezug vs. Batterieentladung für den aktuellen Verbrauch |
| v1.2 | 2026-07-12 13:33 | Sprachlich optimiert: Titel vereinheitlicht, Kurzfassungs-Callout mit Status ergänzt, „Zweck"-Absatz flüssiger strukturiert |
---
[[Impressum|Impressum]] | [[Datenschutzerklärung|Datenschutz]]