fix: drift-free self-consumption (Option B)
🐛 Bug Fix — Self-Consumption inflates over time
Reopened by @j3n5h in #4: after v2.0.2 the self-consumption sensor still wasn't right — it grew faster than the export sensor instead of `pv - export`. The gap between the displayed value and `pv - export` was the actual self-consumption.
This is systemic (not user-specific) and most visible on setups where PV and Export are reported by separate sensors that fire asynchronously (Growatt-HAR, smart meter + inverter, etc.).
Root cause
The previous incremental formula:
```python
delta_self_consumption = max(0.0, delta_pv - delta_export)
self._total_self_consumption_kwh += delta_self_consumption
```
drifts when sensors fire separately. Example sequence with Export-only event followed by PV-only event:
| Event | delta_pv | delta_export | delta_self (with max) | Correct |
|---|---|---|---|---|
| Export +2 | 0 | 2 | 0 ❌ | -2 |
| PV +5 | 5 | 0 | +5 | +5 |
| Sum | +5 ❌ | +3 |
The `max(0, ...)` cuts off the negative correction → self_consumption inflates over time by the amount that should have been subtracted.
Fix — Option B (absolute calculation)
Self-Consumption + Feed-In are now computed from absolute sensor totals via persisted baselines, recomputed on every update:
```python
total_self_consumption = baseline_self
+ (current_pv - baseline_pv)
- (current_export - baseline_export)
```
- Self-correcting on every state-change regardless of which sensor fired
- Mathematically identical for synchronous Wechselrichter (no behaviour change for them)
- Daily/monthly tracking continues to use effective deltas (preserves Tagesreset)
Migration
- New `baseline_*` fields persisted in storage
- Absent on existing installations → seeded from current sensor state at first update after upgrade
- The seed makes the first computation yield Δ=0 → existing values are preserved
- Sensor-reset detection re-seeds baselines without disturbing cumulative totals
✅ No breaking changes
- Config flow unchanged
- Existing storage data preserved
- HACS update + HA restart, watch values stabilise within 1-2 sensor updates
Full Changelog: v2.0.2...v2.0.3