Repository navigation
Predbat Savings #3894
Description
Activity
🤖 Automated first-pass triage. A maintainer will review this before any action is taken.
Classification:
bug— Priority:priority_mediumWhat I checked
Version confirmed as v8.38.0 from your
predbat_debug.yaml(installed_version: v8.38.0), investigated against currentmain(v8.53.2-37-g12412a7e). Both attachments were used; nothing further is needed from you.#3881 did do its job. Your log shows the baseline is now stable —
rate_lowno longer drifts, and across the 8 recalculations from 02:09 to 09:05 on 05-09 the baseline is identical every time (metric 59.2p, charge window{0–330}+{1410–…}). The oscillation #3872 was about is gone.The value you are still seeing is a separate defect, and it's the one that produces exactly your symptom: total rising, daily negative.
Root cause 1 — the total and the daily sensor publish two different numbers
From your debug file, for 05-08:
attribute value saving_real+86.14p saving_adjusted−25.66p sensor state−25.66 savings_yesterday_predbatpublishessaving_adjusted, but the running total accumulatessaving(the unadjusted figure):apps/predbat/output.py:3350—self.savings_today_predbat = saving← realapps/predbat/output.py:3388— sensorstate=dp2(saving_adjusted)← adjustedapps/predbat/predbat.py:1184—savings_total_predbat += self.savings_today_predbat
So
savings_total_predbat(£740.72 in your dump) is a running sum of the positive real savings, while the daily bar chart shows the adjusted ones. The two series are not the same quantity, which is why the total climbs while the daily bars sit below zero. Thesavings_yesterday_pvbatpair does not have this mismatch —output.py:3425and:3458both use the adjusted value. This is unchanged on currentmain.Root cause 2 — the battery-value adjustment charges the SoC level, not the day's change
output.py:3129and:3219subtract the closing stored-energy value from each side:cost_yesterday_adjusted = cost_yesterday - battery_value_yesterday metric_baseline_adjusted = metric_baseline - battery_value_baseline saving_adjusted = metric_baseline_adjusted - cost_yesterday_adjusted # :3326For 05-08:
- Actual: cost −26.94p, closing SoC 2.67 kWh → battery value 19.75p → adjusted −46.69p
- Baseline: cost +59.20p, closing SoC 17.75 kWh → battery value 131.56p → adjusted −72.35p
- −72.35 − (−46.69) = −25.66p
The 2.67 kWh is genuine — Predbat was force-exporting straight through midnight (
00:03:19: Exporting now - current SoC 2.666kWh and target 1.52kWh). But both sides were energy-neutral across the day: the baseline started and ended at 17.75 kWh (log:start_soc 17.75kWh, final_soc 17.75kWh), and the real system started 05-08 at ~2.6 kWh (implied by the previous day'sbattery_value_yesterdayof 19p) and ended at 2.67 kWh. Neither consumed any net stored energy, so neither should attract a battery-value correction at all.Because the adjustment uses the closing level rather than the change over the day, the constant 15 kWh level difference between the counterfactual battery and the real one is billed as a ~112p penalty every single day, in perpetuity — which is what flips a real +86p saving to −26p. The counterfactual's SoC chains from its own previous close (
predbat.py:1186,savings_total_soc), so it stays parked near full forever while a system that profitably exports overnight sits near empty. Any user whose export strategy empties the battery over midnight will see this permanently.A day-over-day comparison would need the battery-value term applied as (closing − opening) on each side; today only the closing term exists.
Secondary observations
savings_total_socis never clamped tosoc_max. Your dump hassoc_max: 19.04kWh (2 × 9.52), but the 05-08 20:35 run started the baseline at 26.54 kWh — 39% above the battery's capacity. It is read straight from the sensor atoutput.py:3043with no bound. That inflates the baseline's starting energy and depresses the apparent saving.- Residual once-a-day step. The 05-09 figure was −57p at 00:06 and −56p at 01:09, then settled at −25.66p from 02:09 onward. That single jump is
soc_yesterdayrolling from the stale 26.54 to 17.75 when the 1am total-increment runs (predbat.py:1183, gated onminutes_now > 60). Small compared to the above, but it does mean the value published in the first ~2 hours after midnight is computed from the wrong starting SoC.
Test
Ran
calculate_yesterday(the only test module that maps cleanly here) against currentmain— passes (exit 0). Neither the total-vs-daily consistency nor the level-vs-delta adjustment is covered by it, so a green suite is expected and doesn't contradict the above.Related
- Predbat Savings #3872 / Fix savings_yesterday_predbat fluctuating throughout the day on dynamic tariffs #3881 — the prior report and its (effective) fix
- Cost saving analysis (with or without Predbat) starting SOC discrepancy #3676 — baseline starting-SoC discrepancy, same
calculate_yesterdaybaseline - Discrepancy in the Metrics savings and the Apex Chart Savings #3541, Total Predbat savings is negative #1485 — other reports in this savings-reporting area
Possibly related; not closing this as a duplicate of any of them.
- addedbugSomething isn't workingSomething isn't workingBOT_TRIAGEDHas been through the triage botHas been through the triage botand removedBOT_REVIEWTrigger an autotriageTrigger an autotriage
on Aug 25, 2026 (Posted by Rik; written by Claude.)
@springfall2008 Closed #5061 given your answer - the total is correctly real, not adjusted, and I'd left that PR pointed the wrong way.
The docs were the actual bug:
output-data.mddescribedsavings_total_predbatas a running total ofsavings_yesterday_predbat's own state, which it never has been - the sensor's displayed state is the adjusted figure, the total accumulates the real one. Fixed that description separately so it says what's actually true.One open question that description-fix doesn't answer: should
savings_yesterday_predbat's own displayed state switch from adjusted to real, so the daily bars visibly reconcile with the (real) running total - i.e. non-negative days that add up to the total actually rising, rather than a daily figure that can legitimately dip below zero next to a total that keeps climbing?saving_adjustedwould stay available as an attribute either way. That's the original reporter's actual complaint (daily negative, total positive, 'shouldn't the total be the sum'), and it's a call about what the daily sensor is for rather than a bug fix, so I didn't want to make it without you weighing in.- added a commit that references this issue
on Sep 14, 2026 - added a commit that references this issue
on Sep 15, 2026 After going round in circles with patches for a while, the conclusion seems to be this is behaving as intended, but the docs were poor.
Docs are updated. No intention to actually change the code at this point.
- addedAUTOCLOSE_CANDIDATEIf we don't hear back, this issue will be autoclosed in around a week.If we don't hear back, this issue will be autoclosed in around a week.
on Sep 16, 2026 We will close this ticket shortly unless you push back
See #3872 and #3881. I tried to reopen my original issue as I don't believe it is fixed but I don't have permission.
From the release notes it appears 3881 was packaged in v8.38.0 which I have been running for a couple days. My daily savings chart still shows negative values...
Here are the total and daily savings for the last three days. The daily values are still fultuating and (IMHO) shouldn't be negative if the total is steadily increasing...
Debug and log files...
predbat.log
predbat_debug.yaml.txt
Please can you have another look.