Skip to content

5.130.0: the 50% overnight minimum holds when Flux cannot plan - #1

Merged
Highsteads merged 3 commits into
mainfrom
fix/cheap-window-minimum
Oct 1, 2026
Merged

Highsteads merged 3 commits into
mainfrom
fix/cheap-window-minimum

Conversation

@Highsteads

Copy link
Copy Markdown
Owner

Not deployed. This is for review before anything is installed or released.

What went wrong on 1 October

  • Octopus published October's Flux import prices (13.92p cheap, 23.19p day, 32.48p peak) but no export price after midnight, in any region. The account is still on E-1R-FLUX-EXPORT-23-02-14-F, open-ended.
  • With no export price, derive_bands refused (correctly: it must not invent a price), so Flux deferred from 00:00 onwards. It was still deferring at 13:40, so there is no Flux peak sale today either.
  • The ordinary manager bought to its own household target of 44%, went back to self consumption at 03:48 and ran the house on the battery. The battery was at about 42% at 5am against the agreed 50%.
  • The 50% rule lived only inside the Flux planner, so it lapsed with it.

What changes

  • One rule, two users: flux_strategy.cheap_window_minimum_pct() gives 50% in 02:00-05:00, or nothing on a day with a booked free hour. Flux and the manager both read it.
  • Manager fallback: while Flux is not running the window, the manager charges to the highest of the 50% minimum, tomorrow's need and the reserve, then holds until 05:00 with the house on the cheap grid. It never buys for the peak.
  • Handing back to Flux: once the manager's charge is only holding, Flux can plan and take the window back.
  • Late-window sizing: the minimum is now sized on the real time left; it used at least 15 minutes. Shortfalls are reported.
  • 5am report: at 5am the Event Log says the battery level actually reached against the minimum. It is a warning if below 50%. Each night is also written to cheap_window_results.jsonl.
  • Clearer message: "no Flux decision" now names the missing side and the time, for example "Octopus has not published the Flux export prices beyond 00:00 on 1 October".

Checks

  • 36 new tests, built on the real published spans from 30 September and 1 October.
  • Eleven mutations, all caught.
  • Full suite 2,367, lint clean.
  • All 29 simulator scenarios are unchanged.

🤖 Generated with Claude Code

Clive and others added 3 commits October 1, 2026 13:51
1-Oct-2026: Octopus published October's Flux import prices but no export
price after 00:00 BST (every region; the account is still on
E-1R-FLUX-EXPORT-23-02-14-F). derive_bands refused, Flux deferred all night,
and the manager's ordinary import bought to its household target (44%),
returned to self consumption at 03:48 and ran the house on the battery: about
42% at 5am against the agreed 50%.

- flux_strategy 2.10: cheap_window_minimum_pct() is the one owner of the
  rule (50% in 02:00-05:00, none on a booked free-hour day). _minimum_charge
  sizes power on the real time left (was at least 15 minutes, so 04:55 asked
  for a third of what was needed) and reports a shortfall. bands_problem()
  names the missing side and when coverage stops.
- battery_manager 3.15: when Flux is not running the window, the manager
  charges to max(minimum, tomorrow, reserve) and holds to 05:00 with the
  house on the cheap grid. Never buys for the peak.
- plugin: drives that hold (cutoff at the level, discharge 0), ends it at
  05:00 whatever it reached, lets Flux take the window back once holding,
  and logs what 5am actually achieved to the event log and
  cheap_window_results.jsonl.

36 tests; eleven mutations, all caught. Simulator unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both kept: the planner reads _flux_planning_spans, and bands_problem() names
what is missing from the carried spans when the bands still refuse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	README.md
#	SigenEnergyManager.indigoPlugin/Contents/Info.plist
#	SigenEnergyManager.indigoPlugin/Contents/Server Plugin/plugin.py
#	docs/changelog.md
#	docs/plugin-changelog.md
@Highsteads
Highsteads merged commit 49c64ac into main Oct 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant