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

387 lines
11 KiB
Markdown

# PyScript Battery Optimizer - Diagnostic Report
**Date**: 2025-11-20
**Files Analyzed**:
- `/config/pyscript/battery_charging_optimizer.py` (v3.2.0)
- `/config/pyscript/hastrom_flex_extended.py` (v2.0)
## Syntax Check Results
**Both files have valid Python syntax** - No compilation errors detected
## Potential Runtime Issues Found
### 1. CRITICAL: Missing Import in hastrom_flex_extended.py
**Issue**: The script uses `task.executor()` but doesn't import the PyScript-specific modules that provide this functionality.
**Location**: Line 37 in `hastrom_flex_extended.py`
```python
response = task.executor(requests.get, url)
```
**Problem**: In PyScript, `task` is a built-in PyScript object, but if the PyScript integration isn't loading properly or if there's an initialization issue, this will fail with `NameError: name 'task' is not defined`.
**Expected Error**:
```
NameError: name 'task' is not defined
```
**Solution**: This should work in PyScript environment, but verify PyScript is properly loaded.
---
### 2. Timezone Import Compatibility
**Issue**: Both files use `from zoneinfo import ZoneInfo`
**Location**:
- Line 11 in `battery_charging_optimizer.py`
- Line 4 in `hastrom_flex_extended.py`
**Problem**: `zoneinfo` is part of Python 3.9+ standard library. Home Assistant should have this, but PyScript might have restrictions.
**Expected Error** (if zoneinfo not available):
```
ModuleNotFoundError: No module named 'zoneinfo'
```
**Alternative**: Use PyScript's built-in timezone handling or `pytz` library if available.
---
### 3. State Access Pattern Issues
**Issue**: Direct state access using dot notation and dictionary methods mixed
**Locations**:
- Line 33: `state.get('input_boolean.battery_optimizer_enabled')`
- Line 35: `input_text.battery_optimizer_status = "Deaktiviert"`
- Line 66: `state.get('sensor.esssoc')`
**Problem**: PyScript has specific patterns for accessing and setting states. The mixing of:
- `state.get()` (dictionary-style)
- `input_text.battery_optimizer_status =` (attribute-style)
This should work, but if there's a timing issue or entity doesn't exist, it will fail silently or raise AttributeError.
**Expected Errors**:
```
AttributeError: 'state' object has no attribute 'input_text'
```
or
```
TypeError: 'NoneType' object is not subscriptable
```
---
### 4. Datetime Comparison with ISO Strings
**Issue**: Comparing datetime objects with ISO strings from stored schedule
**Location**: Lines 590-605 in `battery_charging_optimizer.py`
```python
for entry in schedule:
entry_dt = datetime.fromisoformat(entry['datetime'])
# ...
if entry_date == current_date and entry_hour == current_hour:
```
**Problem**: The schedule stores datetime as ISO string (line 391), then loads it back. If the stored format doesn't match exactly what `fromisoformat()` expects, this will fail.
**Expected Error**:
```
ValueError: Invalid isoformat string: '...'
```
---
### 5. Service Decorator Registration
**Issue**: Services defined with `@service` decorator
**Locations**:
- Line 22: `@service` for `calculate_charging_schedule()`
- Line 556: `@service` for `execute_charging_schedule()`
- Line 15: `@service` for `getprices_extended()`
**Problem**: If PyScript isn't fully initialized or there's a registration conflict, services won't be available.
**Expected Behavior**: Services should appear as:
- `pyscript.calculate_charging_schedule`
- `pyscript.execute_charging_schedule`
- `pyscript.getprices_extended`
**Check Command** (in HA Developer Tools → Services):
Search for services starting with `pyscript.`
---
### 6. Time Trigger Cron Syntax
**Issue**: Multiple cron triggers defined
**Locations in battery_charging_optimizer.py**:
- Line 646: `@time_trigger("cron(5 14 * * *)")` - Daily at 14:05
- Line 653: `@time_trigger("cron(5 * * * *)")` - Hourly at xx:05
- Line 659: `@time_trigger("cron(5 0 * * *)")` - Midnight at 00:05
**Locations in hastrom_flex_extended.py**:
- Line 151: `@time_trigger("cron(0 * * * *)")` - Hourly
- Line 156: `@time_trigger("cron(5 14 * * *)")` - Daily at 14:05
- Line 162: `@time_trigger("cron(5 0 * * *)")` - Midnight
**Problem**: PyScript cron syntax might differ from standard cron. Some implementations use different formats.
**Expected Error** (if syntax wrong):
```
ValueError: Invalid cron expression
```
**Verify**: Check PyScript documentation for correct cron syntax.
---
### 7. Attribute Access on State Objects
**Issue**: Accessing attributes from state objects
**Location**: Lines 114-141 in `battery_charging_optimizer.py`
```python
prices_attr_ext = state.getattr(price_entity_ext)
prices_today = prices_attr.get('prices_today', [])
```
**Problem**: `state.getattr()` might return `None` if entity doesn't exist, then `.get()` on `None` will fail.
**Expected Error**:
```
AttributeError: 'NoneType' object has no attribute 'get'
```
**Better Pattern**:
```python
prices_attr_ext = state.getattr(price_entity_ext) or {}
```
---
### 8. State.set() with Attributes
**Issue**: Setting state with complex attribute structures
**Location**: Lines 484-500 in `battery_charging_optimizer.py`
```python
state.set(
'pyscript.battery_charging_schedule',
value='active',
new_attributes={
'schedule': schedule, # This could be very large
'last_update': get_local_now().isoformat(),
...
}
)
```
**Problem**:
1. Large schedule arrays might exceed PyScript state size limits
2. ISO format string from datetime might not match expected format
3. Datetime objects in schedule must be serializable
**Expected Errors**:
```
ValueError: State attributes too large
```
or
```
TypeError: Object of type datetime is not JSON serializable
```
---
## Most Likely Issues Based on "Not Working" Symptom
### Primary Suspects:
**1. PyScript Not Loading Files**
- PyScript might not be finding the files at `/config/pyscript/`
- File permissions issue
- PyScript integration disabled or in error state
**Check**: Look in HA UI → Settings → Devices & Services → PyScript
---
**2. Entity Dependencies Missing**
- Required entities don't exist or are unavailable:
- `sensor.hastrom_flex_pro_ext` (created by hastrom script)
- `sensor.esssoc` (from OpenEMS)
- `input_boolean.battery_optimizer_enabled`
- Various input_number helpers
**Check**: Developer Tools → States, search for these entities
---
**3. Timezone Module Import Failure**
- If `zoneinfo` import fails, entire script won't load
- PyScript would show error on startup
**Check**: Home Assistant logs for `ModuleNotFoundError`
---
**4. Service Not Calling Other Service**
- Line 650: `pyscript.calculate_charging_schedule()`
- This calls the service from within PyScript
**Problem**: Service-to-service calls in PyScript require specific syntax
**Correct Syntax**: `task.unique("calc")` or use the decorated function directly
---
**5. Schedule State Not Persisting**
- State created by one script not accessible to other
- State lost on Home Assistant restart
- Wrong entity ID format
---
## Recommended Diagnostic Steps
### Step 1: Check PyScript Status
```yaml
# In Home Assistant Developer Tools → Services:
service: pyscript.reload
```
Look for errors in logs immediately after reload.
### Step 2: Verify Entity Existence
Check if these entities exist:
- `sensor.hastrom_flex_pro_ext`
- `sensor.hastrom_flex_ext`
- `pyscript.battery_charging_schedule`
- `sensor.esssoc`
- `input_boolean.battery_optimizer_enabled`
### Step 3: Manual Service Call
Try calling services manually:
```yaml
service: pyscript.getprices_extended
```
Then:
```yaml
service: pyscript.calculate_charging_schedule
```
Watch for errors in Home Assistant logs (Settings → System → Logs)
### Step 4: Check Home Assistant Logs
Look for these specific error patterns:
- `ModuleNotFoundError: No module named 'zoneinfo'`
- `NameError: name 'task' is not defined`
- `AttributeError:` (various)
- `Traceback` lines mentioning `pyscript` or your script names
### Step 5: Verify File Locations
Ensure files are at:
- `/config/pyscript/battery_charging_optimizer.py`
- `/config/pyscript/hastrom_flex_extended.py`
Not:
- `/config/pyscripts/` (note the 's')
- Any other location
---
## Quick Fix Attempts
### Fix 1: Add Error Handling to getprices_extended
In `hastrom_flex_extended.py`, line 37, add try-catch:
```python
try:
response = task.executor(requests.get, url)
data = response.json()
except Exception as e:
log.error(f"API call failed: {e}")
log.error(f"Exception type: {type(e).__name__}")
return
```
### Fix 2: Add Null Checks for State Access
In `battery_charging_optimizer.py`, line 115-125:
```python
prices_attr_ext = state.getattr(price_entity_ext) or {}
prices_attr_old = state.getattr(price_entity_old) or {}
if prices_attr_ext.get('prices_today'):
# ... use extended
```
### Fix 3: Alternative Timezone Import
At top of both files, try:
```python
try:
from zoneinfo import ZoneInfo
except ImportError:
from datetime import timezone, timedelta
# Fallback: create Europe/Berlin manually
TIMEZONE = timezone(timedelta(hours=1)) # CET
```
---
## Expected Log Entries If Working
You should see these log messages if scripts are working:
**From hastrom_flex_extended.py:**
```
Lade Preise für 20251120 und 20251121 (lokale Zeit: ...)
✓ API-Abfrage erfolgreich: 48 Datenpunkte
📊 haStrom FLEX PRO Extended - Preise aktualisiert:
├─ Heute: 24 Stunden
└─ Morgen: 24 Stunden (verfügbar: True)
```
**From battery_charging_optimizer.py:**
```
=== Batterie-Optimierung gestartet (v3.2 - FIXED Timezones) ===
Konfiguration geladen: SOC 20-100%, Max 5000W
Strompreise geladen: 48 Stunden (Tomorrow: True)
PV-Prognose: Heute X.X kWh, Morgen X.X kWh
Aktueller SOC: XX%
🎯 Benötigte Ladestunden: X (bei 5000W pro Stunde)
✓ Top X günstigste Stunden ausgewählt:
✓ Ladeplan gespeichert: XX Stunden, X Ladungen
=== Optimierung abgeschlossen ===
```
---
## Conclusion
Without access to live Home Assistant logs, the most likely issues are:
1. **zoneinfo import failure** - Python environment in PyScript might not have it
2. **Entity dependencies missing** - Required sensors/helpers don't exist
3. **PyScript not loading scripts** - File location or permission issue
4. **State access returning None** - Entities not ready when script runs
**RECOMMENDED ACTION**: Access Home Assistant logs via:
- Settings → System → Logs (Web UI)
- Or download logs via: Settings → System → Advanced → Download Logs
- Or SSH into HA and check: `/config/home-assistant.log`
Look specifically for errors containing:
- `battery_charging_optimizer`
- `hastrom_flex_extended`
- `pyscript`
- `ModuleNotFoundError`
- `NameError`
- `AttributeError`
The actual error message will pinpoint the exact issue.