# PV Peak-Shave – Implementierungsvorlage für Home Assistant

---

## Aufgabe

Dieses Dokument beschreibt die Grundlagen um folgende Komponenten entwickeln zu können:
1. Home Assistant Blueprint (`pv_peak_shave.yaml`)
2. Logging-Automation (`peakshave_log.yaml`)

**Vorgehen:** Mit dieser Checkliste kannst du dir den Status deines Systems erarbeiten, da alle Sensor-Namen und Schwellwerte angepasst werden müssen.

---

## Checkliste (vor Implementierungsbeginn klären)

| # | Punkt | Beschreibung |
|---|---|---|
| 1 | WR-Modell und HA-Integration | z.B. Huawei Solar via HACS |
| 2 | Entity-ID: Betriebsmodus-Select | Zum Schalten des WR-Modus |
| 3 | Entity-ID: Max-Laden-Number | In W |
| 4 | Entity-ID: PV-Leistung aktuell | In W |
| 5 | Entity-ID: SOC | In % |
| 6 | Entity-ID: Netzbezug aktuell | Einheit angeben: W oder kW |
| 7 | Entity-ID: Restprognose kWh (primär) | Welcher Forecast-Dienst? |
| 8 | Entity-ID: Restprognose kWh (Fallback) | Zweiter Dienst falls primärer offline |
| 9 | Peak-Zeitpunkt-Sensor | Sensor oder `today_at('12:00')` als Fallback |
| 10 | `akku_kwh` | Nutzbare Kapazität in kWh |
| 11 | Entity-IDs: 5 Hardware-Zähler | PV, Netzbezug, Einspeisung, Akku-Ladung, Akku-Entladung – direkt vom WR |
| 12 | Dateipfad CSV-Log | z.B. `/config/peakshave_log.csv` |
| 13 | Blueprint-Name | Wird nie mehr geändert |
| 14 | HA-Helfer | `input_boolean.peakshave_analyse_modus` – neu anlegen oder vorhanden? |

---

## Begriffe

| Begriff | Formel / Beschreibung |
|---|---|
| Tick | Blueprint läuft alle 5 Minuten. Alle Regeln werden ausschließlich beim Tick ausgewertet. |
| Entladeleistung | `max(0, WR-Limit kW - Hausverbrauch kW - PV kW)` |
| Notwendige Zeit | `max(0, (SOC - Min SOC) / 100 * akku_kwh / Entladeleistung_kW * 60)` in Minuten. Bei Entladeleistung = 0 → 999 min. |
| DauerA | Verbleibende Zeit bis formalen B-Start. In Zone B immer ≤ 0. |
| PrognoseOK | Restprognose >= Akkuladung + Zeit bis Sonnenuntergang * Hausverbrauch  `Restprognose >= (100 - min_soc) / 100 * akku_kwh + (Sonnenuntergang - Jetzt) / 3600 * hausverbrauch_kw` |
| Rang | Regeln werden in aufsteigender Reihenfolge geprüft. Erste zutreffende Regel gewinnt. Keine Regel → letzter Zustand bleibt. |
| Min SOC | 15% – muss identisch als Hardware-End-of-Discharge-SOC im WR konfiguriert sein. |
| SOC Puffer | 30% – Ziel-SOC in Zone A. |
| Eigenverbrauch | Huawei-Modus `maximise_self_consumption` |
| Einspeisen | Huawei-Modus `fully_fed_to_grid` – Akku entlädt ins Netz. Max-Laden hat keinen Einfluss. |
| sensoren_ok | Prüft nur kritische Hardware-Sensoren (SOC, Modus, Max-Laden, Netzbezug, PV). Forecast-Sensoren nicht einbeziehen. |

---

## Zeiträume

| Zone | Von | Bis |
|---|---|---|
| A | Sonnenaufgang − 60 Min | Peak − Intervall/2 − Notwendige Zeit |
| B | Peak − Intervall/2 − Notwendige Zeit | Peak − Intervall/2 |
| C | Peak − Intervall/2 | Peak + Intervall/2 |
| D | Peak + Intervall/2 | Sonnenuntergang |
| E | Sonnenuntergang | Sonnenaufgang − 60 Min |

---

## Regeln

| Zeitraum | Rang | Status | Bedingung | Modus | Max-Laden |
|---|---|---|---|---|---|
| Immer | 0 | sensoren_ok = false | | Eigenverbrauch | 5000 |
| Immer | 1 | Netzbezug > Schwelle | | Eigenverbrauch | 5000 |
| A | 2 | SOC < Min SOC | | Eigenverbrauch | 5000 |
| A | 3 | SOC < Puffer SOC | | Eigenverbrauch | 1000 |
| A | 4 | SOC > Puffer SOC | PrognoseOK | Einspeisen | 0 |
| A | 5 | – | – | Eigenverbrauch | 5000 |
| B | 2 | SOC < Min SOC | | Eigenverbrauch | 1000 |
| B | 3 | – | NOT PrognoseOK | Eigenverbrauch | 5000 |
| B | 4 | – | PrognoseOK | Einspeisen | 0 |
| B | 5 | – | – | Eigenverbrauch | 5000 |
| C | 2 | – | – | Eigenverbrauch | 5000 |
| D | 2 | – | – | Eigenverbrauch | 5000 |
| E | 2 | – | – | Eigenverbrauch | 0 |

**Rang 0:** Sicherheitszustand – setzt Eigenverbrauch + MaxLade 5000 und bricht den Tick ab. Verhindert dass MaxLade auf 0 bleibt wenn Hardware kurz offline ist.

**Rang 1:** Greift global vor allen Zonen-Regeln. Modus und Max-Laden in **separaten `if`-Blöcken** setzen – `choose` führt nur den ersten Block aus.

**A3 Max-Laden=1000 W:** Sanftes Pendeln um Puffer SOC. Verhindert sofortiges Auslösen von A4.

**A5 / B5:** Fallback ohne Bedingung. Verhindert dass Max-Laden=0 aus Zone E aktiv bleibt bzw. Float-Grenzfall bei SOC == min_soc.

**B4:** In Zone B ist DauerA immer ≤ 0 – die Bedingung `PrognoseOK` ist hinreichend.

**Zone E:** Kein Software-Min-SOC-Schutz. Hardware-End-of-Discharge-SOC im WR muss konfiguriert sein.

---

## Blueprint-Inputs

| Parameter | Default | Beschreibung |
|---|---|---|
| `wr_limit_kw` | 5.0 | WR-Limit in kW |
| `hausverbrauch_w` | 400 | Geschätzter Hausverbrauch in W |
| `min_soc` | 15 | Minimaler SOC in % |
| `puffer_soc` | 30 | Puffer SOC in % |
| `lade_offset_min` | 165 | Intervall/2 in Minuten |
| `netzbezug_schwelle_w` | 1000 | Schwelle für echten Netzbezug in W |

---

## Implementierungshinweise

- Blueprint-Inputs als Variablen: `variable_name: !input input_name`
- `akku_kwh` ist eine feste Konstante – kein Blueprint-Input
- Variablen-Reihenfolge: `now_ts` und `sunset_ts` vor `prognose_ok` definieren
- Sonnenaufgang: wenn `next_rising > now + 43200` → `next_rising - 86400`
- Sonnenuntergang: wenn `next_setting > now + 72000` → `next_setting - 86400` (20h-Schwelle wegen Sommer-Sonnenuntergänge bis ~21:30)
- Peak-Fallback: `today_at('12:00')` – nicht `next_noon` (zeigt nach Mittag auf morgen)
- Forecast-Fallback: primären Dienst mit `| float(-1)` prüfen, bei negativem Ergebnis auf Sekundärdienst wechseln
- `shell_command` funktioniert nicht aus Blueprint-Automationen → Logging in separater Automation
- Betriebsmodus-Strings: `maximise_self_consumption` / `fully_fed_to_grid` – Kleinschreibung mit Unterstrichen

**Kritische Fallstricke:**
- `sensoren_ok` zu streng: Forecast-Sensoren nicht einbeziehen – sonst bricht der Tick bei Cloud-Ausfall ab und A2 (SOC-Schutz) greift nicht mehr
- Wechselrichter Modus und Max-Laden-Wert nur setzen wenn er sich geändert hat.

---

## Logging

**Architektur:** Separate Automation – triggert auf Zustandsänderungen von Modus und Max-Laden. Optional: `time_pattern` alle 5 Minuten wenn `input_boolean.peakshave_analyse_modus` aktiv.

**CSV-Felder:**

| Feld | Einheit | Beschreibung |
|---|---|---|
| datum | YYYY-MM-DD | |
| zeit | HH:MM:SS | |
| zeitraum | A–E | |
| rang | – | Logging-Automation kennt Rang nicht |
| modus_neu / modus_alt | Text | Alt = neu beim Tick |
| max_laden_neu / max_laden_alt | W | Alt = neu beim Tick |
| soc | % | |
| pv_w | W | |
| netzbezug_live | kW | |
| einspeisung_live | kW | |
| prognose_ok | true/false | |
| restprognose_kwh | kWh | Mit Forecast-Fallback |
| peak_zeit | HH:MM | Leer wenn Fallback aktiv |
| notwendige_zeit_min | min | 999 wenn Entladeleistung = 0 |
| grund | Text | `zustandsaenderung` / `tick_analyse` / `sensoren_fehlen` |
