Skip to content

Kraken: applicableRates fallback treats exc-VAT prices as inc-VAT #5417

Description

@springfall2008

Describe the bug

When the Kraken (EDF / E.ON) component cannot get import rates from the REST products API it falls back to the GraphQL applicableRates query. kraken.py stores the single value that query returns as value_inc_vat, on the assumption that it includes VAT.

The BottlecapDave-derived EDF integration (stevekirtley/HomeAssistant-EDFEnergy, api_client/agreement_tariffs.py) states the opposite — "applicableRates publishes exc-VAT prices only" — and scales the values up before using them. If that is right, Predbat's import rates on the fallback path are 5% low whenever VAT is 5%.

Who is affected

Only tariffs REST cannot serve, which take the fallback every cycle:

Tariffs served by REST read value_inc_vat directly and are not affected. Export is not affected (no VAT).

Why nobody will notice yet

GB domestic electricity is zero-rated for VAT from 1 October 2026 to 31 March 2027, so exc-VAT and inc-VAT are the same number today. The error would appear on 1 April 2027.

Evidence and its limits

  • Live schema introspection (EDF, E.ON, Octopus): ApplicableRate has only value, validFrom, validTo, with no descriptions — the schema does not say either way.
  • The exc-VAT claim is the EDF integration author's assertion in code, tests and a commit message. No raw applicableRates value has been compared against a bill here. A user on an affected tariff comparing Predbat's import rate with their bill (after 1 April 2027, or historically) would confirm it.

Proposed fix

Take the VAT multiplier from the import agreement's own standingCharge / preVatStandingCharge (both are on the TariffType interface on EDF and E.ON) and scale applicableRates import values by it. That is 1.0 during the zero-rate window and 1.05 afterwards with no date logic. Export stays unscaled.

Not covered

The GraphQL applicableStandingCharges fallback is also assumed inc-VAT and is unverified either way.

Activity

  1. springfall2008 commented on Oct 6, 2026

    @springfall2008
    OwnerAuthor

    This is an automated first-pass triage (a maintainer will review before any action is taken).

    Classification: bug · Priority: low — it only affects the GraphQL fallback path and only diverges once VAT stops being zero-rated (1 April 2027), and the fix is already open as PR #5418.

    Verified against current main (v9.3.5-9-g82bee43e):

    • The fallback does what the report says: _finalize_graphql_rates stores the raw GraphQL applicableRates value straight into value_inc_vat and derives value_exc_vat = value / 1.05 (apps/predbat/kraken.py:769-770). The "inc VAT" wording in the query comment is Predbat's own assumption; the schema introspection cited in the report proves neither way. Downstream, value_inc_vat feeds the tariff model and the published rate sensors; value_exc_vat is written but read by nothing outside kraken.py.
    • The cited EDF integration does assert exclusivity: api_client/agreement_tariffs.py on its develop branch says "applicableRates publishes exc-VAT prices only" and applies the same cure proposed here — a vat multiplier derived from the agreement's standing_charge / pre_vat_standing_charge, accepted only within 1.0–1.25, applied to import rates only, with the zero-rate window (Oct 2026 – Apr 2027) documented. Checked by reading that file directly; not run against a live account, so the exc-VAT basis remains the reference implementation's interpretation rather than a bill-verified fact.
    • The applicableStandingCharges fallback carries the same inc-VAT assumption (apps/predbat/kraken.py:958) — confirming the report's "not covered" note.
    • The current unit tests bake the assumption in (test_kraken.py asserts value_exc_vat == round(24.57 / 1.05, 4) for a raw value of 24.57), so any fix has to move those assertions with it — which PR fix(kraken): scale exc-VAT applicableRates prices to inc-VAT from the agreement #5418 does.

    On impact: the multiplier, if wrong, scales every import period uniformly, so relative arbitration between cheap window choices is unchanged; what drifts is import-vs-export/solar economics and the agreement between Predbat's published rates and the bill. That, plus the deferred appearance date, is behind the low rating.

    Trigger paths confirmed in the code: EDF day/night tariffs return HTTP 400 on the REST rates endpoint (see #5166) and products retired from REST return 404/410 (cf. #3763) — both take the fallback every cycle, as described.

    No unit test run in this pass: the open question (what the provider's value field actually means) is not something a test of Predbat's own code settles, and the current tests just restate the assumption. PR #5418's verification description covers their side.

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

    BOT_TRIAGEDHas been through the triage botbugSomething isn't workingpriority_low

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions