Skip to content

Add historical rate-mean fallback for short forward rate windows#3958

Open
Scanlia wants to merge 1 commit into
springfall2008:mainfrom
Scanlia:feat/rate-history-fallback
Open

Add historical rate-mean fallback for short forward rate windows#3958
Scanlia wants to merge 1 commit into
springfall2008:mainfrom
Scanlia:feat/rate-history-fallback

Conversation

@Scanlia
Copy link
Copy Markdown

@Scanlia Scanlia commented May 25, 2026

This adds an optional fallback for rate_replicate that uses historical rate data instead of a flat last-known rate when the rate sensor only publishes a short forward window (e.g. Amber Australia ~16h). When enabled, Predbat queries HA recorder history and builds a per-half-hour-of-day mean profile, restoring the diurnal price shape for the plan horizon.

Changes

fetch.py — New build_rate_history_buckets(entity_id, days, scaling) method. Walks HA history via step-function lookup (one sample per half-hour slot per day), resistant to transient spikes. Empty buckets fall back to overall mean. Modified rate_replicate to accept optional history_buckets — history only fills slots with no 24h-back match; existing fallback chain is unchanged.

config.py — New rate_history_days_average input_number (0–30, default 0 to disable). Four new APPS_SCHEMA entries for source entities and scaling multipliers.

test_rate_history_average.py — 9 sub-tests: disabled, no history, unavailable states, scaling, diurnal shape, spike resistance, replication integration, 24h-back preference, backward compatibility.

docs/apps-yaml.md + docs/energy-rates.md — Documented all 5 new config options.

Config

  rate_history_days_average: 7        # 0 to disable (default)
  rate_history_source_import: sensor.amber_general_price
  rate_history_scaling_import: 100.0  # $/kWh → c/kWh

Compatibility

Feature is off by default. No behaviour change when rate_history_days_average is 0.

Adds rate_history_days_average parameter. When > 0, predbat fetches N
days of HA recorder history for the rate source entity, builds 48
half-hour-of-day mean buckets, and uses them as a fallback in
rate_replicate() when neither 24h-back copy nor modulo lookup matches.

Without this, users whose rate sensor only publishes a short forward
window (Amber Australia: 16h; some fixed-tariff template sensors) fall
to the rate_last constant repeat, which kills diurnal shape in the
plan window past the sensor's coverage.

Bucket builder uses step-function rate-at-time sampling: for each
historical 30-min slot in the lookback window, the rate in effect at
that slot start is sampled (latest history row with ts <= slot start).
One sample per slot per day — no spike bias from HA's minimal_response
returning only state-change events.

Defaults: feature disabled (rate_history_days_average=0). Existing
behavior unchanged when off.

Tests: 9 new subtests covering disabled mode, empty history, all-bad
states, scaling, diurnal shape recovery, spike resistance, and
rate_replicate integration. Existing rate_replicate suite still
passes.
Copilot AI review requested due to automatic review settings May 25, 2026 09:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a “rate history average” fallback so Predbat can fill forward-rate gaps using Home Assistant recorder history, preserving diurnal price shapes when live sensors don’t publish a full 48h window.

Changes:

  • Implemented historical half-hour bucket mean builder and integrated it into rate_replicate as a fallback.
  • Added configuration options (days/source/scaling) and documented them in the energy rates and apps.yaml docs.
  • Added a dedicated unit test suite and registered it in the test runner.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
docs/energy-rates.md Documents the new historical-mean fallback behavior and configuration.
docs/apps-yaml.md Lists the new configuration keys and their meaning.
apps/predbat/fetch.py Implements history bucket building and uses it in rate_replicate; adds config parsing.
apps/predbat/config.py Exposes new settings in expert mode and extends config schema.
apps/predbat/unit_test.py Registers the new test suite in the unit test runner.
apps/predbat/tests/test_rate_history_average.py Adds coverage for bucket building and replicate behavior with/without history.

Comment thread apps/predbat/fetch.py
Comment on lines +1459 to +1460
offset = 30 - (slot.minute % 30)
slot = (slot + timedelta(minutes=offset)).replace(second=0, microsecond=0)
Comment thread apps/predbat/config.py
"rate_history_source_import": {"type": "string", "empty": False},
"rate_history_source_export": {"type": "string", "empty": False},
"rate_history_scaling_import": {"type": "float"},
"rate_history_scaling_export": {"type": "float"},
# -----------------------------------------------------------------------------
# Predbat Home Battery System
# Copyright Trefor Southwell 2026 - All Rights Reserved
# This application maybe used for personal use only and not for commercial use
Comment thread apps/predbat/fetch.py

def rate_replicate(self, rates, rate_io={}, is_import=True, is_gas=False, history_buckets=None):
"""
We don't get enough hours of data for Octopus, so lets assume it repeats until told others.
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