Skip to content

fix(octopus): keep Intelligent dispatch markers when export/gas rates are fetched (#5286) - #5290

Merged
springfall2008 merged 2 commits into
mainfrom
fix/io-adjusted-wiped-by-export-5286
Sep 28, 2026
Merged

springfall2008 merged 2 commits into
mainfrom
fix/io-adjusted-wiped-by-export-5286

Conversation

@chalfontchubby

Copy link
Copy Markdown
Collaborator

Addresses #5286. Draft: being dogfooded on a real BottlecapDave (BDC) + Intelligent Octopus Go system before review.

Problem

Since #2826 (v8.27.0, Oct 2025), fetch_octopus_rates() has replaced self.io_adjusted on every call. fetch_sensor_data() calls it for import rates (with adjust_key="is_intelligent_adjusted") and afterwards for metric_octopus_gas and metric_octopus_export (without). Those later calls reset io_adjusted to {}. Before #2826 the assignment only happened when adjust_key was set.

So every BDC Intelligent Octopus user with an export or gas rate sensor has had no dispatch markers at all, even though BDC sends is_intelligent_adjusted: true. This was confirmed on a second BDC 19.1.0 install: HA's stored current_day_rates / next_day_rates events carry the flag, while every Predbat debug dump has io_adjusted: {}.

In #5286 this left dynamic_load_car_strip_feed_rates() (#5229) with nothing to strip. The car's slots were cancelled, but the dispatch stayed priced at 6.9p, and the house battery was planned into it at 15:00 and 15:30.

Changes

  1. octopus.py: fetch_octopus_rates() only replaces self.io_adjusted when called with adjust_key. This restores the pre-Refactor minute_data to utils and fix some issues with energy dashboard #2826 behaviour.
  2. compare.py: now that the markers survive, tariff comparison must not hand the live tariff's markers to a compared tariff that has its own import rates. Each tariff now starts with none. An Octopus import fetch sets its own. A tariff left on the live import rates (no import source, or a bad entity id) gets a copy of the live markers. run_all() restores the live markers afterwards. Before this PR, the export fetch wiped them by accident.

Behaviour change: please read

This switches dispatch-aware logic back on for every affected BDC user. All of it was built or tuned while it was dormant for them, and tested only with hand-set io_adjusted:

Plans for these users will change. The golden coverage/cases all have io_adjusted: {}, so they don't show this.

Testing

  • test_fetch_octopus_rates Test 5a: an export fetch after an import fetch keeps the import's markers. It fails on main.
  • test_compare T26: checks which markers a compared tariff with its own import rates, an existing-rates tariff and a bad-entity tariff each end up with, and that run_all() restores them. Each assertion was checked to fail when its part of the fix is removed.
  • ./run_all --quick and run_pre_commit pass on each commit.
  • Not tested: the whole ESS battery still being planned to charge and charging at peak rate after implementing #5229 #5286 chain end to end through fetch_sensor_data() (flagged import, then export, then a cancelled car, ending with the dispatch at full price).

Follow-ups, not in this PR

  • The compare path never runs dynamic_load_car_strip_feed_rates(), so a compared IOG tariff keeps the markers of a cancelled car's dispatches. This predates this PR.
  • run_all() doesn't restore rate_import / rate_export / thresholds after the loop. This predates this PR and is harmless because the next cycle rebuilds them.

🤖 Generated with Claude Code

chalfontchubby and others added 2 commits September 28, 2026 18:31
… are fetched (#5286)

fetch_octopus_rates() replaced self.io_adjusted on every call, so the export
and gas fetches that follow the import fetch reset it to {} - every
BottlecapDave IOG user with metric_octopus_export or metric_octopus_gas set
lost all is_intelligent_adjusted markers. Regression from #2826, which
dropped the old "only when adjust_key is set" guard.

Among other things this left dynamic_load_car_strip_feed_rates() with
nothing to strip, so a car cancelled by #5229 still left its dispatch priced
cheap and the house battery was planned into it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…its own import rates (#5286)

With io_adjusted no longer wiped by the export fetch, a compared tariff with
its own import rates (URL, flat rates_import, Energi Data Service,
Strømligning) would inherit the live tariff's Intelligent Octopus dispatch
markers, and rate_replicate(), the PV10 prediction and the plan would treat
its minutes as dispatches. Each tariff now starts with none; an Octopus
import fetch sets its own, and a tariff left on the live import rates (no
import source, or a bad entity id) gets a copy of the live markers.
run_all() restores the live markers afterwards.

Co-Authored-By: Claude Opus 5.5 <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.

2 participants