Files
battery-charging-optimizer/openems/battery_calibration_automation.yaml
felix.zoesch 0fa03a566a feat: Major update - Battery Optimizer v3.4.0 with comprehensive fixes
## 🎯 Hauptänderungen

### Version 3.4.0 - SOC-Drift & Charging Capacity
-  Sicherheitspuffer (20-50% konfigurierbar) für untertägige SOC-Schwankungen
-  Monatliche automatische Batterie-Kalibrierung
- 🐛 SOC-Plausibilitäts-Check (filtert 65535% Spikes beim Modus-Wechsel)
- 🐛 Zeitabhängige API-Abfrage (vor/nach 14:00 Uhr)

### Neue Features
- 🔋 **Safety Buffer**: Kompensiert SOC-Drift und Eigenverbrauch
- 🔋 **Auto-Calibration**: Monatlicher Vollzyklus für SOC-Genauigkeit
- 🔋 **Spike Protection**: 4-fach Schutz gegen ungültige SOC-Werte
- 🔋 **Smart API**: Verhindert HTTP 500 Errors bei fehlenden Tomorrow-Preisen

### Dokumentation
- 📚 SOC_CALIBRATION_GUIDE.md - Umfassender Kalibrierungs-Guide
- 📚 FIX_CHARGING_CAPACITY.md - Sicherheitspuffer-Dokumentation
- 📚 FIX_SOC_SPIKE_PROBLEM.md - Spike-Protection-Lösung
- 📚 FIX_API_TIMING.md - Zeitabhängige API-Abfrage
- 📚 DIAGNOSE_LADE_PROBLEM.md - Debug-Guide

### Neue Dateien
- battery_calibration_automation.yaml - 4 Automations für Kalibrierung
- battery_calibration_input_helper.yaml - Input Helper Config
- battery_optimizer_input_helper_safety_buffer.yaml - Puffer Config
- debug_schedule.py - Umfassendes Debug-Script

### Scripts
- battery_charging_optimizer.py v3.4.0
- hastrom_flex_extended.py v1.1.0
- debug_schedule.py v1.0.0

### Fixes
- 🐛 SOC springt auf 65535% beim ESS-Modus-Wechsel → Debounce + Plausibilitäts-Check
- 🐛 API-HTTP-500 vor 14:00 → Zeitabhängige Abfrage
- 🐛 Batterie nicht bis 100% geladen → Sicherheitspuffer
- 🐛 SOC driftet ohne Vollzyklen → Automatische Kalibrierung

## 🚀 Installation

1. Input Helper erstellen (siehe battery_optimizer_input_helper_safety_buffer.yaml)
2. Automations installieren (siehe battery_calibration_automation.yaml)
3. Scripts aktualisieren (battery_charging_optimizer.py v3.4.0)
4. PyScript neu laden

## 📊 Verbesserungen

- Präzisere Ladeplanung durch Sicherheitspuffer
- Robustheit gegen SOC-Drift
- Keine API-Fehler mehr vor 14:00
- Hardware-Stopp bei 100% wird respektiert
- Bessere Batterie-Gesundheit durch regelmäßige Kalibrierung

🤖 Generated with Claude Code (claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 08:04:07 +01:00

204 lines
5.8 KiB
YAML

# Battery Calibration Automation
# Erzwingt einmal im Monat einen vollen Lade-/Entladezyklus zur SOC-Kalibrierung
#
# WARUM: Der SOC wird vom BMS berechnet und driftet ohne volle Zyklen.
# Volle Zyklen (20% → 100%) geben dem BMS Referenzpunkte zur Kalibrierung.
#
# WIE:
# 1. Überschreibt den Optimizer für 24h
# 2. Entlädt Batterie auf 20% (durch normalen Eigenverbrauch)
# 3. Lädt Batterie auf 100% (unabhängig von Strompreisen)
#
# WANN: Jeden 1. des Monats
#
# Installation: In automations.yaml einfügen oder via UI erstellen
# ==========================================
# Automation 1: Kalibrierung starten
# ==========================================
alias: "Batterie Kalibrierung: Monatlicher Zyklus starten"
description: "Startet einmal im Monat einen vollen Lade-/Entladezyklus zur SOC-Kalibrierung"
trigger:
# Jeden 1. des Monats um 00:05 Uhr
- platform: template
value_template: >
{{ now().day == 1 and now().hour == 0 and now().minute == 5 }}
condition:
# Nur wenn Optimizer aktiviert ist
- condition: state
entity_id: input_boolean.battery_optimizer_enabled
state: "on"
action:
# Aktiviere Manual Override für 24h
- service: input_boolean.turn_on
target:
entity_id: input_boolean.battery_optimizer_manual_override
# Setze Helper für Kalibrierungs-Status
- service: input_boolean.turn_on
target:
entity_id: input_boolean.battery_calibration_active
# Benachrichtigung
- service: notify.persistent_notification
data:
title: "Batterie-Kalibrierung gestartet"
message: >
Batterie-Kalibrierung läuft für 24h.
Ziel: Voller Zyklus (20% → 100%) für SOC-Neukalibrierung.
Optimizer ist pausiert.
# Logging
- service: system_log.write
data:
message: "Battery calibration started - full cycle mode for 24h"
level: info
mode: single
# ==========================================
# Automation 2: Kalibrierungs-Laden
# ==========================================
alias: "Batterie Kalibrierung: Laden auf 100%"
description: "Lädt Batterie auf 100% während Kalibrierung (unabhängig von Preisen)"
trigger:
# Stündlich prüfen während Kalibrierung aktiv ist
- platform: time_pattern
minutes: "5"
condition:
# Nur wenn Kalibrierung aktiv
- condition: state
entity_id: input_boolean.battery_calibration_active
state: "on"
# Nur wenn SOC unter 99%
- condition: numeric_state
entity_id: sensor.esssoc
below: 99
action:
# Aktiviere Laden mit voller Leistung
- service: input_number.set_value
target:
entity_id: input_number.charge_power_battery
data:
value: -5000
- service: input_boolean.turn_on
target:
entity_id: input_boolean.goodwe_manual_control
# Logging
- service: system_log.write
data:
message: "Calibration: Charging battery to 100% (SOC: {{ states('sensor.esssoc') }}%)"
level: info
mode: single
# ==========================================
# Automation 3: Kalibrierung beenden
# ==========================================
alias: "Batterie Kalibrierung: Beenden"
description: "Beendet Kalibrierung nach 24h oder wenn 100% erreicht"
trigger:
# Trigger 1: 24h sind vorbei
- platform: state
entity_id: input_boolean.battery_calibration_active
to: "on"
for:
hours: 24
# Trigger 2: 100% SOC erreicht und mindestens 6h gelaufen
- platform: numeric_state
entity_id: sensor.esssoc
above: 99.5
condition:
- condition: state
entity_id: input_boolean.battery_calibration_active
state: "on"
# Kalibrierung muss mindestens 6h gelaufen sein
- condition: template
value_template: >
{% set start = as_timestamp(states.input_boolean.battery_calibration_active.last_changed) %}
{% set now = as_timestamp(now()) %}
{{ (now - start) > (6 * 3600) }}
action:
# Deaktiviere Kalibrierung
- service: input_boolean.turn_off
target:
entity_id: input_boolean.battery_calibration_active
# Deaktiviere Manual Override
- service: input_boolean.turn_off
target:
entity_id: input_boolean.battery_optimizer_manual_override
# Deaktiviere manuelles Laden
- service: input_boolean.turn_off
target:
entity_id: input_boolean.goodwe_manual_control
# Neue Planung triggern
- service: pyscript.calculate_charging_schedule
data: {}
# Benachrichtigung
- service: notify.persistent_notification
data:
title: "Batterie-Kalibrierung abgeschlossen"
message: >
Batterie-Kalibrierung erfolgreich beendet.
SOC: {{ states('sensor.esssoc') }}%
Optimizer ist wieder aktiv.
# Logging
- service: system_log.write
data:
message: "Battery calibration completed - SOC {{ states('sensor.esssoc') }}%"
level: info
mode: single
# ==========================================
# Automation 4: Notfall-Abbruch bei niedrigem SOC
# ==========================================
alias: "Batterie Kalibrierung: Notfall-Abbruch"
description: "Bricht Kalibrierung ab wenn SOC kritisch niedrig"
trigger:
- platform: numeric_state
entity_id: sensor.esssoc
below: 15
condition:
- condition: state
entity_id: input_boolean.battery_calibration_active
state: "on"
action:
# Sofort laden aktivieren
- service: input_number.set_value
target:
entity_id: input_number.charge_power_battery
data:
value: -5000
- service: input_boolean.turn_on
target:
entity_id: input_boolean.goodwe_manual_control
# Warnung
- service: notify.persistent_notification
data:
title: "Batterie-Kalibrierung: NOTFALL"
message: >
SOC kritisch niedrig ({{ states('sensor.esssoc') }}%)!
Notfall-Ladung aktiviert.
Kalibrierung läuft weiter.
# Logging
- service: system_log.write
data:
message: "Calibration: Emergency charging activated (SOC {{ states('sensor.esssoc') }}%)"
level: warning
mode: single