github jasonacox/pypowerwall v0.22.0
v0.22.0 - Local Battery Dispatch, Signed Wi-Fi v1r Failover, Instantaneous Power Limits and FleetAPI 429 Fix

4 hours ago
  • feat(v1r): local timed battery dispatch. Powerwall.dispatch_battery_power(power_watts, duration_seconds) sets battery power for 1-86400 seconds (positive watts discharge, negative charge) and resume_battery_operation() releases it early; the gateway returns to its configured mode when the duration ends. Both use the signed v1r transport (TEG fields 37/38) and write no gateway configuration. Inputs are validated before any I/O, a result is returned only with the gateway's matching acknowledgement, rejections are logged with their status code, and the battery-power samples (status, controller, PW3 vitals) are cleared after an accepted command. A dispatch overrides the backup reserve and the export setting: on a Powerwall 2 (Backup Gateway 1, firmware 26.34.0) a discharge with the reserve at 100% and export set to pv_only/never still ran, exported the excess and raised BackfeedLimited/BatteryUnexpectedPower alerts. Validated on Powerwall 3 over v1r LAN, on one unit (firmware 26.26.4) and on 2x Powerwall 3 (firmware 26.26.11): discharge, 0 W, resume, expiry, the 10,000 W discharge limit (status code 11), and charging from the grid with grid charging enabled (−1000 W). Thanks @longzheng, tested by @BJReplay and @jasonacox-sam; protobuf schema documented by Teslemetry/tesla-protocol (#440, #437).

  • feat(tedapi): Powerwall 2 instantaneous battery power limits. /api/system_status instantaneous_max_charge_power / instantaneous_max_discharge_power (hard-coded 0) are now the sums of the msa TEPOD components' POD_available_charge_power / POD_available_dischg_power, matching the local API, and the TEPOD-- vitals blocks carry the same two values. The V2024_06 device-controller request appends TEPOD to its unsigned msaComp type list (new EXTRA_COMPONENT_TYPES; the capture and its signature are unchanged). A sum is reported only when every POD component gives a usable value; otherwise, and under V2026_06, the fields stay 0. Validated on 2x Powerwall 2 (firmware 26.34.1): 14000/15570 W, equal to the local API in the same read. On 2x Powerwall 3 (firmware 26.26.11, Wi-Fi TEDAPI and v1r) nothing changes: the fields stay 0 and vitals, temps and fans are identical. Thanks @erikgieseler, PW3 check by @jasonacox-sam (#429).

  • feat(v1r): opt-in signed Wi-Fi v1r failover. With Powerwall(..., wifi_v1r_fallback=True) and a wifi_host, the leader gets a second signed TEDAPIv1r transport on the gateway's Wi-Fi; once the v1r LAN failover trips, every leader v1r read and write (config, max backup, backup events, islanding, battery dispatch) uses it and never falls back to legacy Wi-Fi TEDAPI. A failed read returns None; writes are gated by a read-only wifi_v1r_ready() probe and never dispatched when it fails, and a dispatched attempt is final. Default False leaves existing behavior unchanged; followers keep the Wi-Fi TEDAPI session. Validated on a Powerwall 2 (firmware 26.34.1) over an ESP32 bridge: failover, live 401 re-login, and reserve writes with readback; a read-only cold-failover check passed on 2x Powerwall 3. Max backup and islanding over Wi-Fi were not exercised on hardware. Thanks @erikgieseler, PW3 check by @jasonacox-sam (#441).

  • feat(fleetapi): new PW_FLEETAPI_HTTP=1.1 setting forces HTTP/1.1 for all FleetAPI requests, an escape hatch for intermittent HTTP/2 connection-reuse errors (COMPRESSION_ERROR, h2 state errors). Reported in the proxy's /stats config (proxy t109) (#436).

  • fix(fleetapi): request storms and 429 cascades in FleetAPI mode. When the cache expired, every proxy poller thread sent its own identical request (1,332 HTTP 429s vs 547 HTTP 200s in a 10-minute EU-site log). Now:

    • concurrent identical GETs share one in-flight request;
    • Tesla's retry guidance (Retry-After seconds or HTTP-date, or "Retry in N seconds" in the body) opens one shared backoff window, during which cache-missing reads return None immediately - nothing ever sleeps in the library;
    • forced reads (re-reads after a write) always send their own request;
    • cache expiry is jittered so endpoints don't all expire together.

    The reporter's 10-minute run showed zero 429s at default settings. Thanks @jasonacox-sam, reported and field-tested by @VivLloyd (#436, #433).

  • fix(proxy): /stats, /help and the power-flow page no longer show the account email, Tesla site ID or file paths (shipped in proxy t108) (#431).

  • docs(v1r): README and API.md warn that a battery dispatch overrides the backup reserve and the export setting, from @BJReplay's Powerwall 2 run, and record the Powerwall 3 results (#440, #442).

  • tests: new test_v1r_dispatch.py (wire format, validation, acknowledgement, cache) and test_fleetapi_thundering_herd.py (coalescing, backoff, cache recheck, follower deadline, forced reads); test_v1r_wifi_fallback.py covers the signed Wi-Fi routing, the write gate and LAN recovery mid-call; test_pw2_msa_signals.py and test_tedapi_regressions.py cover the TEPOD request and the instantaneous sums (#440, #441, #436, #429).

  • ci: checks work on GitHub's Ubuntu 26.04 runners. The Python 3.9 jobs run on ubuntu-24.04 (3.9 has no 26.04 build; requires-python >= 3.9 is unchanged), the simulator readiness check reads the HTTP status, the simulator (v0.2.6) sends TLS close_notify, and jasonacox/pwsimulator:latest is published only from main (#435).

  • Library version bumped to 0.22.0

⚠️ Dispatch safety note: a battery dispatch overrides the backup reserve and the export setting — on a Powerwall 2 (Backup Gateway 1, firmware 26.34.0) a discharge with the reserve at 100% and export set to pv_only/never still ran and exported the excess, raising BackfeedLimited/BatteryUnexpectedPower alerts (@BJReplay's run). See the README and API.md warnings.

Proxy Docker image: jasonacox/pypowerwall:0.22.1t109 (also latest) — there is no separate 0.22.0 image; t109 contains everything from both releases.

Install: pip install --upgrade pypowerwall==0.22.1


Contributors

This release is a community release, through and through. Every headline feature came from someone who saw what the project could do next and then put in the work to build it, test it on real hardware and refine it through review. Thank you all!

  • @longzheng: local timed battery dispatch (#440). It's a capability people have wanted for a long time, built carefully on the signed v1r transport with thorough validation and tests. Long also ran the Powerwall 3 dispatch tests. Thank you!
  • @erikgieseler: Powerwall 2 instantaneous power limits (#429) and the signed Wi-Fi v1r failover (#441). Erik built an ESP32 bridge to validate them on real hardware and worked through a long review with patience and care. Thank you, Erik!
  • @jasonacox-sam: found and fixed the FleetAPI 429 request storm (#436), and ran the PW3 hardware checks on #429, #441 and #442 that gave us the confidence to ship. I'm proud of you, Sam!
  • @BJReplay: careful Powerwall 2 dispatch testing that found the reserve and export override. That finding keeps everyone safer, and it shaped the warnings in this release.
  • @VivLloyd: reported #433 with excellent logs and field-tested the FleetAPI fix on a live EU site. That's exactly the kind of report that gets things fixed.
  • Teslemetry/tesla-protocol: protobuf schema documentation that made dispatch possible.
  • @jasonacox: proxy /stats redaction (#431, #432), CI on Ubuntu 26.04 runners (#435), dispatch docs and release (#442).

If you have an idea, a bug report or a Powerwall to test on, please join us. This project grows because of people like you.

Don't miss a new pypowerwall release

NewReleases is sending notifications on new releases.