You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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...
🤖 Automated first-pass triage. A maintainer will review this before any action is taken.
Classification:bug — Priority:priority_medium
What I checked
Version confirmed as v8.38.0 from your predbat_debug.yaml (installed_version: v8.38.0), investigated against current main (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_low no 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_predbat publishes saving_adjusted, but the running total accumulates saving (the unadjusted figure):
apps/predbat/output.py:3350 — self.savings_today_predbat = saving ← real
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. The savings_yesterday_pvbat pair does not have this mismatch — output.py:3425 and :3458 both use the adjusted value. This is unchanged on current main.
Root cause 2 — the battery-value adjustment charges the SoC level, not the day's change
output.py:3129 and :3219 subtract the closing stored-energy value from each side:
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's battery_value_yesterday of 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_soc is never clamped to soc_max. Your dump has soc_max: 19.04 kWh (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 at output.py:3043 with 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_yesterday rolling from the stale 26.54 to 17.75 when the 1am total-increment runs (predbat.py:1183, gated on minutes_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 current main — 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.
@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.md described savings_total_predbat as a running total of savings_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_adjusted would 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.
Activity
springfall2008 commentedon Aug 25, 2026
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:
saving_realsaving_adjustedstatesavings_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_predbatSo
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:For 05-08:
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.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
calculate_yesterdaybaselinePossibly related; not closing this as a duplicate of any of them.
test(output): fix the #3894 regression test's soc_kwh_history key (Co…
test(output): stop the #3894 regression test discarding shared soc_kw…
chalfontchubby commentedon Sep 14, 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.Merge pull request #5081 from springfall2008/fix/savings-total-docs-3894
docs(output-data): correct savings_total_predbat's description (sprin…
chalfontchubby commentedon Sep 16, 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.
chalfontchubby commentedon Sep 16, 2026
We will close this ticket shortly unless you push back