Skip to content

Predbat randomly exports instead of freeze export, often in the peak rate #4453

Closed

Description

@gcoan

Describe the bug
I am on a flat 12p export rate. Daily solar is more than I need, and I have more than enough battery capacity (in summer) to see me through the night.
Therefore an optimal plan is freeze export most of the solar day, with occasional demand periods when SoC drops every few days.

This optimal plan is what predbat produces but quite frequently it changes the plan and puts in an export, and the export is almost always in the peak import rate period, so impacting future Octopus Saving Session revenue.

Expected behaviour
Keep to the original plan of Freeze export

Predbat version
8.46.11

Environment details
HAOS HA 2026.7.4
2x gen 1 givenergy hybrid inverters, 1x AC3, each inverter with its own battery

Screenshots
I noticed Predbat was exporting at 17:40 so turned debug mode on to capture the log. Predbat seemed to hang and wasn't responding so I restarted the addon, when it restarted it then planned split slots, slow rate export in the current and next slot, and demand in the next slot. So as well as the unnecessary export, Demand in the first part of the 18:00 slot would just be incurring unnecessary conversion losses by charging and then discharging the battery

Plan after the restart

image

Predbat status showing the change from freeze exporting to exporting,and then the addon being restarted
image

I don't think this is relevant to the export issue, maybe to the 'hung and not responding' issue, but the logfile shows predbat didn't restart cleanly
image

I think I may have restarted the addon again and this time it came back OK and I could set a force freeze exporting
image

As I said, predbat does this frequently in the peak period, I'm wondering if the peak import rate causes it to think that exporting is more valuable (which it isn't)

Log file
predbat.2.log
predbat.1.log

Predbat debug yaml file
predbat_debug_17_45_00.txt

