Update: Battery Optimizer v3.4.0 mit allen Fixes und Features

This commit is contained in:
felix.zoesch
2025-12-12 08:20:19 +01:00
commit d2a41aad2d
78 changed files with 18053 additions and 0 deletions

458
SOC_CALIBRATION_GUIDE.md Normal file
View File

@@ -0,0 +1,458 @@
# SOC-Kalibrierung & Drift-Management
## Problem: SOC ist berechnet, nicht gemessen
### Wie SOC funktioniert
Der State of Charge (SOC) wird vom Battery Management System (BMS) **berechnet**, nicht direkt gemessen:
**Berechnungsmethoden:**
1. **Coulomb Counting** (Hauptmethode)
- Integriert Strom über Zeit: ∫ I(t) dt
- Geladen mit 5A für 1h = +5Ah
- Entladen mit 3A für 1h = -3Ah
- Netto: +2Ah → SOC steigt um ~2%
2. **Spannungsbasiert** (Open Circuit Voltage)
- Zellspannung korreliert mit SOC
- 4.2V/Zelle ≈ 100% SOC
- 3.2V/Zelle ≈ 0% SOC (Minimum)
3. **Kalman-Filter / State Estimation**
- Kombiniert beide Methoden
- Berücksichtigt Temperatur, Alterung, Laderate
### Warum SOC abweicht (Drift)
**Hauptursachen:**
| Ursache | Effekt | Beispiel |
|---------|--------|----------|
| **Keine vollen Zyklen** | BMS verliert Referenzpunkte | Immer 30-92%, nie 20-100% |
| **Coulomb Counting Fehler** | Akkumuliert über Zeit | 0.1% Fehler/Tag = 3% nach 1 Monat |
| **Temperatur** | Kapazität ändert sich | 10kWh bei 20°C, 9.5kWh bei 5°C |
| **Alterung** | Tatsächliche Kapazität sinkt | 10kWh neu, 9.2kWh nach 3 Jahren |
| **Strommessung** | Sensorfehler (±1-2%) | 5.0A gemessen, 5.1A real |
| **Selbstentladung** | Nicht im SOC berücksichtigt | 1-2%/Monat |
**Beispiel SOC-Drift:**
```
Tag 1: BMS kalibriert, SOC = 100% (korrekt)
Tag 5: SOC = 95% (BMS sagt), real = 96% (+1% Drift)
Tag 10: SOC = 88% (BMS sagt), real = 91% (+3% Drift)
Tag 30: SOC = 65% (BMS sagt), real = 72% (+7% Drift)
→ Nach Vollladung: Kalibriert sich neu
```
## GoodWe-spezifische Einstellungen
### Hardware-seitiges 20% Minimum
Du hast im GoodWe eingestellt:
- **Minimum SOC: 20%**
- **Entladung stoppt bei 20%**
- **Freigabe nur bei Netzausfall**
**Bedeutung:**
```
┌─────────────────────────────────────┐
│ 100% ← Hardware-Maximum │
│ ↕ │
│ 80% ← Nutzbare Kapazität │
│ ↕ │
│ 20% ← Hardware-Minimum │ ← GoodWe stoppt hier!
│ ↓ │
│ 0% ← Nur bei Netzausfall │
└─────────────────────────────────────┘
```
**Effektive Kapazität:**
- Physisch: 10 kWh (100%)
- Nutzbar: 8 kWh (80% von 20-100%)
- Reserve für Netzausfall: 2 kWh (20%)
### Integration mit unserem Optimizer
**Unser Optimizer:**
- `min_soc: 20%` (redundant, aber konsistent)
- `max_soc: 100%`
- `reserve_capacity: 2 kWh` (entspricht 20%)
**Das passt perfekt zusammen!**
## Auswirkungen auf die Optimierung
### Problem 1: Ungenaue Planung
**Szenario:**
```
14:05 Uhr (Planung):
BMS zeigt: SOC 30%
Real: SOC 35% (5% Drift)
Optimizer plant: (100 - 30) × 10kWh - 2kWh = 6.8 kWh
Tatsächlich braucht: (100 - 35) × 10kWh - 2kWh = 6.3 kWh
→ Plant 500Wh zu viel
→ Nutzt eventuell 1 Stunde mehr als nötig
→ Könnte teurere Stunde nutzen
```
### Problem 2: Keine Kalibrierung durch Teilzyklen
**Typischer Tagesablauf (OHNE Kalibrierung):**
```
07:00 → SOC 92% (nicht 100% erreicht)
↓ PV-Produktion überschuss lädt minimal
09:00 → SOC 95% (immer noch nicht 100%)
↓ PV reicht für Eigenverbrauch
12:00 → SOC 93% (leicht entladen)
↓ Eigenverbrauch übersteigt PV
18:00 → SOC 65% (Eigenverbrauch ohne PV)
↓ Weiterer Eigenverbrauch
22:00 → SOC 45% (vor Laden)
↓ Günstige Stunden: Laden
23:00 → SOC 60% (teilweise geladen)
00:00 → SOC 75% (weiter geladen)
↓ Auto-Modus
07:00 → SOC 92% (nicht 100%)
→ Kein voller Zyklus!
→ BMS hat keine Referenzpunkte
→ SOC driftet weiter
```
## Lösungen
### Lösung 1: Höherer Sicherheitspuffer (Sofort umsetzbar)
**Empfehlung: 25-30% statt 20%**
```yaml
input_number:
battery_optimizer_safety_buffer:
initial: 30 # Statt 20
```
**Begründung:**
- SOC kann um 5-10% abweichen
- Puffer kompensiert Drift
- Hardware stoppt sowieso bei 100%
- Lieber eine Stunde mehr laden als 8% zu wenig
**Berechnung:**
```
Ohne Drift:
6.8 kWh × 1.20 = 8.16 kWh (20% Puffer)
Mit 5% Drift:
6.8 kWh × 1.30 = 8.84 kWh (30% Puffer)
→ Kompensiert Drift + normale Schwankungen
```
### Lösung 2: Monatliche Kalibrierung (Empfohlen)
**Automatischer Kalibrierungs-Zyklus:**
**Phase 1: Entladung** (natürlich durch Eigenverbrauch)
- Ziel: SOC auf ~20% bringen
- Dauer: Normalerweise 1-2 Tage
- Optimizer pausiert (Manual Override)
**Phase 2: Vollladung** (erzwungen, unabhängig von Preisen)
- Ziel: SOC auf 100% laden
- Dauer: 2-5 Stunden (je nach Start-SOC)
- Volle Ladeleistung (5kW)
**Phase 3: Kalibrierung** (automatisch durch BMS)
- BMS erkennt: Zellen bei 4.2V = 100% SOC
- Vergleicht mit berechnetem SOC
- Korrigiert Coulomb Counter
- Passt Kapazitäts-Schätzung an
**Ergebnis:**
- ✅ SOC wieder präzise
- ✅ BMS hat Referenzpunkte
- ✅ Tatsächliche Kapazität bekannt
- ✅ Drift zurückgesetzt
**Häufigkeit:**
- **Minimum**: Alle 3 Monate
- **Empfohlen**: Jeden Monat
- **Bei Bedarf**: Wenn SOC merklich abweicht
**Installation:** Siehe `battery_calibration_automation.yaml`
### Lösung 3: SOC-Monitoring (Automatisch)
**Erkenne SOC-Drift automatisch:**
```yaml
# Automation: SOC-Drift-Detektor
alias: "Batterie: SOC-Drift Warnung"
description: "Warnt wenn SOC wahrscheinlich driftet"
trigger:
# Wenn Batterie "voll" ist aber nicht 100%
- platform: state
entity_id: input_boolean.goodwe_manual_control
from: "on"
to: "off"
for:
minutes: 30
condition:
# SOC ist unter 98%
- condition: numeric_state
entity_id: sensor.esssoc
below: 98
# Aber Laden lief mehr als 2 Stunden
- condition: template
value_template: >
{% set duration = as_timestamp(now()) - as_timestamp(trigger.from_state.last_changed) %}
{{ duration > 7200 }}
action:
- service: notify.persistent_notification
data:
title: "SOC-Drift erkannt?"
message: >
Laden lief {{ ((as_timestamp(now()) - as_timestamp(trigger.from_state.last_changed)) / 3600) | round(1) }}h,
aber SOC ist nur {{ states('sensor.esssoc') }}%.
Eventuell SOC-Drift? Kalibrierung empfohlen.
```
## Installation der Kalibrierung
### Schritt 1: Input Helper erstellen
```yaml
# In configuration.yaml
input_boolean:
battery_calibration_active:
name: "Batterie Kalibrierung aktiv"
icon: mdi:battery-sync
initial: off
```
**Via UI:**
1. Einstellungen → Geräte & Dienste → Helfer
2. "Helfer hinzufügen" → "Toggle/Schalter"
3. Name: `Batterie Kalibrierung aktiv`
4. Entity ID: `input_boolean.battery_calibration_active`
5. Icon: `mdi:battery-sync`
### Schritt 2: Automations installieren
**Kopiere die 4 Automations aus** `battery_calibration_automation.yaml`:
1. Kalibrierung starten (jeden 1. des Monats)
2. Kalibrierungs-Laden (stündlich während aktiv)
3. Kalibrierung beenden (nach 24h oder bei 100%)
4. Notfall-Abbruch (bei kritisch niedrigem SOC)
**Via UI oder YAML:**
- UI: Einstellungen → Automationen & Szenen → Neue Automation → YAML-Modus
- YAML: In `automations.yaml` einfügen
### Schritt 3: Testen
**Manuelle Kalibrierung triggern:**
```yaml
# Developer Tools → Services
service: input_boolean.turn_on
target:
entity_id: input_boolean.battery_calibration_active
```
**Beobachte:**
1. Manual Override wird aktiviert
2. Batterie lädt auf 100%
3. Nach 24h oder bei 100%: Automatische Deaktivierung
## Best Practices
### Wann Kalibrierung durchführen?
**Automatisch:**
- ✅ Jeden Monat (1. des Monats)
- ✅ Nach Software-Updates
- ✅ Nach längeren Ausfällen
**Manuell:**
- ⚠️ Wenn SOC merklich abweicht
- ⚠️ Wenn Batterie nie 100% erreicht
- ⚠️ Wenn Kapazität sich verändert anfühlt
**Nicht nötig:**
- ❌ Wöchentlich (zu häufig)
- ❌ Wenn SOC präzise ist
- ❌ Bei normalen Teilzyklen
### Optimale Kalibrierungs-Bedingungen
| Faktor | Optimal | Warum |
|--------|---------|-------|
| **Temperatur** | 15-25°C | Beste Messgenauigkeit |
| **Laderate** | 0.5C (5kW bei 10kWh) | Minimiert Fehler |
| **Entladerate** | Natürlich (Eigenverbrauch) | Realistisch |
| **Dauer** | Mindestens 6h | BMS braucht Zeit |
### Was nach Kalibrierung zu erwarten ist
**Sofort:**
- ✅ SOC springt eventuell (z.B. 92% → 97%)
- ✅ BMS hat neue Referenzpunkte
- ✅ Kapazitäts-Schätzung aktualisiert
**In den nächsten Tagen:**
- ✅ Präziserer SOC
- ✅ Bessere Ladeplanung
- ✅ Weniger "überraschende" SOC-Werte
**Langfristig:**
- ✅ Verlangsamter Drift
- ✅ Längere Batterielebensdauer
- ✅ Genauere Kapazitäts-Prognosen
## Erweiterte Lösungen
### Adaptive Pufferberechnung
**Konzept:** Puffer basierend auf historischer Drift anpassen
```python
# Pseudo-Code für zukünftige Version
historical_drift = learn_from_last_30_days()
# Beispiel: SOC war durchschnittlich 5% höher als geplant
adaptive_buffer = base_buffer + historical_drift
# 20% + 5% = 25%
# Plane mit adaptivem Puffer
capacity_with_buffer = capacity × (1 + adaptive_buffer)
```
### SOC-Validierung über Spannung
**Konzept:** Vergleiche BMS-SOC mit Zellspannung
```yaml
# Sensor für SOC-Validierung
sensor:
- platform: template
sensors:
battery_soc_validated:
friendly_name: "SOC (validiert)"
unit_of_measurement: "%"
value_template: >
{% set soc = states('sensor.esssoc') | float %}
{% set voltage = states('sensor.battery_voltage') | float %}
{# Validiere SOC gegen Spannung #}
{% if voltage > 54.0 and soc < 95 %}
{{ 'SOC zu niedrig (Voltage hoch)' }}
{% elif voltage < 50.0 and soc > 30 %}
{{ 'SOC zu hoch (Voltage niedrig)' }}
{% else %}
{{ soc }}
{% endif %}
```
### Batterie-Gesundheits-Tracking
**Konzept:** Überwache tatsächliche Kapazität über Zeit
```yaml
# Berechne echte Kapazität aus Vollzyklus
sensor:
- platform: template
sensors:
battery_true_capacity:
friendly_name: "Wahre Batterie-Kapazität"
unit_of_measurement: "kWh"
value_template: >
{% if is_state('input_boolean.battery_calibration_active', 'on') %}
{# Nach Vollzyklus: Berechne Energie geladen #}
{% set energy = states('sensor.battery_charged_energy') | float %}
{% set soc_diff = 80 %} {# 20% → 100% #}
{{ (energy / (soc_diff / 100)) | round(2) }}
{% else %}
{{ states('input_number.battery_capacity_kwh') }}
{% endif %}
```
## Zusammenfassung
### Empfohlene Maßnahmen
| Priorität | Maßnahme | Aufwand | Nutzen |
|-----------|----------|---------|--------|
| 🔴 **HOCH** | Puffer auf 30% erhöhen | 1 min | Sofort bessere Ergebnisse |
| 🟡 **MITTEL** | Monatliche Kalibrierung | 30 min | Langfristig präziser SOC |
| 🟢 **NIEDRIG** | SOC-Monitoring | 15 min | Frühwarnung bei Drift |
### Checklist
- [ ] Sicherheitspuffer auf 30% erhöhen
- [ ] Input Helper für Kalibrierung erstellen
- [ ] 4 Kalibrierungs-Automations installieren
- [ ] Erste manuelle Kalibrierung durchführen
- [ ] SOC-Monitoring Automation installieren
- [ ] Nach 1 Monat: Überprüfen ob Batterie regelmäßig 100% erreicht
## Technische Details
### GoodWe BMS-Spezifikationen
**SOC-Berechnung:**
- Methode: Coulomb Counting + Voltage Estimation
- Update-Rate: 1 Hz (jede Sekunde)
- Genauigkeit: ±3% (typisch), ±5% (maximum)
- Kalibrierungs-Intervall: Empfohlen alle 30 Tage
**Referenzpunkte:**
- 100% SOC: 54.4V (LiFePO4, 16S × 3.4V)
- 20% SOC: 51.2V (LiFePO4, 16S × 3.2V)
- Floating Voltage: 54.0V
**Kapazitäts-Learning:**
- Algorithmus: Adaptive Weighted Integration
- Lernrate: 0.1-0.5 (abhängig von Confidence)
- Konvergenz: 3-5 Vollzyklen
### Home Assistant Integration
**Wichtige Entities:**
- `sensor.esssoc`: BMS-berechneter SOC
- `sensor.battery_voltage`: Gesamt-Spannung
- `sensor.battery_current`: Lade-/Entladestrom
- `sensor.battery_power`: Leistung (W)
- `sensor.battery_temperature`: Temperatur
**Berechnete Sensoren:**
- SOC-Validierung
- Wahre Kapazität
- Drift-Erkennung
- Health-Score
## Referenzen
### Weiterführende Informationen
- GoodWe BMS Manual: SOC-Algorithmus Details
- Battery University: SOC Estimation Techniques
- OpenEMS Documentation: Battery Management
- Home Assistant: Template Sensors & Automations
### Support & Community
- Home Assistant Community Forum
- GoodWe Support
- OpenEMS Community
- Battery Management System Best Practices
---
**Version**: 1.0
**Datum**: 2025-11-25
**Autor**: Felix + Claude
**Status**: Produktions-bereit