github jasonacox/pypowerwall v0.17.4
v0.17.4 - Powerwall 3 Temperatures and Tesla Remote Meter

latest release: v0.18.0
7 hours ago

v0.17.4 - Powerwall 3 Temperatures and Tesla Remote Meter

  • feat(tedapi): Powerwall 3 temperatures are back. temps() (and the proxy's /temps and /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, and HVP_ShuntTemperature (plus the BMS_LOG_tempOutOfBounds / BMS_LOG_tempOutOfBoundsCharge over-temperature event counters) on each TEPOD--… block, and the inverter's PCH_AmbientTemp (enclosure) and PCH_heatsinkTemp on each TEPINV--… block (None when unavailable; PCH_heatsinkTemp is passed through as delivered but reads a constant 45.45 on current firmware, so temps() doesn't use it). Hardware-validated on a PW3 leader + follower over WiFi TEDAPI and v1r LAN; /temps/pw PWn numbering 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 *SignalNames variables. New EXTRA_SIGNAL_NAMES in tedapi/queries/__init__.py appends 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 default tedapi_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 requested teslaRemoteMeter and its docstring documented the field, but nothing read it - it was fetched and discarded on every poll. (#386)
    • derive_meter_config() gained a types filter 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() mirrors aggregate_neurio_data() but reads teslaRemoteMeter.meters[].reading.ctReadings, also carries the energyImportedWs/energyExportedWs lifetime 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 own Index so 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 query get_status() uses) and returns the aggregated CT hierarchy - but only when config.json declares a trm_mb meter, so installs without one never pay for the extra fetch.
    • vitals() now includes a TRM--<din> block per remote meter, alongside the existing NEURIO--<serial> blocks.
    • /api/meters/aggregates site section: extended the existing Meter X -> Meter Z -> Neurio fallback chain with a Remote Meter tier, reached whenever nothing produced a site CT (not only when Neurio is entirely absent - a Neurio assigned solely to solar/load no longer blocks the fallback).
    • /api/meters/aggregates solar section: voltage (PVAC) and current (Meter Y) sources are now independent, each falling back to a Remote Meter configured for the solar location on its own. A remote-metered solar circuit has no Meter Y at all, so i_a_current/i_b_current/i_c_current used 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 the vitals() 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_lock getter 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 every TEDAPI instance in the process. A server polling several gateways (one TEDAPI each) 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 legacy api_lock-holder convention; None remains a no-op. (#381)
  • tests: test_tedapi_cached_fetch.py gains TestPerInstanceLocks (a held lock on one instance no longer blocks another, per-method/per-instance identity, thread-safe lazy creation, no shared function attribute) and TestAcquireLockWithBackoff (#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 register now 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)

Don't miss a new pypowerwall release

NewReleases is sending notifications on new releases.