v0.17.4 - Powerwall 3 Temperatures and Tesla Remote Meter
- feat(tedapi): Powerwall 3 temperatures are back.
temps()(and the proxy's/tempsand/temps/pw) now report the hottest battery-pack reading per Powerwall 3 and expansion pack; they returned{}on PW3 because the PW2 thermal-controller signal (THC_AmbientTemp) doesn't exist there.vitals()carries the full breakdown in degrees C:HVP_PackTempMax,HVP_PackTempMin, andHVP_ShuntTemperature(plus theBMS_LOG_tempOutOfBounds/BMS_LOG_tempOutOfBoundsChargeover-temperature event counters) on eachTEPOD--…block, and the inverter'sPCH_AmbientTemp(enclosure) andPCH_heatsinkTempon eachTEPINV--…block (Nonewhen unavailable;PCH_heatsinkTempis passed through as delivered but reads a constant 45.45 on current firmware, sotemps()doesn't use it). Hardware-validated on a PW3 leader + follower over WiFi TEDAPI and v1r LAN;/temps/pwPWnnumbering matches/pod. (#390) - feat(tedapi): the signals are requested through the existing signed V2024_06 ComponentsQuery — its signature covers only the query text, and the gateway honors additional
*SignalNamesvariables. NewEXTRA_SIGNAL_NAMESintedapi/queries/__init__.pyappends library-requested signals after the captured ones; the JSON captures are unchanged (see AGENTS.md, "Requesting additional TEDAPI signals"). The V2026_06 query set can't carry extra signals (names are inline in its signed text), so PW3 temperatures need the defaulttedapi_api_version. (#390) - fix(tedapi):
get_pw3_vitals()no longer fails outright when a component entry in the gateway payload is malformed (e.g.None) — the alert collection now guards it, and that battery still reports its energy. (#390) - Additive only: PW2
temps()output is unchanged, and existing vitals fields and component signal positions are preserved. (#390) - feat(tedapi): surface Tesla Remote Meter (wireless CT meter, config.json meter type
trm_mb) data.get_device_controller()'s Device Controller Full query already requestedteslaRemoteMeterand its docstring documented the field, but nothing read it - it was fetched and discarded on every poll. (#386)derive_meter_config()gained atypesfilter parameter (default("neurio_w2_tcp",), unchanged for existing callers) so the same config-driven CT/location/scale-factor lookup used for Neurio also works for remote meters (types=("trm_mb",)).- New
aggregate_remote_meter_data()mirrorsaggregate_neurio_data()but readsteslaRemoteMeter.meters[].reading.ctReadings, also carries theenergyImportedWs/energyExportedWslifetime accumulators, and keys its hierarchy by"{din}:{ct index}"(not just the CT slot) so a second remote meter can't overwrite the first; each entry keeps its ownIndexso consumers map CTs to phases by slot rather than iteration order. - New
get_remote_meter_readings()fetches the Device Controller Full query (remote meter data isn't in the Basic queryget_status()uses) and returns the aggregated CT hierarchy - but only when config.json declares atrm_mbmeter, so installs without one never pay for the extra fetch. vitals()now includes aTRM--<din>block per remote meter, alongside the existingNEURIO--<serial>blocks./api/meters/aggregatessite section: extended the existing Meter X -> Meter Z -> Neurio fallback chain with a Remote Meter tier, reached whenever nothing produced asiteCT (not only when Neurio is entirely absent - a Neurio assigned solely to solar/load no longer blocks the fallback)./api/meters/aggregatessolar section: voltage (PVAC) and current (Meter Y) sources are now independent, each falling back to a Remote Meter configured for thesolarlocation on its own. A remote-metered solar circuit has no Meter Y at all, soi_a_current/i_b_current/i_c_currentused to stay 0 even when PVAC reported voltage and a remote CT was actively reporting current.get_api_meters_aggregates()fetches the remote-meter hierarchy once and shares it between the site and solar extractors instead of each fetching independently.
- tests: new
test_tedapi_remote_meter.py(37 tests) covering the meter-type filter, CT scaling/location/multi-meter hierarchy keys, skipped-CT-slot phase mapping, the config-aware fetch skip, both fallback chains, the shared single-fetch, and thevitals()merge. (#386) - Hardware-validated by the contributor against a Powerwall 3 with a wireless remote CT meter monitoring a solar circuit (#386).
- fix(tedapi): the
@uses_api_lockgetter locks (get_config(),get_status(),get_device_controller(),get_firmware_version(),get_components(),get_battery_block()) were stored on the function object, i.e. one lock per method shared by everyTEDAPIinstance in the process. A server polling several gateways (oneTEDAPIeach) therefore serialized all of them behind whichever gateway's fetch was in flight, and a slow or unreachable gateway starved the others into lock timeouts and stale-cache fallbacks. The locks now live on the instance, keyed by method name (TEDAPI._api_lock()), so gateways never wait on each other; per-method serialization within one gateway is unchanged.acquire_lock_with_backoff()accepts the lock itself in addition to the legacyapi_lock-holder convention;Noneremains a no-op. (#381) - tests:
test_tedapi_cached_fetch.pygainsTestPerInstanceLocks(a held lock on one instance no longer blocks another, per-method/per-instance identity, thread-safe lazy creation, no shared function attribute) andTestAcquireLockWithBackoff(#381) - docs: bearer auth mode is documented as solar-only gateways only — it does not work on Powerwall 2 (hardware-tested) or Powerwall 3. Docstrings, CLI help, README and proxy docs corrected. (#380, #381)
- docs(v1r): corrected key-state semantics: state 2 is
PENDING_VERIFICATION_TIMEOUT(the ~10-minute verification window closed), not a stage between 1 and 3 — re-registering the same key reopens it. Updated physical-proof step: switch the Powerwall 3 On/Off switch OFF for about 15 seconds, then back ON; a quick flick is debounced. README gains a Key States table and a note that some units answer v1r on their home LAN address. Thanks @LAE1990 (#383, #354). - fix(register):
python -m pypowerwall registernow honors-authpath/PW_AUTH_PATH(it silently used the current directory, so re-registering could create a new key instead of reusing the configured one). Key-auth warnings now print the exact command that re-registers the configured key. (#383) - fix(register): the post-proof poll watches for VERIFIED for up to 120 seconds (was ~25 s, shorter than the documented 62 s transition), and a timed-out key (state 2) skips the physical-proof prompt and goes straight to re-register guidance. (#383)
- Library version bumped to
0.17.4
Contributors
Thanks to the community members who made this release possible:
- @dailow (Will Ton) — Tesla Remote Meter (teslaRemoteMeter) support end-to-end, from the
derive_meter_config()types filter through the vitals merge, with 23 tests and live hardware validation on a PW3 with a wireless remote CT (PR #386) - @Nexarian (Christopher Pitstick) — per-instance TEDAPI API locks so multi-gateway pollers don't serialize (PR #381), plus the bearer-auth solar-inverter-only documentation corrections (PR #380)
- @LAE1990 — v1r key-state semantics: correct key state table and physical-proof step in the docs (PR #383)
- @jasonacox — PW3 temperature reporting restored via the EXTRA_SIGNAL_NAMES signed-query extension, hardware-validated on a PW3 leader + follower over WiFi and v1r (PR #390), and the v0.17.4 release engineering (PR #391, #392)