Files
battery-charging-optimizer/TROUBLESHOOTING_GUIDE.md
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

15 KiB

Battery Optimizer PyScript - Troubleshooting Guide

Problem: Battery optimizer scripts updated but not working Files: battery_charging_optimizer.py v3.2.0 + hastrom_flex_extended.py v2.0 Date: 2025-11-20


Quick Diagnostic Checklist

Run through these checks in order to identify the problem:

1. Verify Files Are Copied to Correct Location

Location Required: /config/pyscript/ (not /config/pyscripts/ - no 's'!)

Check via SSH or File Editor add-on:

ls -la /config/pyscript/

Expected Output:

battery_charging_optimizer.py
hastrom_flex_extended.py

If files are missing: Copy them to the correct location


2. Check PyScript Integration Status

Via Home Assistant UI:

  1. Settings → Devices & Services
  2. Search for "PyScript"
  3. Check status - should show "Configured"

If not installed: Install via HACS first If error status: Click for details, note the error message


3. Reload PyScript

Via Developer Tools:

  1. Developer Tools → Services
  2. Service: pyscript.reload
  3. Click "Call Service"

Watch for: Error notifications in UI or logs


4. Check Home Assistant Logs Immediately After Reload

Via UI:

  • Settings → System → Logs
  • Filter for "pyscript"

Look for these specific errors:

Error Type 1: Module Import Error

ModuleNotFoundError: No module named 'zoneinfo'

Cause: Python 3.9+ required for zoneinfo Fix: Update Home Assistant or use alternative (see Fix #1 below)


Error Type 2: Task Executor Not Defined

NameError: name 'task' is not defined

Cause: PyScript not fully initialized or wrong PyScript version Fix: Update PyScript integration to latest version


Error Type 3: Syntax Error

SyntaxError: invalid syntax (line XXX)

Cause: File corruption or copy error Fix: Re-copy files, ensure UTF-8 encoding


Error Type 4: Entity Not Found

AttributeError: 'state' object has no attribute 'input_text'

Cause: Required helper entities don't exist Fix: Create missing entities (see Fix #2 below)


5. Verify Services Were Registered

Via Developer Tools:

  1. Developer Tools → Services
  2. Search for "pyscript"

Expected Services:

  • pyscript.calculate_charging_schedule
  • pyscript.execute_charging_schedule
  • pyscript.getprices_extended
  • pyscript.reload

If services missing: PyScript failed to load files - check logs


6. Test Price Fetcher First

Manual Test:

service: pyscript.getprices_extended

Check Results:

  1. Developer Tools → States
  2. Search for: sensor.hastrom_flex_pro_ext
  3. Check attributes for:
    • prices_today (should be array of 24 prices)
    • prices_tomorrow (might be empty before 14:00)
    • last_update (should show recent timestamp)

If entity doesn't exist: Script failed to run - check logs If no data in attributes: API call failed - check logs for HTTP errors


7. Test Optimizer

Manual Test:

service: pyscript.calculate_charging_schedule

Check Results:

  1. Developer Tools → States
  2. Search for: pyscript.battery_charging_schedule
  3. Check attributes for:
    • schedule (array of hour-by-hour plan)
    • num_charges (number of charging hours)
    • last_update (timestamp)

If state doesn't exist: Optimizer failed to run completely If schedule is empty: Check log for calculation errors


Common Error Scenarios & Fixes

Scenario 1: "Cannot import zoneinfo"

Full Error:

ModuleNotFoundError: No module named 'zoneinfo'

Fix - Option A (Recommended): Update Home Assistant

  • Requires HA 2021.7+ (Python 3.9+)
  • Settings → System → Updates

Fix - Option B: Use pytz fallback

Edit both scripts, replace:

from zoneinfo import ZoneInfo
TIMEZONE = ZoneInfo("Europe/Berlin")

With:

try:
    from zoneinfo import ZoneInfo
    TIMEZONE = ZoneInfo("Europe/Berlin")
except ImportError:
    import pytz
    TIMEZONE = pytz.timezone("Europe/Berlin")

Then reload PyScript.


Scenario 2: Missing Input Helpers

Error:

AttributeError: 'state' object has no attribute 'input_boolean'

Required Entities - Input Booleans:

  • input_boolean.battery_optimizer_enabled
  • input_boolean.goodwe_manual_control
  • input_boolean.battery_optimizer_manual_override

Required Entities - Input Numbers:

  • input_number.battery_capacity_kwh (default: 10)
  • input_number.battery_optimizer_min_soc (default: 20)
  • input_number.battery_optimizer_max_soc (default: 100)
  • input_number.battery_optimizer_max_charge_power (default: 5000)
  • input_number.battery_optimizer_price_threshold (default: 28)
  • input_number.battery_optimizer_reserve_capacity (default: 2)
  • input_number.battery_optimizer_pv_threshold (default: 500)
  • input_number.charge_power_battery

Required Entities - Input Text:

  • input_text.battery_optimizer_status

Create via UI:

  1. Settings → Devices & Services → Helpers
  2. Click "Create Helper"
  3. Choose "Number" or "Toggle" or "Text"
  4. Set ID exactly as shown above

Or via configuration.yaml:

input_boolean:
  battery_optimizer_enabled:
    name: Battery Optimizer Enabled
    initial: on

  goodwe_manual_control:
    name: GoodWe Manual Control
    initial: off

  battery_optimizer_manual_override:
    name: Battery Optimizer Manual Override
    initial: off

input_number:
  battery_capacity_kwh:
    name: Battery Capacity (kWh)
    min: 0
    max: 50
    step: 0.1
    initial: 10
    unit_of_measurement: kWh

  battery_optimizer_min_soc:
    name: Min SOC
    min: 0
    max: 100
    step: 1
    initial: 20
    unit_of_measurement: '%'

  battery_optimizer_max_soc:
    name: Max SOC
    min: 0
    max: 100
    step: 1
    initial: 100
    unit_of_measurement: '%'

  battery_optimizer_max_charge_power:
    name: Max Charge Power
    min: 0
    max: 10000
    step: 100
    initial: 5000
    unit_of_measurement: W

  battery_optimizer_price_threshold:
    name: Price Threshold
    min: 0
    max: 100
    step: 0.1
    initial: 28
    unit_of_measurement: ct/kWh

  battery_optimizer_reserve_capacity:
    name: Reserve Capacity
    min: 0
    max: 10
    step: 0.1
    initial: 2
    unit_of_measurement: kWh

  battery_optimizer_pv_threshold:
    name: PV Threshold
    min: 0
    max: 5000
    step: 100
    initial: 500
    unit_of_measurement: Wh

  charge_power_battery:
    name: Charge Power Battery
    min: 0
    max: 10000
    step: 100
    initial: 0
    unit_of_measurement: W

input_text:
  battery_optimizer_status:
    name: Battery Optimizer Status
    initial: "Initialisiert"
    max: 255

Scenario 3: Time Triggers Not Firing

Symptom: Manual calls work, but automated schedule doesn't run

Check 1: Verify triggers are registered

# Developer Tools → Services
service: pyscript.debug

Look in logs for registered triggers.

Check 2: Verify system time and timezone

Fix: Ensure Home Assistant timezone is set correctly:

# configuration.yaml
homeassistant:
  time_zone: Europe/Berlin

Check 3: PyScript might not support cron syntax used

Try alternative trigger in configuration.yaml:

automation:
  - alias: "Trigger Battery Optimizer Daily"
    trigger:
      - platform: time
        at: "14:05:00"
    action:
      - service: pyscript.calculate_charging_schedule

  - alias: "Execute Battery Schedule Hourly"
    trigger:
      - platform: time_pattern
        minutes: "05"
    action:
      - service: pyscript.execute_charging_schedule

Scenario 4: Sensors Not Created by hastrom_flex_extended.py

Symptom: Service runs without error, but sensors don't appear

Check: State must be set with a numeric value first In hastrom_flex_extended.py, ensure lines 87 and 109 execute:

state.set("sensor.hastrom_flex_ext", value=float(current_price))
state.set("sensor.hastrom_flex_pro_ext", value=float(current_price))

Problem: If current_price is None, state.set won't create entity

Debug: Add logging before state.set:

log.info(f"Current price: {current_price}, type: {type(current_price)}")
if current_price is not None:
    state.set("sensor.hastrom_flex_ext", value=float(current_price))
else:
    log.error("Current price is None - sensor not created")

Scenario 5: Schedule Executes at Wrong Time

Symptom: Charging starts at wrong hour (e.g., 15:00 instead of 14:00)

Cause: UTC/Local timezone mismatch

Check: What timezone does PyScript use? Add debug logging in execute_charging_schedule():

now = get_local_now()
log.info(f"Current time: {now}")
log.info(f"Current hour: {now.hour}")
log.info(f"Timezone: {now.tzinfo}")
log.info(f"UTC offset: {now.utcoffset()}")

Fix: Verify get_local_now() returns Europe/Berlin time

  • During winter: UTC+1 (CET)
  • During summer: UTC+2 (CEST)

Scenario 6: State Attribute Size Too Large

Error:

ValueError: State attributes exceed maximum size

Cause: Schedule with 48+ hours of detailed data

Fix - Option A: Reduce schedule detail Store only charging hours, not all hours:

# In save_schedule(), filter before saving
schedule_compact = [s for s in schedule if s['action'] == 'charge']
state.set(..., new_attributes={'schedule': schedule_compact, ...})

Fix - Option B: Use separate entity for each day

# Save today and tomorrow separately
schedule_today = [s for s in schedule if not s.get('is_tomorrow')]
schedule_tomorrow = [s for s in schedule if s.get('is_tomorrow')]

state.set('pyscript.battery_schedule_today', ...)
state.set('pyscript.battery_schedule_tomorrow', ...)

Advanced Debugging

Enable PyScript Debug Logging

configuration.yaml:

logger:
  default: info
  logs:
    custom_components.pyscript: debug
    custom_components.pyscript.file.battery_charging_optimizer: debug
    custom_components.pyscript.file.hastrom_flex_extended: debug

Restart Home Assistant, then check logs.


Add Comprehensive Error Handling

Edit both scripts, wrap main logic in detailed try-catch:

battery_charging_optimizer.py, line 38:

try:
    # Existing code...
except Exception as e:
    log.error(f"EXCEPTION in calculate_charging_schedule: {e}")
    log.error(f"Exception type: {type(e).__name__}")
    import traceback
    log.error(f"Traceback:\n{traceback.format_exc()}")
    input_text.battery_optimizer_status = f"Error: {str(e)[:100]}"
    raise  # Re-raise to see in HA logs

Manual Execution with Timing

Test each component manually and time them:

# 1. Test price fetch (should take 1-3 seconds)
service: pyscript.getprices_extended

# Wait 5 seconds, then check logs

# 2. Test optimization (should take < 1 second)
service: pyscript.calculate_charging_schedule

# Wait 5 seconds, then check logs

# 3. Test execution (should be instant)
service: pyscript.execute_charging_schedule

# Check logs immediately

Check for Conflicting Automations

Search for automations that might interfere:

  1. Developer Tools → States
  2. Filter: automation.
  3. Look for automations controlling:
    • input_boolean.goodwe_manual_control
    • input_number.charge_power_battery

If other automations are modifying these, they might conflict.


Expected Successful Log Output

When everything works, you should see:

After pyscript.getprices_extended:

Lade Preise für 20251120 und 20251121 (lokale Zeit: 2025-11-20 15:00:00 CET)
✓ API-Abfrage erfolgreich: 48 Datenpunkte
📊 haStrom FLEX PRO Extended - Preise aktualisiert:
  ├─ Heute: 24 Stunden
  └─ Morgen: 24 Stunden (verfügbar: True)
  📈 Heute: Min=18.50, Max=35.20, Avg=25.30 ct/kWh
  📈 Morgen: Min=17.80, Max=34.50, Avg=24.80 ct/kWh

After pyscript.calculate_charging_schedule:

=== Batterie-Optimierung gestartet (v3.2 - FIXED Timezones) ===
Konfiguration geladen: SOC 20-100%, Max 5000W
✓ Nutze Extended-Sensor: sensor.hastrom_flex_pro_ext
Strompreise geladen: 48 Stunden (Tomorrow: True)
PV-Prognose: Heute 12.5 kWh, Morgen 8.3 kWh
Aktueller SOC: 45%
Lokale Zeit: 2025-11-20 15:00:00 CET
Planungsfenster: 45 Stunden (ab jetzt)
Preise: Min=17.80, Max=35.20, Avg=25.05 ct/kWh
Verfügbare Ladekapazität: 5.50 kWh
🎯 Benötigte Ladestunden: 2 (bei 5000W pro Stunde)
✓ Top 2 günstigste Stunden ausgewählt:
  - Preise: 17.80 - 18.20 ct/kWh
  - Durchschnitt: 18.00 ct/kWh
  - Ersparnis vs. Durchschnitt: 7.05 ct/kWh
  - Davon morgen: 1
  - Zeiten: 02:00 heute (17.80ct), 03:00 morgen (18.20ct)
✓ Ladeplan gespeichert: 45 Stunden, 2 Ladungen (1 morgen)
📊 Statistik:
  - Planungsfenster: 45 Stunden
  - Tomorrow-Daten: ✓ Ja
  - Ladungen heute: 1
  - Ladungen morgen: 1
  - Energie heute: 5.0 kWh @ 17.80 ct/kWh
  - Energie morgen: 0.5 kWh @ 18.20 ct/kWh
=== Optimierung abgeschlossen ===

After pyscript.execute_charging_schedule (during charging hour):

Suche Ladeplan für 2025-11-20 02:00 Uhr (lokal)
✓ Gefunden: 2025-11-20T02:00:00+01:00
⚡ Stunde 02:00 [heute]: action=charge, power=-5000W, price=17.80ct
   Grund: Rang 1/45: 17.80ct [heute]
🔋 AKTIVIERE LADEN mit 5000W
✓ Manuelles Laden aktiviert

After pyscript.execute_charging_schedule (during auto hour):

Suche Ladeplan für 2025-11-20 15:00 Uhr (lokal)
✓ Gefunden: 2025-11-20T15:00:00+01:00
⚡ Stunde 15:00 [heute]: action=auto, power=0W, price=28.50ct
   Grund: Rang 25 (nicht unter Top 2)
✓ Auto-Modus bereits aktiv

Final Checklist Before Requesting Help

If you've tried everything above and still have issues, gather this info:

  1. Home Assistant version:

    • Settings → System → Info
  2. PyScript version:

    • Settings → Devices & Services → PyScript
  3. Python version in HA:

    docker exec homeassistant python --version
    
  4. Complete error log:

    • Settings → System → Logs
    • Filter for "pyscript"
    • Copy last 50 lines
  5. Entity status:

    • Check if these exist: sensor.hastrom_flex_pro_ext, pyscript.battery_charging_schedule
  6. Service availability:

    • List all pyscript.* services
  7. File locations confirmed:

    ls -la /config/pyscript/*.py
    
  8. Recent manual test results:

    • What happened when you called each service manually?

Quick Reference Commands

# Reload PyScript
service: pyscript.reload

# Test price fetch
service: pyscript.getprices_extended

# Test optimizer
service: pyscript.calculate_charging_schedule

# Test executor
service: pyscript.execute_charging_schedule

# Enable optimizer
service: input_boolean.turn_on
data:
  entity_id: input_boolean.battery_optimizer_enabled

# Disable optimizer
service: input_boolean.turn_off
data:
  entity_id: input_boolean.battery_optimizer_enabled

# Check schedule state
# Developer Tools → States → pyscript.battery_charging_schedule

# Check price sensor
# Developer Tools → States → sensor.hastrom_flex_pro_ext

Contact & Support

If issues persist after following this guide:

  1. Export logs: Settings → System → Advanced → Download Logs
  2. Check PyScript GitHub issues: https://github.com/custom-components/pyscript
  3. Home Assistant Community: https://community.home-assistant.io/

Include in your report:

  • HA version
  • PyScript version
  • Complete error logs
  • Output of validation script (python3 validate_pyscript.py)
  • Steps already tried from this guide