# 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