Skip to content

fix(octopus): keep the dispatch rate on an elapsed half hour until Octopus lists it as completed (#5520) - #5533

Merged
springfall2008 merged 3 commits into
mainfrom
fix/octopus-hold-elapsed-dispatch-5520
Oct 14, 2026
Merged

springfall2008 merged 3 commits into
mainfrom
fix/octopus-hold-elapsed-dispatch-5520

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

Fixes #5520.

Problem

A planned Octopus Intelligent dispatch only covers what is still to come. The Octopus API component advances the start of a running dispatch to now (trim_started_dispatch()), and an ended one is dropped, while Octopus lists it in completedDispatches 15 to 60 minutes later. Since #4114 a planned dispatch is deliberately not promoted to completed, so in between nothing covers the half hour: it goes back to the day rate, and because today_cost() prices every elapsed minute from the current rate table, cost_today steps up after each half hour of car charging and falls back when the completed dispatch arrives.

Fix

Each cycle, after the slot confirmation check (dynamic_load_car_check()), Predbat records the half hour a planned dispatch is running in. Once no planned dispatch covers that half hour any more, it goes back into octopus_slots as a finished dispatch, so it keeps the dispatch rate.

This is done on the Predbat side (octopus_held_update() / octopus_held_dispatches() in octopus.py, called from fetch.py) rather than in the Octopus API component, because that is where the cancel decision lives. It therefore also covers the Home Assistant Octopus Energy integration and Ohme sources.

Points for review

Testing

  • New test octopus_dispatch_hold (11 scenarios: the report's rolling start, completed taking over, a zero-energy completed, expiry, cancelled, cancelled after charging, mid-half-hour end, not-yet-started, ineligible sources, compare runs, midnight, slot confirmation off).
  • ./run_all --quick and pre-commit pass.
  • The test follows the fetch order rather than running fetch_sensor_data() itself, and no real debug dump was replayed.

Also adds a note to docs/car-charging.md and a row to tools/debug-journal.md.

🤖 Generated with Claude Code

…h ran in until it is listed as completed (#5520)

A planned Octopus Intelligent dispatch only covers what is still to come: the
Octopus API component advances the start of a running one to now, and an ended
one is dropped, while Octopus lists it as completed 15 to 60 minutes later. In
between the half hour went back to the day rate, and as today's cost is priced
from the current rates the day's cost stepped up after each half hour of car
charging and fell back when the completed dispatch arrived.

Each cycle, after the slot confirmation check, remember the half hour a started
planned dispatch is running in unless the car was cancelled in it, and put it
back into the slots as a finished dispatch until a completed dispatch overlaps
it or OCTOPUS_DISPATCH_HOLD_MINUTES (90) have passed. A dispatch still to start
is never held.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@springfall2008
springfall2008 marked this pull request as ready for review October 13, 2026 08:09
Copilot AI balanced review requested due to automatic review settings October 13, 2026 08:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Ended stale planned entries can be incorrectly recorded as genuine dispatches, creating phantom cheap half-hours.

1 open finding
What changed in this PR

This PR preserves Octopus Intelligent dispatch rates while awaiting completed-dispatch confirmation.

Changes:

  • Tracks eligible running dispatch half-hours for 90 minutes.
  • Integrates held slots into rate calculation without forcing replans.
  • Adds regression tests and documentation.
File Description
apps/​predbat/​const.py Defines the 90-minute hold period.
apps/​predbat/​predbat.py Initializes dispatch-hold state.
apps/​predbat/​octopus.py Implements held-dispatch tracking and pricing.
apps/​predbat/​fetch.py Integrates held slots into fetch cycles.
apps/​predbat/​tests/​test_octopus_dispatch_hold.py Tests dispatch-hold scenarios.
apps/​predbat/​unit_test.py Registers the new tests.
docs/​car-charging.md Documents temporary rate retention.
tools/​debug-journal.md Adds troubleshooting guidance.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/predbat/octopus.py Outdated
CI and others added 2 commits October 14, 2026 08:25
…on the exact clock (#5520)

A planned entry still listed after its end passed the running check while its
half hour was current, so one first seen after it ended was held without ever
being seen running - and dispatch_billed_off_peak() takes an ended entry as
finished, so an AWAY one became a phantom cheap half hour. Require the exact
clock to be before the dispatch end as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@springfall2008
springfall2008 merged commit 9bbe3f7 into main Oct 14, 2026
2 checks passed
@springfall2008
springfall2008 deleted the fix/octopus-hold-elapsed-dispatch-5520 branch October 14, 2026 07:31
chalfontchubby added a commit that referenced this pull request Oct 15, 2026
…-planned-slots-5339

Conflicts:
- apps/predbat/fetch.py (fetch_sensor_data_cars): main (#5520/#5533) now
  collects the planned dispatches a car uses into planned_used, inserts the
  held half hours from octopus_held_dispatches() ahead of them and records
  them in octopus_slots_planned for octopus_held_update(). This branch
  filtered the planned dispatches through smart_control_off_slots() while
  Smart Control is off. Combined: the filtered list (planned_kept) is what
  the plugged-in check gates, so the held dispatches, octopus_slots and
  octopus_slots_planned all see only the dispatches Predbat still uses. A
  re-tagged charger-schedule slot is not billed off-peak, so it is never
  held; a half hour already held from before Smart Control went off stays
  held until the completed list has it, as Octopus billed it off-peak.
- apps/predbat/octopus.py (imports): keep both OCTOPUS_MANUAL_DISPATCH_SOURCES
  (this branch) and OCTOPUS_DISPATCH_HOLD_MINUTES (main).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
springfall2008 added a commit that referenced this pull request Oct 16, 2026
…ark GH#5520 fixed (#5533) and the GH#5548 new-install gap fixed (#5553) (#5557)

Co-authored-by: CI <ci@example.com>
Co-authored-by: Claude Code <noreply@anthropic.com>
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.

Octopus API: a just-finished half hour of a running Intelligent dispatch is re-priced at day rate until completedDispatches lists it

2 participants