Skip to content

Fix Tesla/Powerwall data handling and improve robustness of control loop#3232

Open
NicoP-codeing wants to merge 2 commits intoopenWB:masterfrom
NicoP-codeing:master
Open

Fix Tesla/Powerwall data handling and improve robustness of control loop#3232
NicoP-codeing wants to merge 2 commits intoopenWB:masterfrom
NicoP-codeing:master

Conversation

@NicoP-codeing
Copy link
Copy Markdown

see also OpenWB Forum entry: https://forum.openwb.de/viewtopic.php?t=11634

Problem
Tesla/Powerwall sometimes provides unusable or inconsistent per-phase energy values.
/api/status is not critical for the control loop, but currently can still affect it.
Missing current values from Tesla/Neurio result in incomplete data, causing load management to fail.
Critical HTTP errors currently do not stop the Tesla cycle, which can lead to cascading issues.

Changes
Restored aggregate-based import/export counters (site-level data)
Per-phase energy is now used for diagnostic purposes only
Reduced /api/status usage and marked it as non-critical
Added fallback calculation for currents and power factor from P/Q/U
Implemented fail-fast behavior for critical requests
Added additional diagnostics and session logging

Motivation / Background
The main goal of this change is to restore reliable load management by using per-phase values for current-related calculations and diagnostics while keeping consistent aggregate site import/export counters.

Additional improvements were made to increase robustness and observability of the Tesla/Powerwall integration, especially in cases of incomplete data or intermittent API issues.

Testing
Tested with a real Tesla Powerwall setup
Verified that load management works reliably again
Checked that import/export counters are consistent and plausible
Simulated missing current values → fallback calculation works
Simulated API timeouts → control loop continues without cascading failures

…d gateway diagnostics

- add structured HTTP error handling in PowerwallHttpClient
  - distinguish transport, HTTP and JSON parsing failures
  - support fail_fast=False for non-critical requests
  - track cycle_failed and cookie_renewed state across one polling cycle

- add fail-fast handling in device.py
  - stop remaining Tesla component updates once a critical Powerwall request fails
  - log native TCP connection state diagnostics via /proc/net/tcp(/tcp6)
  - emit periodic session / connection health logs
  - keep cookie reuse, but mark startup + reauth cycles explicitly

- reduce /api/status traffic in counter.py
  - fetch firmware only after startup or after a new auth cookie was negotiated
  - treat /api/status as non-critical so it cannot fail the whole cycle

- keep import/export counters based on aggregate["site"]["energy_imported/exported"]
  - do not use summed per-phase energy counters as meter source
  - keep /api/meters/site for phase details only
  - add derived fallback currents and signed power factors from P/Q/U when Tesla/Neurio currents are 0
  - expose additional diagnostics such as frequency / serial number
  - add throttled debug logging to compare aggregate counters with per-phase sums
  - restore aggregate-based site counters so load management works correctly again
Copy link
Copy Markdown
Contributor

@LKuemmel LKuemmel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leider bläht dein PR den Code ganz schon auf. Von 154 Zeilen für die drei Python-Dateien auf 565.
Einige Punkte sind zentral gelöst, andere sind für den Entwickler des Moduls interressant, müssen aber nicht dauerhaft im Code enthalten sein.
Wichtig ist, dass der Code wartbar und verständlich bleibt. Gibt es konkrete Probleme mit der Powerwall, die du mit deinem PR lösen willst?

Comment on lines +167 to +176
# If all API currents are 0 -> use calculated currents
if all(self._nearly_zero(i) for i in api_currents):
currents = calculated_currents
log.debug(
"Tesla/Neurio phase currents missing (all 0). Calculated currents from P/Q and U."
)
else:
currents = api_currents
# PF still useful even if currents exist
log.debug("Using phase currents from Tesla/Neurio API.")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wenn es Modelle gibt, die keine Ströme liefern, dann dürfen diese im CounterState nicht gesetzt werden. Dann werden sie automatisch gesetzt.

def _nearly_zero(x: float, eps: float = 1e-9) -> bool:
return abs(x) < eps

def _calc_currents_and_pf_from_pqu(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diese Berechnung erfolgt zentral im CounterState, wenn keine Ströme gesetzt sind, aber Phasenspannungen und Phasenleistungen vorhanden sind. Die Berechnung soll nicht in jedem Modul erfolgen.

self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))

@staticmethod
def _safe_float(val, default: float = 0.0) -> float:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default Werte werden zentral im CounterState gesetzt, damit sie konsistent sind.


# --- throttled diagnostics (1x per hour) ---
# Log aggregate vs. per-phase sums to spot counter mismatches without affecting behaviour.
now = time.time()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am Freitag wurde ein Peak-Filter gemergt, ein separates Logging der Peaks ist nicht nötig.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants