TEDAPI bearer authentication mode (#359) — a new authentication transport that reaches the Gateway over its wired LAN IP, no WiFi static route required. Powerwall(..., tedapi_auth_mode="bearer") logs in with the installer credentials (the full gateway password from the QR sticker), obtains a Bearer token, and wraps every TEDAPI query in a protobuf AuthEnvelope. Hardware-verified on PW2 and solar-only inverters; not supported on Powerwall 3 — for PW3 wired access use v1r mode (rsa_key_path).
Changes
- feat(tedapi): new
bearerauthentication mode — logs in viaPOST /api/login/Basicwith the installer credentials to obtain a Bearer token, then wraps every TEDAPI query in a protobufAuthEnvelope(externalAuth.type = PRESENCE). Unlikebasic(HTTP Basic Auth, only reachable over the Gateway's Wi-Fi), bearer also works over the Gateway's wired LAN IPPowerwall(..., tedapi_auth_mode="basic")— new constructor parameter;"basic"(default) keeps existing HTTP Basic behavior,"bearer"selects the new transport. Forwarded throughPyPowerwallTEDAPItoTEDAPI(auth_mode=...)- New
AuthModestr-enum (pypowerwall/tedapi/auth_mode.py) withcoerce()— an unrecognized mode raisesValueError(never silently selects a different transport); env-var callers passdefault=for a logged warning + fallback - TEDAPI CLI: new
--auth-mode basic|bearerflag (python -m pypowerwall.tedapi <gw_pwd> --auth-mode bearer) - An expired or rejected token triggers a single transparent re-login and retry;
api_logoutnow invalidates the bearer session (best-effort) andapi_login_basicdelegates to the bearer login — both were previously mock stubs
- V2026_06 coupling: pair
tedapi_auth_mode="bearer"withtedapi_api_version="V2026_06"(minimum, not exact match).bearer+V2024_06logs a warning but does not fail — existing setups keep working while the likely misconfiguration is surfaced.bearer+ v1r raisesValueError(incompatible transports) - fix(tedapi):
get_firmware_version()/_get_system_info()now parse correctly underV2026_06+ bearer — the bearer transport (like v1r) hands back a bareMessageEnvelope, not the fullMessagewrapper; envelope-class choice and unwrap now follow the same bare/full test - feat(proxy): new
PW_TEDAPI_AUTH_MODE=basic|bearerenv var (defaultbasic); applies to full TEDAPI mode. An unrecognized value warns and falls back tobasic— a typo in a container env var shouldn't surface as a fatal connection error and a restart loop. Active auth mode reported in/statsand/health - tests: new
test_bearer_auth.py(55 tests —AuthMode.coercepaths, login/logout, envelope wrap/unwrap, re-login on expiry, V2026_06 coupling, v1r incompatibility) andtest_bearer_wiring.py(22 tests — parameter plumbing and the CLI flag);test_api_version.pyextended (+21); new proxytest_tedapi_auth_mode.py(7 tests) — merged tree: 483 passed, 10 skipped - fix(tests):
Powerwallfixtures intest_powerwall_core.py/test_cloud_regressions.pynow patch the cloud backend by name — a cached.pypowerwall.authin the working directory no longer sends tests to the real Tesla auth endpoint - docs: README (
tedapi_auth_mode), proxy README (PW_TEDAPI_AUTH_MODE), and theserver.pyheader gain a TEDAPI Mode section
Proxy (t100)
- Legacy proxy image:
jasonacox/pypowerwall:0.17.0t100(also taggedlatest) — carries this release's library changes, includingPW_TEDAPI_AUTH_MODE. The proxy is in maintenance mode (#368); new feature development has moved to pypowerwall-server
Follow-ups
- #370 — AuthEnvelope type-pun clarity refactor
- #371 —
get_configtransport dedup - #373 — surface the bearer/v1r mutual-exclusion
ValueErrorthrough the facade fallback chain
Full Changelog: v0.16.5...v0.17.0
Contributors
Thanks to the community members who made this release possible:
- @Nexarian — authored the bearer auth mode (#359): designed the
AuthModetransport andAuthEnvelopewrapping, worked through every review round (envelope-parse fix, credential handling, presence-mode removal), hardware-verified on solar-only inverters (fw 26.18.3), and filed the follow-up cleanups #370 / #371 / #373 - @F1p — hardware-tested the presence/toggle flow against a real Powerwall 3 and surfaced the 404s that established it as a Gateway 1/2-only feature — the negative result that correctly scoped bearer mode to PW2/inverters and kept PW3 on v1r
- @jasonacox — the seven-point review that shaped the final design (installer-scope flag, credential hygiene, test bar), merge-conflict resolution against #372, and the 0.17.0 version call