Activity

  1. gcoan commented on Aug 7, 2026

    @gcoan
    CollaboratorAuthor

    Some additional information/example and an additional wrinkle/bug I encountered

    This morning found predbat was planning a number of exports and demand slots in amongst the freeze exports, no real benefit in doing this and extra battery churn/loss

    Image

    Turned debug mode on to capture the log, and predbat plan changed to demand then freeze export

    Image

    later on (debug off) similar pattern

    Image

    There appears to be an issue that turning debug mode on causes the plan to change, and change quite significantly

    with debug mode off

    Image

    predbat_debug.yaml-2.txt

    turn debug mode on

    Image

    predbat_debug.yaml-3.txt

    turn debug mode off

    Image

    predbat_debug.yaml-4.txt

    log files through this period

    predbat.2.log

    predbat.1.log

    predbat.log

    and debug files I captured:

    predbat_debug_09_05_00.txt
    predbat_debug_08_50_00.txt
    predbat_debug_08_45_00.yaml
    predbat_debug_08_40_00.yaml
    predbat_debug_07_20_00.yaml
    predbat_debug_07_15_00.txt

    so two issues:

    • random demand and then exports when export rate is flat throughout
    • turning debug mode on causes the plan to change significantly, preferring demand over freeze export
  2. chalfontchubby commented on Aug 7, 2026

    @chalfontchubby
    Collaborator

    For the record - predbat was actively logging at the point you restarted it - It does not look like it was in an infinite loop, it was just busy - but debug does force it to use the python kernel and the is way slower than c++, and you have quite a complex system generating a huge amount of spew.

  3. gcoan commented on Aug 8, 2026

    @gcoan
    CollaboratorAuthor

    For the record - predbat was actively logging at the point you restarted it - It does not look like it was in an infinite loop, it was just busy - but debug does force it to use the python kernel and the is way slower than c++, and you have quite a complex system generating a huge amount of spew.

    Thanks, useful to know about debug mode and python kernel. I’m running predbat on a mac m4 mini and its usually very responsive, and since it wasn’t loading the web console nor responding I assumed it had stopped.

  4. chalfontchubby commented on Aug 8, 2026

    @chalfontchubby
    Collaborator

    On the debug-vs-no-debug plan difference specifically - dug into the mechanism and ran a direct test against your data.

    Why it happens: kernel_supported() in prediction_kernel.py is gated on not debug_enable - turning debug on routes every scenario through the Python engine instead of the C++ kernel for as long as it's on. That alone doesn't explain a different plan though - the kernel and Python engine are tightly parity-tested to agree to 1e-6 on identical inputs. The actual cause is a second effect: the optimizer's coarse search pass (enable_fast_mode_levels, on by default, nothing to do with debug) requests a coarser time step to keep the search fast. The kernel silently ignores that and always computes at full 5-minute resolution internally (cheap enough in C++ to just always do it regardless); the Python fallback genuinely honours the coarser step, aggregating PV/load into bigger time buckets before simulating. So in normal (kernel) operation the "fast" pass is secretly exact; in debug mode it's genuinely coarser. On a flat/near-flat rate period, where many different battery decisions cost almost the same, that's enough to tip which near-tied option the search lands on.

    Tested directly against your first debug.yaml (17:45:00 capture from the original report): replayed the same captured state twice through the real optimizer, changing only debug_enable, nothing else. Deterministic and repeatable both ways:

    • 4 of 9 export windows in the 48h plan landed on different SoC targets between the two runs
    • Overall plan cost: kernel -1605.0281p vs debug -1605.0225p - a 0.0056p difference on ~1605p total (if anything, kernel was marginally the cheaper of the two)
    • The windows that differed were all >24h out in the forecast horizon, not the slot you were watching live at the time
    • Recomputing fresh from that 17:45 snapshot, kernel and debug both agreed the immediate window should be frozen, not exported

    So as far as we can tell, neither plan looks "bad" - they're both close to optimal by Predbat's own cost model, just two equally-scored answers to a near-tie. Separately, I checked whether a known future Octopus Saving Session or Axle event was loaded at the time of the original decision (which would make draining the battery then a genuine mistake, not just a coin-flip) - it wasn't; the only saving-session/Axle data present in that snapshot was for already-past dates, so there was nothing upcoming for Predbat to have protected against at that moment.

    Given that, I want to make sure I'm not missing what specifically feels "wrong" here beyond the debug/no-debug mismatch itself, which - per the above - looks like two valid, similarly-priced plans rather than one right and one wrong. If there's something else you'd still call a bug rather than "harmless churn" - the demand slots landing where they do, battery wear from the extra cycling, something in the newer debug.yaml set from this morning - could you spell that out again? Happy to dig into the 07:15-09:05 captures the same way if that's a distinct case worth checking separately.

  5. jHamshaw commented on Aug 9, 2026

    @jHamshaw

    Adding a data point that may be the same root cause, seen on different hardware (Fox ESS H1-G2-6.0-Wl, not GivEnergy), Predbat v8.47.7, on Octopus Intelligent Octopus Go (fixed 6.9p off-peak 23:30-05:30, 30.27p standard rate, 12p flat export).

    Like the OP, I'm seeing the plan discharge/export well beyond what house load or a sensible pre-cheap-window taper would need, specifically during the standard/peak-rate (30.27p) evening period — and it's costing me an unplanned peak-rate import later to bridge the gap to the next cheap window.

    Example (Saturday, actual/historical, not forecast):

    Sat 20:30 30.27p SoC 70%
    Sat 21:00 30.27p SoC 60% cost -31p
    Sat 21:30 30.27p SoC 28% cost -15p
    Sat 22:00 30.27p SoC 10% cost +12p <- min SoC hit, now importing
    Sat 22:30 30.27p SoC 10% cost +12p
    Sat 23:00 30.27p SoC 10% cost +9p
    Sat 23:30 6.90p SoC 10%→ Chrg (cheap window opens)

    A 10-point SoC drop on ~0.38kWh load should be worth roughly 11-12p in avoided import (self-consumption), not -31p — the extra is only explained by force-exporting well beyond load, at 12p, during a period where avoiding 30.27p import would have been strictly better for every kWh discharged. This then leaves the battery empty an hour-plus before the cheap window, forcing exactly the kind of unplanned peak-rate import the OP flags.

    Same shape repeated on the following two nights (Sun→Mon, Mon→Tue) since updating to 8.47.7 — this wasn't happening before the update. One night was clean after an unrelated IOG slot reallocation earlier that day, so it's not literally every night, but frequent enough to be a clear regression rather than an edge case.

    Supports the OP's hypothesis that the peak/standard import rate itself may be causing Predbat to overvalue export relative to self-consumption during that window.

    predbat_debug.yaml.txt

  6. gcoan commented on Aug 11, 2026

    @gcoan
    CollaboratorAuthor

    Another example this morning, can't see an obvious reason why predbat will let the battery charge in demand mode and then export stored charge?

    Image

    predbat.log

    predbat_debug.yaml-5.txt

  7. chalfontchubby commented on Aug 20, 2026

    @chalfontchubby
    Collaborator

    Replayed the attached debug.yaml (predbat_debug.yaml-5.txt, 2026-08-11 08:50 capture) against current main - can't reproduce.

    The plan for that day shows sensible behaviour throughout: FrzExp then Demand from 08:50-13:00 (SoC rises 49%->100% via solar surplus, not grid import, holds steady at 100%), then the only export in the whole day is a legitimate Exp at 18:00 for 14.00p - a genuine high evening peak rate. No unexplained low-rate export anywhere.

    This doesn't confirm why the original screenshot happened, or pin down which specific fix (if any) resolved it - just that replaying the same captured inputs against current code no longer shows the reported symptom. We've been tinkering with freeze-export modelling this session (#4207/#4582), so it's plausible that's related, but not confirmed. Given it's not reproducing, happy to close if you agree - otherwise let us know if it recurs and we'll take another look.

  8. jHamshaw commented on Aug 21, 2026

    @jHamshaw

    Given the rapid pace of change this week I've been monitoring thsi and from my perspective it appears to have been resolved...

  9. gcoan commented on Aug 29, 2026

    @gcoan
    CollaboratorAuthor

    Given there have been code changes since this occurred I will close this. The points about the plan being potentially different for debug and non debug mode is interesting, perhaps something for the FAQ's?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions