OpenEMS Battery Charging Optimizer für Home Assistant
Intelligente Batterieladesteuerung für Home Assistant mit OpenEMS und GoodWe Hardware. Das System optimiert die Batterieladung basierend auf dynamischen Strompreisen (haStrom FLEX PRO) und Solarprognosen.
Features
- Dynamische Preisoptimierung: Lädt die Batterie während der günstigsten Strompreis-Stunden
- Solar-Integration: Berücksichtigt PV-Prognosen (Forecast.Solar)
- Cross-Midnight Optimierung: Findet die günstigsten Stunden über Tagesgrenzen hinweg
- Tomorrow-Support: Nutzt morgige Strompreise für 48h-Vorausplanung (ab 14:00)
- Automatische Modbus-Steuerung: Direkte Batteriesteuerung via OpenEMS Modbus TCP
- Intelligente Keep-Alive: Erhält Ladebefehle automatisch alle 30 Sekunden aufrecht
- Restart-Safe: Automatische Neuberechnung nach Home Assistant Neustart
Hardware-Voraussetzungen
- Batterie: GoodWe Lynx Home U (10 kWh)
- Inverter: GoodWe GW10K-ET Plus+ (10 kW)
- PV-Anlage: 9.2 kWp (Ost-West auf Flachdach)
- EMS: BeagleBone mit OpenEMS
- Kommunikation: Modbus TCP (Port 502) + JSON-RPC (Port 8074)
Software-Voraussetzungen
- Home Assistant 2024.2 oder neuer
- PyScript Integration
- Custom Components:
- Mushroom Cards (HACS)
- Bubble Card (HACS)
- Plotly Graph Card (HACS)
- Power Flow Card Plus (HACS)
Schnellstart
- Installation: Siehe INSTALLATION.md
- Konfiguration: Passe
battery_optimizer_config.yamlan deine Hardware an - Erste Schritte: Aktiviere
input_boolean.battery_optimizer_enabled - Dashboard: Importiere eines der Dashboards aus
dashboards/
Architektur
14:05 täglich → calculate_charging_schedule → Erstellt Ladeplan
↓
xx:05 stündlich → execute_charging_schedule → Führt Plan aus
↓
Bei Laden → goodwe_manual_control ON → Triggert Automationen
↓
Automation aktivieren → ESS REMOTE-Modus → Enables Keep-Alive
↓
Keep-Alive (30s) → ess_set_power → Modbus Befehl an Batterie
Repository-Struktur
.
├── pyscripts/
│ ├── battery_charging_optimizer.py # Haupt-Optimierer (v3.3.1)
│ ├── hastrom_flex_extended.py # Strompreis-Integration
│ └── ess_set_power.py # Modbus Batteriesteuerung
├── config/
│ ├── battery_optimizer_config.yaml # Input Helper Konfiguration
│ └── rest_requests.yaml # ESS Modus-Umschaltung
├── automations/
│ ├── battery_optimizer_automations.yaml # Optimizer Automationen
│ ├── speicher_manuell_laden.yaml # Keep-Alive
│ ├── manuelle_speicherbeladung_aktivieren.yaml # ESS → REMOTE
│ └── manuelle_speicherbeladung_deaktivieren.yaml # ESS → INTERNAL
├── dashboards/
│ ├── battery_optimizer_sections_standard.yaml # Empfohlenes Dashboard
│ ├── battery_optimizer_sections_compact.yaml # Kompakte Variante
│ └── battery_optimizer_sections_minimal.yaml # Minimal-Ansicht
├── docs/
│ ├── EMS_OpenEMS_HomeAssistant_Dokumentation.md # Technische Details
│ ├── INSTALLATION.md # Installationsanleitung
│ └── TROUBLESHOOTING.md # Fehlerbehebung
├── legacy/
│ ├── v1/ # Erste Implementation (threshold-based)
│ ├── v2/ # Verbesserte Version
│ └── v3/ # Ranking-based (Basis für v3.3.1)
└── README.md
Algorithmus
Ranking-Based Optimization (v3.x):
- Berechne benötigte Ladestunden:
(Ziel-SOC - aktueller SOC) × Kapazität ÷ Ladeleistung - Kombiniere Heute + Morgen Preisdaten in ein Dataset
- Score jede Stunde:
Preis - (PV-Prognose / 1000) - Sortiere nach Score (niedrigster = best)
- Wähle die N günstigsten Stunden
- Führe chronologisch aus
Beispiel: Bei 10 kWh Batterie, 50% SOC, 5 kW Ladeleistung:
- Benötigt: (100% - 50%) × 10 kWh ÷ 5 kW = 10 Stunden
- Wählt die 10 günstigsten Stunden aus den nächsten 48h
Wichtige Konzepte
Timezone-Handling
PyScript läuft in UTC, Home Assistant speichert in Europe/Berlin:
from zoneinfo import ZoneInfo
TIMEZONE = ZoneInfo("Europe/Berlin")
def get_local_now():
return datetime.now(TIMEZONE)
Power Value Convention
Negativ = Laden, Positiv = Entladen
input_number.charge_power_battery = -5000 # Lädt mit 5000W
input_number.charge_power_battery = +3000 # Entlädt mit 3000W
Controller Priority (OpenEMS)
Controller führen in alphabetischer Reihenfolge aus. Spätere Controller können frühere überschreiben.
Lösung: ctrlBalancing0 mit SET_GRID_ACTIVE_POWER für höchste Priorität verwenden.
Konfiguration
Passe diese Werte in battery_optimizer_config.yaml an:
input_number:
battery_capacity_kwh:
initial: 10 # Deine Batteriekapazität in kWh
battery_optimizer_max_charge_power:
initial: 5000 # Maximale Ladeleistung in W
battery_optimizer_min_soc:
initial: 20 # Minimum SOC in %
battery_optimizer_max_soc:
initial: 100 # Maximum SOC in %
Entwicklung
Version History
- v3.3.1 (aktuell): SOC-Plausibilitäts-Check, negative Power-Values
- v3.2.0: Timezone-Fixes durchgehend
- v3.1.0: Ranking-based Optimization, Tomorrow-Support
- v2.x: Verbesserte Dashboards, Error Handling
- v1.x: Initial Release, Threshold-based
Siehe CHANGELOG.md für Details.
Testing
# In Home Assistant Developer Tools → Services:
# Schedule berechnen
service: pyscript.calculate_charging_schedule
# Aktuellen Plan ausführen
service: pyscript.execute_charging_schedule
# PyScript neu laden
service: pyscript.reload
Debugging
# Logs anzeigen (Home Assistant)
tail -f /config/home-assistant.log | grep -i battery
# OpenEMS Logs (BeagleBone)
tail -f /var/log/openems/openems.log
Datenquellen
- haStrom FLEX PRO:
http://eex.stwhas.de/api/spotprices/flexpro - Forecast.Solar: Automatisch via Home Assistant Integration
- OpenEMS Modbus:
192.168.89.144:502 - OpenEMS JSON-RPC:
192.168.89.144:8074
Beitragende
Entwickelt von Felix für das eigene Heimenergiesystem.
Contributions sind willkommen! Bitte erstelle ein Issue oder Pull Request.
Lizenz
MIT License - siehe LICENSE für Details.
Support
Bei Fragen oder Problemen:
- Prüfe TROUBLESHOOTING.md
- Schaue in die Issues
- Erstelle ein neues Issue mit Logs und Konfiguration
Danksagungen
- Home Assistant Community
- PyScript Integration
- OpenEMS Projekt
- haStrom für die API
- Forecast.Solar für PV-Prognosen