8.0 KiB
Diagnose: Battery Charging nicht funktioniert
Problem-Beschreibung
Heute Nacht wurde nicht geladen, obwohl:
- Der Speicher von INTERNAL auf REMOTE geschaltet wurde
goodwe_manual_controlaktiviert wurde- Nach ein paar Sekunden wurde es wieder deaktiviert
Wahrscheinliche Ursachen
1. Stündliche Ausführung stoppt das Laden
Problem: Die Automation "Batterie Optimierung: Stündliche Ausführung" läuft jede Stunde um xx:05 und prüft den Schedule für die aktuelle Stunde.
Verhalten:
- Stunde mit
action='charge'→ Laden wird aktiviert - Stunde mit
action='auto'→ Laden wird deaktiviert
Szenario:
23:05 → Schedule sagt "charge" → Laden startet
00:05 → Schedule sagt "auto" → Laden stoppt
Mögliche Ursachen:
- Schedule enthält nur 1 Ladestunde statt mehrere
- Zeitzone-Problem: Falsche Stunde wird geprüft
- Tomorrow-Daten fehlen im Schedule
2. Schedule wurde nicht richtig erstellt
Problem: Die tägliche Berechnung um 14:05 hat keinen sinnvollen Ladeplan erstellt.
Mögliche Ursachen:
- Batterie war schon voll (kein Ladebedarf)
- Tomorrow-Preise waren noch nicht verfügbar
- Alle Nachtstunden waren nicht unter den N günstigsten
3. Zeitzone-Problem in execute_charging_schedule
Problem: Der Vergleich zwischen aktueller Zeit und Schedule-Einträgen schlägt fehl.
Code in Zeile 593-606:
entry_dt = datetime.fromisoformat(entry['datetime'])
if entry_dt.tzinfo is None:
entry_dt = entry_dt.replace(tzinfo=TIMEZONE)
entry_date = entry_dt.date()
entry_hour = entry_dt.hour
if entry_date == current_date and entry_hour == current_hour:
current_entry = entry
Mögliches Problem: Die Datetimes im Schedule sind nicht korrekt timezone-aware.
Debug-Schritte
Schritt 1: Schedule prüfen
Gehe zu Developer Tools → States und suche nach:
pyscript.battery_charging_schedule
Was zu prüfen:
- Wann wurde
last_updatezuletzt aktualisiert? - Wie viele
num_chargessind geplant? - Wie viele
num_charges_tomorrowfür die Nacht? - Schau dir das
scheduleArray in den Attributen an
Interpretation:
num_charges = 0→ Keine Ladungen geplant (Batterie war voll?)num_charges_tomorrow = 0→ Keine Nachtstunden geplanthas_tomorrow_data = false→ Morgen-Preise fehlen
Schritt 2: Home Assistant Logs prüfen
Öffne die Home Assistant Logs und suche nach PyScript-Ausgaben:
Für die tägliche Berechnung (sollte um 14:05 laufen):
=== Batterie-Optimierung gestartet (v3.2 - FIXED Timezones) ===
Konfiguration geladen: SOC 20-100%, Max 5000W
Strompreise geladen: X Stunden (Tomorrow: true/false)
Benötigte Ladestunden: X (bei 5000W pro Stunde)
Top X günstigste Stunden ausgewählt
Für die stündliche Ausführung (läuft jede Stunde um xx:05):
Suche Ladeplan für YYYY-MM-DD HH:00 Uhr (lokal)
✓ Gefunden: YYYY-MM-DDTHH:00:00+01:00
⚡ Stunde HH:00 [heute/morgen]: action=charge/auto, power=XW, price=X.XXct
Kritische Warnungen zu suchen:
⚠ Keine Daten für YYYY-MM-DD HH:00
Keine zukünftigen Preise verfügbar
Schritt 3: Zeitzone-Verifikation
Führe manuell den Schedule aus und beobachte die Logs:
Developer Tools → Services:
service: pyscript.execute_charging_schedule
data: {}
Was zu beobachten:
- Welche Zeit wird gesucht? "Suche Ladeplan für ..."
- Wird ein Eintrag gefunden? "✓ Gefunden: ..."
- Welche Aktion wird ausgeführt? "action=charge" oder "action=auto"
Schritt 4: Manuellen Test durchführen
Um zu verifizieren, dass das Laden grundsätzlich funktioniert:
Developer Tools → Services:
service: input_number.set_value
target:
entity_id: input_number.charge_power_battery
data:
value: -5000
Dann:
service: input_boolean.turn_on
target:
entity_id: input_boolean.goodwe_manual_control
Erwartetes Verhalten:
- ESS schaltet auf REMOTE
- Keep-Alive Automation startet (alle 30s)
- Batterie beginnt zu laden
Wenn das funktioniert: Problem liegt im Schedule/Optimizer Wenn das nicht funktioniert: Problem liegt in den Automations/OpenEMS
Schritt 5: Schedule-Berechnung triggern
Führe eine neue Berechnung aus:
Developer Tools → Services:
service: pyscript.calculate_charging_schedule
data: {}
Dann prüfe:
- Die Logs für die Berechnung
- Den neuen Schedule in
pyscript.battery_charging_schedule - Ob Ladestunden für heute Nacht geplant sind
Typische Probleme und Lösungen
Problem A: "Keine Ladung nötig (Batterie voll)"
Symptom: num_charges = 0 im Schedule
Ursache: current_soc >= max_soc - reserve
Lösung: Normal, wenn Batterie voll ist. Warte bis SOC sinkt.
Problem B: "Tomorrow-Daten fehlen"
Symptom: has_tomorrow_data = false, nur wenige Stunden im Schedule
Ursache: Berechnung lief vor 14:00, als Preise für morgen noch nicht verfügbar waren
Lösung: Warte bis nach 14:00, dann läuft automatische Neuberechnung
Problem C: "Zeitzone-Mismatch"
Symptom: "⚠ Keine Daten für YYYY-MM-DD HH:00" obwohl Schedule existiert Ursache: Zeitvergleich matcht nicht Lösung: Siehe Code-Fix unten
Problem D: "Keep-Alive Automation läuft nicht"
Symptom: ESS ist auf REMOTE, aber keine Modbus-Befehle werden gesendet Ursache: Automation "Speicher manuell laden" ist deaktiviert oder fehlerhaft Lösung: Prüfe ob Automation aktiviert ist und läuft
Code-Verbesserungsvorschläge
Fix 1: Logging verbessern in execute_charging_schedule
Füge mehr Debug-Output hinzu in Zeile 587:
log.info(f"=== Stündliche Ausführung gestartet ===")
log.info(f"Lokale Zeit: {now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
log.info(f"Suche Ladeplan für {current_date} {current_hour}:00 Uhr (lokal)")
log.info(f"Schedule hat {len(schedule)} Einträge")
# Zeige alle Schedule-Einträge für Debugging
for i, entry in enumerate(schedule):
entry_dt = datetime.fromisoformat(entry['datetime'])
if entry_dt.tzinfo is None:
entry_dt = entry_dt.replace(tzinfo=TIMEZONE)
log.debug(f" [{i}] {entry_dt} → {entry['action']}")
Fix 2: Robusteres Datetime-Matching
Ersetze den exakten Stunden-Match durch ein Zeitfenster (Zeile 603):
# Statt exaktem Match:
if entry_date == current_date and entry_hour == current_hour:
# Verwende Zeitfenster (z.B. ±5 Minuten):
entry_start = entry_dt.replace(minute=0, second=0)
entry_end = entry_start + timedelta(hours=1)
if entry_start <= now < entry_end:
current_entry = entry
log.info(f"✓ Match gefunden für Zeitfenster {entry_start} - {entry_end}")
break
Fix 3: Fallback für fehlende Matches
Nach der Schleife (Zeile 608):
if not current_entry:
log.warning(f"⚠ Keine Daten für {current_date} {current_hour}:00")
# Debug: Zeige nächsten verfügbaren Eintrag
future_entries = []
for entry in schedule:
entry_dt = datetime.fromisoformat(entry['datetime'])
if entry_dt.tzinfo is None:
entry_dt = entry_dt.replace(tzinfo=TIMEZONE)
if entry_dt > now:
future_entries.append((entry_dt, entry['action']))
if future_entries:
next_entry = min(future_entries, key=lambda x: x[0])
log.info(f"ℹ Nächster Schedule-Eintrag: {next_entry[0]} → {next_entry[1]}")
else:
log.warning("⚠ Keine zukünftigen Schedule-Einträge gefunden!")
return
Nächste Schritte
- JETZT: Führe Debug-Schritte 1-3 aus und notiere die Ergebnisse
- Prüfe: Wie sieht der aktuelle Schedule aus?
- Teste: Funktioniert manuelles Laden (Schritt 4)?
- Entscheide: Basierend auf den Ergebnissen, welche Fix-Strategie anzuwenden ist
Monitoring für die nächste Nacht
Um zu sehen, was heute Nacht passiert:
- Prüfe Schedule um 14:05: Nach der täglichen Berechnung
- Setze Benachrichtigung: Für 23:05 (erste mögliche Ladestunde)
- Überwache Logs: Live während der Ladestunden
- Prüfe OpenEMS: Logs auf dem BeagleBone für Controller-Aktivität
# Auf BeagleBone
tail -f /var/log/openems/openems.log | grep -i "active.*power"