Add Feed-in Tariff (FIT) payment feature for solar self-consumption optimisation#2
Merged
Merged
Conversation
Extract FIT generation and deemed export income from the yesterday prediction simulations in calculate_yesterday() and publish a new predbat.fit_income_yesterday sensor so users can see yesterday's FIT income breakdown alongside the existing savings sensors. https://claude.ai/code/session_01BCLRCPFLDp96Ck2vWMiX12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Users on legacy UK Feed-in Tariff (FIT) schemes receive a generation tariff on all solar produced and a deemed export payment on a fixed percentage (typically 50%) of generation — regardless of how much electricity actually flows to the grid. This means actual export has zero additional value for these users. The optimal strategy is self-consumption: using solar to charge the battery and offset imports (~25–35p/kWh) rather than spilling it to the grid.
Predbat's optimizer previously treated any non-zero export rate as real income and would charge the battery to 100% from cheap overnight grid slots, leaving no headroom for the next day's solar. For a FIT user this is counterproductive — it forces solar to spill to the grid (earning nothing extra) instead of charging the battery.
Changes
Three new Expert Mode config items (
config.py)metric_fit_generation_ratemetric_fit_deemed_export_ratemetric_fit_deemed_export_percentageWhen
metric_fit_generation_rate > 0, FIT mode is active.How the optimiser changes (
prediction.py)The per-minute
export_rateis zeroed insiderun_prediction()when FIT is active. The grid-search optimiser inplan.pyevaluates charge/discharge windows against the cost metric returned byrun_prediction(), so this single change propagates everywhere: plans that rely on exporting lose their apparent payoff, and plans that self-consume solar win naturally — leaving battery headroom for the next day's solar without any separate heuristic.FIT generation income and deemed export income are tracked per simulation step and subtracted from the cost metric so predicted cost/savings figures reflect actual FIT earnings.
New HA sensors
predbat.fit_incomepredbat.fit_income_bestpredbat.fit_income_yesterdayAll sensors include attributes:
generation_income,deemed_export_income,generation_rate,deemed_export_rate,deemed_export_percentage. Sensors are only published when FIT is enabled — non-FIT users see no change.Yesterday savings calculations (
output.py)The FIT export zeroing already applied correctly to both yesterday simulations (the
Predictionobject inherits FIT config from the PredBat instance). Added extraction of FIT income from those simulations and publication of thefit_income_yesterdaysensor so users can see yesterday's FIT income breakdown.Backwards compatibility
Fully opt-in and defaults off. With
metric_fit_generation_rate = 0(the default), every code path is a no-op and behaviour is identical to the currentmain. Existing non-FIT users see no change in plans, metrics, or sensors.Files changed
config.pyCONFIG_ITEMSentries (Expert Mode)fetch.pyprediction.pyplan.pyfit_income/fit_income_bestoutput.pyfit_income_yesterdaytests/test_infra.pyMockConfigProviderandreset_inverter()CLAUDE.mdTest plan
./run_allfromcoverage/)reset_inverter()set FIT defaults to off so every existing test boots with FIT disabledhttps://claude.ai/code/session_01BCLRCPFLDp96Ck2vWMiX12