Describe the bug
teslemetry.py's handoff to Tesla's own Time-Based Control (TBC) engine gives it no reason to export early within a committed discharge window, and in a live capture this let a Powerwall sit almost completely idle for most of a ~2.5 hour export window before dumping most of the discharge in the last ~30 minutes — after Predbat had already correctly and continuously asserted a fully permissive device state the whole time.
Unlike every other supported inverter, Predbat never sends the Powerwall a live "stop now" command — inverter.py::adjust_force_export always writes the hardware discharge-target register as self.reserve_percent (the absolute physical minimum reserve), not the plan's live/shrinking export target. That's correct by design for inverters where Predbat's own 5-minute loop is the real-time enforcement (it flips force_export off itself the instant SoC crosses the live plan target). Tesla Powerwall has no equivalent "stop discharging now" API — teslemetry.py can only set operation_mode + backup_reserve + a synthetic TOU tariff (build_tariff / _carve_interval), and then Tesla's own onboard optimizer decides in real time how to spend the discharge budget across whatever window it was given.
_carve_interval/build_tariff prices the entire committed discharge window as a single flat ON_PEAK band. There is no time-varying incentive inside the window, so exporting at the start of the window and exporting at the end are equally "optimal" from Tesla's own cost-minimising point of view — nothing in the signal discourages its optimizer from procrastinating.
Captured timeline (relative to when Predbat committed the discharge window; all writes below returned HTTP 200 / Operation mode updated):
T+0:00 Discharge window committed (later extended once, still same day).
Asserted to device: operation_mode=autonomous, backup_reserve=4%
(the configured hardware minimum), grid export=battery_ok.
T+0:00 → T+2:25
No further commands sent — correct, nothing Predbat-side had
changed (dedup on write-on-change). Powerwall battery power
stayed ~0 kW the entire time, aside from two ~5-minute blips
of 1.3–1.6 kW roughly a third of the way through.
T+2:30 Powerwall begins discharging at its full ~5 kW rate for the
first time.
T+3:00 Discharge stops abruptly as the (by-then-extended) window
closes. SoC had only fallen from ~100% to ~69% — nowhere
near the 4% floor Predbat had asserted (and left unchanged)
throughout.
Predbat's own logs/config were correct and stable for the entire window — this isn't a mode-flapping or wrong-command bug like #4165, and optimization_strategy=economics / the day-of-week mapping are already correctly applied (#4600, #4610 are fixed and present). The problem is purely that a uniformly-priced window leaves Tesla's own TBC free to defer almost all of the export to the very end, so a wide, flat-priced window converts into only a fraction of its intended export.
Expected behaviour
The synthetic tariff Predbat pushes for a committed discharge window should give Tesla's own optimizer an actual incentive to act early in the window rather than at its own discretion near the end — e.g. front-load/decline the boost price across the window, or split it into several narrower priced sub-slots — so a wide export opportunity doesn't collapse into a last-minute partial discharge.
Predbat version
v8.54.2
Environment details
- Tesla Powerwall (13.5 kWh class), Teslemetry/Fleet API integration (
inverter_type: TESLA, teslemetry_automatic)
- Octopus-style time-of-day export tariff with a multi-hour high-price window
Log file & apps.yaml
Not attached to keep this report anonymised — I can provide a sanitised log excerpt covering the window above on request. Happy to point at specific line numbers in teslemetry.py/execute.py/inverter.py if useful for triage.
Describe the bug
teslemetry.py's handoff to Tesla's own Time-Based Control (TBC) engine gives it no reason to export early within a committed discharge window, and in a live capture this let a Powerwall sit almost completely idle for most of a ~2.5 hour export window before dumping most of the discharge in the last ~30 minutes — after Predbat had already correctly and continuously asserted a fully permissive device state the whole time.Unlike every other supported inverter, Predbat never sends the Powerwall a live "stop now" command —
inverter.py::adjust_force_exportalways writes the hardware discharge-target register asself.reserve_percent(the absolute physical minimum reserve), not the plan's live/shrinking export target. That's correct by design for inverters where Predbat's own 5-minute loop is the real-time enforcement (it flipsforce_exportoff itself the instant SoC crosses the live plan target). Tesla Powerwall has no equivalent "stop discharging now" API —teslemetry.pycan only setoperation_mode+backup_reserve+ a synthetic TOU tariff (build_tariff/_carve_interval), and then Tesla's own onboard optimizer decides in real time how to spend the discharge budget across whatever window it was given._carve_interval/build_tariffprices the entire committed discharge window as a single flatON_PEAKband. There is no time-varying incentive inside the window, so exporting at the start of the window and exporting at the end are equally "optimal" from Tesla's own cost-minimising point of view — nothing in the signal discourages its optimizer from procrastinating.Captured timeline (relative to when Predbat committed the discharge window; all writes below returned HTTP 200 /
Operation mode updated):Predbat's own logs/config were correct and stable for the entire window — this isn't a mode-flapping or wrong-command bug like #4165, and
optimization_strategy=economics/ the day-of-week mapping are already correctly applied (#4600, #4610 are fixed and present). The problem is purely that a uniformly-priced window leaves Tesla's own TBC free to defer almost all of the export to the very end, so a wide, flat-priced window converts into only a fraction of its intended export.Expected behaviour
The synthetic tariff Predbat pushes for a committed discharge window should give Tesla's own optimizer an actual incentive to act early in the window rather than at its own discretion near the end — e.g. front-load/decline the boost price across the window, or split it into several narrower priced sub-slots — so a wide export opportunity doesn't collapse into a last-minute partial discharge.
Predbat version
v8.54.2
Environment details
inverter_type: TESLA,teslemetry_automatic)Log file & apps.yaml
Not attached to keep this report anonymised — I can provide a sanitised log excerpt covering the window above on request. Happy to point at specific line numbers in
teslemetry.py/execute.py/inverter.pyif useful for triage.