# Hotfix: Preisschwelle wurde nicht angewendet (v3.5.1) ## Problem Die Preisschwelle (`price_threshold`) wurde zwar aus den Input Helpern geladen, aber **nie im Code verwendet**. Das führte dazu, dass: - System lud auch bei Preisen ÜBER der Schwelle - Beispiel: Schwelle 25ct, aber Ladung bei 25.93ct geplant - User-Erwartung: Keine Ladung wenn alle Preise über Schwelle ## Analyse ```python # battery_charging_optimizer.py:110 'price_threshold': float(state.get('input_number.battery_optimizer_price_threshold') or 25), # ✅ Wurde geladen # battery_charging_optimizer.py:317-340 (ALT) for p in future_price_data: charging_candidates.append({...}) # ❌ Keine Prüfung gegen threshold! ``` **Resultat**: Alle zukünftigen Stunden wurden in die Ranking-Liste aufgenommen, unabhängig vom Preis. ## Lösung (v3.5.1) ### 1. Filter VOR dem Ranking ```python # Zeile 315-334: Neuer Filter price_threshold = config['price_threshold'] affordable_hours = [] expensive_hours = [] for p in future_price_data: if p['price'] <= price_threshold: affordable_hours.append(p) else: expensive_hours.append(p) # Wenn keine bezahlbaren Stunden verfügbar if not affordable_hours: log.warning(f"⚠️ Keine Stunden unter Preisschwelle {price_threshold} ct/kWh") return create_auto_only_schedule(future_price_data) # Keine Ladung! ``` ### 2. Ranking nur mit bezahlbaren Stunden ```python # Zeile 341: Nur affordable_hours verwenden for p in affordable_hours: # Statt future_price_data charging_candidates.append({...}) ``` ### 3. Besseres Logging ```python log.info(f"💶 Preisschwelle: {price_threshold} ct/kWh") log.info(f" - Stunden unter Schwelle: {len(affordable_hours)}") log.info(f" - Stunden über Schwelle: {len(expensive_hours)} (werden ignoriert)") # Im Schedule: reason = f"Zu teuer: {p['price']:.2f}ct (Schwelle: {price_threshold}ct)" ``` ### 4. Warnung bei Teilladung ```python if actual_hours_needed < needed_hours: log.warning(f"⚠️ Nur {actual_hours_needed} von {needed_hours} benötigten Stunden unter Preisschwelle") log.warning(f" Batterie wird nur teilweise geladen") ``` ## Verhalten vorher vs. nachher ### Szenario: Schwelle 25ct, alle Preise 25-30ct **VORHER (v3.5.0)**: ``` Preis-Array: [25.93, 26.45, 27.12, 28.50, ...] → Ranking: Sortiere alle nach Preis → Wähle günstigste: 25.93ct (Rang 1) → ✗ LÄDT bei 25.93ct (über Schwelle 25ct!) ``` **NACHHER (v3.5.1)**: ``` Preis-Array: [25.93, 26.45, 27.12, 28.50, ...] → Filter: Alle über 25ct → affordable_hours = [] → ⚠️ Keine Stunden unter Preisschwelle 25ct → ✓ KEINE LADUNG (Auto-Modus) ``` ### Szenario: Schwelle 25ct, Preise 20-30ct **VORHER (v3.5.0)**: ``` Preis-Array: [20.50, 24.80, 25.93, 26.45, ...] → Ranking: [20.50, 24.80, 25.93, 26.45, ...] → Wähle Top 3: [20.50, 24.80, 25.93] → ✗ LÄDT auch bei 25.93ct (über Schwelle!) ``` **NACHHER (v3.5.1)**: ``` Preis-Array: [20.50, 24.80, 25.93, 26.45, ...] → Filter: affordable_hours = [20.50, 24.80] → Ranking: [20.50, 24.80] → Wähle Top 2: [20.50, 24.80] → ✓ NUR unter Schwelle, 25.93ct ignoriert → Warnung: "Nur 2 von 3 benötigten Stunden" ``` ## Log-Ausgaben neu (v3.5.1) ``` === Batterie-Optimierung gestartet (v3.5.1 - Preisschwelle aktiv) === Preise: Min=20.50, Max=30.45, Avg=25.67 ct/kWh Verfügbare Ladekapazität: 5.00 kWh (bis 100% SOC) 🎯 Benötigte Ladestunden: 1 (bei 8000W pro Stunde) 💶 Preisschwelle: 25.0 ct/kWh - Stunden unter Schwelle: 18 - Stunden über Schwelle: 12 (werden ignoriert) ✓ Top 1 günstigste Stunden ausgewählt: - Preise: 20.50 - 20.50 ct/kWh ``` Oder wenn KEINE günstigen Stunden: ``` 💶 Preisschwelle: 25.0 ct/kWh - Stunden unter Schwelle: 0 - Stunden über Schwelle: 30 (werden ignoriert) ⚠️ Keine Stunden unter Preisschwelle 25.0 ct/kWh gefunden! Günstigster Preis: 25.93 ct/kWh → Keine Ladung, bleibe im Auto-Modus ``` ## Impact **Severity**: 🔴 **CRITICAL** - Führte zu ungewollten Ladevorgängen bei zu teuren Preisen - Kosteneinsparungen wurden nicht realisiert - User-Erwartung komplett ignoriert **Betroffene Versionen**: - v3.5.0 (heute released) - Wahrscheinlich auch v3.0.0 - v3.4.0 (zu prüfen) **Fix-Priorität**: SOFORT - Hotfix v3.5.1 released - User sollten SOFORT updaten ## Migration 3.5.0 → 3.5.1 1. Update `battery_charging_optimizer.py` (v3.5.1) 2. PyScript neu laden 3. Neuberechnung: `pyscript.calculate_charging_schedule` 4. Log prüfen: Sollte "Preisschwelle: X ct/kWh" zeigen **Keine Breaking Changes** - Nur Bugfix. ## Testing Test-Szenarien: 1. **Alle Preise über Schwelle**: - Setze `price_threshold` auf 20ct - Wenn alle Preise > 20ct → Keine Ladung - Log: "Keine Stunden unter Preisschwelle" 2. **Mix aus günstigen/teuren Stunden**: - Setze `price_threshold` auf 25ct - Nur Stunden ≤ 25ct sollten im Plan sein - Log: "X Stunden unter Schwelle, Y über Schwelle" 3. **Alle Preise unter Schwelle**: - Setze `price_threshold` auf 50ct - Normales Verhalten wie bisher - Log: "30 Stunden unter Schwelle, 0 über Schwelle" ## Lessons Learned 1. **Configuration muss verwendet werden**: - Laden von Config ≠ Verwenden von Config - Code-Review: Prüfe ob alle Config-Werte auch benutzt werden 2. **User-Feedback ernst nehmen**: - User hat Bug sofort entdeckt beim ersten Test - Ohne User-Test wäre Bug unentdeckt geblieben 3. **Logging ist essentiell**: - Mit neuem Logging ist sofort ersichtlich was passiert - "X Stunden unter Schwelle" macht Verhalten transparent ## Danke Großes Dankeschön an Felix für das sofortige Melden des Bugs! 🙏 --- **Version**: 3.5.1 **Datum**: 2025-12-28 **Severity**: Critical **Status**: ✅ Fixed