Description
When the battery needs more capacity than the discharge rate can deliver within the best-priced export window, Predbat pulls the extra discharge from a much cheaper, non-adjacent hour instead of from the better-priced hours immediately next to the main window. This leaves higher-priced hours completely unused while discharging at a worse price further away in time.
Environment
Predbat version: v8.45.3
Inverter: Kostal (soc_max 42.53 kWh, discharge rate 10.8 kW)
Relevant config: combine_rate_threshold(2.0), metric_min_improvement_export(3.0øre), metric_min_improvement_export_freeze(3.0øre), metric_battery_cycle(4-6øre/kWh), inverter_loss(5%), battery_loss(4%), battery_loss_discharge(4%), inverter_hybrid(True)
Evidence
Plan computed 2026-07-18 19:03:29, Export windows filtered:
18-07 19:50:00 - 18-07 20:00:00 @ 78.88øre -> target 91%
18-07 20:00:00 - 18-07 21:00:00 @ 92.28øre -> (not present, target stays 91%)
18-07 21:00:00 - 18-07 22:00:00 @ 100.80øre -> (not present, target stays 91%)
18-07 22:00:00 - 19-07 01:00:00 @ 104.01øre -> target 9%
So the battery is planned to discharge from 91% down to 9% (82 percentage points ≈ 34.9 kWh of a 42.53 kWh battery) entirely within the 22:00-01:00 (~104øre) window, while the 92.28øre (20:00-21:00) and 100.80øre (21:00-22:00) hours in between are left completely untouched (SoC held flat), and a small early discharge is instead taken at 78.88øre (19:50-20:00) — the worst price of the four candidate hours.
Analysis
The discharge rate is 10.8 kW, so the 3-hour window (22:00-01:00) can deliver at most 3 × 10.8 = 32.4 kWh — less than the 34.9 kWh the plan wants to move in that window. So it makes sense that some discharge has to happen outside the main window due to the power limit.
However, if extra time is needed, it should be taken from the best available adjacent price first (100.80øre @ 21:00, then 92.28øre @ 20:00) before resorting to a cheaper, more distant hour. Instead the plan skips both of those and discharges at 78.88øre, which is worse than both of the skipped hours. This looks like the price-level sweep in the optimiser (Optimise price set X, pass normal/trim/low) accepts a lower price threshold that happens to improve the metric, without checking whether an already-available higher-priced adjacent hour would have covered the same shortfall more cheaply.
Internal trace showing the threshold being accepted:
2026-07-18 19:03:25.362214: Optimise price set 92.2øre, pass normal, price 92.28øre ... best_metric -5023.92øre (no improvement)
2026-07-18 19:03:25.393257: Optimise price set 78.8øre, pass normal, price 78.88øre ... best_metric -5090.34øre (improves)
Expected behavior
When the discharge rate limit forces some export volume outside the primary high-price window, Predbat should fill that overflow from the highest-priced unused adjacent hours first (here: 100.80øre, then 92.28øre) before considering any cheaper hour further away.
Actual behavior
The plan leaves two better-priced hours (92.28øre, 100.80øre) completely unused and instead discharges at a worse price (78.88øre) two hours earlier to make up the shortfall.
predbat (5).log
predbat_debug.yaml (1).txt
predbat_plan (1).html
Description
When the battery needs more capacity than the discharge rate can deliver within the best-priced export window, Predbat pulls the extra discharge from a much cheaper, non-adjacent hour instead of from the better-priced hours immediately next to the main window. This leaves higher-priced hours completely unused while discharging at a worse price further away in time.
Environment
Predbat version: v8.45.3
Inverter: Kostal (soc_max 42.53 kWh, discharge rate 10.8 kW)
Relevant config: combine_rate_threshold(2.0), metric_min_improvement_export(3.0øre), metric_min_improvement_export_freeze(3.0øre), metric_battery_cycle(4-6øre/kWh), inverter_loss(5%), battery_loss(4%), battery_loss_discharge(4%), inverter_hybrid(True)
Evidence
Plan computed 2026-07-18 19:03:29, Export windows filtered:
18-07 19:50:00 - 18-07 20:00:00 @ 78.88øre -> target 91%
18-07 20:00:00 - 18-07 21:00:00 @ 92.28øre -> (not present, target stays 91%)
18-07 21:00:00 - 18-07 22:00:00 @ 100.80øre -> (not present, target stays 91%)
18-07 22:00:00 - 19-07 01:00:00 @ 104.01øre -> target 9%
So the battery is planned to discharge from 91% down to 9% (82 percentage points ≈ 34.9 kWh of a 42.53 kWh battery) entirely within the 22:00-01:00 (~104øre) window, while the 92.28øre (20:00-21:00) and 100.80øre (21:00-22:00) hours in between are left completely untouched (SoC held flat), and a small early discharge is instead taken at 78.88øre (19:50-20:00) — the worst price of the four candidate hours.
Analysis
The discharge rate is 10.8 kW, so the 3-hour window (22:00-01:00) can deliver at most 3 × 10.8 = 32.4 kWh — less than the 34.9 kWh the plan wants to move in that window. So it makes sense that some discharge has to happen outside the main window due to the power limit.
However, if extra time is needed, it should be taken from the best available adjacent price first (100.80øre @ 21:00, then 92.28øre @ 20:00) before resorting to a cheaper, more distant hour. Instead the plan skips both of those and discharges at 78.88øre, which is worse than both of the skipped hours. This looks like the price-level sweep in the optimiser (Optimise price set X, pass normal/trim/low) accepts a lower price threshold that happens to improve the metric, without checking whether an already-available higher-priced adjacent hour would have covered the same shortfall more cheaply.
Internal trace showing the threshold being accepted:
2026-07-18 19:03:25.362214: Optimise price set 92.2øre, pass normal, price 92.28øre ... best_metric -5023.92øre (no improvement)
2026-07-18 19:03:25.393257: Optimise price set 78.8øre, pass normal, price 78.88øre ... best_metric -5090.34øre (improves)
Expected behavior
When the discharge rate limit forces some export volume outside the primary high-price window, Predbat should fill that overflow from the highest-priced unused adjacent hours first (here: 100.80øre, then 92.28øre) before considering any cheaper hour further away.
Actual behavior
The plan leaves two better-priced hours (92.28øre, 100.80øre) completely unused and instead discharges at a worse price (78.88øre) two hours earlier to make up the shortfall.
predbat (5).log
predbat_debug.yaml (1).txt
predbat_plan (1).html