github springfall2008/batpred v9.7.0
Octopus/Kraken billing in History, ~95% fewer GE Cloud API calls and an MCP security fix

one hour ago

What's Changed

This release shows what Octopus and Kraken (EDF, E.ON Next) actually billed you beside Predbat's own cost in the History view. It cuts GE Cloud API calls by about 95%, ahead of GivEnergy's new monthly limit of 10,000 calls. It also closes a security hole in the MCP server. Planned exports must now pay their way in the expected forecast, so you should see fewer exports that lose money. There are also fixes for Control SOC only charging, Sunsynk battery size and Solcast's PV10/PV90 band.

Action needed if you use MCP with the default secret: set your own mcp_secret, or the MCP server will not start. Every OAuth client has to authorise again once after upgrading. See the Security section below.

New features

  • Octopus/Kraken billing in the History view. If you set octopus_api_key or use the Kraken component, Predbat now reads your supplier's half-hourly billing and shows it next to its own recorded cost in the Plan page's History view. That answers "was I billed what Predbat said I'd be billed?".

    • New Billed and Diff columns after Cost. Hover over Billed to see the supplier's rate buckets.
    • A summary strip compares Predbat's cost with the billed cost and kWh with the meter. It also shows both standing charges, how far the billing reaches and any missing half-hours.
    • A 7-day day picker, with a dot on days that had a saving session, free electricity session, Axle event or rate override. Expect a Diff on those days, because the bill doesn't price them the way Predbat did.
    • New sensor.predbat_billing holds the last 7 days of billing per meter, refreshed every 3 hours. New predbat.plan_history holds the replayed days.
    • New binary_sensor.predbat_rate_override_import / _export are on while the current slot's rate is a manual rate or an apps.yaml rates_import_override / rates_export_override.
    • Any figure Predbat can't trust is shown as "—", not as a wrong number.
    • Billing appears as soon as it arrives. Octopus publishes export about a day after import, so a recent half-hour can show its import charge marked "(import, export not billed yet)", with no Diff, until the export lands.
    • Only Octopus has been checked against a live account so far. Users who get rates only through the HA Octopus Energy integration, without octopus_api_key, don't get billing.

    @springfall2008 in #5926 and #6009

  • GE Cloud: about 95% fewer API calls. GivEnergy is introducing a monthly limit of 10,000 API calls per account, with a charge for going over it. On one inverter with default settings, Predbat's calls fall from about 13,800 a day to about 700.

    • Registers are read by purpose instead of all of them every 10 minutes. The control registers Predbat uses are read at start-up and every 12 hours. All other registers are read at most every 7 days, or when a new device is found. Predbat already updates its own copy from each write, so the changes it makes need no re-read.
    • A change you make in the GivEnergy app can now take up to 12 hours to show in Predbat, or 7 days for a register Predbat doesn't control. Set ge_cloud_poll_settings: true to bring back the old 10-minute sweep.
    • Live data (inverter status, meter, EV charger) is polled every 5 minutes instead of every 2. Device info is read daily.
    • Inverters that GE Cloud says export at full power in Eco mode keep Eco on during exports, which saves two writes per export.

    @springfall2008 in #6005

Security

  • MCP: /oauth/register no longer hands out mcp_secret. Anyone who could reach the MCP port (8199) could register, read the secret and use it to control Predbat. MCP is off by default (mcp_enable: false), so only installs that turned it on were affected. @chalfontchubby in #5992, fixes #5847
    • The MCP server will not start with an empty or default mcp_secret. Set your own. Until you do, the MCP component reports as failed, /api/ping returns 500 and the status page says Predbat is not running, but planning carries on normally. If something restarts your container from /api/ping, set a secret first.
    • Tokens are now signed with a random key, so each OAuth client has to authorise once more after upgrading. Changing mcp_secret still revokes every token.
    • Token scopes are enforced: set_config and set_plan_override need mcp:write or mcp:control.
    • The authorise page is hardened against crafted links.

Plan and battery behaviour

  • An export must pay its way in the expected forecast. A planned export now has to improve the expected (nominal) cost on its own. An export that only looked good because of the optimistic PV90 scenario is now dropped, where before it could never be removed once it had been planned. On the dump from #5969 this removes the evening exports the reporter complained about, and the expected cost falls from 548.76p to 523.76p. @springfall2008 in #5977, refs #5969

  • Solcast: PV10 and PV90 follow the calibrated forecast. PV calibration moved Solcast's central forecast but left its 10% and 90% figures on the raw curve. So PV90 could overstate the upside, and PV10 could end up above the central forecast. Both are now scaled with it and held to the array's ceiling. This applies to the Solcast API and the HA integration. @springfall2008 in #5974, refs #5969

  • Control SOC only: a running charge is treated as a charge. When the inverter ran its own charge window, Predbat counted it as no charge:

    • the status showed Demand and binary_sensor.predbat_charging was off;
    • the target could be reset to 100% (with inverter_soc_reset on);
    • set_freeze_export_during_demand could pause the charge;
    • a near-tie could swing the target part way through the charge.

    The commands Predbat sends are unchanged. In every mode, the planner's preference for keeping a running charge rises from 0.1p to 0.5p, the same as a running export already has. @springfall2008 in #6001, fixes #5991

  • Sunsynk: battery size is measured, not taken from Batt Capacity. The inverter's Batt Capacity is a figure typed in at commissioning. On one install it was half the real bank, so the battery was planned as 7.2 kWh and the forecast showed it emptying hours early.

    • Predbat now estimates the size from the BMS, usually after one night's charge, and uses Batt Capacity only until then.
    • A soc_max in apps.yaml now always wins.
    • New sensor.predbat_sunsynk_<serial>_battery_power_bms.

    @springfall2008 in #6007

  • Export start time kept while an export runs (all inverters). An export running up to midnight, or straight into a charge slot, had its start time rewritten to "now" every 5 minutes. Now it is left alone. @springfall2008 in #6005

  • Teslemetry, SolaX and Sigenergy act on the minute. These components start and end windows from their own loop, which ran at whatever second Predbat started and drifted later. So exports could start up to a minute late. They now run 1 second past each minute. Sigenergy window durations are also rounded up, so a command sent at 16:00:01 for a 16:00–16:30 window asks for 30 minutes, not 29. @springfall2008 in #5976

  • set_reserve_min can't be set below the inverter's floor. Home Assistant and the web /config slider allowed values below battery_min_soc, which Predbat then quietly raised. The slider's minimum is now the real floor. @springfall2008 in #6000, fixes #5995

Web UI

  • Discovery info on the Components page. Each component that reports to the discovery catalogue gets a teal ⓘ button and a Discovery line ("1 inverter", "2 meters, 1 car"). Tap either to see what it found, such as your inverter's serial or what Predbat can control on it. @springfall2008 in #5945
  • Components page fits a phone screen. @springfall2008 in #5952
  • Charts no longer zoom from a drag on the title. That made the Compare page hard to scroll on a phone. @springfall2008 in #5980, fixes #5979

Documentation

  • Octopus saving sessions (Power Down): explains why a battery that already covers your evening peak may earn little from a session, and which settings reduce a session's pull on the plan. @upton68 in #5989
  • PV10/PV90 described as the pessimistic and optimistic scenarios, with guidance on scaling load_scaling10 and load_scaling90 along with load_scaling. No settings are renamed. @chalfontchubby in #5949
  • Debug journal compacted from 730KB to 126KB and updated with recent investigations. @springfall2008 in #5988 and #5993

For developers

  • Owner gate: it no longer fails the run while it waits, so contributors stop getting "run failed" emails. It now records its verdict as a commit status, so a PR whose checks are all green is no longer stuck at "Waiting for status to be reported". @springfall2008 in #5978, #6004 and #6008
  • Triage bot: higher turn limits, and an issue whose triage label was swapped is no longer triaged a second time. @springfall2008 in #5981 and #5985
  • Random scenario tests: car slots no longer leak between runs of the same scenario. @mgazza in #5946

Full Changelog: v9.6.5...v9.7.0

Don't miss a new batpred release

NewReleases is sending notifications on new releases.