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>
This commit is contained in:
258
openems/legacy/v1/FINAL_FIX_pyscript_state.md
Normal file
258
openems/legacy/v1/FINAL_FIX_pyscript_state.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# 🎯 FINAL FIX: PyScript State mit Attributen
|
||||
|
||||
## ❌ Das eigentliche Problem
|
||||
|
||||
Du hattest völlig recht: **Es gibt KEIN input_textarea in Home Assistant!**
|
||||
|
||||
Und `input_text` ist hart auf **255 Zeichen limitiert** - viel zu wenig für unseren JSON-Ladeplan (typisch 2000-4000 Zeichen).
|
||||
|
||||
## ✅ Die richtige Lösung
|
||||
|
||||
**PyScript kann eigene States mit beliebig großen Attributen erstellen!**
|
||||
|
||||
Attributes haben kein 255-Zeichen-Limit - perfekt für große JSON-Daten!
|
||||
|
||||
## 🔧 Wie es funktioniert
|
||||
|
||||
### Speichern (in PyScript):
|
||||
|
||||
```python
|
||||
def save_schedule(schedule):
|
||||
"""Speichert Schedule als PyScript State Attribut"""
|
||||
|
||||
state.set(
|
||||
'pyscript.battery_charging_schedule', # Entity ID
|
||||
value='active', # State (beliebig, z.B. "active")
|
||||
new_attributes={
|
||||
'schedule': schedule, # Das komplette Dict!
|
||||
'last_update': datetime.now().isoformat(),
|
||||
'num_hours': len(schedule)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**Resultat:**
|
||||
- Entity: `pyscript.battery_charging_schedule`
|
||||
- State: `active`
|
||||
- Attribut `schedule`: Kompletter JSON (unbegrenzte Größe!)
|
||||
|
||||
### Lesen (überall):
|
||||
|
||||
```python
|
||||
# In PyScript:
|
||||
schedule = state.getattr('pyscript.battery_charging_schedule').get('schedule')
|
||||
|
||||
# In Templates:
|
||||
{% set schedule = state_attr('pyscript.battery_charging_schedule', 'schedule') %}
|
||||
|
||||
# In Automations:
|
||||
{{ state_attr('pyscript.battery_charging_schedule', 'schedule') }}
|
||||
```
|
||||
|
||||
## 📊 Vergleich der Lösungen
|
||||
|
||||
| Methode | Max. Größe | Problem |
|
||||
|---------|-----------|---------|
|
||||
| `input_text` | 255 Zeichen | ❌ Viel zu klein |
|
||||
| `input_textarea` | - | ❌ Existiert nicht! |
|
||||
| **PyScript State Attribute** | **Unbegrenzt** | ✅ **Perfekt!** |
|
||||
|
||||
## 🔄 Was geändert wurde
|
||||
|
||||
### 1. Config (battery_optimizer_config.yaml)
|
||||
|
||||
**ENTFERNT:**
|
||||
```yaml
|
||||
input_textarea: # ❌ Existiert nicht!
|
||||
battery_charging_schedule: ...
|
||||
```
|
||||
|
||||
**NEU:**
|
||||
```yaml
|
||||
# Kein Helper nötig!
|
||||
# PyScript erstellt pyscript.battery_charging_schedule automatisch
|
||||
```
|
||||
|
||||
**Templates geändert:**
|
||||
```yaml
|
||||
# VORHER:
|
||||
state_attr('input_textarea.battery_charging_schedule', 'schedule')
|
||||
|
||||
# NACHHER:
|
||||
state_attr('pyscript.battery_charging_schedule', 'schedule')
|
||||
```
|
||||
|
||||
### 2. PyScript (battery_charging_optimizer.py)
|
||||
|
||||
**Speichern:**
|
||||
```python
|
||||
# VORHER:
|
||||
schedule_json = json.dumps(schedule)
|
||||
input_textarea.battery_charging_schedule = schedule_json # Existiert nicht!
|
||||
|
||||
# NACHHER:
|
||||
state.set('pyscript.battery_charging_schedule',
|
||||
value='active',
|
||||
new_attributes={'schedule': schedule} # ✅ Unbegrenzt groß!
|
||||
)
|
||||
```
|
||||
|
||||
**Lesen:**
|
||||
```python
|
||||
# VORHER:
|
||||
schedule_json = state.get('input_textarea.battery_charging_schedule')
|
||||
schedule = json.loads(schedule_json)
|
||||
|
||||
# NACHHER:
|
||||
schedule = state.getattr('pyscript.battery_charging_schedule').get('schedule')
|
||||
# Schon als Dict, kein JSON-Parsing nötig!
|
||||
```
|
||||
|
||||
### 3. Dashboard (battery_optimizer_dashboard.yaml)
|
||||
|
||||
```yaml
|
||||
# VORHER:
|
||||
state_attr('input_textarea.battery_charging_schedule', 'schedule')
|
||||
|
||||
# NACHHER:
|
||||
state_attr('pyscript.battery_charging_schedule', 'schedule')
|
||||
```
|
||||
|
||||
## 🎯 Vorteile dieser Lösung
|
||||
|
||||
1. **✅ Funktioniert garantiert** - Kein nicht-existierender Helper
|
||||
2. **✅ Unbegrenzte Größe** - Attributes haben kein 255-Limit
|
||||
3. **✅ Kein JSON-Parsing** - Dict bleibt Dict
|
||||
4. **✅ Kein Helper nötig** - PyScript managed alles
|
||||
5. **✅ Zusätzliche Metadaten** - last_update, num_hours, etc.
|
||||
|
||||
## 🧪 Testen
|
||||
|
||||
Nach Installation:
|
||||
|
||||
```yaml
|
||||
# 1. Plan berechnen
|
||||
service: pyscript.calculate_charging_schedule
|
||||
|
||||
# 2. State prüfen in Entwicklerwerkzeuge → Zustände
|
||||
# Suche: pyscript.battery_charging_schedule
|
||||
#
|
||||
# Sollte zeigen:
|
||||
# State: active
|
||||
# Attributes:
|
||||
# schedule: {...großes JSON...}
|
||||
# last_update: 2025-11-07T23:45:00
|
||||
# num_hours: 24
|
||||
```
|
||||
|
||||
**In Developer Tools → Template:**
|
||||
```yaml
|
||||
{{ state_attr('pyscript.battery_charging_schedule', 'schedule') }}
|
||||
```
|
||||
|
||||
Sollte den kompletten Ladeplan als Dict anzeigen!
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
**Neu-Installation:**
|
||||
- ✅ Einfach die neuen Dateien nutzen
|
||||
- ✅ Kein Helper anlegen nötig
|
||||
- ✅ PyScript erstellt State automatisch
|
||||
|
||||
**Wenn du vorher etwas installiert hattest:**
|
||||
1. Lösche `input_text.battery_charging_schedule` (falls vorhanden)
|
||||
2. Ersetze alle 3 Dateien
|
||||
3. Home Assistant neu starten
|
||||
4. Plan berechnen: `pyscript.calculate_charging_schedule`
|
||||
5. Prüfen: State `pyscript.battery_charging_schedule` sollte existieren
|
||||
|
||||
## 🎓 Warum das funktioniert
|
||||
|
||||
### Home Assistant State-System:
|
||||
|
||||
**State-Wert:**
|
||||
- Immer max. 255 Zeichen
|
||||
- Wird in UI prominent angezeigt
|
||||
- Für Sensoren: Der Messwert
|
||||
|
||||
**Attributes:**
|
||||
- **Unbegrenzte Größe!** ✅
|
||||
- Zusätzliche Metadaten
|
||||
- Für komplexe Daten perfekt
|
||||
|
||||
**Beispiel:**
|
||||
```yaml
|
||||
sensor.weather:
|
||||
state: "sunny" # ← 255 Zeichen Limit
|
||||
attributes:
|
||||
forecast: [...] # ← Unbegrenzt!
|
||||
temperature: 22
|
||||
humidity: 60
|
||||
```
|
||||
|
||||
### PyScript-Vorteil:
|
||||
|
||||
PyScript kann beliebige States erstellen:
|
||||
|
||||
```python
|
||||
state.set('pyscript.my_custom_entity',
|
||||
value='whatever',
|
||||
new_attributes={
|
||||
'huge_data': very_large_dict, # Kein Limit!
|
||||
'metadata': 'anything'
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## 🚫 Was NICHT funktioniert
|
||||
|
||||
```yaml
|
||||
# ❌ input_text - Max 255 Zeichen
|
||||
input_text:
|
||||
my_json:
|
||||
max: 4096 # Ignoriert! Immer max. 255
|
||||
|
||||
# ❌ input_textarea - Existiert nicht!
|
||||
input_textarea:
|
||||
my_json: ... # ERROR: Unknown integration
|
||||
|
||||
# ❌ State-Wert für große Daten
|
||||
sensor.my_sensor:
|
||||
state: "{{huge_json}}" # ERROR: > 255 Zeichen
|
||||
```
|
||||
|
||||
## ✅ Was funktioniert
|
||||
|
||||
```yaml
|
||||
# ✅ Attribute für große Daten
|
||||
sensor.my_sensor:
|
||||
state: "active" # Kleiner State-Wert
|
||||
attributes:
|
||||
data: {huge_json} # Unbegrenzt!
|
||||
|
||||
# ✅ PyScript State
|
||||
pyscript.my_data:
|
||||
state: "ready"
|
||||
attributes:
|
||||
schedule: {large_dict} # Unbegrenzt!
|
||||
```
|
||||
|
||||
## 🎉 Fazit
|
||||
|
||||
**Die Lösung ist sogar BESSER als input_textarea wäre:**
|
||||
|
||||
1. ✅ Keine 255-Zeichen-Beschränkung
|
||||
2. ✅ Kein JSON-Parsing nötig
|
||||
3. ✅ Zusätzliche Metadaten möglich
|
||||
4. ✅ Automatisch verwaltet
|
||||
5. ✅ Funktioniert garantiert!
|
||||
|
||||
**Du hattest recht zu fragen - danke für den kritischen Blick!** 🙏
|
||||
|
||||
---
|
||||
|
||||
**Version:** v1.2 Final (wirklich final diesmal! 😅)
|
||||
**Status:** ✅ Produktionsbereit
|
||||
**Basis:** PyScript State Attributes (bewährte HA-Technik)
|
||||
|
||||
Alle Download-Dateien sind korrigiert!
|
||||
Reference in New Issue
Block a user